node-rul.mkxl /size: 19 Kb    last modification: 2024-01-16 09:03
1%D \module
2%D   [       file=node-rul,
3%D        version=2009.11.03, % 1995.10.10,
4%D          title=\CONTEXT\ Core Macros,
5%D       subtitle=Bars,
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% todo: ex and and em traveling with attribute
15% todo: this will move to typo-rul + ctxcommands
16
17\writestatus{loading}{ConTeXt Core Macros / Bars}
18
19%D \macros
20%D   {underbar,underbars,
21%D    overbar,overbars,
22%D    overstrike,overstrikes,
23%D    setupbar}
24%D
25%D In the rare case that we need undelined words, for instance because all font
26%D alternatives are already in use, one can use \type {\underbar} and \type
27%D {\overstrike} and their plural forms.
28%D
29%D \startbuffer
30%D \underbars {drawing \underbar{bars} under words is a typewriter leftover}
31%D \overstrikes {striking words makes them \overstrike {unreadable} but
32%D sometimes even \overbar {top lines} come into view.}
33%D \stopbuffer
34%D
35%D \typebuffer
36%D
37%D \startlines
38%D \getbuffer
39%D \stoplines
40%D
41%D The formal definitions are:
42%D
43%D \showsetup{underbar}
44%D \showsetup{underbars}
45%D \showsetup{overbar}
46%D \showsetup{overbars}
47%D \showsetup{overstrike}
48%D \showsetup{overstrikes}
49%D
50%D \showsetup{setupbars}
51%D
52%D Units can be any normal \TEX\ unit:
53%D
54%D \startbuffer
55%D \setupbars[unit=mm,rulethickness=1]     bar\startbar[underbar]foo\stopbar bar\blank
56%D \setupbars[unit=ex,rulethickness=1]     bar\startbar[underbar]foo\stopbar bar\blank
57%D \setupbars[unit=pt,rulethickness=1]     bar\startbar[underbar]foo\stopbar bar\blank
58%D \setupbars[unit=pt,rulethickness=10pt]  bar\startbar[underbar]foo\stopbar bar
59%D \stopbuffer
60%D
61%D \typebuffer \blank \getbuffer \blank
62%D
63%D As with many early usage of \LUA\ in \MKIV\ this mechanism explores a way
64%D to deal with local settings at the \TEX\ end and remembering parameters
65%D at the \LUA\ end. We might do things differently now, but as settings normally
66%D don't change that often, we're not in a hurry to do that now. The problem at
67%D the \LUA\ end is that we don't know when to clean up.
68
69\unprotect
70
71%definesystemattribute[ruled]
72%definesystemattribute[shifted]
73
74\newdimension\d_rule_width
75\newdimension\d_rule_height
76\newdimension\d_rule_depth
77\newdimension\d_rule_h
78\newdimension\d_rule_v
79\newdimension\d_rule_line
80\newdimension\d_rule_offset
81\newdimension\d_rule_factor
82
83\mutable\lettonothing\m_rule_direction
84%mutable\lettonothing\m_rule_factor
85\mutable\lettonothing\m_rule_option
86\mutable\lettonothing\m_rule_color
87
88\registerctxluafile{node-rul}{autosuffix}
89
90\installcorenamespace{bar}
91\installcorenamespace{barstack}
92
93\installcommandhandler \??bar {bar} \??bar
94
95\mutable\lettonothing\p_node_color  % of just \p_*
96\mutable\lettonothing\p_node_text
97\mutable\lettonothing\p_node_offset
98
99\aliased\let\setupbars\setupbar
100
101\appendtoks
102    \frozen\protected\instance\edefcsname\currentbar\endcsname{\node_rules_direct{\currentbar}}%
103\to \everydefinebar
104
105% \protected\def\node_rules_direct#1%
106%   {\groupedcommand
107%      {\node_rules_set{#1}\barparameter\c!left}%
108%      {\relax\barparameter\c!right}}
109
110\protected\def\node_rules_direct#1%
111  {\groupedcommand
112     {\dontleavehmode % this should not be needed but it is in \bTD
113      \node_rules_set{#1}%
114      \barparameter\c!left
115      }%\ignorespaces}%
116     {%\removeunwantedspaces
117      \barparameter\c!right}}
118
119\permanent\protected\def\inlinebar[#1]%
120  {\node_rules_direct{#1}}
121
122%D \overbar{Über} \underbar{Unterstrich \underbar{steigt \overbar{auf} den \underbar{Unterberg}}}.
123%D
124%D \underbar {\underbar {\samplefile{tufte}}}\par
125%D \underbar {\underdot {\samplefile{tufte}}}\par
126%D \underbar {\underdot {\samplefile{tufte}}}\par
127%D \underdot {\underbar {\samplefile{tufte}}}\par
128%D \underbars{\underdot {\samplefile{tufte}}}\par
129%D \underbar {\underdots{\samplefile{tufte}}}\par
130%D \underdots{\underdots{\samplefile{tufte}}}\par
131
132\newinteger\c_node_rules_nesting % todo: same as colors
133\newinteger\c_node_rules_level
134\newinteger\c_node_rules_up
135\newinteger\c_node_rules_down
136
137% \permanent\protected\def\node_rules_set#1%
138%   {\cdef\currentbar{#1}%
139%    \advanceby\c_node_rules_level\plusone
140%    \usebarstyleandcolor\c!foregroundstyle\c!foregroundcolor
141%    \edef\p_node_color {\barparameter\c!color}% todo
142%    \edef\p_node_text  {\barparameter\c!text}%
143%    \edef\p_node_offset{\barparameter\c!offset}%
144%    % better is a dedicated key: up/down .. todo
145%    \advanceby\ifdim\p_node_offset\onepoint<\zeropoint\c_node_rules_down\else\c_node_rules_up\fi\plusone
146%    \clf_setrule
147%        continue      {\barparameter\c!continue}%
148%        unit          {\barparameter\c!unit}%
149%        order         {\barparameter\c!order}%
150%        level         \c_node_rules_level
151%        stack         \ifdim\p_node_offset\onepoint<\zeropoint\c_node_rules_down\else\c_node_rules_up\fi
152%        rulethickness {\barparameter\c!rulethickness}%
153%        method        \barparameter\c!method
154%        max           \barparameter\c!max\space % number
155%        mp            {\includeMPgraphic{\barparameter\c!mp}}
156%        ma            \c_attr_colormodel
157%        ca            \rawcolorattribute\p_node_color
158%        ta            \rawtransparencyattribute\p_node_color
159%        offset        \p_node_offset\space % number
160%        dy            \barparameter\c!dy\space % number, also fraction
161%        empty         {\barparameter\c!empty}%
162%      \ifempty\p_node_text\else
163%        text          \hbox{\p_node_text}%
164%        repeat        {\barparameter\c!repeat}%
165%      \fi
166%    \relax}
167
168\permanent\protected\def\node_rules_set#1%
169  {\cdef\currentbar{#1}%
170   \advanceby\c_node_rules_level\plusone
171   \usebarstyleandcolor\c!foregroundstyle\c!foregroundcolor
172   \edef\p_node_color {\barparameter\c!color}% todo
173   \edef\p_node_offset{\barparameter\c!offset}%
174   % better is a dedicated key: up/down .. todo
175   \advanceby\ifdim\p_node_offset\onepoint<\zeropoint\c_node_rules_down\else\c_node_rules_up\fi\plusone
176   \scratchcounter\barparameter\c!method\relax
177   \clf_setrule
178         method        \scratchcounter
179         continue      {\barparameter\c!continue}%
180         rulethickness {\barparameter\c!rulethickness}%
181         mp            {\includeMPgraphic{\barparameter\c!mp}}
182         ma            \c_attr_colormodel
183         ca            \rawcolorattribute\p_node_color
184         ta            \rawtransparencyattribute\p_node_color
185         order         {\barparameter\c!order}%
186     \ifnum\scratchcounter=\plustwo
187         height        \dimexpr\barparameter\c!height\relax
188         depth         \dimexpr\barparameter\c!depth\relax
189     \else
190         unit          {\barparameter\c!unit}%
191         level         \c_node_rules_level
192         stack         \ifdim\p_node_offset\onepoint<\zeropoint\c_node_rules_down\else\c_node_rules_up\fi
193         max           \barparameter\c!max\space % number
194         offset        \p_node_offset\space % number
195         dy            \barparameter\c!dy\space % number, also fraction
196         empty         {\barparameter\c!empty}%
197       \ifempty{\barparameter\c!text}\else
198         text          \hbox{\lastnamedcs}%
199         repeat        {\barparameter\c!repeat}%
200       \fi
201     \fi
202   \relax}
203
204\permanent\protected\def\resetbar
205  {\c_attr_ruled\attributeunsetvalue}
206
207\permanent\protected\def\nobar
208  {\groupedcommand
209     {\resetbar\barparameter\c!left}%
210     {\relax\barparameter\c!right}}
211
212\permanent\protected\def\startbar[#1]%
213  {\begingroup
214   \node_rules_set{#1}%
215   \ignorespaces
216   \barparameter\c!left}
217
218\permanent\protected\def\stopbar
219  {\removeunwantedspaces
220   \barparameter\c!right
221   \endgroup}
222
223\permanent\protected\def\setbar[#1]%
224  {\node_rules_set{#1}}
225
226\aliased\let\directsetbar\node_rules_set
227
228% ungrouped % todo: use the lua based stacker
229
230\permanent\protected\def\pushbar[#1]%
231  {\global\advanceby\c_node_rules_nesting\plusone
232   \edefcsname\??barstack\the\c_node_rules_nesting\endcsname
233     {\c_node_rules_level\the\c_node_rules_level
234      \c_attr_ruled      \the\c_attr_ruled}%
235   \node_rules_set{#1}}
236
237\permanent\protected\def\popbar
238  {\csname\??barstack\the\c_node_rules_nesting\endcsname\relax
239   \global\advanceby\c_node_rules_nesting\minusone}
240
241% we can save some by havign defaults at the lua end
242
243\setupbars
244  [\c!method=0,                 % new: 0=center nested, 1=stack nested
245   \c!continue=\v!no,
246   \c!level=\v!yes,
247   \c!empty=,                   % new: yes = hide text
248   \c!offset=0,                 % upwards, replaces: topoffset bottomoffset
249   \c!dy=0,
250   \c!max=3,
251   \c!style=,
252   \c!rulethickness=.1,
253   \c!order=\v!foreground,
254   \c!height=\zeropoint,
255   \c!depth=\zeropoint,
256   \c!unit=ex,                  % so now we are relative
257   \c!color=]                   % replaces: rulecolor
258
259% \definebar[touchbar]    [\c!method=0,\c!dy=-0.4,\c!offset=-0.0]
260% \definebar[touchbars]   [touchbar]   [\c!continue=\v!yes]
261
262\pushoverloadmode
263
264\aliased\let\normalmathoverbar    \overbar
265\aliased\let\normalmathunderbar   \underbar
266%aliased\let\normalmathoverstrike \overstrike
267%aliased\let\normalmathunderstrike\understrike
268
269\definebar[\v!overbar]   [\c!method=1,\c!dy=0.4,\c!offset=1.8,\c!continue=\v!yes]
270\definebar[\v!underbar]  [\c!method=1,\c!dy=-0.4,\c!offset=-0.3,\c!continue=\v!yes]
271\definebar[\v!overstrike][\c!method=0,\c!dy=0.4,\c!offset=0.5,\c!continue=\v!yes]
272
273\definebar
274  [\v!understrike]
275  [\c!method=0,
276   \c!offset=1.375,
277   \c!rulethickness=2.5,
278   \c!continue=\v!yes,
279   \c!order=\v!background,
280   \c!color=lightgray]
281
282\definebar[\v!overbars]    [\v!overbar]    [\c!continue=\v!no]
283\definebar[\v!underbars]   [\v!underbar]   [\c!continue=\v!no]
284\definebar[\v!overstrikes] [\v!overstrike] [\c!continue=\v!no]
285\definebar[\v!understrikes][\v!understrike][\c!continue=\v!no]
286
287\definebar
288  [\v!hiddenbar]
289  [\v!underbar]
290  [\c!continue=\v!yes,
291   \c!empty=\v!yes,
292   \c!left=\zwj,
293   \c!right=\zwj]
294
295\definebar
296  [\v!outline]
297  [\c!method=2,
298   \c!offset=0,
299   \c!rulethickness=0.25,
300   \c!continue=\v!yes,
301   \c!order=\v!background,
302   \c!color=lightgray]
303
304\definebar
305  [\v!outlined]
306  [\v!outline]
307  [\c!height=\strutht,
308   \c!depth=\strutdp]
309
310% \setupbar[\v!overstrike][continue=all]
311
312% we want these always so ...
313
314\ifdefined\normalmathunderbar
315    \enforced\permanent\expandafter\let\expandafter\normaltextunderbar\csname\v!underbar\endcsname
316    \enforced\permanent\protected\def\underbar{\mathortext\normalmathunderbar\normaltextunderbar}
317\else
318    \enforced\permanent\expandafter\let\expandafter\underbar\csname\v!underbar\endcsname
319\fi
320
321\ifdefined\normalmathoverbar
322    \enforced\permanent\expandafter\let\expandafter\normaltextoverbar\csname\v!overbar\endcsname
323    \enforced\permanent\protected\def\overbar{\mathortext\normalmathoverbar\normaltextoverbar}
324\else
325    \enforced\permanent\expandafter\let\expandafter\overbar\csname\v!overbar\endcsname
326\fi
327
328% \ifdefined\normalmathunderstrike
329%     \enforced\permanent\expandafter\let\expandafter\normaltextunderstrike\csname\v!understrike\endcsname
330%     \enforced\permanent\protected\def\understrike{\mathortext\normalmathunderstrike\normaltextunderstrike}
331% \else
332%     \enforced\permanent\expandafter\let\expandafter\understrike\csname\v!understrike\endcsname
333% \fi
334%
335% \ifdefined\normalmathoverstrike
336%     \enforced\permanent\expandafter\let\expandafter\normaltextoverstrike\csname\v!overstrike\endcsname
337%     \enforced\permanent\protected\def\overstrike{\mathortext\normalmathoverstrike \normaltextoverstrike}
338% \else
339%     \enforced\permanent\expandafter\let\expandafter\overstrike\csname\v!overstrike\endcsname
340% \fi
341
342\enforced\permanent\expandafter\let\expandafter\overstrikes\csname\v!overstrikes\endcsname
343\enforced\permanent\expandafter\let\expandafter\underbars  \csname\v!underbars  \endcsname
344\enforced\permanent\expandafter\let\expandafter\overbars   \csname\v!overbars   \endcsname
345
346\enforced\permanent\protected\def\setupunderbar[#1]% too incompatible for the moment
347  {}
348
349\popoverloadmode
350
351%D An experimental new feature:
352%D
353%D \startbuffer
354%D test {\red\underrandoms{test me}} and \underrandom{test} or \underrandom{grep} \blank
355%D test {\red\underdashes {test me}} and \underdash  {test} or \underdash  {grep} \blank
356%D test {\red\underdots   {test me}} and \underdot   {test} or \underdot   {grep} \blank
357%D \stopbuffer
358%D
359%D \typebuffer \getbuffer
360
361\startuseMPgraphic{rules:under:random}
362    draw
363        ((0,RuleDepth) ... (RuleWidth,RuleDepth)) randomized (4*RuleThickness)
364        shifted (0,RuleFactor*RuleOffset)
365        withpen pencircle scaled RuleThickness
366        withcolor RuleColor ;
367    setbounds currentpicture to unitsquare xysized(RuleWidth,RuleHeight) ;
368\stopuseMPgraphic
369
370\startuseMPgraphic{rules:under:dash}
371    draw
372        ((0,RuleDepth) -- (RuleWidth,RuleDepth))
373        shifted (0,RuleFactor*RuleOffset)
374        dashed dashpattern(on RuleFactor/2 off RuleFactor/2)
375        withpen pencircle scaled RuleThickness
376        withcolor RuleColor ;
377    setbounds currentpicture to unitsquare xysized(RuleWidth,RuleHeight) ;
378\stopuseMPgraphic
379
380\startuseMPgraphic{rules:under:dots}
381    path p ; p := (0,RuleDepth) -- (RuleWidth,RuleDepth) ;
382    numeric l ; l := arclength(p);
383    l := l mod RuleThickness/4;
384    draw
385        p
386        shifted (l,RuleFactor*RuleOffset)
387        dashed dashpattern(off 2RuleThickness+l on 0 off 2RuleThickness)
388        withpen pencircle scaled 2RuleThickness
389        withcolor RuleColor ;
390    setbounds currentpicture to unitsquare xysized(RuleWidth,RuleHeight) ;
391\stopuseMPgraphic
392
393\definebar
394  [undergraphic]
395  [\c!mp=rules:under:dash,
396   \c!level=\v!auto,
397   \c!offset=-.2,
398   \c!dy=.4,
399   \c!continue=\v!yes,
400   \c!order=\v!background]
401
402\definebar[underrandom] [undergraphic][\c!mp=rules:under:random,]
403\definebar[underrandoms][underrandom] [\c!continue=\v!no]
404
405\definebar[underdash]   [undergraphic][\c!mp=rules:under:dash]
406\definebar[underdashes] [underdash]   [\c!continue=\v!no]
407
408\definebar[underdot]    [undergraphic][\c!mp=rules:under:dots]
409\definebar[underdots]   [underdot]    [\c!continue=\v!no]
410
411%D This will move: (a bit duplicated)
412
413\installcorenamespace{shift}
414
415\installcommandhandler \??shift {shift} \??shift
416
417\let\setupshifts\setupshift
418
419\appendtoks
420    \frozen\protected\instance\edefcsname\currentshift\endcsname{\node_shifts_direct{\currentshift}}%
421\to \everydefineshift
422
423\protected\def\node_shifts_set#1% todo: check parent ! todo: move attr etc to lua
424  {\cdef\currentshift{#1}%
425   \useshiftstyleandcolor\c!style\c!color
426   \dosetupisolatedalign{\shiftparameter\c!align}% a weird feature that i probably needed once
427   \clf_setshift
428       continue {\shiftparameter\c!continue}%
429       unit     {\shiftparameter\c!unit}%
430       method    \shiftparameter\c!method
431       dy        \shiftparameter\c!dy % number
432   \relax}
433
434\permanent\protected\def\startshift[#1]%
435  {\begingroup
436   \node_shifts_set{#1}%
437   \ignorespaces}
438
439\permanent\protected\def\stopshift
440  {\removeunwantedspaces
441   \endgroup}
442
443\protected\def\node_shifts_direct#1%
444  {\groupedcommand
445     {\begingroup\dostartisolation\begingroup\node_shifts_set{#1}\ignorespaces}
446     {\removeunwantedspaces\endgroup\dostopisolation\endgroup}}
447
448\setupshifts
449  [\c!method=0,
450   \c!continue=\v!no,
451   \c!dy=0,
452   \c!unit=ex,
453   \c!align=,
454   \c!style=,
455   \c!color=]
456
457\defineshift [\v!shiftup]   [\c!method=0,\c!dy=-1,\c!unit=ex,\c!continue=\v!yes,\c!style=\txx,\c!color=]
458\defineshift [\v!shiftdown] [\c!method=1,\c!dy=.3,\c!unit=ex,\c!continue=\v!yes,\c!style=\txx,\c!color=]
459
460% we want these always so ...
461
462\expandafter\let\expandafter\shiftup  \csname\v!shiftup  \endcsname
463\expandafter\let\expandafter\shiftdown\csname\v!shiftdown\endcsname
464
465% This is a weird helper.. these might go away:
466
467\permanent\protected\def\dostartisolation{\signalcharacter}
468\permanent\protected\def\dostopisolation {\signalcharacter}
469\permanent\protected\def\doisolator      {\signalcharacter}
470
471\permanent\protected\def\dosetupisolatedalign#1%
472  {\doisolator
473   \setupalign[#1]\relax}
474
475\permanent\protected\def\doisolatedgroupedalign#1#2%
476  {\groupedcommand
477     {\begingroup\dostartisolation\begingroup#1}
478     {#2\endgroup\dostopisolation\endgroup}}
479
480%D More rules.
481
482% The following code rocks and was written with the Toto Live in Poland bluray
483% in loop mode on my 5.1 surround development setup (the Toto lineup with Simon
484% Phillips on drums). The Amsterdam concert is equally energizing.
485
486\installcorenamespace{linefiller}
487
488\installcommandhandler \??linefiller {linefiller} \??linefiller
489
490\definesystemattribute[linefiller][public]
491
492\aliased\let\setuplinefillers\setuplinefiller
493
494\protected\def\node_linefiller_set#1% todo: check parent ! todo: move attr etc to lua
495  {\cdef\currentlinefiller{#1}%
496   \edef\p_node_color{\linefillerparameter\c!color}%
497   \clf_setlinefiller
498      %method         \linefillerparameter\c!method
499       location      {\linefillerparameter\c!location}%
500       scope         {\linefillerparameter\c!scope}%
501       mp            {\includeMPgraphic{\linefillerparameter\c!mp}}%
502       ma             \c_attr_colormodel
503       ca             \rawcolorattribute\p_node_color
504       ta             \rawtransparencyattribute\p_node_color
505       height         \dimexpr\linefillerparameter\c!height\relax
506       depth          \dimexpr\linefillerparameter\c!depth\relax
507       distance       \dimexpr\linefillerparameter\c!distance\relax
508       threshold      \dimexpr\linefillerparameter\c!threshold\relax
509       rulethickness  \dimexpr\linefillerparameter\c!rulethickness\relax
510   \relax}
511
512\permanent\tolerant\protected\def\startlinefiller[#1]#*[#S#2]%
513  {\begingroup
514   \par
515   \cdef\currentlinefiller{#1}%
516   \ifparameter#2\or
517     % we need to update settings
518     \setuplinefiller[#1][#2]% no \setupcurrentlinefiller as we need to update settings
519   \fi
520   \node_linefiller_set{#1}%
521   \linefillerparameter\c!before
522   \usealignparameter\linefillerparameter
523   \uselinefillerstyleandcolor\c!textstyle\c!textcolor} % bars have foregroundcolor
524
525\permanent\protected\def\stoplinefiller
526  {\par
527   \linefillerparameter\c!after
528   \endgroup}
529
530\permanent\protected\def\setlinefiller[#1]%
531  {\node_linefiller_set{#1}}
532
533\setuplinefillers
534  [%c!method=0,
535   %c!mp=,
536   \c!location=\v!both,
537   \c!scope=\v!local,
538   \c!distance=\zeropoint,
539   \c!threshold=\zeropoint,
540   \c!rulethickness=\linewidth,
541   \c!height=\linewidth,
542   \c!depth=\zeropoint,
543  %\c!textcolor=,
544  %\c!textstyle=,
545  %\c!align=,
546  %\c!before=,
547  %\c!after=,
548   \c!color=]
549
550\definelinefiller
551  [filler]
552  [\c!height=.75\exheight,
553  %\c!mp=rules:filler:demo,
554  %\c!threshold=.25\emwidth,
555   \c!distance=.25\emwidth,
556   \c!rulethickness=.25\exheight]
557
558%D Bonus:
559%D
560%D \starttyping
561%D \startuseMPgraphic{foo}
562%D     fill unitsquare
563%D         xyscaled (RuleWidth,RuleHeight+RuleDepth) enlarged (ExHeight/4,ExHeight/8)
564%D         shifted  (-ExHeight/8,ExHeight/16)
565%D         withcolor RuleColor ;
566%D \stopuseMPgraphic
567%D
568%D \definelinefiller[foo][mp=foo,color=darkred]
569%D
570%D \linefillerhbox[foo]{OEPS}
571%D \stoptyping
572
573\protected\def\node_backgrounds_filler_box#1#2[#3]%
574  {\bgroup
575   \clf_enablebackgroundboxes
576   \dowithnextbox{%
577     \node_linefiller_set{#3}% already sets the attribute
578     #1%
579        attr \backgroundattribute \plusone
580       {\box\nextbox}%
581     \egroup}%
582   #2}
583
584\permanent\protected\def\linefillerhbox{\node_backgrounds_filler_box\hpack\hbox}
585\permanent\protected\def\linefillervbox{\node_backgrounds_filler_box\vpack\vbox}
586\permanent\protected\def\linefillervtop{\node_backgrounds_filler_box\tpack\vtop}
587
588%D Bonus:
589
590% \autorule : defined at the lua end
591
592\protect \endinput
593