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