m-crappyspec.mkxl /size: 6396 b    last modification: 2024-01-16 10:22
1%D \module
2%D   [       file=m-crappyspec,
3%D        version=2022.07.01, % about
4%D          title=\CONTEXT\ Extra Modules,
5%D       subtitle=Meeting weird demands,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14%D This module is for Benjamin Buchmuller who has to meet rather weird demands with
15%D respect to the number of characters per line. So, it's not about quality but more
16%D sort of previous century typewriter specification.
17%D
18%D \setmainparbuilder[crappyspec]
19
20\startluacode
21
22local type = type
23
24local nuts            = nodes.nuts
25
26local glyph_code      = nodes.nodecodes.glyph
27local hlist_code      = nodes.nodecodes.hlist
28local vlist_code      = nodes.nodecodes.vlist
29local disc_code       = nodes.nodecodes.disc
30
31local line_code       = nodes.listcodes.line
32
33local traverselist    = nuts.traverselist
34local traversecontent = nuts.traversecontent
35
36local flushlist       = nuts.flushlist
37local copylist        = nuts.copylist
38local getcharspec     = nuts.getcharspec
39local getreplace      = nuts.getreplace
40local getparstate     = nuts.getparstate
41local getlist         = nuts.getlist
42local getwidth        = nuts.getwidth
43local setwidth        = nuts.setwidth
44
45local texset          = tex.set
46local texsetdimen     = tex.setdimen
47local texgetdimen     = tex.getdimen
48local texgetcount     = tex.getcount
49local texlinebreak    = tex.linebreak
50
51local characters      = fonts.hashes.characters
52
53local function countglyphs(h)
54    local c = 0
55    if h then
56        for n, t, s in traversecontent(h) do
57            if t == glyph_code then
58                if true then
59                    local g, f = getcharspec(n)
60                    local d = characters[f][g] -- maybe cache
61                    local u = d and d.unicode
62                    if type(u) == "table" then
63                       c = c + #u
64                    else
65                       c = c + 1
66                    end
67                else
68                    c = c + 1
69                end
70            elseif t == disc_code then
71                c = c + countglyphs(getreplace(n),c)
72            elseif t == hlist_code or s == vlist_code then
73                c = c + countglyphs(getlist(h),c)
74            else
75                -- leader
76            end
77        end
78    end
79    return c
80end
81
82local function overflow(h, max)
83    for n, t, s in traverselist(h) do
84        if t == hlist_code and s == line_code then
85            local c = countglyphs(getlist(n))
86            if c > max then
87                return c, getwidth(n)
88            end
89        end
90    end
91    return false
92end
93
94function builders.paragraphs.constructors.methods.crappyspec(head)
95    -- todo: prevent useless calls
96    local p = getparstate(head)
97    if p then
98        local hsize = p.hsize
99        local max   = texgetcount("crappyspeccount")
100        local step  = texgetdimen("crappyspecstep")
101        if step <= 65536 then
102            step = 65536
103        end
104        while true do
105            local n = copylist(head)
106            local l, d = texlinebreak(n, { hsize = hsize })
107            local c, w = overflow(l,max)
108            if w and hsize > 10*step then -- safeguard
109                flushlist(l)
110                hsize = hsize - step
111            else
112                texsetdimen("crappyspecdimen",hsize)
113                flushlist(head)
114                head = l
115                local hsize = p.hsize
116                for n, t, s in traverselist(head) do
117                    if t == hlist_code and s == line_code then
118                     -- todo: add delta to rightskip or so
119                        setwidth(n,hsize)
120                    end
121                end
122                texset("prevdepth",d.prevdepth)
123                break
124            end
125        end
126    end
127    return head
128end
129\stopluacode
130
131\newinteger  \crappyspeccount
132\newdimension\crappyspecstep   \crappyspecstep \onepoint
133\newdimension\crappyspecdimen
134
135\defineparbuilder [crappyspec] % implemented in the builder namespace
136\defineparbuilder [default]    % implemented in the builder namespace
137
138\continueifinputfile{m-crappyspec.mkxl}
139
140\setupbodyfont
141  [pagella]
142
143\setuptolerance
144  [verytolerant,stretch]
145
146\showmakeup
147  [line]
148
149\setmainparbuilder
150  [crappyspec]
151
152\dontcomplain
153
154\protected\def\CrappyTraced
155  {\par \strut \rlap \bgroup\infofont
156     (\enspace
157         max   = \the\crappyspeccount \quad
158         step  = \the\crappyspecstep  \quad
159         hsize = \the\hsize           \quad
160         used  = \the\crappyspecdimen \enspace
161     )
162   \egroup \par}
163
164\starttext
165
166\crappyspeccount60  \samplefile{tufte} \CrappyTraced \par
167\crappyspeccount40  \samplefile{tufte} \CrappyTraced \par
168%   \crappyspecstep 2pt \samplefile{tufte} \CrappyTraced \par
169
170\samplefile{tufte} \CrappyTraced
171\startitemize
172    \startitem
173        \samplefile{tufte} \CrappyTraced
174    \stopitem
175    \startitem
176        \samplefile{ward}  \CrappyTraced
177    \stopitem
178\stopitemize
179
180\startnarrower[6*left,right]
181    \samplefile{tufte} \CrappyTraced
182\stopnarrower
183
184\starthanging [distance=4em,n=2] {test}
185    \samplefile{tufte} \CrappyTraced
186\stophanging
187
188\page % \stoptext
189
190\setuppapersize[landscape,letter]
191
192\samplefile{knuth} \CrappyTraced
193\startitemize[width=5em]
194    \startitem
195        \samplefile{knuth} \CrappyTraced
196    \stopitem
197    \startitem
198        {\smallcaps \darkblue \samplefile{knuth}} \CrappyTraced
199    \stopitem
200\stopitemize
201\crappyspeccount60
202\startitemize[width=5em]
203    \startitem
204        \samplefile{knuth} \CrappyTraced
205    \stopitem
206    \startitem
207        {\smallcaps \darkgreen \samplefile{knuth}} \CrappyTraced
208    \stopitem
209\stopitemize
210
211\page
212
213\crappyspecstep  1pt \crappyspeccount 60 % 5.5
214\crappyspecstep  2pt \crappyspeccount 60 % 3.2
215\crappyspecstep  5pt \crappyspeccount 60 % 1.4
216\crappyspecstep 10pt \crappyspeccount 60 % 0.9
217
218\crappyspecstep  1pt \crappyspeccount 80 % 0.8
219\crappyspecstep  2pt \crappyspeccount 80 % 0.8
220\crappyspecstep  5pt \crappyspeccount 80 % 0.8
221\crappyspecstep 10pt \crappyspeccount 80 % 0.6
222
223% \crappyspecstep  1pt \crappyspeccount 120 % 0.25
224% \crappyspecstep  2pt \crappyspeccount 120 % 0.25
225% \crappyspecstep  5pt \crappyspeccount 120 % 0.25
226
227% \testfeatureonce{100}{\samplefile{tufte}\par\CrappyTraced} % \page \elapsedtime
228
229\stoptext
230