From: Benjamin Buchmuller via ntg-context <ntg-context@ntg.nl>
To: Max Chernoff <mseven@telus.net>
Cc: Benjamin Buchmuller <benjamin.buchmuller@gmail.com>, ntg-context@ntg.nl
Subject: Re: Count (and limit) glyphs per line?
Date: Sat, 25 Jun 2022 11:38:05 -0400 [thread overview]
Message-ID: <384D9F49-B377-426F-B6FA-483F58945687@gmail.com> (raw)
In-Reply-To: <5a679f35-3c56-b020-79ff-c8b8ac969601@telus.net>
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 <mseven@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
___________________________________________________________________________________
next prev parent reply other threads:[~2022-06-25 15:38 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-06-24 3:15 Benjamin Buchmuller via ntg-context
2022-06-24 5:44 ` Max Chernoff via ntg-context
2022-06-25 15:38 ` Benjamin Buchmuller via ntg-context [this message]
2022-06-25 20:25 ` Benjamin Buchmuller via ntg-context
2022-06-25 21:40 ` Max Chernoff via ntg-context
2022-06-26 15:59 ` Benjamin Buchmuller via ntg-context
2022-06-26 22:32 ` Max Chernoff via ntg-context
2022-06-27 9:33 ` Hans Hagen via ntg-context
2022-07-18 21:24 ` Benjamin Buchmuller via ntg-context
2022-07-26 17:40 ` Hans Hagen via ntg-context
2022-06-26 17:11 ` Hans Hagen via ntg-context
2022-06-26 8:28 ` Hans Hagen via ntg-context
2022-06-24 7:31 ` Henning Hraban Ramm via ntg-context
2022-06-24 17:58 ` Hans Hagen via ntg-context
2022-06-26 19:26 Benjamin Buchmuller via ntg-context
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=384D9F49-B377-426F-B6FA-483F58945687@gmail.com \
--to=ntg-context@ntg.nl \
--cc=benjamin.buchmuller@gmail.com \
--cc=mseven@telus.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).