typo-mar.mkxl /size: 18 Kb    last modification: 2023-12-21 09:44
1% macros=mkvi
2
3%D \module
4%D   [       file=typo-mar,
5%D        version=2010.02.15, % was experimental code
6%D          title=\CONTEXT\ Typesetting Macros,
7%D       subtitle=Margindata,
8%D         author=Hans Hagen,
9%D           date=\currentdate,
10%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
11%C
12%C This module is part of the \CONTEXT\ macro||package and is
13%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
14%C details.
15
16% maybe dontleavehmode when scope is local
17
18% todo: tags
19% todo: force inline with option (saves pos)
20% todo: margintitle (also less position then)
21
22\writestatus{loading}{ConTeXt Typesetting Macros / Margindata}
23
24\unprotect
25
26%D This module has been on the agenda for a while. Actually, it is one of the things
27%D that I really need myself, for instance when rendering rather unpredictable
28%D (educational) tests encoded in XML. This module permits anchoring for instance
29%D item numbers and also overload them when they have subnumbers. In the future it
30%D might replace the current maginal note mechanism (that then will be just an
31%D instance).
32%D
33%D In spite of what might be expected, the more advanced \LUA\ based variant is upto
34%D twice as fast on simple entries. Also, we no longer need an extra pass to get
35%D inner and outer alignments in sync with the pagebuilder.
36
37\registerctxluafile{typo-mar}{autosuffix}
38
39%definesystemattribute[margindata] % only at the lua end
40
41%D In \MKII\ we have three categories and their historically meaning is as follows:
42%D
43%D marginlines: These are flushed relative to the start of a line and need to be
44%D invoked there.
45%D
46%D marginwords: These can be issued in the text flow and will migrate sidewards; in
47%D spite of the name, it can be a paragraph of text as well, but normally it's
48%D words.
49%D
50%D margintexts: These can be set beforehand and are flushed at the next paragraph of
51%D text (of header).
52%D
53%D In \MKIV\ we have further integrated the mechanism and we now have:
54%D
55%D margindata: This can be anything that needs to go into the margin. It can be
56%D anchored in the text or given beforehand in which case it gets flushed at the
57%D first occasion.
58%D
59%D margintext: This runs on top of margindata and the only difference is that it
60%D uses the framed mechanism for packaging.
61%D
62%D Stacking is done differently as is inner and outer alignment (in most cases more
63%D efficient). The functionality is mostly the same as in \MKII, but there are a few
64%D additions, like names entries, where later ones overload preceding not yet
65%D flushed ones. Data can get catagorized and is then treated as a group (e.g. when
66%D stacking is needed).
67%D
68%D The amount of \TEX\ code is less than in \MKII\ because we do all trickery in at
69%D the \LUA\ end. At the end of this file we define several commands, like \type
70%D {\inleftmargin} and \type {\inleft}. You can configure them individually or as a
71%D group. There is an inheritance model in place.
72%D
73%D The following notes will be stacked:
74%D
75%D \starttyping
76%D \ininner[line=2]{IM A}
77%D \ininner[stack=yes]{IM B}
78%D \ininner[stack=yes]{IM C}
79%D \stoptyping
80%D
81%D The distance between them is determined by \type {dy}:
82%D
83%D \starttyping
84%D \ininner[stack=yes,dy=2ex][frame=on] {IM A}
85%D \ininner[stack=yes,dy=2ex][frame=on] {IM B}
86%D \stoptyping
87%D
88%D There are several methods of vertical alignment.
89%D
90%D \starttyping
91%D \inmargin [method=first]             [frame=on]                              {first\\second} \input ward \par
92%D \inmargin [method=first]             [frame=on,offset=3pt]                   {first\\second} \input ward \par
93%D \inmargin [method=first,voffset=-3pt][frame=on,offset=3pt,rulethickness=3pt] {first\\second} \input ward \par
94%D \inmargin [method=first,voffset=-6pt][frame=on,offset=3pt,rulethickness=3pt] {first\\second} \input ward \par
95%D \stoptyping
96%D
97%D You sometimes need to combine \type {voffset} with \type {offset}. The first
98%D argument concerns the data, the second the framed. Not sharing the setup is on
99%D purpose: location, offset, alignment and other parameters might clash.
100
101\installcorenamespace{margindata}
102\installcorenamespace{marginframed}
103
104\installcommandhandler       \??margindata   {margindata}   \??margindata
105\installframedcommandhandler \??marginframed {marginframed} \??marginframed
106
107\setupmargindata
108  [\c!location=\v!left,
109 % \c!align=,
110 % \c!method=,
111   \c!style=\v!bold,
112   \c!color=, % maybe \maintextcolor
113 % \c!name=,
114 % \c!category=,
115   \c!threshold=.25\exheight,
116   \c!margin=\v!normal,
117   \c!scope=\v!global,
118   \c!width=,
119 % \c!stack=,
120 % \c!stackname=,
121 % \c!option=, % \v!paragraph (follow shape)
122   \c!line=0,
123   \c!anchor=\v!text,
124   \c!bottomspace=\strutdepth, % slack used for keeptogether
125   \c!dy=\zeropoint,
126   \c!distance=\zeropoint,
127   \c!hoffset=\zeropoint,
128   \c!voffset=\zeropoint]
129
130\setupmarginframed  % so, align should be set with the data command
131  [\c!strut=\v!yes, % so by default we scale the strut to the font !
132   \c!offset=\v!overlay,
133   \c!fr!analyze=\v!yes,
134   \c!frame=\v!off,
135   \c!width=\margindataparameter\c!width,
136   \c!align=\margindataparameter\c!align]
137
138\appendtoks
139    \frozen\instance\protected\edefcsname\currentmargindata\endcsname{\margindata[\currentmargindata]}%
140\to \everydefinemargindata
141
142\newconditional\inhibitmargindata      % This one is used at the Lua end!
143\newtoks       \everymargindatacontent % Later on we will set this one.
144
145\mutable\lettonothing\currentmargindatastrut
146\mutable\lettonothing\currentmargindatawidth
147\mutable\lettonothing\currentmarginfirstheight
148\mutable\lettonothing\currentmarginreference
149
150\appendtoks
151    \inhibitmargindata\conditionaltrue
152\to \everyforgetall
153
154\appendtoks
155    \forgetall
156    \tf
157    \resetallattributes % \deactivatecolor % needed, but maybe we should switch to maintextcolor: \onlyinheritmaintextcolor
158    \pickupattributes
159\to \everymargindatacontent
160
161% trialtypesetting: no need for margin stuff while trialing as
162% is has no dimensions
163
164\newinteger\nofmargintexts
165\newinteger\c_typo_margins_n
166
167\ifdefined\dotagmarginanchor \else \aliased\let\dotagmarginanchor\gobbleoneargument \fi
168\ifdefined\dotagmargintext   \else \aliased\let\dotagmargintext  \gobbleoneargument \fi
169
170\definepagestate[\s!margintext]
171
172\protected\def\typo_margins_data_synchronize
173  {\doforcedtrackpagestate\s!margintext\nofmargintexts % includes increment
174   \docheckpagestate\s!margintext\nofmargintexts
175  %\doifelserightpagestate\s!margintext\nofmargintexts\relax\relax
176   \realpageno\realpagestateno
177   \page_layouts_swap_margins\v!margin}
178
179\permanent\protected\def\margindata
180  {\iftrialtypesetting
181     \expandafter\typo_margins_data_nop
182   \else
183     \expandafter\typo_margins_data_yes
184   \fi}
185
186\permanent\tolerant\protected\def\typo_margins_data_nop[#name]#spacer[#S#dataparameters]#spacer[#S#textparameters]#:#content%
187  {}
188
189\permanent\tolerant\protected\def\typo_margins_data_yes[#name]#spacer[#S#dataparameters]#spacer[#S#textparameters]#:#content%
190  {\inhibitmargindata\conditionalfalse % flushing afterwards
191   \begingroup
192  %\inhibitmargindata\conditionaltrue  % no flushing in here
193   \def\currentmargindata{#name}%
194   \let\currentmarginframed\currentmargindata
195   \ifparameter#dataparameters\or
196     \setupcurrentmargindata[#dataparameters]%
197   \fi
198   \ifparameter#content\donefalse\or\donetrue\else\donefalse\fi
199   \global\advanceby\c_typo_margins_n\plusone
200   \ifdone
201     \edef\currentmarginreference{\margindataparameter\c!reference}%
202     \ifempty\currentmarginreference \else
203       \strc_references_set_page_only_destination_box_attribute\currentmarginreference\currentmarginreference
204     \fi
205     \edef\currentmargindatastrut{\margindataparameter\c!strut}%
206     \dostarttaggedchained\t!margintext\currentmargindata\??margindata
207     \dotagmargintext\c_typo_margins_n
208     \ifcsname\currentmarginframedhash\s!parent\endcsname
209       \setbox\nextbox\naturalhbox \currentmarginreference \bgroup
210         \expand\everymargindatacontent
211         \usemargindatastyleandcolor\c!style\c!color
212         \setupcurrentmarginframed[\c!location=\v!normal,#textparameters]%
213         \typo_margins_data_synchronize
214         \inheritedmarginframedframed\bgroup
215           \ifempty\currentmargindatastrut \else
216             \synchronizestrut\currentmargindatastrut
217           \fi
218           \begstrut
219           \strc_references_flush_destination_nodes
220           \margindataparameter\c!command{#content}%
221           \endstrut
222         \egroup
223       \egroup
224       \edef\currentmarginfirstheight{\number\dimexpr\framedfirstheight}%
225     \else
226       \edef\currentmargindatawidth{\margindataparameter\c!width}%
227       \ifempty\currentmargindatawidth
228         \setbox\nextbox\naturalhbox \currentmarginreference \bgroup
229           \typo_margins_data_synchronize
230           \expand\everymargindatacontent
231           \usemargindatastyleandcolor\c!style\c!color
232           \ifempty\currentmargindatastrut \else
233             \synchronizestrut\currentmargindatastrut
234           \fi
235           \begstrut
236           \strc_references_flush_destination_nodes
237           \margindataparameter\c!command{#content}%
238           \endstrut
239         \egroup
240         \lettonothing\currentmarginfirstheight
241       \else
242         \setbox\nextbox\naturalhbox \currentmarginreference \bgroup
243           \typo_margins_data_synchronize
244           \dosetraggedcommand{\margindataparameter\c!align}%
245           \vtop \bgroup
246             \expand\everymargindatacontent
247             \usemargindatastyleandcolor\c!style\c!color
248             \hsize\currentmargindatawidth
249             \raggedcommand
250             \ifempty\currentmargindatastrut \else
251               \synchronizestrut\currentmargindatastrut
252             \fi
253             \begstrut
254             \strc_references_flush_destination_nodes
255             \margindataparameter\c!command{#content}%
256             \endstrut
257           \egroup
258         \egroup
259         \edef\currentmarginfirstheight{true}%
260       \fi
261     \fi
262     \dostoptagged
263   \fi
264   \ifdone
265     \edef\p_anchor{\margindataparameter\c!anchor}%
266     \anch_positions_initialize % we use positions at the lua end
267     \dostarttagged\t!marginanchor\empty
268     \dotagmarginanchor\c_typo_margins_n
269     \clf_savemargindata
270       location    {\margindataparameter\c!location}%
271       method      {\margindataparameter\c!method}%
272       category    {\margindataparameter\c!category}%
273       name        {\margindataparameter\c!name}%
274       scope       {\margindataparameter\c!scope}%
275       option      {\margindataparameter\c!option}%
276       number      \nextbox
277       margin      {\margindataparameter\c!margin}% local normal margin edge
278       distance    \dimexpr\margindataparameter\c!distance\relax
279       hoffset     \dimexpr\margindataparameter\c!hoffset\relax
280       voffset     \dimexpr\margindataparameter\c!voffset\relax
281       dy          \dimexpr\margindataparameter\c!dy\relax
282       bottomspace \dimexpr\margindataparameter\c!bottomspace\relax
283     \ifempty\currentmarginfirstheight \else
284       baseline    {\currentmarginfirstheight}%
285     \fi
286       threshold   \dimexpr\margindataparameter\c!threshold\relax % overlap related, will change
287     \ifhmode
288       inline      true %
289     \fi
290       anchor      {\p_anchor\ifx\p_anchor\v!region:0\fi}% kind of a hack to force column anchoring (for now)
291   %
292   % we're not in forgetall
293   %
294   % \ifzeropt\leftskip \else
295   %   leftskip    \dimexpr\leftskip\relax
296   % \fi
297   % \ifzeropt\leftskip \else
298   %   rightskip   \dimexpr\rightskip\relax
299   % \fi
300       align       {\margindataparameter\c!align}%
301       line        \numexpr\margindataparameter\c!line\relax
302       stackname   {\margindataparameter\c!stackname}%
303       stack       {\margindataparameter\c!stack}%
304       index       \c_typo_margins_n
305     \relax
306     \dostoptagged
307   \else
308     \clf_savemargindata
309       location    {\margindataparameter\c!location}%
310       method      {\margindataparameter\c!method}%
311       category    {\margindataparameter\c!category}%
312       name        {\margindataparameter\c!name}%
313       scope       {\margindataparameter\c!scope}%
314       number      \nextbox
315     \relax
316   \fi
317   \endgroup}
318
319%D Downward compatible hack:
320
321\appendtoks
322    \enforced\let\\\spaceorpar
323\to \everymargindatacontent
324
325%D Another one:
326
327% \installcorenamespace{oppositemargin}
328%
329% \letcsname\??oppositemargin\v!left  \endcsname\v!right
330% \letcsname\??oppositemargin\v!right \endcsname\v!left
331% \letcsname\??oppositemargin\v!inner \endcsname\v!outer
332% \letcsname\??oppositemargin\v!outer \endcsname\v!inner
333% \letcsname\??oppositemargin\v!normal\endcsname\v!normal
334%
335% \def\oppositemargin#1%
336%   {\csname\??oppositemargin\ifcsname\??oppositemargin#1\endcsname#1\else\v!normal\fi\endcsname}
337
338%D Definitions:
339
340% common to lines and text
341
342\setupmargindata [\v!left ] [\c!method=\v!first,\c!location=\v!left ,\c!margin=\v!margin,\c!align=\v!flushright,\s!parent=\??margindata] % we could autoparent when no define yet
343\setupmargindata [\v!right] [\c!method=\v!first,\c!location=\v!right,\c!margin=\v!margin,\c!align=\v!flushleft, \s!parent=\??margindata]
344\setupmargindata [\v!outer] [\c!method=\v!first,\c!location=\v!outer,\c!margin=\v!margin,\c!align=\v!inner,     \s!parent=\??margindata]
345\setupmargindata [\v!inner] [\c!method=\v!first,\c!location=\v!inner,\c!margin=\v!margin,\c!align=\v!outer,     \s!parent=\??margindata]
346
347% lines
348
349\definemargindata [\v!inleftmargin]  [\v!left ] [\c!margin=\v!margin,\c!width=\leftmarginwidth ,\c!style=,\c!color=]
350\definemargindata [\v!inrightmargin] [\v!right] [\c!margin=\v!margin,\c!width=\rightmarginwidth,\c!style=,\c!color=]
351\definemargindata [\v!inoutermargin] [\v!outer] [\c!margin=\v!margin,\c!width=\outermarginwidth,\c!style=,\c!color=]
352\definemargindata [\v!ininnermargin] [\v!inner] [\c!margin=\v!margin,\c!width=\innermarginwidth,\c!style=,\c!color=]
353
354\definemargindata [\v!inleftedge]    [\v!left ] [\c!margin=\v!edge  ,\c!width=\leftedgewidth   ,\c!style=,\c!color=,\c!category=\v!edge]
355\definemargindata [\v!inrightedge]   [\v!right] [\c!margin=\v!edge  ,\c!width=\rightedgewidth  ,\c!style=,\c!color=,\c!category=\v!edge]
356\definemargindata [\v!inouteredge]   [\v!outer] [\c!margin=\v!edge  ,\c!width=\outeredgewidth  ,\c!style=,\c!color=,\c!category=\v!edge]
357\definemargindata [\v!ininneredge]   [\v!inner] [\c!margin=\v!edge  ,\c!width=\inneredgewidth  ,\c!style=,\c!color=,\c!category=\v!edge]
358
359\definemargindata [\v!atleftmargin]  [\v!left ] [\c!margin=\v!normal,\c!width=\leftmarginwidth ,\c!style=,\c!color=]
360\definemargindata [\v!atrightmargin] [\v!right] [\c!margin=\v!normal,\c!width=\rightmarginwidth,\c!style=,\c!color=]
361
362% text: \v!added
363
364\definemargindata [\v!inleft]     [\v!left ]    [\c!margin=\v!margin,\c!width=\leftmarginwidth ,\c!align=\v!flushright]
365\definemargindata [\v!inright]    [\v!right]    [\c!margin=\v!margin,\c!width=\rightmarginwidth,\c!align=\v!flushleft]
366\definemargindata [\v!inouter]    [\v!outer]    [\c!margin=\v!margin,\c!width=\outermarginwidth,\c!align=\v!inner]
367\definemargindata [\v!ininner]    [\v!inner]    [\c!margin=\v!margin,\c!width=\innermarginwidth,\c!align=\v!outer]
368
369% no longer auto auto-other
370
371\definemargindata [\v!inmargin]   [\v!left]     [\c!margin=\v!margin,\c!width=\leftmarginwidth, \c!align=\v!flushright]
372\definemargindata [\v!inother]    [\v!right]    [\c!margin=\v!margin,\c!width=\rightmarginwidth,\c!align=\v!flushleft]
373
374\definemargindata [\v!margintext] [\v!left]     [\c!margin=\v!margin,\c!width=\leftmarginwidth, \c!align=\v!flushright,\c!stack=\v!yes]
375
376\setupmarginframed [\v!left ] [\c!method=\v!first,\c!align=\v!flushright,\s!parent=\??marginframed] % we could autoparent when no define yet
377\setupmarginframed [\v!right] [\c!method=\v!first,\c!align=\v!flushleft, \s!parent=\??marginframed]
378\setupmarginframed [\v!outer] [\c!method=\v!first,\c!align=\v!inner,     \s!parent=\??marginframed]
379\setupmarginframed [\v!inner] [\c!method=\v!first,\c!align=\v!outer,     \s!parent=\??marginframed]
380
381\definemarginframed [\v!inleft]   [\v!left ]
382\definemarginframed [\v!inright]  [\v!right]
383\definemarginframed [\v!inouter]  [\v!outer]
384\definemarginframed [\v!ininner]  [\v!inner]
385\definemarginframed [\v!inmargin] [\v!inleft]
386\definemarginframed [\v!inother]  [\v!inright]
387
388\aliased\let\marginword   \margintext
389\aliased\let\margintitle  \margintext
390\aliased\let\inothermargin\inother    % for old times sake
391
392%definemargindata [inouterextra] [\v!outer] [\c!margin=\v!edge,\c!location=\v!outer,\c!width=\outeredgewidth,\c!align=\v!outer,\c!category=\v!edge]
393%definemargindata [ininnerextra] [\v!inner] [\c!margin=\v!edge,\c!location=\v!inner,\c!width=\inneredgewidth,\c!align=\v!inner,\c!category=\v!edge]
394%
395%definemarginframed [inouterextra] [\v!outer]
396%definemarginframed [ininnerextra] [\v!inner]
397
398%D As we have more control we are not backward compatible although in
399%D practice it won't hurt that much. So, from now on use:
400%D
401%D \starttyping
402%D \definemargindata
403%D \setupmargindata
404%D \definemarginframed
405%D \setupmarginframed
406%D \stoptyping
407
408% The following sort of works okay but is to be avoided ... it will disappear from lmtx:
409
410\permanent\tolerant\protected\def\defineinmargin[#name]#spacer[#location]#spacer[#align]#spacer[#S#settings]% not completely compatible
411  {\ifparameter#1\else
412     \definemargindata[#name][\c!location=#location,\c!align=#align,#settings]%
413     \definemarginframed[#name][#location][\c!align=#align,#settings]%
414   \fi}
415
416\aliased\let\definemarginline\definemargindata % for old times sake
417\aliased\let\setupinmargin   \setupmargindata  % only partial (no framed), for old times sake
418
419% begin of experimental code (will move)
420%
421% \dosetanchor{x}test \dostarthanchoring{x}\llap{crap}\dostophanchoring{x}test test test
422% test \dostarthanchoring{text}\llap{crap}\dostophanchoring{text}test test test
423
424% \def\dosetanchor      #1{\dontleavehmode\latelua{anchors.set("#1")}}
425% \def\doresetanchor    #1{\dontleavehmode\latelua{anchors.reset("#1")}}
426% \def\doresetanchornow #1{\directlua{anchors.reset("#1")}}
427% \def\dostartanchoring #1{\dontleavehmode\latelua{anchors.startmove("#1")}}
428% \def\dostopanchoring  #1{\dontleavehmode\latelua{anchors.stopmove("#1")}}
429% \def\dostarthanchoring#1{\dontleavehmode\latelua{anchors.startmove("#1","h")}}
430% \def\dostartvanchoring#1{\dontleavehmode\latelua{anchors.startmove("#1","v")}}
431% \let\dostophanchoring    \dostopanchoring
432% \let\dostopvanchoring    \dostopanchoring
433
434%D Here because in strc-ren we are too early:
435
436% % \definemargindata
437% %   [margintext:chapter]
438% %   [margintext:section]
439% %
440% % \defineheadalternative
441% %   [margintext:chapter]
442% %   [margintext]
443% %   [margintext=margintext:chapter]
444% %
445% % \setuphead
446% %   [chapter]
447% %   [alternative=margintext:chapter]
448%
449% \setuphead
450%   [chapter]
451%   [alternative=margintext]
452
453\definemargindata
454  [\v!margintext:\v!section]
455  [\v!left]
456  [\c!margin=\v!margin,
457   \c!width=\leftmarginwidth,
458   \c!align=\v!flushright]
459
460\defineheadalternative
461  [\v!margintext]
462  [\c!alternative=\v!somewhere,
463   \c!margintext=\v!margintext:\v!section,
464   \c!renderingsetup=\??headrenderings:\v!margintext]
465
466\startsetups[\??headrenderings:\v!margintext]
467    \executeifdefined{\headalternativeparameter\c!margintext}\margintext {
468        \ifconditional\headshownumber
469            \headnumbercontent
470            \hkern\headnumberdistance
471        \fi
472        \headtextcontent
473    }
474\stopsetups
475
476\protect \endinput
477