I've been confronted with the following 'intriguing' formatting requirement for 
a document:

"Intriguing" is definitely right here. I suspect these guidelines were made for typewriters and haven't been updated since.

to limit the number of glyphs per line to 112.

112 characters per line sounds much too long anyways.

From "The Elements of Typographic Style":
> Anything from 45 to 75 characters is widely regarded as a satisfactory
> length of line for a single-column page set in a serifed text face
> in a text size. The 66-character line (counting both letters and
> spaces) is widely regarded as ideal. For multiple-column work, a
> better average is 40 to 50 characters.
>
> If the type is well set and printed, lines of 85 or 90 characters
> will pose no problem in discontinuous texts, such as bibliographies,
> or, with generous leading, in footnotes. But even with generous
> leading, a line that averages more than 75 or so characters is likely
> to be too long for continuous reading.

If you use something like

    \setuplayout[width=80\averagecharwidth]

then your lines will for sure have fewer than 112 characters and will probably be more readable too.

I'm nevertheless curious if there is a Lua/TeX solution to this "problem"?

Option 1: Use a monospaced font. Then 112 characters per line <=> page width = 112em.

Option 2: A hacky Lua solution

    \startluacode
        local max_length = 112

        local glyph_id = node.id "glyph"
        local disc_id = node.id "disc"
        local glue_id = node.id "glue"

        function userdata.limiter(head)
            language.hyphenate(head)

            local chars = 0
            local width = 0
            local n = head
            while n do
                if n.id == glyph_id or n.id == glue_id then
                    chars = chars + 1
                    width = width + n.width - (n.shrink or 0)
                end

                if chars >= max_length or width > tex.hsize then
                    local back_chars = 0
                    local end_disc = nil

                    while n do
                        if n.id == glue_id then
                            local penalty = node.new "penalty"
                            penalty.penalty = -10000
                            node.insertbefore(head, n, penalty)
                            break
                        end

                        if not end_disc and n.id == disc_id then
                            end_disc = n
                        end

                        if end_disc and back_chars >= 5 then
                            end_disc.penalty = -10000
                            break
                        end

                        if n.id == glyph_id then
                            back_chars = back_chars + 1
                        end

                        n = n.prev
                    end

                    width = 0
                    chars = 0
                end

                n = n.next
            end

            return head
        end

        nodes.tasks.appendaction(
            "processors",
            "before",
            "userdata.limiter"
        )
    \stopluacode

    \setuppapersize[landscape,letter]
    \showframe

    \starttext
        \setupalign[flushleft]

        \setupbodyfont[14pt]
        \samplefile{knuth}

        \setupbodyfont[12pt]
        \samplefile{knuth}

        \setupbodyfont[10pt]
        \samplefile{knuth}

        \page
        \setupalign[normal]

        \setupbodyfont[14pt]
        \samplefile{knuth}

        \setupbodyfont[12pt]
        \samplefile{knuth}

        \setupbodyfont[10pt]
        \samplefile{knuth}
    \stoptext

This code will ensure that no line ever exceeds "max_length" characters. It uses a greedy algorithm instead of the standard TeX algorithm for line breaking, but it still produces mostly decent results.

-- Max
___________________________________________________________________________________
If your question is of interest to others as well, please add an entry to the 
Wiki!

maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
webpage  : http://www.pragma-ade.nl / http://context.aanhet.net
archive  : https://bitbucket.org/phg/context-mirror/commits/
wiki     : http://contextgarden.net
___________________________________________________________________________________

Reply via email to