Wow, that works like a charm! Thank you, Max! 

It's also a very insightful example of how to use and inject Lua code in the 
TeX output routine. Do you mind if I add it to the wiki? (Probably under 
"Wrapping".)

Many thanks again!


Benjamin

> On Jun 24, 2022, at 01:44, Max Chernoff <mse...@telus.net> wrote:
> 
>> 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