Where to enforce paragraph-cohesion policy in text system?

  • My goal is to impose a policy in my series of text containers, such
    that a paragraph is never split across two containers. Because I have
    very small paragarphs (clues of a crossword puzzle), it makes sense to
    leave a blank space at the bottom of one container (a column) than it
    does to break the paragraph across two columns.

    I'm trying to figure out the most appropriate place to impose this
    kind of policy. I'm intrigued by NSTypesetter because it seems to be
    where the action of determining line fragment rectangles happens.
    Should I be subclassing NSTypesetter and somehow causing it to avoid
    seeking to fill a container with line fragments, if it won't succeed
    in filling an entire paragraph?

    I'm a little intrigued by NSLayoutManager's
    textContainerForGlyphAtIndex:effectiveRange:withoutAdditionalLayout,
    but I suspect I won't really know until it's too late that a paragraph
    didn't fit in the container. By then it seems complicated to undo the
    previously laid out line fragments.

    Is it possible I'm overlooking an easy solution to this problem? If
    not, what would be a good strategy to implement my own general solution?

    Daniel
  • You might want to look into NSTextBlock.  I believe they are tied to
    one text container at a time and therefore move to the next container
    as a block instead of line by line.  You access the text block
    through NSMutableParagraphStyle's setTextBlocks: method.  You could
    also look into the NSTextTable class which uses a sub-class of
    NSTextBlock for its cells.  I haven't done this myself though, so I
    could very well be wrong on this one.
    ->Ben

    --
    Ben Lachman
    Acacia Tree Software

    http://acaciatreesoftware.com

    <blachman...>
    740.590.0009

    On Feb 17, 2008, at 8:03 PM, Daniel Jalkut wrote:

    >
    > My goal is to impose a policy in my series of text containers, such
    > that a paragraph is never split across two containers. Because I
    > have very small paragarphs (clues of a crossword puzzle), it makes
    > sense to leave a blank space at the bottom of one container (a
    > column) than it does to break the paragraph across two columns.
    >
    > I'm trying to figure out the most appropriate place to impose this
    > kind of policy. I'm intrigued by NSTypesetter because it seems to
    > be where the action of determining line fragment rectangles
    > happens. Should I be subclassing NSTypesetter and somehow causing
    > it to avoid seeking to fill a container with line fragments, if it
    > won't succeed in filling an entire paragraph?
    >
    > I'm a little intrigued by NSLayoutManager's
    > textContainerForGlyphAtIndex:effectiveRange:withoutAdditionalLayout, b
    > ut I suspect I won't really know until it's too late that a
    > paragraph didn't fit in the container. By then it seems complicated
    > to undo the previously laid out line fragments.
    >
    > Is it possible I'm overlooking an easy solution to this problem? If
    > not, what would be a good strategy to implement my own general
    > solution?
  • Oh, nice lead! Thanks. I hadn't come across that class yet. I will
    poke around.

    Daniel

    On Feb 17, 2008, at 10:05 PM, Ben Lachman wrote:

    > You might want to look into NSTextBlock.  I believe they are tied to
    > one text container at a time and therefore move to the next
    > container as a block instead of line by line.  You access the text
    > block through NSMutableParagraphStyle's setTextBlocks: method.  You
    > could also look into the NSTextTable class which uses a sub-class of
    > NSTextBlock for its cells.  I haven't done this myself though, so I
    > could very well be wrong on this one.
    > ->Ben
    >
    > --
    > Ben Lachman
    > Acacia Tree Software
    >
    > http://acaciatreesoftware.com
    >
    > <blachman...>
    > 740.590.0009
    >
    >
    >
    > On Feb 17, 2008, at 8:03 PM, Daniel Jalkut wrote:
    >
    >>
    >> My goal is to impose a policy in my series of text containers, such
    >> that a paragraph is never split across two containers. Because I
    >> have very small paragarphs (clues of a crossword puzzle), it makes
    >> sense to leave a blank space at the bottom of one container (a
    >> column) than it does to break the paragraph across two columns.
    >>
    >> I'm trying to figure out the most appropriate place to impose this
    >> kind of policy. I'm intrigued by NSTypesetter because it seems to
    >> be where the action of determining line fragment rectangles
    >> happens. Should I be subclassing NSTypesetter and somehow causing
    >> it to avoid seeking to fill a container with line fragments, if it
    >> won't succeed in filling an entire paragraph?
    >>
    >> I'm a little intrigued by NSLayoutManager's
    >> textContainerForGlyphAtIndex:effectiveRange:withoutAdditionalLayout
    >> , but I suspect I won't really know until it's too late that a
    >> paragraph didn't fit in the container. By then it seems complicated
    >> to undo the previously laid out line fragments.
    >>
    >> Is it possible I'm overlooking an easy solution to this problem? If
    >> not, what would be a good strategy to implement my own general
    >> solution?
  • On Feb 17, 2008, at 5:03 PM, Daniel Jalkut wrote:

    > I'm trying to figure out the most appropriate place to impose this
    > kind of policy. I'm intrigued by NSTypesetter because it seems to be
    > where the action of determining line fragment rectangles happens.
    > Should I be subclassing NSTypesetter and somehow causing it to avoid
    > seeking to fill a container with line fragments, if it won't succeed
    > in filling an entire paragraph?

    NSTypesetter would be the appropriate place for this sort of policy,
    since it is responsible for actually laying out the lines of text.
    Bear in mind, though, that the typesetter won't know that a paragraph
    doesn't fit until it has laid out some of the lines and discovered
    that it has run out of space before the end of the paragraph.
    NSTypesetter gets called to layout a paragraph at once, and then
    queries the text container for each individual line; probably what you
    would need to do would be to subclass NSTypesetter and at some point
    detect that condition, then set some flag indicating that the
    paragraph should be moved to the next container, and restart layout
    from the beginning of the paragraph.  I'm not sure offhand exactly
    where the right override points in NSTypesetter would be.

    The suggestion of using tables/blocks is also a reasonable one, but
    it's not a complete solution to the keep-together issue because the
    editing behavior of table cells/blocks is somewhat different from that
    of ordinary paragraphs.  If you're dealing with non-editable text this
    might be a good solution, but for freely editable text I would tend to
    look at a typesetter-based solution.

    Douglas Davidson
  • Thanks, Douglas. Really appreciate your input.

    On Feb 18, 2008, at 1:55 PM, Douglas Davidson wrote:

    > NSTypesetter would be the appropriate place for this sort of policy,
    > since it is responsible for actually laying out the lines of text.
    > Bear in mind, though, that the typesetter won't know that a
    > paragraph doesn't fit until it has laid out some of the lines and
    > discovered that it has run out of space before the end of the
    > paragraph.  NSTypesetter gets called to layout a paragraph at once,
    > and then queries the text container for each individual line;
    > probably what you would need to do would be to subclass NSTypesetter
    > and at some point detect that condition, then set some flag
    > indicating that the paragraph should be moved to the next container,
    > and restart layout from the beginning of the paragraph.  I'm not
    > sure offhand exactly where the right override points in NSTypesetter
    > would be.
    >
    > The suggestion of using tables/blocks is also a reasonable one, but
    > it's not a complete solution to the keep-together issue because the
    > editing behavior of table cells/blocks is somewhat different from
    > that of ordinary paragraphs.  If you're dealing with non-editable
    > text this might be a good solution, but for freely editable text I
    > would tend to look at a typesetter-based solution.