typo-mar.mkxl /size: 18 Kb    last modification: 2021-10-28 13:51
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\setuevalue\currentmargindata{\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\let\currentmargindatastrut  \empty
146\mutable\let\currentmargindatawidth  \empty
147\mutable\let\currentmarginfirstheight\empty
148\mutable\let\currentmarginreference  \empty
149
150\appendtoks
151    \settrue\inhibitmargindata
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\newcount\nofmargintexts
165\newcount\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}
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[#dataparameters]#spacer[#textparameters]#:#content%
187  {}
188
189\permanent\tolerant\protected\def\typo_margins_data_yes[#name]#spacer[#dataparameters]#spacer[#textparameters]#:#content%
190  {\setfalse\inhibitmargindata % flushing afterwards
191   \begingroup
192  %\settrue\inhibitmargindata  % no flushing in here
193   \def\currentmargindata{#name}%
194   \let\currentmarginframed\currentmargindata
195   \ifparameter#dataparameters\or
196     \setupcurrentmargindata[#dataparameters]%
197   \fi
198 % \doifelsenothing{#content}\donefalse\donetrue
199 % \doifelsetext{#content}\donetrue\donefalse
200   \ifparameter#content\donefalse\or\donetrue\else\donefalse\fi
201   \global\advance\c_typo_margins_n\plusone
202   \ifdone
203     \edef\currentmarginreference{\margindataparameter\c!reference}%
204     \ifempty\currentmarginreference \else
205       \strc_references_set_page_only_destination_box_attribute\currentmarginreference\currentmarginreference
206     \fi
207     \edef\currentmargindatastrut{\margindataparameter\c!strut}%
208     \dostarttaggedchained\t!margintext\currentmargindata\??margindata
209     \dotagmargintext\c_typo_margins_n
210     \ifcsname\currentmarginframedhash\s!parent\endcsname
211       \setbox\nextbox\naturalhbox \currentmarginreference \bgroup
212         \the\everymargindatacontent
213         \usemargindatastyleandcolor\c!style\c!color
214         \setupcurrentmarginframed[\c!location=\v!normal,#textparameters]%
215         \typo_margins_data_synchronize
216         \inheritedmarginframedframed\bgroup
217           \ifempty\currentmargindatastrut \else
218             \synchronizestrut\currentmargindatastrut
219           \fi
220           \begstrut
221           \strc_references_flush_destination_nodes
222           \margindataparameter\c!command{#content}%
223           \endstrut
224         \egroup
225       \egroup
226       \edef\currentmarginfirstheight{\number\dimexpr\framedfirstheight}%
227     \else
228       \edef\currentmargindatawidth{\margindataparameter\c!width}%
229       \ifempty\currentmargindatawidth
230         \setbox\nextbox\naturalhbox \currentmarginreference \bgroup
231           \typo_margins_data_synchronize
232           \the\everymargindatacontent
233           \usemargindatastyleandcolor\c!style\c!color
234           \ifempty\currentmargindatastrut \else
235             \synchronizestrut\currentmargindatastrut
236           \fi
237           \begstrut
238           \strc_references_flush_destination_nodes
239           \margindataparameter\c!command{#content}%
240           \endstrut
241         \egroup
242         \let\currentmarginfirstheight\empty
243       \else
244         \setbox\nextbox\naturalhbox \currentmarginreference \bgroup
245           \typo_margins_data_synchronize
246           \dosetraggedcommand{\margindataparameter\c!align}%
247           \vtop \bgroup
248             \the\everymargindatacontent
249             \usemargindatastyleandcolor\c!style\c!color
250             \hsize\currentmargindatawidth
251             \raggedcommand
252             \ifempty\currentmargindatastrut \else
253               \synchronizestrut\currentmargindatastrut
254             \fi
255             \begstrut
256             \strc_references_flush_destination_nodes
257             \margindataparameter\c!command{#content}%
258             \endstrut
259           \egroup
260         \egroup
261         \edef\currentmarginfirstheight{true}%
262       \fi
263     \fi
264     \dostoptagged
265   \fi
266   \ifdone
267     \edef\p_anchor{\margindataparameter\c!anchor}%
268     \anch_positions_initialize % we use positions at the lua end
269     \dostarttagged\t!marginanchor\empty
270     \dotagmarginanchor\c_typo_margins_n
271     \clf_savemargindata
272       location    {\margindataparameter\c!location}%
273       method      {\margindataparameter\c!method}%
274       category    {\margindataparameter\c!category}%
275       name        {\margindataparameter\c!name}%
276       scope       {\margindataparameter\c!scope}%
277       option      {\margindataparameter\c!option}%
278       number      \nextbox
279       margin      {\margindataparameter\c!margin}% local normal margin edge
280       distance    \dimexpr\margindataparameter\c!distance\relax
281       hoffset     \dimexpr\margindataparameter\c!hoffset\relax
282       voffset     \dimexpr\margindataparameter\c!voffset\relax
283       dy          \dimexpr\margindataparameter\c!dy\relax
284       bottomspace \dimexpr\margindataparameter\c!bottomspace\relax
285     \ifempty\currentmarginfirstheight \else
286       baseline    {\currentmarginfirstheight}%
287     \fi
288       threshold   \dimexpr\margindataparameter\c!threshold\relax % overlap related, will change
289     \ifhmode
290       inline      true %
291     \fi
292       anchor      {\p_anchor\ifx\p_anchor\v!region:0\fi}% kind of a hack to force column anchoring (for now)
293   %
294   % we're not in forgetall
295   %
296   % \ifzeropt\leftskip \else
297   %   leftskip    \dimexpr\leftskip\relax
298   % \fi
299   % \ifzeropt\leftskip \else
300   %   rightskip   \dimexpr\rightskip\relax
301   % \fi
302       align       {\margindataparameter\c!align}%
303       line        \numexpr\margindataparameter\c!line\relax
304       stackname   {\margindataparameter\c!stackname}%
305       stack       {\margindataparameter\c!stack}%
306       index       \c_typo_margins_n
307     \relax
308     \dostoptagged
309   \else
310     \clf_savemargindata
311       location    {\margindataparameter\c!location}%
312       method      {\margindataparameter\c!method}%
313       category    {\margindataparameter\c!category}%
314       name        {\margindataparameter\c!name}%
315       scope       {\margindataparameter\c!scope}%
316       number      \nextbox
317     \relax
318   \fi
319   \endgroup}
320
321%D Downward compatible hack:
322
323\appendtoks
324    \enforced\let\\\spaceorpar
325\to \everymargindatacontent
326
327%D Another one:
328
329% \installcorenamespace{oppositemargin}
330%
331% \letvalue{\??oppositemargin\v!left  }\v!right
332% \letvalue{\??oppositemargin\v!right }\v!left
333% \letvalue{\??oppositemargin\v!inner }\v!outer
334% \letvalue{\??oppositemargin\v!outer }\v!inner
335% \letvalue{\??oppositemargin\v!normal}\v!normal
336%
337% \def\oppositemargin#1%
338%   {\csname\??oppositemargin\ifcsname\??oppositemargin#1\endcsname#1\else\v!normal\fi\endcsname}
339
340%D Definitions:
341
342% common to lines and text
343
344\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
345\setupmargindata [\v!right] [\c!method=\v!first,\c!location=\v!right,\c!margin=\v!margin,\c!align=\v!flushleft, \s!parent=\??margindata]
346\setupmargindata [\v!outer] [\c!method=\v!first,\c!location=\v!outer,\c!margin=\v!margin,\c!align=\v!inner,     \s!parent=\??margindata]
347\setupmargindata [\v!inner] [\c!method=\v!first,\c!location=\v!inner,\c!margin=\v!margin,\c!align=\v!outer,     \s!parent=\??margindata]
348
349% lines
350
351\definemargindata [\v!inleftmargin]  [\v!left ] [\c!margin=\v!margin,\c!width=\leftmarginwidth ,\c!style=,\c!color=]
352\definemargindata [\v!inrightmargin] [\v!right] [\c!margin=\v!margin,\c!width=\rightmarginwidth,\c!style=,\c!color=]
353\definemargindata [\v!inoutermargin] [\v!outer] [\c!margin=\v!margin,\c!width=\outermarginwidth,\c!style=,\c!color=]
354\definemargindata [\v!ininnermargin] [\v!inner] [\c!margin=\v!margin,\c!width=\innermarginwidth,\c!style=,\c!color=]
355
356\definemargindata [\v!inleftedge]    [\v!left ] [\c!margin=\v!edge  ,\c!width=\leftedgewidth   ,\c!style=,\c!color=,\c!category=\v!edge]
357\definemargindata [\v!inrightedge]   [\v!right] [\c!margin=\v!edge  ,\c!width=\rightedgewidth  ,\c!style=,\c!color=,\c!category=\v!edge]
358\definemargindata [\v!inouteredge]   [\v!outer] [\c!margin=\v!edge  ,\c!width=\outeredgewidth  ,\c!style=,\c!color=,\c!category=\v!edge]
359\definemargindata [\v!ininneredge]   [\v!inner] [\c!margin=\v!edge  ,\c!width=\inneredgewidth  ,\c!style=,\c!color=,\c!category=\v!edge]
360
361\definemargindata [\v!atleftmargin]  [\v!left ] [\c!margin=\v!normal,\c!width=\leftmarginwidth ,\c!style=,\c!color=]
362\definemargindata [\v!atrightmargin] [\v!right] [\c!margin=\v!normal,\c!width=\rightmarginwidth,\c!style=,\c!color=]
363
364% text: \v!added
365
366\definemargindata [\v!inleft]     [\v!left ]    [\c!margin=\v!margin,\c!width=\leftmarginwidth ,\c!align=\v!flushright]
367\definemargindata [\v!inright]    [\v!right]    [\c!margin=\v!margin,\c!width=\rightmarginwidth,\c!align=\v!flushleft]
368\definemargindata [\v!inouter]    [\v!outer]    [\c!margin=\v!margin,\c!width=\outermarginwidth,\c!align=\v!inner]
369\definemargindata [\v!ininner]    [\v!inner]    [\c!margin=\v!margin,\c!width=\innermarginwidth,\c!align=\v!outer]
370
371% no longer auto auto-other
372
373\definemargindata [\v!inmargin]   [\v!left]     [\c!margin=\v!margin,\c!width=\leftmarginwidth, \c!align=\v!flushright]
374\definemargindata [\v!inother]    [\v!right]    [\c!margin=\v!margin,\c!width=\rightmarginwidth,\c!align=\v!flushleft]
375
376\definemargindata [\v!margintext] [\v!left]     [\c!margin=\v!margin,\c!width=\leftmarginwidth, \c!align=\v!flushright,\c!stack=\v!yes]
377
378\setupmarginframed [\v!left ] [\c!method=\v!first,\c!align=\v!flushright,\s!parent=\??marginframed] % we could autoparent when no define yet
379\setupmarginframed [\v!right] [\c!method=\v!first,\c!align=\v!flushleft, \s!parent=\??marginframed]
380\setupmarginframed [\v!outer] [\c!method=\v!first,\c!align=\v!inner,     \s!parent=\??marginframed]
381\setupmarginframed [\v!inner] [\c!method=\v!first,\c!align=\v!outer,     \s!parent=\??marginframed]
382
383\definemarginframed [\v!inleft]   [\v!left ]
384\definemarginframed [\v!inright]  [\v!right]
385\definemarginframed [\v!inouter]  [\v!outer]
386\definemarginframed [\v!ininner]  [\v!inner]
387\definemarginframed [\v!inmargin] [\v!inleft]
388\definemarginframed [\v!inother]  [\v!inright]
389
390\aliased\let\marginword   \margintext
391\aliased\let\margintitle  \margintext
392\aliased\let\inothermargin\inother    % for old times sake
393
394%definemargindata [inouterextra] [\v!outer] [\c!margin=\v!edge,\c!location=\v!outer,\c!width=\outeredgewidth,\c!align=\v!outer,\c!category=\v!edge]
395%definemargindata [ininnerextra] [\v!inner] [\c!margin=\v!edge,\c!location=\v!inner,\c!width=\inneredgewidth,\c!align=\v!inner,\c!category=\v!edge]
396%
397%definemarginframed [inouterextra] [\v!outer]
398%definemarginframed [ininnerextra] [\v!inner]
399
400%D As we have more control we are not backward compatible although in
401%D practice it won't hurt that much. So, from now on use:
402%D
403%D \starttyping
404%D \definemargindata
405%D \setupmargindata
406%D \definemarginframed
407%D \setupmarginframed
408%D \stoptyping
409
410% The following sort of works okay but is to be avoided ... it will disappear from lmtx:
411
412\permanent\tolerant\protected\def\defineinmargin[#name]#spacer[#location]#spacer[#align]#spacer[#settings]% not completely compatible
413  {\ifarguments\else
414     \definemargindata[#name][\c!location=#location,\c!align=#align,#settings]%
415     \definemarginframed[#name][#location][\c!align=#align,#settings]%
416   \fi}
417
418\aliased\let\definemarginline\definemargindata % for old times sake
419\aliased\let\setupinmargin   \setupmargindata  % only partial (no framed), for old times sake
420
421% begin of experimental code (will move)
422%
423% \dosetanchor{x}test \dostarthanchoring{x}\llap{crap}\dostophanchoring{x}test test test
424% test \dostarthanchoring{text}\llap{crap}\dostophanchoring{text}test test test
425
426% \def\dosetanchor      #1{\dontleavehmode\latelua{anchors.set("#1")}}
427% \def\doresetanchor    #1{\dontleavehmode\latelua{anchors.reset("#1")}}
428% \def\doresetanchornow #1{\directlua{anchors.reset("#1")}}
429% \def\dostartanchoring #1{\dontleavehmode\latelua{anchors.startmove("#1")}}
430% \def\dostopanchoring  #1{\dontleavehmode\latelua{anchors.stopmove("#1")}}
431% \def\dostarthanchoring#1{\dontleavehmode\latelua{anchors.startmove("#1","h")}}
432% \def\dostartvanchoring#1{\dontleavehmode\latelua{anchors.startmove("#1","v")}}
433% \let\dostophanchoring    \dostopanchoring
434% \let\dostopvanchoring    \dostopanchoring
435
436%D Here because in strc-ren we are too early:
437
438% % \definemargindata
439% %   [margintext:chapter]
440% %   [margintext:section]
441% %
442% % \defineheadalternative
443% %   [margintext:chapter]
444% %   [margintext]
445% %   [margintext=margintext:chapter]
446% %
447% % \setuphead
448% %   [chapter]
449% %   [alternative=margintext:chapter]
450%
451% \setuphead
452%   [chapter]
453%   [alternative=margintext]
454
455\definemargindata
456  [\v!margintext:\v!section]
457  [\v!left]
458  [\c!margin=\v!margin,
459   \c!width=\leftmarginwidth,
460   \c!align=\v!flushright]
461
462\defineheadalternative
463  [\v!margintext]
464  [\c!alternative=\v!somewhere,
465   \c!margintext=\v!margintext:\v!section,
466   \c!renderingsetup=\??headrenderings:\v!margintext]
467
468\startsetups[\??headrenderings:\v!margintext]
469    \executeifdefined{\headalternativeparameter\c!margintext}\margintext {
470        \ifconditional\headshownumber
471            \headnumbercontent
472            \hskip\headnumberdistance
473        \fi
474        \headtextcontent
475    }
476\stopsetups
477
478\protect \endinput
479