strc-not.mkvi /size: 71 Kb    last modification: 2021-10-28 13:50
1%D \module
2%D   [       file=strc-not,
3%D        version=2008.10.20,
4%D          title=\CONTEXT\ Structure Macros,
5%D       subtitle=Note Handling,
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\writestatus{loading}{ConTeXt Structure Macros / Note Handling}
15
16\registerctxluafile{strc-not}{}
17
18\unprotect
19
20% todo: finish local rendering
21% todo: more p_strc_notations_* (outside trial loop)
22% todo: see if we can now use \insertpenalties (>0 == some left)
23
24\ifdefined\dotagsetnotesymbol \else \let\dotagsetnotesymbol\relax \fi
25\ifdefined\dotagsetnotation   \else \let\dotagsetnotation  \relax \fi
26
27%D \LMTX\ testcase:
28%D
29%D \starttyping
30%D \hbox {\hbox{\footnote{HH1}\footnote{HH2}}} \par
31%D \hbox {\hbox{x\footnote{XHH1}x\footnote{XHH2}}} \par
32%D \vbox {\setbox0\hbox{\footnote{VH1}\footnote{VH2}}\box0} \par
33%D \vbox         {\hbox{\footnote{VH1}xxx\footnote{VH2}}} \par
34%D \vbox         {\hbox{\footnote{VH1}\footnote{VH2}}
35%D                \hbox{\footnote{VH1}\footnote{VH2}}} \par
36%D \vbox {\hbox{x\footnote{XVH1}x\footnote{XVH2}}} \par
37%D \vbox {\vbox{\footnote{VV1}\footnote{VV2}}} \par % two lines
38%D \vbox {\vbox{x\footnote{XVV1}x\footnote{XVV2}}} \par
39%D \stoptyping
40
41%D Notes have two handlers: notations and notes. Although notations can be defined
42%D independently it makes not much sense. In principle we can treat notes as lists
43%D but they are currently done as a variant on enumerations. I will provide a list
44%D variant as well. One complication is that for page related notes inserts are used
45%D and therefore notes are typeset immediately and descriptions are better suited
46%D for that. For instance endnotes can as well be typeset using lists.
47
48% textcommand/textstyle/textcolor : set by note commandhandler and used for inline number
49
50%D \macros
51%D   {setupnote,setupnotation}
52%D
53%D We can influence footnote typesetting with the setup command:
54%D
55%D \showsetup{setupnotation}
56%D \showsetup{setupnote}
57%D
58%D The definition command indicate that we can frame the footnote area. The
59%D footnotes themselves are treated as descriptions.
60%D
61%D \showsetup{definenote}
62%D
63%D It's sort of a custom to precede footnotes by a horizontal rule and although
64%D fancy rules like
65%D
66%D \starttyping
67%D \hbox to 10em{\hskip-3em\dotfill}
68%D \stoptyping
69%D
70%D Are quite ligitimate, we default to a simple one 20\% of the text width.
71
72%    \c!headstyle=\noteparameter\c!style,
73%    \c!headcolor=\noteparameter\c!color,
74
75\installcorenamespace{notation}
76
77\installcommandhandler \??notation {notation} \??notation
78
79\installcounterassociation{notation}
80
81\let\setupnotations\setupnotation
82
83\definesymbol[\v!note:\v!previouspage][\llap{\low{\symbol[\v!previouspage]}}]
84\definesymbol[\v!note:\v!nextpage    ][\llap{\low{\symbol[\v!nextpage    ]}}]
85
86\setupnotations % check with old
87  [\c!alternative=\v!note,
88  %\c!headstyle=,
89  %\c!titlestyle=,
90  %\c!style=,
91  %\c!color=,
92  %\c!headcolor=,
93  %\c!titlecolor=,
94   \c!numbercommand=\high,
95  %\c!symbolcommand=\lowllap, % experiment
96  %\c!indicator=\v!no, % was \v!yes in mkii for page notes
97   \c!width=\v!fit,
98   \c!titledistance=.5em,
99   \c!distance=.5em,
100  %\c!hang=,
101  %\c!sample=,
102  %\c!align=,
103  %\c!headalign=,
104   \c!margin=\v!no,
105   \c!before=,
106   \c!inbetween=,
107   \c!after=,
108   \c!indentnext=\v!yes,
109   \c!indenting=\v!never,
110   \c!titleleft=(,
111   \c!titleright=),
112  %\c!closesymbol=,
113   \c!closecommand=\wordright,
114   \c!display=\v!yes,
115  %\c!command=,
116   \c!titlecommand=,
117   \c!expansion=\v!no,
118  %\c!xmlsetup=,
119  %\s!catcodes=,
120   \c!way=\v!by\v!text,
121   \c!prefix=\v!no,
122   \c!prefixconnector=.,
123  %\c!starter=,
124  %\c!stopper=,
125   \c!number=\v!yes,
126   \c!text=,
127   \c!start=0,
128   \c!state=\v!start,
129   \c!levels=3]
130
131%D The code here is mostly the same as enumerations but we want to keep them
132%D isolated and at some point we might differentiate.
133
134% \installcorenamespace{noteclass}
135
136\unexpanded\def\strc_define_commands_notation#tag#level#parent%
137  {\doifelsenothing{#parent}
138     {\normalexpanded{\defineconstruction[#tag][\s!handler=\v!notation,\c!level=#level]}%
139      \setevalue{\??notation#tag:\s!parent}{\??notation}}%
140     {\normalexpanded{\defineconstruction[#tag][#parent][\s!handler=\v!notation,\c!level=#level]}%
141      \setevalue{\??note#tag:\s!parent}{\??note#parent}% see later for \s!note
142      \setevalue{\??notation#tag:\s!parent}{\??notation#parent}}%
143   \setuevalue{\e!next #tag}{\strc_notations_next   {#tag}{\number#level}}% obsolete
144   \setuevalue{\c!reset#tag}{\strc_notations_reset  {#tag}{\number#level}}% obsolete
145   %setuevalue{\c!set  #tag}{\strc_notations_set    {#tag}{\number#level}}% obsolete
146   \setuevalue        {#tag}{\strc_notations_command{#tag}}%
147   \setuevalue{\e!start#tag}{\strc_notations_start  {#tag}{#tag}}% okay?
148   \setuevalue{\e!stop #tag}{\strc_notations_stop   }}
149
150\appendtoks
151    \ifx\currentnotationparent\empty
152       % clone => parent | subclone => clone | subsubclone => subclone
153       \let\currentnotationsub\empty
154       \strc_define_commands_notation
155         {\currentnotationsub\currentnotation}%
156         \plusone
157         \empty
158       \edef\p_levels{\notationparameter\c!levels}%
159       \dostepwiserecurse\plustwo\p_levels\plusone
160         {\strc_define_commands_notation
161            {\v!sub\currentnotationsub\currentnotation}%
162            \recurselevel
163            {\currentnotationsub\currentnotation}%
164          \edef\currentnotationsub{\v!sub\currentnotationsub}}%
165        \definelist[\currentnotation]% goodie
166   \else
167       % clone => parent | subclone => subparent | subsubclone => subsubparent
168       \let\currentnotationsub\empty
169       \edef\p_levels{\notationparameter\c!levels}%
170       \dorecurse\p_levels
171         {\strc_define_commands_notation
172            {\currentnotationsub\currentnotation}%
173            \recurselevel
174            {\currentnotationsub\currentnotationparent}%
175          \edef\currentnotationsub{\v!sub\currentnotationsub}}%
176        \definelist[\currentnotation][\currentnotationparent]% goodie
177   \fi
178   \edef\p_counter{\notationparameter\s!counter}% can inherit from parent
179   \ifx\p_counter\empty %
180       \let\p_counter\currentnotation
181   \fi
182   \doifelsecounter\p_counter\donothing{\strc_notes_define_counter\p_counter}%
183   \letnotationparameter\s!counter\p_counter
184  %\strc_notes_setup_counter\currentnotation
185\to \everydefinenotation
186
187\let\p_strc_constructions_title \empty
188\let\p_strc_constructions_number\empty
189
190\unexpanded\setvalue{\??constructioninitializer\v!notation}%
191  {\let\currentnotation                 \currentconstruction
192   \let\constructionparameter           \notationparameter
193   \let\constructionnamespace           \??notation
194   \let\detokenizedconstructionparameter\detokenizednotationparameter
195   \let\letconstructionparameter        \letnotationparameter
196   \let\useconstructionstyleandcolor    \usenotationstyleandcolor
197   \let\setupcurrentconstruction        \setupcurrentnotation
198   \edef\p_strc_constructions_number{\constructionparameter\c!number}%
199   \ifx\p_strc_constructions_number\v!yes
200     \settrue\c_strc_constructions_number_state
201     \iftrialtypesetting
202       \strc_counters_save\currentconstructionnumber
203     \fi
204%      \strc_counters_increment_sub\currentconstructionnumber\currentconstructionlevel
205   \else
206     \setfalse\c_strc_constructions_number_state
207   \fi
208   \edef\p_strc_constructions_title{\constructionparameter\c!title}%
209   \ifx\p_strc_constructions_title\v!yes
210     \settrue\c_strc_constructions_title_state
211   \else
212     \setfalse\c_strc_constructions_title_state
213   \fi}
214
215\unexpanded\setvalue{\??constructionfinalizer\v!notation}%
216  {\ifconditional\c_strc_constructions_number_state
217     \iftrialtypesetting
218       \strc_counters_restore\currentconstructionnumber
219     \fi
220   \fi}
221
222%D Notations (we simply needed a word that relates to notes and is and sounds like
223%D description and enumeration) are a special case in the sense that they are
224%D stored, rendered elsewhere and referered to from where they are specified. For
225%D that reason they have a different set op main commands.
226
227% \notation[ref]{title}
228% \notation[reference=,title=]
229% \startnotation[ref] title \stopnotation
230
231\unexpanded\def\strc_notations_next {\strc_constructions_next_indeed \namednotationparameter} % #1#2
232\unexpanded\def\strc_notations_reset{\strc_constructions_reset_indeed\namednotationparameter} % #1#2
233%unexpanded\def\strc_notations_set  {\strc_constructions_set_indeed  \namednotationparameter} % #1#2
234
235\newconditional\c_strc_notations_anchored_next
236
237\def\strc_notations_finalize
238  {\ifconditional\c_strc_notations_anchored_next
239     \expandafter\strc_notations_finalize_next
240   \else
241     \expandafter\strc_notations_finalize_previous
242   \fi}
243
244\def\strc_notations_finalize_previous
245  {\normalexpanded{\endgroup\noteparameter\c!next}}
246
247\def\strc_notations_finalize_next
248  {\endgroup\ignorespaces}
249
250\unexpanded\def\strc_notations_command#tag%
251  {\begingroup
252   \edef\currentnote{#tag}%
253   \strc_constructions_initialize{#tag}%
254   \strc_notes_synchronize
255   \edef\p_next{\noteparameter\c!anchor}%
256   \ifx\p_next\v!next % for now only two states
257     \settrue \c_strc_notations_anchored_next
258   \else
259     \setfalse\c_strc_notations_anchored_next
260   \fi
261   \ifnotesenabled
262     \strc_counters_increment_sub\currentconstructionnumber\currentconstructionlevel
263   \fi
264   \doifelsenextoptionalcs\strc_notations_command_yes\strc_notations_command_nop}
265
266\unexpanded\def\strc_notations_command_nop#title%
267  {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#title},\c!bookmark=,\c!list=]%
268   \csname\??constructionnotehandler\currentconstructionhandler\endcsname
269   \strc_constructions_finalize
270   \strc_notations_finalize}
271
272\unexpanded\def\strc_notations_command_yes[#optional]%
273  {\doifelseassignment{#optional}\strc_notations_command_assignment\strc_notations_command_argument[#optional]}
274
275\unexpanded\def\strc_notations_command_assignment[#settings]%
276  {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,#settings]%
277   \csname\??constructionnotehandler\currentconstructionhandler\endcsname
278   \strc_constructions_finalize
279   \strc_notations_finalize}
280
281\unexpanded\def\strc_notations_command_argument[#reference]#title%
282  {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#reference},\c!title={#title},\c!bookmark=,\c!list=]%
283   \csname\??constructionnotehandler\currentconstructionhandler\endcsname
284   \strc_constructions_finalize
285   \strc_notations_finalize}
286
287\unexpanded\def\strc_notations_start#tag#stoptag%
288  {\begingroup
289   \edef\currentnote{#tag}%
290   \strc_constructions_initialize{#tag}%
291   \strc_notes_synchronize
292   \ifnotesenabled
293     \strc_counters_increment_sub\currentconstructionnumber\currentconstructionlevel
294   \fi
295   \normalexpanded % not that efficient but also not that frequently used (\normaldef for parser)
296     {\def\noexpand\strc_pickup_yes[#one]#two\csname\e!stop#stoptag\endcsname{\strc_notations_command_yes[#one]{#two}}%
297      \def\noexpand\strc_pickup_nop      #one\csname\e!stop#stoptag\endcsname{\strc_notations_command_nop      {#one}}}%
298   \doifelsenextoptionalcs\strc_pickup_yes\strc_pickup_nop}
299
300\unexpanded\def\strc_notations_start_yes[#reference]#title%
301  {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#reference},\c!title={#title},\c!bookmark=,\c!list=]%
302   \csname\??constructionnotehandler\currentconstructionhandler\endcsname
303   \strc_constructions_finalize
304   \strc_notations_finalize}
305
306\unexpanded\def\strc_notations_start_nop#title%
307  {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#title},\c!bookmark=,\c!list=]%
308   \csname\??constructionnotehandler\currentconstructionhandler\endcsname
309   \strc_constructions_finalize
310   \strc_notations_finalize}
311
312\unexpanded\def\strc_notations_stop
313  {}
314
315%D A complication is that we need to set up rather specific properties of e.g.
316%D footnotes. It is for this reason that we introduce an extra level of
317%D indirectness. This way notations don't bark on undefined macros when used in
318%D combination.
319
320\unexpanded\setvalue{\??constructionnotehandler\v!notation}%
321  {\csname\??constructionnotehandler\currentconstructionhandler:\constructionparameter\c!type\endcsname}
322
323\unexpanded\setvalue{\??constructionnotehandler\v!notation:}% empty case
324  {[\currentconstructionhandler:\currentconstruction]}
325
326%D Here is a simple renderer for notes
327
328\defineconstructionalternative
329  [\v!note]
330  [\c!renderingsetup=\??constructionrenderings:\v!note]
331
332\startsetups[\??constructionrenderings:\v!note]
333    \noindent
334    \leftboundary % experiment, to be done in more places
335    \llap{\box\constructionheadbox\hskip\constructionparameter\c!distance}%
336    \useconstructionstyleandcolor\c!style\c!color
337    \ignorespaces
338\stopsetups
339
340%D We now implement the note definer.
341
342\installcorenamespace{note}
343
344\installframedcommandhandler \??note {note} \??note
345
346\let\setupnotes\setupnote
347
348% These only concern the inline symbol/number and wrapping of the whole list.
349
350\setupnotes % not all make sense here
351  [\c!location=\v!page,
352  %\c!conversion=,
353   \c!rule=\v!on,
354   \c!before=\blank,
355   \c!bodyfont=\v!small,
356   \c!anchor=, % can also be v!next
357  %\c!style=,
358  %\c!color=,
359  %\c!after=,
360  %\c!rulecolor=,
361  %\c!rulecommand=,
362   \c!rulethickness=\linewidth,
363   \c!frame=\v!off,
364   \c!distance=.125em, % in the text between symbols
365 % \c!textseparator={,}, % optional separator
366   \c!columndistance=1em,
367 % \c!margindistance=.5em,
368   \c!align=, % also use instead of \c!tolerance
369   \c!split=\v!tolerant,
370   \c!width=\makeupwidth, % \ifdim\hsize<\makeupwidth\hsize\else\makeupwidth\fi
371   \c!height=\textheight,
372   \c!command=, % \noteparameter\c!numbercommand, % (command in enumeration) too messy, called twice
373   \c!separator=,%
374   \c!textcommand=\high,
375   \c!textstyle=\tx,
376  %\c!textcolor=,
377   \c!interaction=\v!yes,
378  %\c!factor=,
379  %\c!scope=, % \v!text \v!page
380   \c!prefixconnector=.,
381  %\c!next=\autoinsertnextspace,
382   \c!prefix=\v!no,
383  %\c!continue=\v!no,
384   \c!paragraph=\v!no,
385   \c!inbetween=\hskip\emwidth,
386   \c!symbol=\mathematics{*},
387   \c!n=1]
388
389\setupnotes
390  [\c!expansion=\v!no,
391   \c!xmlsetup=,
392   \s!catcodes=]
393
394%D Insertions are part of notes.
395
396% \installcorenamespace{noteinsertion}
397
398\def\currentnoteinsertion      {\noteparameter\s!insert}
399\def\currentnoteinsertionnumber{\namedinsertionnumber{\noteparameter\s!insert}}
400
401\appendtoks
402    \ifx\currentnoteparent\empty
403        \doifelseinsertion\currentnote
404          \donothing
405          {\defineinsertion[\currentnote]% could be an option
406           \normalexpanded{\t_strc_notes{\the\t_strc_notes\noexpand\strc_notes_process_list{\currentnote}}}}%
407        \letnoteparameter\s!insert\currentnote
408        \definenotation[\currentnote][\c!type=\v!note]%
409    \else
410        \setexpandednoteparameter\s!insert{\namednoteparameter\currentnoteparent\s!insert}%
411        \definenotation[\currentnote][\currentnoteparent][\c!type=\v!note]%
412    \fi
413    \clf_definenote
414      {\currentnote}%
415      {insert}%
416      \currentnoteinsertionnumber
417    \relax
418\to \everydefinenote
419
420% maybe we will share this at some point:
421
422\def\strc_notes_define_counter#tag% todo: move inline
423  {\definecounter[#tag]%
424   \registerenumerationcounter{#tag}}
425
426\appendtoks
427    \synchronizenotationcounters
428\to \everysetupnotation
429
430\appendtoks
431    \synchronizenotationcounters
432\to \everydefinenotation
433
434% so far
435
436%expandafter\let\csname\??constructionstarthandler  \v!notation\expandafter\endcsname\csname\??constructionstarthandler  \v!enumeration\endcsname
437\expandafter\let\csname\??constructionstarthandler  \v!notation\expandafter\endcsname\csname\??constructionstarthandler  \v!construction\endcsname % no par mess
438\expandafter\let\csname\??constructionstophandler   \v!notation\expandafter\endcsname\csname\??constructionstophandler   \v!enumeration \endcsname
439\expandafter\let\csname\??constructioncommandhandler\v!notation\expandafter\endcsname\csname\??constructioncommandhandler\v!enumeration \endcsname
440\expandafter\let\csname\??constructiontexthandler   \v!notation\expandafter\endcsname\csname\??constructiontexthandler   \v!enumeration \endcsname
441
442\unexpanded\setvalue{\??constructionmainhandler\v!notation}#following%
443  {\iftrialtypesetting \else
444     \begingroup
445     \currentconstructionsynchronize
446     \c_attr_destination\currentconstructionattribute\relax % todo, whole text
447     \signalcharacter
448     \endgroup
449   \fi#following}
450
451\unexpanded\setvalue{\??constructionnotehandler\v!notation:\v!note}% in the running text
452  {\ifnotesenabled
453     % do be done elsewhere
454     %
455     %let\currentnote\currentconstructionmain
456     \let\currentnote\currentconstruction % else wrong inheritance
457     %
458     \iftrialtypesetting
459        \strc_notes_inject_dummy
460     \else
461       \begingroup
462       \edef\currentnotenumber{\clf_storenote{\currentnote}\currentconstructionlistentry}%
463       \settrue\processingnote
464       \ifconditional\c_strc_notes_skip
465         \glet\lastnotesymbol\strc_notes_inject_symbol_nop
466       \else
467         \iftypesettinglines % otherwise problems with \type <crlf> {xxx}
468           \ignorelines % makes footnotes work in \startlines ... \stoplines
469         \fi
470         \ifconditional\c_strc_notes_symbol
471           \strc_notes_inject_symbol_yes
472         \else
473           \unskip\unskip
474           \glet\lastnotesymbol\strc_notes_inject_symbol_yes
475         \fi
476       \fi
477       \ifconditional\postponingnotes % todo: per note class
478         \global\settrue\postponednote
479       \else\ifconditional\inlocalnotes % todo: per note class
480         \global\settrue\postponednote
481       \else\ifconditional\c_strc_notes_delayed
482         % probably end notes
483       \else
484         \handlenoteinsert\currentnote\currentnotenumber % either an insert or just delayed
485       \fi\fi\fi
486       \endgroup
487     \fi
488   \fi
489   \ifconditional\c_strc_notes_skip
490     \global\setfalse\c_strc_notes_skip
491   \else
492     \kern\notesignal\relax % \relax is needed to honor spaces
493   \fi}
494
495%D Interaction in notes is somewhat complex due to the way notes get flushed. In
496%D principle it is more or less the same as lists but where in lists we pack whole
497%D entries, in notes this doesn't happen. Okay, in retrospect we could have made
498%D descriptions lists but that will be a backward compatibility mess. At some point
499%D a completely new mechanism might show up, but not now. Also, as notes are inserts
500%D there is some extra mess to be kept in mind and it's easier to maintain two
501%D mechanisms than to combine too much.
502%D
503%D Interaction is also complicated because we want to provide several variants. For
504%D simple reference there is no need for anything special, as page references will
505%D do and we store them in the list anyway. But if we want a destination with
506%D dimensions we will use an additional destination because we can have only one
507%D with the same name and we always have the number as one.
508
509% interaction:
510%
511% all       : text and number
512% number|yes: only number
513% text      : only text
514%
515% \dogetsimple : injects
516
517\installcorenamespace{noteinteractioninline}
518\installcorenamespace{noteinteractiondisplay}
519
520\newconstant\a_strc_notes_symbol_reference
521\newconstant\a_strc_notes_number_reference
522\newconstant\a_strc_notes_text_reference
523\newconstant\a_strc_notes_text_destination
524
525\let\strc_notes_get_reference_attribute_symbol  \empty
526\let\strc_notes_get_destination_attribute_symbol\empty
527
528\def\strc_notes_interaction_check_inline
529  {\edef\p_interaction{\noteparameter\c!interaction}%
530   \csname\??noteinteractioninline
531     \ifcsname\??noteinteractioninline\p_interaction\endcsname\p_interaction\else\v!no\fi
532   \endcsname}
533
534\def\strc_notes_interaction_check_display
535  {\edef\p_interaction{\noteparameter\c!interaction}%
536   \csname\??noteinteractiondisplay
537     \ifcsname\??noteinteractiondisplay\p_interaction\endcsname\p_interaction\else\v!no\fi
538   \endcsname}
539
540\def\currentnotenumber{0}
541
542\let\strc_notes_get_reference_attribute_symbol  \empty
543\let\strc_notes_get_destination_attribute_symbol\empty
544
545\let\strc_notes_set_reference_attribute_number\donothing
546\let\strc_notes_set_reference_attribute_text  \donothing
547\let\strc_notes_set_destination_attribute_text\donothing
548
549% inline
550
551\def\strc_references_prepare_inline_references_nop
552  {\let\strc_notes_get_reference_attribute_symbol\empty
553   \let\strc_notes_get_destination_attribute_symbol\empty
554   \let\strc_notes_set_style_color_inline\strc_notes_set_style_color_inline_nop}
555
556% \def\strc_references_prepare_inline_references_yes
557%   {\strc_references_set_simple_reference{symb:\currentnote:\currentnotenumber}% destination
558%    \strc_references_get_simple_reference{internal(\clf_noteinternal{\currentnote}\currentnotenumber)}% reference
559%    \edef\strc_notes_get_destination_attribute_symbol{attr\destinationattribute\currentdestinationattribute}%
560%    \edef\strc_notes_get_reference_attribute_symbol{attr\referenceattribute\currentreferenceattribute}%
561%    \let\strc_notes_set_style_color_inline\strc_notes_set_style_color_inline_yes}
562
563\def\strc_references_prepare_inline_references_yes
564  {\edef\currentnoteinternal{\clf_noteinternal{\currentnote}\currentnotenumber}%
565   \strc_references_set_simple_reference{*\currentnoteinternal}% destination
566   \strc_references_get_simple_reference{internal(\currentnoteinternal)}% reference
567   \edef\strc_notes_get_destination_attribute_symbol{attr\destinationattribute\currentdestinationattribute}%
568   \edef\strc_notes_get_reference_attribute_symbol{attr\referenceattribute\currentreferenceattribute}%
569   \let\strc_notes_set_style_color_inline\strc_notes_set_style_color_inline_yes}
570
571\letvalue{\??noteinteractioninline\v!no    }\strc_references_prepare_inline_references_nop
572\letvalue{\??noteinteractioninline\v!all   }\strc_references_prepare_inline_references_yes
573\letvalue{\??noteinteractioninline\v!number}\strc_references_prepare_inline_references_yes
574\letvalue{\??noteinteractioninline\v!text  }\strc_references_prepare_inline_references_yes
575\letvalue{\??noteinteractioninline\v!yes   }\strc_references_prepare_inline_references_yes
576
577% display (for 'all' we need unique text and number attributes so we resolve twice
578% as we otherwise don't get the number one which is lapped in the margin so we need
579% to explicitly visit it)
580
581\def\strc_references_prepare_display_references_nop
582  {\let\strc_notes_set_reference_attribute_number\donothing
583   \let\strc_notes_set_reference_attribute_text\donothing
584   \let\strc_notes_set_destination_attribute_text\donothing
585   \let\strc_notes_set_style_color_display\strc_notes_set_style_color_display_nop}
586
587\def\strc_references_prepare_display_references_yes_number
588  {\edef\currentnoteinternal{\clf_noteinternal{\currentnote}\currentnotenumber}%
589   \ifcase\currentnoteinternal\relax
590     \strc_references_prepare_display_references_nop
591   \else
592     \let\strc_notes_set_reference_attribute_text\donothing
593     \strc_references_get_simple_reference{*\currentnoteinternal}% reference
594     \edef\strc_notes_set_reference_attribute_number{\c_attr_reference\currentreferenceattribute}%
595     \let\strc_notes_set_style_color_display\strc_notes_set_style_color_display_yes
596   \fi}
597
598\def\strc_references_prepare_display_references_yes_text
599  {\edef\currentnoteinternal{\clf_noteinternal{\currentnote}\currentnotenumber}%
600   \ifcase\currentnoteinternal\relax
601     \strc_references_prepare_display_references_nop
602   \else
603     \strc_references_get_simple_reference{*\currentnoteinternal}% reference
604     \edef\strc_notes_set_reference_attribute_text{\c_attr_reference\currentreferenceattribute}%
605     \let\strc_notes_set_reference_attribute_number\donothing
606     \let\strc_notes_set_style_color_display\strc_notes_set_style_color_display_yes
607   \fi}
608
609\def\strc_references_prepare_display_references_yes_all
610  {\edef\currentnoteinternal{\clf_noteinternal{\currentnote}\currentnotenumber}%
611   \ifcase\currentnoteinternal\relax
612     \strc_references_prepare_display_references_nop
613   \else
614     \strc_references_get_simple_reference{*\currentnoteinternal}% reference
615     \edef\strc_notes_set_reference_attribute_text{\c_attr_reference\currentreferenceattribute}%
616     \strc_references_get_simple_reference{*\currentnoteinternal}% reference
617     \edef\strc_notes_set_reference_attribute_number{\c_attr_reference\currentreferenceattribute}%
618     \let\strc_notes_set_style_color_display\strc_notes_set_style_color_display_yes
619   \fi}
620
621\letvalue{\??noteinteractiondisplay\v!no    }\strc_references_prepare_display_references_nop
622\letvalue{\??noteinteractiondisplay\v!all   }\strc_references_prepare_display_references_yes_all
623\letvalue{\??noteinteractiondisplay\v!number}\strc_references_prepare_display_references_yes_number
624\letvalue{\??noteinteractiondisplay\v!text  }\strc_references_prepare_display_references_yes_text
625\letvalue{\??noteinteractiondisplay\v!yes   }\strc_references_prepare_display_references_yes_number
626
627\let\strc_notes_set_style_color_inline_nop \usenotestyleandcolor
628\let\strc_notes_set_style_color_display_nop\usenotationstyleandcolor
629
630\unexpanded\def\strc_notes_set_style_color_inline_yes#style#color%
631  {\usenotestyleandcolor#style#color%
632   \iflocation\strc_notes_set_style_color_special\fi}
633
634\unexpanded\def\strc_notes_set_style_color_display_yes#style#color%
635  {\usenotationstyleandcolor#style#color%
636   \iflocation\strc_notes_set_style_color_special\fi}
637
638\def\strc_notes_set_style_color_special
639  {\iftrialtypesetting
640      % keep
641   \else\ifx\currentcolorparameter\empty
642     \scratchcounter\clf_notedeltapage{\currentnote}\currentnotenumber\relax % todo calculate once
643     \setlocationcolorspecified\scratchcounter
644   \fi\fi}
645
646\setvalue{\??constructiontexthandler\v!notation}%
647  {\begingroup
648   % we need to retrigger the reference as otherwise it gets lost because we don't do nested
649   % references with the same id ... maybe some day if we can figure out a nice heuristic ...
650   % the problem is that normally it's no issue but here we lap into the margin, so maybe that's
651   % a criterium
652 % \strc_notes_interaction_check_display
653   \strc_notes_set_reference_attribute_number
654   \dotagsetnotation
655   \strc_notes_set_style_color_display\c!headstyle\c!headcolor
656   \strc_enumerations_text
657   \endgroup}
658
659% in mkii the pointer only showed up in pagewise notes
660
661\unexpanded\def\strc_notes_inject_pointer % todo calculate once
662  {\ifcase\clf_notedeltapage{\currentnote}\currentnotenumber\relax\relax
663     % unknown
664   \or
665     % same page
666   \or
667     \noteparameter\c!symbolcommand{\symbol[\v!note:\v!nextpage]}%
668   \or
669     \noteparameter\c!symbolcommand{\symbol[\v!note:\v!previouspage]}%
670   \fi}
671
672\unexpanded\def\strc_notes_inject_symbol_yes
673  {\strc_notes_inject_symbol_indeed\conditionaltrue}
674
675\unexpanded\def\strc_notes_inject_symbol_nop
676  {\strc_notes_inject_symbol_indeed\conditionalfalse}
677
678\definemargindata
679  [strc_notes_destination_margin]
680  [\v!left]
681  [\c!margin=\zeropoint,
682   \c!width=\zeropoint,
683   \c!style=,
684   \c!color=]
685
686% \unexpanded\def\strc_notes_destination_hack
687%   {\ifx\strc_notes_get_destination_attribute_symbol\empty\else
688%      \strc_notes_destination_hack_indeed
689%    \fi}
690%
691% \unexpanded\def\strc_notes_destination_hack_indeed % can be a helper
692%   {\strc_notes_destination_margin
693%      {\setbox\scratchbox\hpack \strc_notes_get_destination_attribute_symbol{}%
694%       \wd\scratchbox\makeupwidth
695%       \ht\scratchbox\strutht
696%       \dp\scratchbox\strutdp
697%       \hpack to \zeropoint{\box\scratchbox\hss}}}
698
699\unexpanded\def\strc_notes_inject_symbol_indeed#synchronize%
700  {\ifconditional\c_strc_notations_anchored_next\else
701     \removeunwantedspaces
702     \doifelseitalic\/\donothing % Charles IV \footnote{the fourth}
703   \fi
704   \ifdim\lastkern=\notesignal
705   % \kern\noteparameter\c!distance % yes or no note font? or main text
706     \strc_notes_inject_separator
707   \fi
708   \nobreak
709   \begingroup
710   \strc_notes_interaction_check_inline
711   \strc_notes_set_style_color_inline\c!textstyle\c!textcolor
712   \hbox \strc_notes_get_reference_attribute_symbol \strc_notes_get_destination_attribute_symbol \bgroup
713  % \hbox \strc_notes_get_reference_attribute_symbol \bgroup \strc_notes_destination_hack
714     \strc_references_flush_destination_nodes % a bit late but ok
715     \dostarttagged\t!descriptionsymbol\currentnote
716     \dotagsetnotesymbol
717     \noteparameter\c!textcommand{\clf_noteprefixednumber{\currentnote}\currentnotenumber\relax}%
718     % the next one can cycle so we need to make sure it has no advance width
719     \doif{\noteparameter\c!indicator}\v!yes\strc_notes_inject_pointer
720     \dostoptagged
721   \egroup
722   \endgroup
723   \glet\lastnotesymbol\relax}
724
725\unexpanded\def\strc_notes_inject_dummy % temp hack
726  {\removeunwantedspaces
727   \doifelseitalic\/\donothing % Charles IV \footnote{the fourth}
728   \ifdim\lastkern=\notesignal
729   % \kern\noteparameter\c!distance % yes or no note font? or main text
730     \strc_notes_inject_separator
731   \fi
732   \nobreak
733   \hpack to .5\emwidth{}%
734   \glet\lastnotesymbol\relax}
735
736\unexpanded\def\strc_notes_inject_separator % patch by WS due to request on list
737  {\edef\p_textseparator{\noteparameter\c!textseparator}%
738   \ifx\p_textseparator\empty
739     \kern\noteparameter\c!distance
740   \else
741     % skip or kern
742     \nobreak
743     \hbox\bgroup
744       \strc_notes_interaction_check_inline
745       \strc_notes_set_style_color_inline\c!textstyle\c!textcolor
746       \noteparameter\c!textcommand{\p_textseparator}%
747       \kern\noteparameter\c!distance
748     \egroup
749     \nobreak
750   \fi}
751
752% this needs a further cleanup ... soon as it's a slow mechanism
753%
754% -- set breakpoint in descriptions
755% -- reset after trialtypesetting
756% -- that way we can trick the symbol space
757
758% removed:
759%
760% \pushsomestates
761%
762% core-ins -> obsolete
763%
764% saveinsertiondata
765% restoreinsertiondata
766% saveinsertionbox
767% eraseinsertionbackup
768% restoreinsertionbackup
769
770\def\savenotedata      {} % \writestatus{todo}{save    note data}}
771\def\restorenotedata   {} % \writestatus{todo}{restore note data}}
772\def\savenotecontent   {} % \writestatus{todo}{save    note content}}
773\def\restorenotecontent{} % \writestatus{todo}{restore note content}}
774\def\erasenotebackup   {} % \writestatus{todo}{erase   note backup}}
775
776% page-set:
777
778\def\enablenotes    {\writestatus{todo}{enable  notes}}
779\def\disablenotes   {\writestatus{todo}{disable notes}}
780\def\savenotes      {\writestatus{todo}{save    notes}}
781\def\flushsavednotes{\writestatus{todo}{flush   notes}}
782
783% experiment: (compare scope=text and scope=page)
784%
785% \definenote[mynote][way=bytext,location=text,width=\leftmarginwidth,scope=page,rule=,before=,after=,factor=0]
786% \setuptexttexts[margin][\vbox to \textheight{\placenotes[mynote]\vfill}][]
787
788%D Footnotes are can be characterized by three components:
789%D
790%D \startitemize[packed]
791%D \item a small number \footnote {a footnote number} or symbol {\setupfootnotes
792%D   [conversion=set 2]\footnote {a footnote}}
793%D \item and a similar mark at the bottom of the page
794%D \item followed by some additional text
795%D \stopitemize
796%D
797%D Because footnotes are declared at the location of their reference they can be
798%D seen as a special kind of floating bodies. Their placement is postponed but has
799%D to be taken into account in the pagebreak calculations. This kind of calculations
800%D are forced by using \type{\insert}s and dealing with all cases is not trivial.
801
802%D \macros
803%D   {notesenabled}
804%D
805%D We need a couple of states because at some moments we don't want to mess around
806%D with inserts at all. Take for instance a table of contents. And so we can
807%D temporary disable footnotes by saying
808%D
809%D \starttyping
810%D \notesenabledfalse
811%D \stoptyping
812
813\newif\ifnotesenabled \notesenabledtrue
814
815% better mark a note .. once flushed no more flushing
816
817%appendtoks \notesenabledfalse \to \everymarking
818\appendtoks \notesenabledfalse \to \everybeforepagebody
819\appendtoks \notesenabledfalse \to \everystructurelist    % quick hack
820\appendtoks \notesenabledfalse \to \everysimplifycommands % quick hack
821\appendtoks \notesenabledfalse \to \everypreroll          % quick hack
822
823%D Often we need to process the whole set of notes and to make that fast, we use a
824%D token register:
825
826% we have several synchronizers:
827%
828% - after a definition
829% - after a specific setup
830% - after a general setup (inheritance of dimensions)
831% - just before a note is typeset
832
833\newtoks\t_strc_notes
834
835\let\strc_notes_process_list\gobbleoneargument
836
837\unexpanded\def\strc_notes_process#action% argument is a \macro that uses \currentnote
838  {\def\strc_notes_process_list##1{\edef\currentnote{##1}\let\currentdescription\currentnote#action}%
839   \the\t_strc_notes}
840
841\newtoks\everychecknote       % just before a note is typeset
842\newtoks\everysynchronizenote % after a general setup has happened
843
844\appendtoks
845    \ifx\currentnote\empty \else
846        \setupnotations[\currentnote][]% also a synchronize
847    \fi
848\to \everysynchronizenote
849
850\def\strc_notes_synchronize
851  {\the\everysynchronizenote} % we can speed this one up if needed by avoiding the commalist
852
853\appendtoks
854    \strc_notes_process\strc_notes_synchronize
855\to \everysetupnoteroot
856
857\appendtoks
858    \the\everysynchronizenote
859\to \everydefinenote
860
861% \starttext
862%     text \startfootnote Test.\stopfootnote
863%     test \footnote{xxxx} \subfootnote{xxxx}
864%     test \footnote{xxxx} \subfootnote{xxxx}
865% \stoptext
866
867\installcorenamespace{notecommand}
868\installcorenamespace{notealign}
869\installcorenamespace{notepenalty}
870\installcorenamespace{noterule}
871
872\def\currentnoterulecommand{\begincsname\??notecommand\currentnote\endcsname}
873\def\currentnoterulealign  {\begincsname\??notealign  \currentnote\endcsname}
874
875\def\currentnoterulecommandcommand{\noteparameter\c!rulecommand}
876\def\currentnoterulecommandnormal {\normalnoterule} % no let as it can be changed afterwards
877%def\currentnoterulecommandunknown{\noteparameter\c!rule}
878
879\def\letcurrentnoterulecommand{\expandafter\let\csname\??notecommand\currentnote\endcsname}
880\def\letcurrentnoterulealign  {\expandafter\let\csname\??notealign  \currentnote\endcsname}
881
882\appendtoks
883    \letvalue{\??notecommand\currentnote}\currentnoterulecommandnormal
884    \letvalue{\??notealign  \currentnote}\lefttoright
885\to \everysynchronizenote
886
887\def\strc_notes_set_rule
888  {\letcurrentnoterulecommand\relax % so we default to nothing
889   \letcurrentnoterulealign  \relax
890   \processcommacommand[\noteparameter\c!rule]\strc_notes_set_rule_step}
891
892\def\strc_notes_set_rule_step#alternative%
893  {\begincsname\??noterule#alternative\endcsname}
894
895\def\strc_notes_set_rule_autodir
896  {\doifelserighttoleftinbox\currentnoteinsertionnumber\righttoleft\lefttoright}
897
898\setvalue{\??noterule  \v!command}{\letcurrentnoterulecommand\currentnoterulecommandcommand}
899\setvalue{\??noterule       \v!on}{\letcurrentnoterulecommand\currentnoterulecommandnormal}
900\setvalue{\??noterule   \v!normal}{\letcurrentnoterulecommand\currentnoterulecommandnormal}
901\setvalue{\??noterule     \v!left}{\letcurrentnoterulecommand\currentnoterulecommandnormal
902                                   \letcurrentnoterulealign  \lefttoright}
903\setvalue{\??noterule    \v!right}{\letcurrentnoterulecommand\currentnoterulecommandnormal
904                                   \letcurrentnoterulealign  \righttoleft}
905\setvalue{\??noterule\v!paragraph}{\letcurrentnoterulecommand\currentnoterulecommandnormal
906                                   \letcurrentnoterulealign  \strc_notes_set_rule_autodir}
907\setvalue{\??noterule      \v!off}{\letcurrentnoterulecommand\relax}
908
909\appendtoks
910    \strc_notes_set_rule
911\to \everysynchronizenote
912
913\def\currentnotepenalty
914  {\ifcsname\??notepenalty\noteparameter\c!split\endcsname
915     \lastnamedcs
916   \else
917     \numexpr\noteparameter\c!split\relax
918   \fi}
919
920\setnewconstant\notepenaltytolerant  \zerocount
921\setnewconstant\notepenaltystrict    9999
922\setnewconstant\notepenaltyverystrict\maxdimen
923
924\letvalue{\??notepenalty\v!tolerant  }\notepenaltytolerant
925\letvalue{\??notepenalty\v!strict    }\notepenaltystrict
926\letvalue{\??notepenalty\v!verystrict}\notepenaltyverystrict
927\letvalue{\??notepenalty             }\notepenaltytolerant
928
929%D The following switch can be used to disable limiting the height of the footnote
930%D area, something that is needed in multi column balancing. Use this switch with
931%D care.
932
933\newif\ifnotelimit \notelimittrue % shared
934
935\def\strc_notes_set_factor
936  {\edef\p_factor{\noteparameter\c!factor}%
937   \ifx\p_factor\empty \else
938     \ifnum\p_factor<\zerocount \else
939%        \global
940       \count\currentnoteinsertionnumber\p_factor % new: global
941     \fi
942   \fi}
943
944\appendtoks
945    \strc_notes_set_factor
946\to \everysynchronizenote
947
948% locations:
949
950\installcorenamespace{notelocationvariant}
951\installcorenamespace{notepositionvariant}
952\installcorenamespace{notedelayedvariant}
953\installcorenamespace{notelocation}
954
955\newconditional\c_strc_notes_delayed
956
957\unexpanded\def\strc_notes_set_delayed_yes{\settrue \c_strc_notes_delayed}
958\unexpanded\def\strc_notes_set_delayed_nop{\setfalse\c_strc_notes_delayed}
959
960\setvalue{\??notelocation\v!page       }{\letvalue{\??notedelayedvariant \currentnote}\strc_notes_set_delayed_nop
961                                         \letvalue{\??notelocationvariant\currentnote}\strc_notes_set_location_page}
962\setvalue{\??notelocation\v!columns    }{\letvalue{\??notedelayedvariant \currentnote}\strc_notes_set_delayed_nop
963                                         \letvalue{\??notelocationvariant\currentnote}\strc_notes_set_location_columns}
964\setvalue{\??notelocation\v!lastcolumn }{\letvalue{\??notedelayedvariant \currentnote}\strc_notes_set_delayed_nop
965                                         \letvalue{\??notelocationvariant\currentnote}\strc_notes_set_location_lastcolumn}
966\setvalue{\??notelocation\v!firstcolumn}{\letvalue{\??notedelayedvariant \currentnote}\strc_notes_set_delayed_nop
967                                         \letvalue{\??notelocationvariant\currentnote}\strc_notes_set_location_firstcolumn}
968\setvalue{\??notelocation\v!none       }{\letvalue{\??notedelayedvariant \currentnote}\strc_notes_set_delayed_yes
969                                         \letvalue{\??notelocationvariant\currentnote}\strc_notes_set_location_none}
970\setvalue{\??notelocation\v!text       }{\letvalue{\??notedelayedvariant \currentnote}\strc_notes_set_delayed_yes
971                                         \letvalue{\??notelocationvariant\currentnote}\strc_notes_set_location_text}
972\setvalue{\??notelocation\v!high       }{\letvalue{\??notepositionvariant\currentnote}\strc_notes_set_position_high}
973\setvalue{\??notelocation\v!bottom     }{\letvalue{\??notepositionvariant\currentnote}\strc_notes_set_position_bottom}
974
975\setvalue{\??notedelayedvariant \??notedelayedvariant }{\strc_notes_set_delayed_nop}      % not let
976\setvalue{\??notepositionvariant\??notepositionvariant}{\strc_notes_set_position_bottom}  % not let
977\setvalue{\??notelocationvariant\??notelocationvariant}{\strc_notes_set_location_page}    % not let
978
979\unexpanded\def\strc_notes_set_delayed
980  {\csname\??notedelayedvariant
981     \ifcsname\??notedelayedvariant\currentnote\endcsname
982       \currentnote
983     \else
984       \??notedelayedvariant
985     \fi
986   \endcsname}
987
988% \let\strc_notes_set_delayed_yes\truecondition
989% \let\strc_notes_set_delayed_nop\falsecondition
990%
991% \def\c_strc_notes_delayed
992%   {\csname\??notedelayedvariant
993%      \ifcsname\??notedelayedvariant\currentnote\endcsname
994%        \currentnote
995%      \else
996%        \??notedelayedvariant
997%      \fi
998%    \endcsname}
999
1000\unexpanded\def\strc_notes_set_position
1001  {\csname\??notepositionvariant
1002     \ifcsname\??notepositionvariant\currentnote\endcsname
1003       \currentnote
1004     \else
1005       \??notepositionvariant
1006     \fi
1007   \endcsname}
1008
1009\unexpanded\def\strc_notes_set_location
1010  {\csname\??notelocationvariant
1011     \ifcsname\??notelocationvariant\currentnote\endcsname
1012       \currentnote
1013     \else
1014       \??notelocationvariant
1015     \fi
1016   \endcsname}
1017
1018\unexpanded\def\strc_notes_set_variants
1019  {\normalexpanded{\rawprocesscommalist[\noteparameter\c!location]\strc_notes_set_location_step}}
1020
1021\unexpanded\def\strc_notes_set_location_step#alternative% the insert related one
1022 %{\ifcsname\??notelocation#alternative\endcsname\csname\??notelocation#alternative\endcsname\fi}
1023  {\begincsname\??notelocation#alternative\endcsname}
1024
1025\appendtoks
1026    \strc_notes_set_variants
1027    \strc_notes_set_delayed
1028\to \everysynchronizenote
1029
1030\newskip \s_strc_notes_distance % we need to implement stretch
1031\newcount\c_strc_notes_columns
1032
1033\newskip       \s_strc_notes_before
1034\newskip       \s_strc_notes_inbetween
1035\newconditional\c_strc_notes_first_flushed
1036
1037\appendtoks
1038    \edef\p_spacebefore{\rootnoteparameter\c!spacebefore}%
1039    \ifx\p_spacebefore\empty
1040        \global\s_strc_notes_before\zeropoint
1041    \else
1042        \setbox\scratchbox\vbox{\blank[\p_spacebefore]\global\s_strc_notes_before\lastskip}%
1043    \fi
1044    \edef\p_spaceinbetween{\rootnoteparameter\c!spaceinbetween}%
1045    \ifx\p_spaceinbetween\empty
1046        \global\s_strc_notes_inbetween\zeropoint
1047    \else
1048        \setbox\scratchbox\vbox{\blank[\p_spaceinbetween]\global\s_strc_notes_inbetween\lastskip}%
1049    \fi
1050\to \everysynchronizenote
1051
1052\def\strc_notes_set_distance
1053  {\begingroup
1054   \restoreglobalbodyfont
1055   \setbox\scratchbox\vbox % no reuse as it can mirror
1056     {\forgetall
1057      \dontcomplain
1058      \noteparameter\c!before
1059      \placenoterule
1060      \strut
1061      \noteparameter\c!after}%
1062   % also dp now
1063   \scratchdimen\dimexpr\htdp\scratchbox-\lineheight\relax
1064   \ifgridsnapping
1065     \getnoflines\scratchdimen
1066     \scratchdimen\noflines\lineheight
1067   \fi
1068   \expandafter\endgroup\expandafter
1069   \s_strc_notes_distance\the\scratchdimen\relax}
1070
1071\def\strc_notes_set_columns
1072  {\c_strc_notes_columns\noteparameter\c!n\relax
1073   \ifcase\c_strc_notes_columns
1074     \c_strc_notes_columns\plusone
1075   \fi}
1076
1077% \def\strc_notes_set_location_page
1078%   {\setfalse\c_strc_notes_delayed
1079%    \strc_notes_set_distance
1080%    \strc_notes_set_columns
1081%    \page_inserts_set_location\currentnoteinsertion\v!page % \setupinsertion[\currentnote][\c!location=\v!page]%
1082%    \global\count\currentnoteinsertionnumber\numexpr\plusthousand/\c_strc_notes_columns\relax
1083%    \global\dimen\currentnoteinsertionnumber\ifnotelimit\dimexpr\noteparameter\c!height*\c_strc_notes_columns\relax\else\maxdimen\fi
1084%    \global\skip \currentnoteinsertionnumber\s_strc_notes_distance\relax}
1085
1086\def\strc_notes_set_location_page
1087  {\setfalse\c_strc_notes_delayed
1088   \strc_notes_set_distance
1089   \strc_notes_set_columns
1090   \page_inserts_set_location\currentnoteinsertion\v!page % \setupinsertion[\currentnote][\c!location=\v!page]%
1091   \global\count\currentnoteinsertionnumber\numexpr(\plusthousand/\c_strc_notes_columns)*\nofmulticolumns\relax
1092   \global\dimen\currentnoteinsertionnumber\ifnotelimit\dimexpr\noteparameter\c!height*\c_strc_notes_columns\relax\else\maxdimen\fi
1093   \global\skip \currentnoteinsertionnumber\s_strc_notes_distance}
1094
1095\def\strc_notes_set_location_columns
1096  {\setfalse\c_strc_notes_delayed
1097   \strc_notes_set_distance
1098   \strc_notes_set_columns
1099   \ifnum\currentnofcolumns=\zerocount
1100     \c_strc_notes_columns\plusone
1101   \fi
1102   \page_inserts_set_location\currentnoteinsertion\v!columns % \setupinsertion[\currentnote][\c!location=\v!columns]%
1103   \global\count\currentnoteinsertionnumber\numexpr\plusthousand/\c_strc_notes_columns\relax
1104   \global\dimen\currentnoteinsertionnumber\ifnotelimit\dimexpr\noteparameter\c!height*\c_strc_notes_columns\relax\else\maxdimen\fi
1105   \global\skip \currentnoteinsertionnumber\s_strc_notes_distance}
1106
1107\def\strc_notes_set_location_somecolumn#whatcolumn%
1108  {\setfalse\c_strc_notes_delayed
1109   \strc_notes_set_distance
1110   \strc_notes_set_columns
1111   \page_inserts_set_location\currentnoteinsertion#whatcolumn% \setupinsertion[\currentnote][\c!location=#whatcolumn]%
1112   \global\count\currentnoteinsertionnumber\plusthousand
1113   \global\dimen\currentnoteinsertionnumber\ifnotelimit\noteparameter\c!height\else\maxdimen\fi
1114   \global\skip \currentnoteinsertionnumber\s_strc_notes_distance}
1115
1116\def\strc_notes_set_location_firstcolumn{\strc_notes_set_location_somecolumn\v!firstcolumn}
1117\def\strc_notes_set_location_lastcolumn {\strc_notes_set_location_somecolumn\v!lastcolumn }
1118
1119\def\strc_notes_set_location_text % we don't use inserts anyway (e.g. endnotes)
1120  {\settrue\c_strc_notes_delayed
1121   \clf_setnotestate{\currentnote}{store}%
1122   \page_inserts_set_location\currentnoteinsertion\v!text % \setupinsertion[\currentnote][\c!location=\v!text]%
1123   \global\count\currentnoteinsertionnumber\zerocount
1124   \global\dimen\currentnoteinsertionnumber\maxdimen
1125   \global\skip \currentnoteinsertionnumber\zeropoint}
1126
1127\let\strc_notes_set_location_none\strc_notes_set_location_text
1128
1129\def\strc_notes_set_properties
1130  {\strc_notes_set_columns
1131   \strc_notes_set_distance
1132   \strc_notes_set_location
1133   \strc_notes_set_delayed}
1134
1135\let\strc_notes_set_position_high\relax
1136
1137\def\strc_notes_set_position_bottom
1138  {\settrue\c_notes_bottom_present}
1139
1140\appendtoks
1141    \strc_notes_set_properties
1142\to \everysynchronizenote
1143
1144%D A fast checker for bottom notes being used:
1145
1146\newconditional\c_notes_bottom_present
1147
1148\def\strc_notes_check_if_bottom_present_indeed % in otr !
1149  {\ifvoid\currentnoteinsertionnumber\else
1150     \strc_notes_set_position
1151   \fi}
1152
1153\def\strc_notes_check_if_bottom_present_step
1154  {\ifconditional\c_notes_bottom_present\else\strc_notes_check_if_bottom_present_indeed\fi}
1155
1156\def\strc_notes_check_if_bottom_present
1157  {\setfalse\c_notes_bottom_present
1158   \strc_notes_process\strc_notes_check_if_bottom_present_step}
1159
1160% Example of using factor:
1161%
1162% \definenote[mynote][way=bypage,location=text,width=\marginwidth,rule=,before=,factor=0]
1163% \setuplayout[backspace=5cm,margin=3cm,margindistance=.5cm,width=middle]
1164% \setuptexttexts[margin][\vbox to \textheight{\placenotes[mynote]\vfill}][]
1165% \starttext
1166% \dorecurse{10}{test \mynote{one one one one one one} \input zapf \mynote{one one one one one one} }
1167% \stoptext
1168
1169%D The noterule can be a graphic and therefore calling this setup macro at every
1170%D skipswitch is tricky (many many MP runs). Let's just reserve a few points, that
1171%D probably match those of the stretch component. A bit messy:
1172
1173\unexpanded\def\placenoterule
1174  {\begingroup
1175   \currentnoterulealign
1176   \currentnoterulecommand
1177   \par
1178   \endgroup}
1179
1180\unexpanded\def\normalnoterule
1181  {\ifvmode
1182     \dontleavehmode \blackrule
1183       [\c!color=\noteparameter\c!rulecolor,
1184        \c!width=.2\hsize,
1185        \c!height=\noteparameter\c!rulethickness,
1186        \c!depth=\zeropoint]%
1187     \endgraf
1188     \kern\strutdepth
1189   \fi}
1190
1191%D The formatting depends on the width of the table, so we have to set \type {n} to
1192%D zero.
1193%D
1194%D \starttyping
1195%D \startbuffer
1196%D \bTABLE
1197%D \bTR \bTD one \footnote{\dorecurse{10}{abcd }} \eTD \bTD two \eTD \eTR
1198%D \bTR \bTD three fout five six seven eight nine \eTD \bTD ten \eTD \eTR
1199%D \eTABLE
1200%D \stopbuffer
1201%D
1202%D \startlocalfootnotes[n=0,location={text,none}]
1203%D \placelegend[n=2]{\getbuffer}{\placelocalfootnotes}
1204%D \stoplocalfootnotes
1205%D \stoptyping
1206
1207%D \macros
1208%D   {footnote}
1209%D
1210%D A footnote can have a reference as optional argument and therefore its formal
1211%D specification looks like:
1212%D
1213%D \showsetup{footnote}
1214%D
1215%D This command has one optional command: the reference. By saying \type{[-]} the
1216%D number is omitted. The footnote command is not that sensitive to spacing, so it's
1217%D quite legal to say:
1218%D
1219%D \startbuffer
1220%D Users of \CONTEXT\ must keep both feet \footnote {Given they have two.} on the
1221%D ground and not get confused \footnote {Or even crazy.} by all those obscure
1222%D \footnote {But fortunately readable.} parameters.
1223%D \stopbuffer
1224%D
1225%D \typebuffer
1226%D
1227%D When setting the \type{conversion} to \type{set 2} we get
1228%D something like:
1229%D
1230%D \bgroup
1231%D \startnarrower
1232%D \setupfootnotes[conversion=set 1]
1233%D \getbuffer
1234%D \stopnarrower
1235%D \egroup
1236%D
1237%D Typesetting footnotes is, at least for the moment, disabled when reshaping boxes.
1238%D The additional macro \type {\footnotetext} and the associated \type {\note} macro
1239%D were implemented at request of users on the mailing list and a suggestion by taco
1240%D to split of the symbol placement. I decided to merge this functionality with the
1241%D existing \type {\note} functionality.
1242
1243\newconditional\c_strc_notes_symbol \settrue\c_strc_notes_symbol % not used
1244\newconditional\c_strc_notes_skip
1245
1246\unexpanded\def\setnote    [#tag]{\csname#tag\endcsname}
1247\unexpanded\def\setnotetext[#tag]{\global\settrue\c_strc_notes_skip\csname#tag\endcsname}
1248
1249\unexpanded\def\handlenoteinsert#tag#id%
1250  {\begingroup
1251   \edef\currentnote{#tag}%
1252   \strc_constructions_initialize{#tag}%
1253   \strc_notes_synchronize
1254   \the\everybeforenoteinsert
1255   \insert\currentnoteinsertionnumber\bgroup
1256     \the\everyinsidenoteinsert\relax
1257     \usesetupsparameter\noteparameter % experimental
1258     \useinterlinespaceparameter\noteparameter
1259     \doifelse{\noteparameter\c!paragraph}\v!yes
1260        {\nointerlineskip
1261         \startvboxtohboxseparator
1262           \noteparameter\c!inbetween
1263         \stopvboxtohboxseparator
1264         \startvboxtohbox
1265           \handlenoteitself{#tag}{#id}%
1266         \stopvboxtohbox}
1267        {\handlenoteitself{#tag}{#id}}%
1268   \egroup
1269   \the\everyafternoteinsert
1270   \endgroup}
1271
1272\unexpanded\def\betweennoteitself#tag% used ?
1273  {\edef\currentnote{#tag}%
1274   \doif{\noteparameter\c!paragraph}\v!yes{\noteparameter\c!inbetween}}
1275
1276\unexpanded\def\handlenoteitself#tag#id%
1277  {\edef\currentnotenumber{#id}%
1278   \edef\currentnote{#tag}%
1279   \strc_constructions_initialize{#tag}%
1280   \strc_notes_synchronize
1281   \edef\currentconstructionlistentry{\clf_notelistindex{\currentnote}#id}% index in list cache
1282   % as we can have collected notes (e.g. in tables) we need to recover
1283   % \currentdescriptionattribute and \currentdescriptionsynchronize
1284   %
1285   \reinstatecachedconstructionnumberentry\currentconstructionlistentry % we could store the number in the entry (e.g. needed when local notes in table)
1286   %
1287   \dontcomplain
1288   %begingroup
1289   \strc_notes_interaction_check_display
1290   \strc_notes_set_reference_attribute_text
1291   \strc_constructions_stored_start
1292   \begstrut
1293   \strc_references_flush_destination_nodes
1294   \strc_notes_set_destination_attribute_text
1295   \strc_notes_inject_text\relax
1296   \ifvmode\obeydepth\else\endstrut\fi % \obeydepth is new per 2015-01-10
1297   \strc_constructions_stored_stop
1298   %endgroup
1299   }
1300
1301\unexpanded\def\strc_notes_inject_text % hm main?
1302  {\clf_savedlisttitle{\currentconstructionmain}\currentconstructionlistentry\relax}
1303
1304\let\startpushnote\relax
1305\let\stoppushnote \relax
1306
1307\newsignal\notesignal
1308
1309\newconditional\processingnote
1310\newconditional\postponednote
1311
1312\newtoks\everybeforenoteinsert
1313\newtoks\everyinsidenoteinsert
1314\newtoks\everyafternoteinsert
1315
1316\unexpanded\def\doifelseinnote
1317  {\ifconditional\processingnote
1318     \expandafter\firstoftwoarguments
1319   \else
1320     \expandafter\secondoftwoarguments
1321   \fi}
1322
1323\appendtoks
1324   \let\flushnotes\relax
1325   \let\postponenotes\relax
1326   \forgetall
1327   \resetallattributes   % new, we don't want color bleed into notes
1328   \inheritmaintextcolor % but we do want to obey the textcolor
1329\to \everybeforenoteinsert
1330
1331% \def\strc_notes_set_penalties
1332%  {\doif{\noteparameter\c!scope}\v!page{\floatingpenalty\maxdimen}% experiment
1333%  %\interlinepenalty\maxdimen % todo
1334%   \penalty\currentnotepenalty}
1335
1336\def\strc_notes_set_penalties
1337  {% stored in insert node
1338   \floatingpenalty \currentnotepenalty
1339   % used when typesetting
1340   \interlinepenalty\plushundred % plain value
1341   % used when we need to split in columns
1342   \ifnum\noteparameter\c!n>\plusone
1343     \penalty\zerocount % otherwise no split in columns, maybe just always (tex just adds it to accumulated)
1344   \fi}
1345
1346\appendtoks
1347    \strc_notes_set_penalties
1348    \forgetall % again
1349    \strc_notes_set_bodyfont
1350    \redoconvertfont % to undo \undo calls in in headings etc
1351    \splittopskip\strutht  % not actually needed here
1352    \splitmaxdepth\strutdp % not actually needed here
1353    %
1354    % not:
1355    %
1356  % \leftmargindistance \noteparameter\c!margindistance
1357  % \rightmargindistance\leftmargindistance
1358  % \ifnum\noteparameter\c!n=\zerocount % no ifcase new 31-07-99 ; always ?
1359  %   \doifnotinset{\noteparameter\c!width}{\v!fit,\v!broad}\setnotehsize % ?
1360  % \fi
1361    %
1362    \pickupattributes
1363\to \everyinsidenoteinsert
1364
1365%D Nasty, the might be more:
1366
1367\appendtoks \strc_itemgroups_push \to \everybeforenoteinsert
1368\appendtoks \strc_itemgroups_pop  \to \everyafternoteinsert
1369
1370% maybe but better use [scope=local] here
1371%
1372% \appendtoks
1373%     \setfalse\inhibitmargindata
1374% \to \everyinsidenoteinsert
1375
1376\setupnotes
1377  [\c!width=\v!auto]
1378
1379\unexpanded\def\setnotehsize
1380  {\ifinsidemulticolumns
1381     \setnoteparameter\c!width{\makeupwidth}%
1382   \else
1383     \edef\p_width{\noteparameter\c!width}%
1384     \ifx\p_width\v!auto
1385     % \ifinsidecolumns
1386         \setnoteparameter\c!width{\ifdim\hsize<\makeupwidth\hsize\else\makeupwidth\fi}%
1387     % \else
1388     %   \setnoteparameter\c!width{\makeupwidth}%
1389     % \fi
1390     \else\ifx\p_width\empty
1391       \setnoteparameter\c!width{\hsize}%
1392     \fi\fi
1393  \fi
1394  \hsize\noteparameter\c!width\relax}
1395
1396\appendtoks
1397    % only needed when columns (could be three \set...)
1398    \setnotehsize
1399    \setsimplecolumnshsize[\c!distance=\noteparameter\c!columndistance,\c!n=\noteparameter\c!n,\c!width=\noteparameter\c!width]%
1400\to \everyinsidenoteinsert
1401
1402%D Normally footnotes are saved as inserts that are called upon as soon as the
1403%D pagebody is constructed. The footnote insertion routine looks just like the
1404%D \PLAIN\ \TEX\ one, except that we check for the end note state.
1405
1406% testcase for split bottom alignment see (a) below
1407%
1408% \dorecurse{6}{\input tufte\footnote{\input ward \input tufte \relax}}
1409
1410\newconditional\c_strc_notes_first_placed
1411
1412\unexpanded\def\placenoteinserts
1413  {\setfalse\c_strc_notes_first_placed
1414   \strc_notes_process\strc_notes_place_inserts}
1415
1416\def\strc_notes_place_inserts
1417  {\strc_notes_set_delayed % \strc_notes_synchronize % we need to know if it's delayed
1418   \ifconditional\c_strc_notes_delayed \else
1419     \ifdim\ht\currentnoteinsertionnumber>\zeropoint % or a faster delayed test
1420       \strc_notes_place_inserts_indeed
1421       \settrue\c_strc_notes_first_placed
1422     \fi
1423   \fi}
1424
1425\def\strc_notes_place_inserts_indeed
1426  {\relax
1427   \ifdim\ht\currentnoteinsertionnumber>\zeropoint
1428     \endgraf
1429     \ifvmode
1430       \whitespace
1431       \ifconditional\c_strc_notes_first_placed
1432         \edef\p_spaceinbetween{\noteparameter\c!spaceinbetween}%
1433         \ifx\p_spaceinbetween\empty\else
1434           \blank[\p_spaceinbetween]%
1435         \fi
1436       \else
1437         \edef\p_spacebefore{\noteparameter\c!spacebefore}%
1438         \ifx\p_spacebefore\empty\else
1439           \blank[\p_spacebefore]%
1440         \fi
1441       \fi
1442       \noteparameter\c!before
1443     \fi
1444     \placenoterule
1445     \bgroup
1446     \strc_notes_set_bodyfont
1447     \setbox\scratchbox\hbox
1448       {\strc_notes_flush_inserts}%
1449     \page_postprocessors_linenumbers_deepbox\scratchbox
1450     \setbox\scratchbox\hbox
1451       {\setupcurrentnote
1452          [\c!location=,
1453           \c!width=\v!fit,
1454           \c!height=\v!fit,
1455           \c!strut=\v!no,
1456           \c!offset=\v!overlay]%
1457        \inheritednoteframed
1458          {\ifzeropt\dp\scratchbox                  % this hack is needed because \vadjust
1459             \hpack{\lower\strutdp\box\scratchbox}% % in margin number placement
1460           \else                                    % hides the (always) present depth
1461             \box\scratchbox
1462           \fi}}%
1463     \setbox\scratchbox\hpack{\lower\strutdepth\box\scratchbox}%
1464     \dp\scratchbox\strutdepth % so we know that it has the note bodyfont depth
1465     \ifvmode
1466       \nointerlineskip % else sometimes empty line
1467     \fi
1468     \box\scratchbox
1469     \egroup
1470     \endgraf
1471     \ifvmode
1472       \noteparameter\c!after
1473     \fi
1474   \fi}
1475
1476\def\strc_notes_flush_inserts
1477  {\ifcase\noteparameter\c!n\relax
1478     % should not happen
1479   \or
1480     \strc_notes_flush_inserts_normal
1481   \else
1482     \strc_notes_flush_inserts_columns
1483   \fi}
1484
1485\def\strc_notes_flush_inserts_normal
1486  {\strc_notes_flush_global
1487   \obeydepth} % (a) added , since split footnotes will not align properly
1488
1489\def\strc_notes_flush_inserts_columns
1490  {\begingroup
1491   \setnotehsize % probably still not ok for columns
1492   \startsimplecolumns[\c!distance=\noteparameter\c!columndistance,\c!n=\noteparameter\c!n,\c!width=\noteparameter\c!width]%
1493     \strc_notes_flush_global
1494   \stopsimplecolumns
1495   \endgroup}
1496
1497% idea: tag with attr and then just flush them again
1498
1499\def\strc_notes_flush_global
1500  {\begingroup
1501   \useinterlinespaceparameter\noteparameter
1502   \doifelse{\noteparameter\c!paragraph}\v!yes
1503     {\leftorrightvbox % cf mail from ws to list
1504        {\starthboxestohbox
1505           \iftrialtypesetting\unvcopy\else\unvbox\fi\currentnoteinsertionnumber
1506         \stophboxestohbox}}
1507     {\iftrialtypesetting
1508        \ifvmode\unvcopy\else\copy\fi
1509      \else
1510        \ifvmode\unvbox \else\box \fi
1511      \fi
1512      \currentnoteinsertionnumber}%
1513   \endgroup}
1514
1515%D Supporting end notes is surprisingly easy. Even better, we can combine this
1516%D feature with solving the common \TEX\ problem of disappearing inserts when
1517%D they're called for in deeply nested boxes. The general case looks like:
1518%D
1519%D \starttyping
1520%D \postponenotes
1521%D \.box{whatever we want with footnotes}
1522%D \flushnotes
1523%D \stoptyping
1524%D
1525%D This alternative can be used in headings, captions, tables etc. The latter one
1526%D sometimes calls for notes local to the table, which can be realized by saying
1527%D
1528%D \starttyping
1529%D \setlocalfootnotes
1530%D some kind of table with local footnotes
1531%D \placelocalfootnotes
1532%D \stoptyping
1533%D
1534%D Postponing is accomplished by simply redefining the (local) insert operation. A
1535%D not too robust method uses the \type{\insert} primitive when possible. This
1536%D method fails in situations where it's not entirely clear in what mode \TEX\ is.
1537%D Therefore the auto method can is to be overruled when needed.
1538
1539\newconditional\postponingnotes
1540
1541% we need a proper state: normal, postponing, flushing
1542
1543\unexpanded\def\postponenotes
1544  {\ifcase\insertionmigrationmode
1545     \ifconditional\postponingnotes\else
1546       \global\settrue\postponingnotes
1547       \glet\flushnotes\doflushnotes
1548       \clf_postponenotes
1549     \fi
1550   \fi}
1551
1552\let\flushnotes\relax
1553
1554% also \ifcase\insertionmigrationmode here, needs testing:
1555
1556\unexpanded\def\startpostponingnotes % experimental, page-mix
1557  {\ifconditional\postponingnotes\else
1558     \global\settrue\postponingnotes
1559    %\glet\flushnotes\doflushnotes
1560     \clf_postponenotes
1561   \fi}
1562
1563\unexpanded\def\stoppostponingnotes % experimental, page-mix
1564  {\doflushnotes}
1565
1566\unexpanded\def\doflushnotes
1567  {\ifconditional\postponingnotes
1568     \begingroup
1569     \let\flushnotes   \relax
1570     \let\postponenotes\relax
1571     \ifconditional\postponednote
1572       \ifhmode
1573         % needed for tagging ... otherwise we get some weird node free error
1574         \signalcharacter
1575       \fi
1576     \fi
1577     \clf_flushpostponednotes% this also resets the states !
1578     \global\setfalse\postponednote
1579     \global\setfalse\postponingnotes
1580     \glet\flushnotes\relax
1581     \endgroup
1582   \fi}
1583
1584%D \macros
1585%D   {startlocalfootnotes,placelocalfootnotes}
1586%D
1587%D The next two macros can be used in for instance tables, as we'll demonstrate
1588%D later on.
1589%D
1590%D \showsetup{startlocalfootnotes}
1591%D \showsetup{placelocalfootnotes}
1592
1593% todo: compatibility mode: when first arg is assignment or missing, then all
1594
1595\newtoks\everyplacelocalnotes
1596
1597\appendtoks
1598    \let\flushnotes   \relax
1599    \let\postponenotes\relax
1600\to \everyplacelocalnotes
1601
1602\newconditional\inlocalnotes
1603
1604\unexpanded\def\startlocalnotes
1605  {\dosingleempty\strc_notes_local_start}
1606
1607\def\strc_notes_local_start[#list]% grouping ? (we used to have a second argument ... settings)
1608  {\def\localnoteslist{#list}%
1609   \settrue\inlocalnotes
1610   \processcommacommand[\localnoteslist]\strc_notes_local_start_step}
1611
1612\unexpanded\def\stoplocalnotes
1613  {\processcommacommand[\localnoteslist]\strc_notes_local_stop_step
1614   \setfalse\inlocalnotes}
1615
1616\let\p_strc_notes_continue\empty
1617
1618\def\strc_notes_local_start_step#tag%
1619  {\p_strc_notes_continue{\noteparameter\c!continue}%
1620   \ifx\p_strc_notes_continue\v!yes \else
1621      \strc_counters_save{#tag}%
1622      \strc_counters_reset{#tag}%
1623   \fi
1624   \clf_savenote{#tag}{store}}
1625
1626\def\strc_notes_local_stop_step#tag%
1627  {\p_strc_notes_continue{\noteparameter\c!continue}%
1628   \ifx\p_strc_notes_continue\v!yes \else
1629     \strc_counters_restore{#tag}%
1630   \fi
1631   \clf_restorenote{#tag}}
1632
1633\unexpanded\def\placelocalnotes
1634  {\dodoubleempty\strc_notes_local_place}
1635
1636\def\strc_notes_local_place[#tag][#settings]%
1637  {\doif{\clf_getnotestate{#tag}}{store}{\strc_notes_local_place_indeed{#settings}{#tag}}}
1638
1639\def\strc_notes_local_place_indeed#settings#tag%
1640  {\begingroup
1641   \edef\currentnote{#tag}% is already set?
1642   \the\everyplacelocalnotes
1643   % beware, we cannot trust setting \currentnote here
1644   \setupcurrentnote[#settings]% later we set height etc for framed
1645   \strc_notes_place_local_alternative
1646   \strc_notes_set_properties % restore globals (if needed)
1647   \endgroup
1648  }% TODO: just restore properties \the\everychecknote} % we need to restore the old state
1649
1650%D These commands can be used like:
1651%D
1652%D \startbuffer
1653%D \startlocalnotes[footnote]
1654%D   \placetable
1655%D     {Some Table}
1656%D     \placeontopofeachother
1657%D       {\starttable[|l|r|]
1658%D        \HL
1659%D        \VL Nota\footnote{Bene} \VL Bene\footnote{Nota} \VL\SR
1660%D        \VL Bene\footnote{Nota} \VL Nota\footnote{Bene} \VL\SR
1661%D        \HL
1662%D        \stoptable}
1663%D       {\setupnotation[footnote][alternative={serried},distance=.5em,after=\hskip1em]%
1664%D        \placelocalnotes[footnote]}
1665%D \stoplocalnotes
1666%D \stopbuffer
1667%D
1668%D \typebuffer
1669%D
1670%D Because this table placement macro expect box content, and thanks to the grouping
1671%D of the local footnotes, we don't need additional braces.
1672%D
1673%D \getbuffer
1674
1675%D \macros
1676%D   {placefootnotes}
1677%D
1678%D We still have no decent command for placing footnotes somewhere else than at the
1679%D bottom of the page (for which no user action is needed). Footnotes (endnotes) can
1680%D be placed by using
1681%D
1682%D \showsetup{placefootnotes}
1683
1684\unexpanded\def\placebottomnotes
1685  {\strc_notes_process\strc_notes_place_inserts}
1686
1687\unexpanded\def\placenotes
1688  {\dodoubleempty\strc_notes_place}
1689
1690\def\strc_notes_place[#list][#settings]%
1691  {\processcommalist[#list]{\strc_notes_place_indeed{#settings}}}
1692
1693\def\strc_notes_place_indeed#settings#tag% settings note
1694  {\edef\currentnote{#tag}% grouping ?
1695   \doifelse{\clf_getnotestate{#tag}}{store}
1696     \strc_notes_local_place_indeed
1697     \strc_notes_global_place_indeed
1698     {#settings}{#tag}}
1699
1700\def\strc_notes_global_place_indeed#settings#tag%
1701  {\begingroup
1702   \setupnote[#tag][#settings]%
1703   \strc_notes_place_inserts
1704   \endgroup
1705   \the\everysetupnote} % to be checked .. synchronize
1706
1707%D Placement
1708
1709\installcorenamespace{notealternative}
1710
1711\unexpanded\def\installnotealternative#alternative#command%
1712  {\setvalue{\??notealternative#alternative}{#command}}
1713
1714\unexpanded\def\doifnotescollected#tag%
1715  {\clf_doifnotecontent{#tag}}
1716
1717\def\strc_notes_place_local_alternative % will be a setup (wrapper)
1718  {\doifnotescollected\currentnote
1719     {\endgraf
1720      \ifvmode
1721        \whitespace
1722        \noteparameter\c!before
1723      \fi
1724      \begingroup
1725      \strc_notes_set_bodyfont
1726      \csname\??notealternative\noteparameter\c!alternative\endcsname
1727      \endgroup
1728      \ifvmode
1729        \noteparameter\c!after
1730      \fi}}
1731
1732%D A stupid alternative is also provided:
1733%D
1734%D \starttyping
1735%D \setupfootnotes[location=text,alternative=none]
1736%D \stoptyping
1737
1738% setups ?
1739
1740\def\flushlocalnotes#tag{\clf_flushnotes{#tag}{store}{\noteparameter\c!criterium}}
1741
1742\installnotealternative \v!none
1743  {\flushlocalnotes\currentnote}
1744
1745\installnotealternative \empty
1746  {\flushlocalnotes\currentnote}
1747
1748\installnotealternative \v!grid % test if n > 0
1749  {\begingroup
1750   \setupcurrentnote[\c!location=]%
1751   \snaptogrid\hbox
1752     {\inheritednoteframed
1753        {\flushlocalnotes\currentnote}}%
1754   \endgroup}
1755
1756\installnotealternative \v!fixed % test if n > 0
1757  {\begingroup
1758   \setupcurrentnote[\c!location=]%
1759   \inheritednoteframed
1760     {\flushlocalnotes\currentnote}%
1761   \endgroup}
1762
1763\installnotealternative \v!columns % redundant
1764  {\begingroup
1765   \setupcurrentnote[\c!location=]%
1766   \inheritednoteframed
1767     {\edef\currentnotewidth{\noteparameter\c!width}%
1768      \doifelsedimension\currentnotewidth\donothing
1769        {\edef\currentnotewidth{\the\hsize}}%
1770      \startsimplecolumns[\c!distance=\noteparameter\c!columndistance,\c!n=\noteparameter\c!n,\c!width=\currentnotewidth]%
1771        \flushlocalnotes\currentnote
1772      \stopsimplecolumns}%
1773   \endgroup}
1774
1775% 0:page 1:firstcolumn 2:lastcolumn
1776
1777\newconstant\c_strc_notes_page_location
1778
1779\unexpanded\def\strc_notes_check_locations
1780  {\edef\p_strc_notes_location{\rootnoteparameter\c!location}%
1781   \c_strc_notes_page_location
1782      \ifx\p_strc_notes_location\v!firstcolumn\plusone  \else
1783      \ifx\p_strc_notes_location\v!lastcolumn \plustwo  \else
1784                                              \zerocount\fi\fi}
1785
1786\appendtoks
1787    \strc_notes_check_locations
1788\to \everysynchronizenote
1789
1790% still semi public (but will change)
1791
1792\newif\ifnotespresent
1793
1794\unexpanded\def\checknotepresence
1795  {\notespresentfalse
1796   \strc_notes_process\strc_notes_check_presence}
1797
1798\def\strc_notes_check_presence
1799  {\ifdim\ht\currentnoteinsertionnumber>\zeropoint
1800     \notespresenttrue
1801   \fi}
1802
1803%D \macros
1804%D   {fakenotes}
1805
1806    % used in page-mul
1807
1808    \ifdefined\currentnofcolumns\else \def\currentnofcolumns{\nofcolumns} \fi
1809
1810    \unexpanded\def\fakenotes
1811      {\ifhmode\endgraf\fi\ifvmode
1812         \calculatetotalclevernoteheight
1813         \ifdim\totalnoteheight>\zeropoint \kern\totalnoteheight \fi
1814       \fi}
1815
1816    \unexpanded\def\fakepagenotes
1817      {\ifhmode\endgraf\fi\ifvmode
1818         \calculatetotalpagenoteheight
1819         \ifdim\totalnoteheight>\zeropoint \kern\totalnoteheight \fi
1820       \fi}
1821
1822    % used in page-not but not yet ok
1823
1824    \newdimen\totalnoteheight
1825
1826    \unexpanded\def\additionaltotalnoteheight#insert% temp hacks anyway
1827      {\dimexpr
1828         \ifdim\ht#insert>\zeropoint
1829           \ifcase\count#insert %
1830             \zeropoint
1831           \else % todo: divide by count
1832             \ht#insert+\skip#insert% hm, no stretch but a dimen anyway
1833           \fi
1834         \else
1835           \zeropoint
1836         \fi
1837      \relax}
1838
1839    \def\docalculatetotalnoteheight
1840      {\ifcase\c_strc_notes_page_location % tricky here ! ! ! to be sorted out ! ! !
1841         \advance\totalnoteheight\normalexpanded{\additionaltotalnoteheight\currentnoteinsertionnumber}%
1842       \fi}
1843
1844    \def\docalculatetotalclevernoteheight
1845      {\ifcase\c_strc_notes_page_location \else % tricky here ! ! ! to be sorted out ! ! !
1846         \advance\totalnoteheight\normalexpanded{\additionaltotalnoteheight\currentnoteinsertionnumber}%
1847       \fi}
1848
1849    \def\docalculatetotalpagenoteheight
1850      {\advance\totalnoteheight\normalexpanded{\additionaltotalnoteheight\currentnoteinsertionnumber}}
1851
1852    \def\calculatetotalnoteheight      {\totalnoteheight\zeropoint\strc_notes_process\docalculatetotalnoteheight}
1853    \def\calculatetotalclevernoteheight{\totalnoteheight\zeropoint\strc_notes_process\docalculatetotalclevernoteheight}
1854    \def\calculatetotalpagenoteheight  {\totalnoteheight\zeropoint\strc_notes_process\docalculatetotalpagenoteheight}
1855
1856%D Now how can this mechanism be hooked into \CONTEXT\ without explictly postponing
1857%D footnotes? The solution turned out to be rather simple:
1858%D
1859%D \starttyping
1860%D \everypar  {...\flushnotes...}
1861%D \neverypar {...\postponenotes}
1862%D \stoptyping
1863%D
1864%D We can use \type {\neverypar} because in most commands sensitive to footnote
1865%D gobbling we disable \type {\everypar} in favor for \type {\neverypar}. In fact,
1866%D this footnote implementation is the first to use this scheme.
1867
1868%D This is a nasty and new secondary footnote flusher. It can be hooked into \type
1869%D {\everypar} like:
1870%D
1871%D \starttyping
1872%D \appendtoks \synchronizenotes \to \everypar
1873%D \stoptyping
1874
1875% \def\dosynchronizenotes
1876%   {\ifvoid\currentnoteinsertionnumber\else\insert\currentnoteinsertionnumber{\unvbox\currentnoteinsertionnumber}\fi}
1877%
1878% \def\synchronizenotes
1879%   {\strc_notes_process\dosynchronizenotes}
1880
1881\let\synchronizenotes\relax
1882
1883%D When typesetting footnotes, we have to return to the footnote specific bodyfont
1884%D size, which is in most cases derived from the global document bodyfont size. In
1885%D the previous macros we already used a footnote specific font setting macro.
1886
1887\def\strc_notes_set_bodyfont
1888  {\let\strc_notes_set_bodyfont\relax
1889   \restoreglobalbodyfont
1890   \usebodyfontparameter\noteparameter
1891   \usealignparameter\noteparameter}
1892
1893%D The footnote mechanism defaults to a traditional one column way of showing them.
1894%D By default we precede them by a small line.
1895
1896% end notes in the margin:
1897%
1898% \setuptexttexts
1899%   [margin]
1900%   [] [{\directsetup{notabene}}]
1901%
1902% \startsetups notabene
1903%     \vbox to \textheight \bgroup
1904%         \setupalign[tolerant]
1905%         \topskipcorrection
1906%         \placenotes[endnote][before=,after=]
1907%         \vfilll
1908%     \egroup
1909% \stopsetups
1910
1911\definenote [\v!footnote]
1912\definenote [\v!endnote ] [\c!location=\v!none] % else no break
1913
1914%D Compatibility macros:
1915
1916\unexpanded\def\setupfootnotedefinition{\setupnotation                                 [\v!footnote]}
1917\unexpanded\def\setupfootnotes         {\setupnote                                     [\v!footnote]}
1918           \def\footnotetext           {\setnotetext                                   [\v!footnote]}
1919\unexpanded\def\placefootnotes         {\dodoubleempty\strc_notes_place_footnotes      [\v!footnote]}
1920\unexpanded\def\placelocalfootnotes    {\dodoubleempty\strc_notes_place_local_footnotes[\v!footnote]}
1921\unexpanded\def\startlocalfootnotes    {\startlocalnotes                               [\v!footnote]} %  alleen footnote
1922\unexpanded\def\stoplocalfootnotes     {\stoplocalnotes }
1923
1924\def\strc_notes_place_footnotes[#list][#settings]%
1925  {\ifsecondargument
1926     \placenotes[#list][#settings,\c!height=\textheight]%
1927   \else
1928     \placenotes[#list][\c!height=\textheight]%
1929   \fi}
1930
1931\def\strc_notes_place_local_footnotes[#list][#settings]%
1932  {\ifsecondargument
1933     \placelocalnotes[#list][#settings,\c!height=\textheight]%
1934   \else
1935     \placelocalnotes[#list][\c!height=\textheight]%
1936   \fi}
1937
1938%D Goodies:
1939%D
1940%D \starttyping
1941%D \dorecurse {100} {
1942%D     test \footnote{\doifnoteonsamepageelse[footnote]{ibidem}{aaa}}
1943%D }
1944%D \stoptyping
1945
1946\def\doifelsenoteonsamepage#tag{\clf_doifnoteonsamepageasprevious{#tag}}
1947
1948\let\doifnoteonsamepageelse\doifelsenoteonsamepage
1949
1950%D New trickery:
1951
1952%D \macros
1953%D   {note}
1954%D
1955%D Refering to a note is accomplished by the rather short command:
1956%D
1957%D \showsetup{note}
1958%D
1959%D This command is implemented rather straightforward as:
1960
1961\installcorenamespace{notesymbol}
1962
1963\let\lastnotesymbol\relax % todo: per class
1964
1965\unexpanded\def\notesymbol
1966  {\dodoubleempty\strc_notes_symbol}
1967
1968\def\strc_notes_symbol[#tag][#reference]%
1969  {\ifnotesenabled
1970     \dontleavehmode
1971     \begingroup
1972     \edef\currentnote{#tag}%
1973     \usenotestyleandcolor\c!textstyle\c!textcolor
1974     \ifsecondargument
1975       \unskip
1976       \noteparameter\c!textcommand{\in[#reference]}% command here?
1977     \else
1978       \noteparameter\c!textcommand\lastnotesymbol % check if command double
1979     \fi
1980     \endgroup
1981   \fi}
1982
1983\unexpanded\def\note
1984  {\dodoubleempty\strc_notes_note}
1985
1986\def\strc_notes_note[#tag][#reference]%
1987  {\ifsecondargument
1988     \strc_notes_symbol[#tag][#reference]%
1989   \else
1990     \secondargumenttrue
1991     \strc_notes_symbol[\v!footnote][#tag]%
1992   \fi}
1993
1994% will be redone if needed
1995%
1996% \def\ownnotesymbol#1% #1 gets number passed
1997%   {\executeifdefined{\??notesymbol\currentnote}\empty}
1998%
1999% \unexpanded\def\setnotesymbol[#1]#2#3%
2000%   {\prewordbreak % prevent lookback
2001%    \setgvalue{\??notesymbol#1}{#3}
2002%    \strc_notes_inject_symbol}
2003%
2004% \unexpanded\def\ownnote[#1]#2#3#4%
2005%   {\setnotesymbol[#1]{#2}{#3}%
2006%    \setnotetext  [#1]{#4}}
2007%
2008% \defineconversion
2009%   [ownnote]
2010%   [\ownnotesymbol]
2011
2012% tricky:
2013%
2014% \enabletrackers[nodes.areas]
2015% \enabletrackers[nodes.references]
2016% \enabletrackers[nodes.destinations]
2017%
2018% \setupnotes[interaction=all,rule=no]
2019% \setupinteraction[state=start,focus=standard]
2020%
2021% \starttext
2022%     \goto{\input tufte\relax}[page(2)] \par
2023%     \ruledhbox{\gotobox{\vtop{\input tufte\relax}}[page(2)]} \par
2024%     \ruledhbox{\gotobox{\vbox{\input tufte\relax}}[page(2)]} \par
2025%     % \completecontent
2026%     % \chapter{Chapter}
2027%     % \dorecurse{5}{\input knuth}
2028%     a\footnote{\input tufte\par\input ward\relax}
2029% \stoptext
2030
2031%D Bonus:
2032
2033\appendtoks
2034   \setsystemmode\currentnote
2035\to \everysynchronizenote
2036
2037\protect \endinput
2038