diff options
author | Hans Hagen <pragma@wxs.nl> | 2020-10-31 00:09:22 +0100 |
---|---|---|
committer | Context Git Mirror Bot <phg@phi-gamma.net> | 2020-10-31 00:09:22 +0100 |
commit | 7043cd3b7046f6a11112a5d49c4ae5e2dc0c6896 (patch) | |
tree | 92ffcd258fb29e37b4a136eb071fbfd0717be29e /tex/context/base/mkiv/strc-not.mklx | |
parent | a0270f13065d116355a953c6f246cbba26289fc2 (diff) | |
download | context-7043cd3b7046f6a11112a5d49c4ae5e2dc0c6896.tar.gz |
2020-10-30 22:27:00
Diffstat (limited to 'tex/context/base/mkiv/strc-not.mklx')
-rw-r--r-- | tex/context/base/mkiv/strc-not.mklx | 1972 |
1 files changed, 1972 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/strc-not.mklx b/tex/context/base/mkiv/strc-not.mklx new file mode 100644 index 000000000..6e82c9c4e --- /dev/null +++ b/tex/context/base/mkiv/strc-not.mklx @@ -0,0 +1,1972 @@ +%D \module +%D [ file=strc-not, +%D version=2008.10.20, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Note Handling, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Structure Macros / Note Handling} + +\registerctxluafile{strc-not}{} + +\unprotect + +% todo: finish local rendering +% todo: more p_strc_notations_* (outside trial loop) +% todo: see if we can now use \insertpenalties (>0 == some left) + +\ifdefined\dotagsetnotesymbol \else \let\dotagsetnotesymbol\relax \fi +\ifdefined\dotagsetnotation \else \let\dotagsetnotation \relax \fi + +\protected\def\unvboxed {\ifvmode\unvbox \else\box \fi} % will change or used more often +\protected\def\unvcopied{\ifvmode\unvcopy\else\copy\fi} % will change or used more often + +%D \LMTX\ testcase: +%D +%D \starttyping +%D \hbox {\hbox{\footnote{HH1}\footnote{HH2}}} \par +%D \hbox {\hbox{x\footnote{XHH1}x\footnote{XHH2}}} \par +%D \vbox {\setbox0\hbox{\footnote{VH1}\footnote{VH2}}\box0} \par +%D \vbox {\hbox{\footnote{VH1}xxx\footnote{VH2}}} \par +%D \vbox {\hbox{\footnote{VH1}\footnote{VH2}} +%D \hbox{\footnote{VH1}\footnote{VH2}}} \par +%D \vbox {\hbox{x\footnote{XVH1}x\footnote{XVH2}}} \par +%D \vbox {\vbox{\footnote{VV1}\footnote{VV2}}} \par % two lines +%D \vbox {\vbox{x\footnote{XVV1}x\footnote{XVV2}}} \par +%D \stoptyping + +%D Notes have two handlers: notations and notes. Although notations can be defined +%D independently it makes not much sense. In principle we can treat notes as lists +%D but they are currently done as a variant on enumerations. I will provide a list +%D variant as well. One complication is that for page related notes inserts are used +%D and therefore notes are typeset immediately and descriptions are better suited +%D for that. For instance endnotes can as well be typeset using lists. + +% textcommand/textstyle/textcolor : set by note commandhandler and used for inline number + +%D \macros +%D {setupnote,setupnotation} +%D +%D We can influence footnote typesetting with the setup command: +%D +%D \showsetup{setupnotation} +%D \showsetup{setupnote} +%D +%D The definition command indicate that we can frame the footnote area. The +%D footnotes themselves are treated as descriptions. +%D +%D \showsetup{definenote} +%D +%D It's sort of a custom to precede footnotes by a horizontal rule and although +%D fancy rules like +%D +%D \starttyping +%D \hbox to 10em{\hskip-3em\dotfill} +%D \stoptyping +%D +%D Are quite ligitimate, we default to a simple one 20\% of the text width. + +% \c!headstyle=\noteparameter\c!style, +% \c!headcolor=\noteparameter\c!color, + +\installcorenamespace{notation} + +\installcommandhandler \??notation {notation} \??notation + +\installcounterassociation{notation} + +\aliased\let\setupnotations\setupnotation + +\definesymbol[\v!note:\v!previouspage][\llap{\low{\symbol[\v!previouspage]}}] +\definesymbol[\v!note:\v!nextpage ][\llap{\low{\symbol[\v!nextpage ]}}] + +\setupnotations % check with old + [\c!alternative=\v!note, + %\c!headstyle=, + %\c!titlestyle=, + %\c!style=, + %\c!color=, + %\c!headcolor=, + %\c!titlecolor=, + \c!numbercommand=\high, + %\c!symbolcommand=\lowllap, % experiment + %\c!indicator=\v!no, % was \v!yes in mkii for page notes + \c!width=\v!fit, + \c!titledistance=.5em, + \c!distance=.5em, + %\c!hang=, + %\c!sample=, + %\c!align=, + %\c!headalign=, + \c!margin=\v!no, + \c!before=, + \c!inbetween=, + \c!after=, + \c!indentnext=\v!yes, + \c!indenting=\v!never, + \c!titleleft=(, + \c!titleright=), + %\c!closesymbol=, + \c!closecommand=\wordright, + \c!display=\v!yes, + %\c!command=, + \c!titlecommand=, + \c!expansion=\v!no, + %\c!xmlsetup=, + %\s!catcodes=, + \c!way=\v!by\v!text, + \c!prefix=\v!no, + \c!prefixconnector=., + %\c!starter=, + %\c!stopper=, + \c!number=\v!yes, + \c!text=, + \c!start=0, + \c!state=\v!start, + \c!levels=3] + +%D The code here is mostly the same as enumerations but we want to keep them +%D isolated and at some point we might differentiate. + +% \installcorenamespace{noteclass} + +\protected\def\strc_define_commands_notation#tag#level#parent% + {\doifelsenothing{#parent} + {\normalexpanded{\defineconstruction[#tag][\s!handler=\v!notation,\c!level=#level]}% + \setevalue{\??notation#tag:\s!parent}{\??notation}}% + {\normalexpanded{\defineconstruction[#tag][#parent][\s!handler=\v!notation,\c!level=#level]}% + \setevalue{\??note #tag:\s!parent}{\??note#parent}% see later for \s!note + \setevalue{\??notation#tag:\s!parent}{\??notation#parent}}% + \instance\setuevalue{\e!next #tag}{\strc_notations_next {#tag}{\number#level}}% obsolete + \instance\setuevalue{\c!reset#tag}{\strc_notations_reset {#tag}{\number#level}}% obsolete + \instance\setuevalue {#tag}{\strc_notations_command[#tag]}% + \instance\setuevalue{\e!start#tag}{\strc_notations_start [#tag]}% + \instance\setuevalue{\e!stop #tag}{\strc_notations_stop }} + +\appendtoks + \ifx\currentnotationparent\empty + % clone => parent | subclone => clone | subsubclone => subclone + \let\currentnotationsub\empty + \strc_define_commands_notation + {\currentnotationsub\currentnotation}% + \plusone + \empty + \edef\p_levels{\notationparameter\c!levels}% + \dostepwiserecurse\plustwo\p_levels\plusone + {\strc_define_commands_notation + {\v!sub\currentnotationsub\currentnotation}% + \recurselevel + {\currentnotationsub\currentnotation}% + \edef\currentnotationsub{\v!sub\currentnotationsub}}% + \definelist[\currentnotation]% goodie + \else + % clone => parent | subclone => subparent | subsubclone => subsubparent + \let\currentnotationsub\empty + \edef\p_levels{\notationparameter\c!levels}% + \dorecurse\p_levels + {\strc_define_commands_notation + {\currentnotationsub\currentnotation}% + \recurselevel + {\currentnotationsub\currentnotationparent}% + \edef\currentnotationsub{\v!sub\currentnotationsub}}% + \definelist[\currentnotation][\currentnotationparent]% goodie + \fi + \edef\p_counter{\notationparameter\s!counter}% can inherit from parent + \ifx\p_counter\empty % + \let\p_counter\currentnotation + \fi + \doifelsecounter\p_counter\donothing{\strc_notes_define_counter\p_counter}% + \letnotationparameter\s!counter\p_counter + %\strc_notes_setup_counter\currentnotation +\to \everydefinenotation + +\let\p_strc_constructions_title \empty +\let\p_strc_constructions_number\empty + +\protected\setvalue{\??constructioninitializer\v!notation}% + {\let \currentnotation \currentconstruction + \enforced\let\constructionparameter \notationparameter + \enforced\let\constructionnamespace \??notation + \enforced\let\detokenizedconstructionparameter\detokenizednotationparameter + \enforced\let\letconstructionparameter \letnotationparameter + \enforced\let\useconstructionstyleandcolor \usenotationstyleandcolor + \enforced\let\setupcurrentconstruction \setupcurrentnotation + \edef\p_strc_constructions_number{\constructionparameter\c!number}% + \ifx\p_strc_constructions_number\v!yes + \settrue\c_strc_constructions_number_state + \iftrialtypesetting + \strc_counters_save\currentconstructionnumber + \fi + %\strc_counters_increment_sub\currentconstructionnumber\currentconstructionlevel + \else + \setfalse\c_strc_constructions_number_state + \fi + \edef\p_strc_constructions_title{\constructionparameter\c!title}% + \ifx\p_strc_constructions_title\v!yes + \settrue\c_strc_constructions_title_state + \else + \setfalse\c_strc_constructions_title_state + \fi} + +\protected\setvalue{\??constructionfinalizer\v!notation}% + {\ifconditional\c_strc_constructions_number_state + \iftrialtypesetting + \strc_counters_restore\currentconstructionnumber + \fi + \fi} + +%D Notations (we simply needed a word that relates to notes and is and sounds like +%D description and enumeration) are a special case in the sense that they are +%D stored, rendered elsewhere and referered to from where they are specified. For +%D that reason they have a different set op main commands. + +% \notation[ref]{title} +% \notation[reference=,title=] +% \startnotation[ref] title \stopnotation + +\protected\def\strc_notations_next {\strc_constructions_next_indeed \namednotationparameter} % #1#2 +\protected\def\strc_notations_reset{\strc_constructions_reset_indeed\namednotationparameter} % #1#2 +%protected\def\strc_notations_set {\strc_constructions_set_indeed \namednotationparameter} % #1#2 + +\newconditional\c_strc_notations_anchored_next + +\def\strc_notations_finalize + {\ifconditional\c_strc_notations_anchored_next + \expandafter\strc_notations_finalize_next + \else + \expandafter\strc_notations_finalize_previous + \fi} + +\def\strc_notations_finalize_previous + {\normalexpanded{\endgroup\noteparameter\c!next}} + +\def\strc_notations_finalize_next + {\endgroup\ignorespaces} + +\tolerant\protected\def\strc_notations_command[#1]#*[#2]% + {\begingroup + \edef\currentnote{#1}% + \strc_constructions_initialize{#1}% + \strc_notes_synchronize + \edef\p_next{\noteparameter\c!anchor}% + \ifx\p_next\v!next % for now only two states + \settrue \c_strc_notations_anchored_next + \else + \setfalse\c_strc_notations_anchored_next + \fi + \ifnotesenabled + \strc_counters_increment_sub\currentconstructionnumber\currentconstructionlevel + \fi + \ifhastok={#2}% + \expandafter\strc_notations_command_setups + \else + \expandafter\strc_notations_command_reference + \fi[#2]} + +\def\strc_notations_command_setups[#1]% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,#1]% + \strc_notations_wrapup} + +\tolerant\def\strc_notations_command_reference[#1]#*#=% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=]% + \strc_notations_wrapup} + +\def\strc_notations_wrapup + {\csname\??constructionnotehandler\currentconstructionhandler\endcsname + \strc_constructions_finalize + \strc_notations_finalize} + +\tolerant\protected\def\strc_notations_start[#1]#*[#2]% + {\begingroup + \edef\currentnote{#1}% + \strc_constructions_initialize{#1}% + \strc_notes_synchronize + \ifnotesenabled + \strc_counters_increment_sub\currentconstructionnumber\currentconstructionlevel + \fi + \ifhastok={#2}% + \expandafter\strc_notations_start_setups + \else + \expandafter\strc_notations_start_reference + \fi[#2]} + +\protected\def\strc_notations_start_setups[#1]% + {\normalexpanded{\def\noexpand\strc_pickup_yes##/\csname\e!stop\currentconstruction\endcsname{\strc_notations_start_setups_indeed[#1]{##1}}}% + \strc_pickup_yes} + +\protected\def\strc_notations_start_setups_indeed[#1]#*#2% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#2},\c!bookmark=,\c!list=,#1]% + \strc_notations_wrapup} + +\protected\def\strc_notations_start_reference[#1]% + {\normalexpanded{\def\noexpand\strc_pickup_yes##/\csname\e!stop\currentconstruction\endcsname{\strc_notations_start_reference_indeed[#1]{##1}}}% + \strc_pickup_yes} + +\protected\def\strc_notations_start_reference_indeed[#1]#*#2% + {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=]% + \strc_notations_wrapup} + +\protected\def\strc_notations_stop + {} + +%D A complication is that we need to set up rather specific properties of e.g. +%D footnotes. It is for this reason that we introduce an extra level of +%D indirectness. This way notations don't bark on undefined macros when used in +%D combination. + +\protected\setvalue{\??constructionnotehandler\v!notation}% + {\csname\??constructionnotehandler\currentconstructionhandler:\constructionparameter\c!type\endcsname} + +\protected\setvalue{\??constructionnotehandler\v!notation:}% empty case + {[\currentconstructionhandler:\currentconstruction]} + +%D Here is a simple renderer for notes + +\defineconstructionalternative + [\v!note] + [\c!renderingsetup=\??constructionrenderings:\v!note] + +\startsetups[\??constructionrenderings:\v!note] + \noindent + \leftboundary % experiment, to be done in more places + \llap{\box\constructionheadbox\hskip\constructionparameter\c!distance}% + \useconstructionstyleandcolor\c!style\c!color + \ignorespaces +\stopsetups + +%D We now implement the note definer. + +\installcorenamespace{note} + +\installframedcommandhandler \??note {note} \??note + +\let\setupnotes\setupnote + +% These only concern the inline symbol/number and wrapping of the whole list. + +\setupnotes % not all make sense here + [\c!location=\v!page, + %\c!conversion=, + \c!rule=\v!on, + \c!before=\blank, + \c!bodyfont=\v!small, + \c!anchor=, % can also be v!next + %\c!style=, + %\c!color=, + %\c!after=, + %\c!rulecolor=, + %\c!rulecommand=, + \c!rulethickness=\linewidth, + \c!frame=\v!off, + \c!distance=.125em, % in the text between symbols + % \c!textseparator={,}, % optional separator + \c!columndistance=1em, + % \c!margindistance=.5em, + \c!align=, % also use instead of \c!tolerance + \c!split=\v!tolerant, + \c!width=\makeupwidth, % \ifdim\hsize<\makeupwidth\hsize\else\makeupwidth\fi + \c!height=\textheight, + \c!command=, % \noteparameter\c!numbercommand, % (command in enumeration) too messy, called twice + \c!separator=,% + \c!textcommand=\high, + \c!textstyle=\tx, + %\c!textcolor=, + \c!interaction=\v!yes, + %\c!factor=, + %\c!scope=, % \v!text \v!page + \c!prefixconnector=., + %\c!next=\autoinsertnextspace, + \c!prefix=\v!no, + %\c!continue=\v!no, + \c!paragraph=\v!no, + \c!inbetween=\hskip\emwidth, + \c!symbol=\mathematics{*}, + \c!n=1] + +\setupnotes + [\c!expansion=\v!no, + \c!xmlsetup=, + \s!catcodes=] + +%D Insertions are part of notes. + +% \installcorenamespace{noteinsertion} + +\permanent\def\currentnoteinsertion {\noteparameter\s!insert} +\permanent\def\currentnoteinsertionnumber{\namedinsertionnumber{\noteparameter\s!insert}} + +\appendtoks + \ifx\currentnoteparent\empty + \doifelseinsertion\currentnote + \donothing + {\defineinsertion[\currentnote]% could be an option + \normalexpanded{\t_strc_notes{\the\t_strc_notes\noexpand\strc_notes_process_list{\currentnote}}}}% + \letnoteparameter\s!insert\currentnote + \definenotation[\currentnote][\c!type=\v!note]% + \else + \setexpandednoteparameter\s!insert{\namednoteparameter\currentnoteparent\s!insert}% + \definenotation[\currentnote][\currentnoteparent][\c!type=\v!note]% + \fi + \clf_definenote + {\currentnote}% + {insert}% + \currentnoteinsertionnumber + \relax +\to \everydefinenote + +% maybe we will share this at some point: + +\def\strc_notes_define_counter#tag% todo: move inline + {\definecounter[#tag]% + \registerenumerationcounter{#tag}} + +\appendtoks + \synchronizenotationcounters +\to \everysetupnotation + +\appendtoks + \synchronizenotationcounters +\to \everydefinenotation + +% so far + +%expandafter\let\csname\??constructionstarthandler \v!notation\expandafter\endcsname\csname\??constructionstarthandler \v!enumeration\endcsname +\expandafter\let\csname\??constructionstarthandler \v!notation\expandafter\endcsname\csname\??constructionstarthandler \v!construction\endcsname % no par mess +\expandafter\let\csname\??constructionstophandler \v!notation\expandafter\endcsname\csname\??constructionstophandler \v!enumeration \endcsname +\expandafter\let\csname\??constructioncommandhandler\v!notation\expandafter\endcsname\csname\??constructioncommandhandler\v!enumeration \endcsname +\expandafter\let\csname\??constructiontexthandler \v!notation\expandafter\endcsname\csname\??constructiontexthandler \v!enumeration \endcsname + +\protected\setvalue{\??constructionmainhandler\v!notation}#following% + {\iftrialtypesetting \else + \begingroup + \currentconstructionsynchronize + \c_attr_destination\currentconstructionattribute\relax % todo, whole text + \signalcharacter + \endgroup + \fi#following} + +\protected\setvalue{\??constructionnotehandler\v!notation:\v!note}% in the running text + {\ifnotesenabled + % do be done elsewhere + % + %let\currentnote\currentconstructionmain + \let\currentnote\currentconstruction % else wrong inheritance + % + \iftrialtypesetting + \strc_notes_inject_dummy + \else + \begingroup + \edef\currentnotenumber{\clf_storenote{\currentnote}\currentconstructionlistentry}% + \settrue\processingnote + \ifconditional\c_strc_notes_skip + \glet\lastnotesymbol\strc_notes_inject_symbol_nop + \else + \iftypesettinglines % otherwise problems with \type <crlf> {xxx} + \ignorelines % makes footnotes work in \startlines ... \stoplines + \fi + \ifconditional\c_strc_notes_symbol + \strc_notes_inject_symbol_yes + \else + \unskip\unskip + \glet\lastnotesymbol\strc_notes_inject_symbol_yes + \fi + \fi + \ifconditional\postponingnotes % todo: per note class + \global\settrue\postponednote + \orelse\ifconditional\inlocalnotes % todo: per note class + \global\settrue\postponednote + \orelse\ifconditional\c_strc_notes_delayed + % probably end notes + \else + \handlenoteinsert\currentnote\currentnotenumber % either an insert or just delayed + \fi + \endgroup + \fi + \fi + \ifconditional\c_strc_notes_skip + \global\setfalse\c_strc_notes_skip + \else + \kern\notesignal\relax % \relax is needed to honor spaces + \fi} + +%D Interaction in notes is somewhat complex due to the way notes get flushed. In +%D principle it is more or less the same as lists but where in lists we pack whole +%D entries, in notes this doesn't happen. Okay, in retrospect we could have made +%D descriptions lists but that will be a backward compatibility mess. At some point +%D a completely new mechanism might show up, but not now. Also, as notes are inserts +%D there is some extra mess to be kept in mind and it's easier to maintain two +%D mechanisms than to combine too much. +%D +%D Interaction is also complicated because we want to provide several variants. For +%D simple reference there is no need for anything special, as page references will +%D do and we store them in the list anyway. But if we want a destination with +%D dimensions we will use an additional destination because we can have only one +%D with the same name and we always have the number as one. + +% interaction: +% +% all : text and number +% number|yes: only number +% text : only text +% +% \dogetsimple : injects + +\installcorenamespace{noteinteractioninline} +\installcorenamespace{noteinteractiondisplay} + +\newconstant\a_strc_notes_symbol_reference +\newconstant\a_strc_notes_number_reference +\newconstant\a_strc_notes_text_reference +\newconstant\a_strc_notes_text_destination + +\let\strc_notes_get_reference_attribute_symbol \empty +\let\strc_notes_get_destination_attribute_symbol\empty + +\def\strc_notes_interaction_check_inline + {\edef\p_interaction{\noteparameter\c!interaction}% + \csname\??noteinteractioninline + \ifcsname\??noteinteractioninline\p_interaction\endcsname\p_interaction\else\v!no\fi + \endcsname} + +\def\strc_notes_interaction_check_display + {\edef\p_interaction{\noteparameter\c!interaction}% + \csname\??noteinteractiondisplay + \ifcsname\??noteinteractiondisplay\p_interaction\endcsname\p_interaction\else\v!no\fi + \endcsname} + +\def\currentnotenumber{0} + +\let\strc_notes_get_reference_attribute_symbol \empty +\let\strc_notes_get_destination_attribute_symbol\empty + +\let\strc_notes_set_reference_attribute_number\donothing +\let\strc_notes_set_reference_attribute_text \donothing +\let\strc_notes_set_destination_attribute_text\donothing + +% inline + +\def\strc_references_prepare_inline_references_nop + {\let\strc_notes_get_reference_attribute_symbol\empty + \let\strc_notes_get_destination_attribute_symbol\empty + \let\strc_notes_set_style_color_inline\strc_notes_set_style_color_inline_nop} + +% \def\strc_references_prepare_inline_references_yes +% {\strc_references_set_simple_reference{symb:\currentnote:\currentnotenumber}% destination +% \strc_references_get_simple_reference{internal(\clf_noteinternal{\currentnote}\currentnotenumber)}% reference +% \edef\strc_notes_get_destination_attribute_symbol{attr\destinationattribute\currentdestinationattribute}% +% \edef\strc_notes_get_reference_attribute_symbol{attr\referenceattribute\currentreferenceattribute}% +% \let\strc_notes_set_style_color_inline\strc_notes_set_style_color_inline_yes} + +\def\strc_references_prepare_inline_references_yes + {\edef\currentnoteinternal{\clf_noteinternal{\currentnote}\currentnotenumber}% + \strc_references_set_simple_reference{*\currentnoteinternal}% destination + \strc_references_get_simple_reference{internal(\currentnoteinternal)}% reference + \edef\strc_notes_get_destination_attribute_symbol{attr\destinationattribute\currentdestinationattribute}% + \edef\strc_notes_get_reference_attribute_symbol{attr\referenceattribute\currentreferenceattribute}% + \let\strc_notes_set_style_color_inline\strc_notes_set_style_color_inline_yes} + +\letvalue{\??noteinteractioninline\v!no }\strc_references_prepare_inline_references_nop +\letvalue{\??noteinteractioninline\v!all }\strc_references_prepare_inline_references_yes +\letvalue{\??noteinteractioninline\v!number}\strc_references_prepare_inline_references_yes +\letvalue{\??noteinteractioninline\v!text }\strc_references_prepare_inline_references_yes +\letvalue{\??noteinteractioninline\v!yes }\strc_references_prepare_inline_references_yes + +% display (for 'all' we need unique text and number attributes so we resolve twice +% as we otherwise don't get the number one which is lapped in the margin so we need +% to explicitly visit it) + +\def\strc_references_prepare_display_references_nop + {\let\strc_notes_set_reference_attribute_number\donothing + \let\strc_notes_set_reference_attribute_text\donothing + \let\strc_notes_set_destination_attribute_text\donothing + \let\strc_notes_set_style_color_display\strc_notes_set_style_color_display_nop} + +\def\strc_references_prepare_display_references_yes_number + {\edef\currentnoteinternal{\clf_noteinternal{\currentnote}\currentnotenumber}% + \ifcase\currentnoteinternal\relax + \strc_references_prepare_display_references_nop + \else + \let\strc_notes_set_reference_attribute_text\donothing + \strc_references_get_simple_reference{*\currentnoteinternal}% reference + \edef\strc_notes_set_reference_attribute_number{\c_attr_reference\currentreferenceattribute}% + \let\strc_notes_set_style_color_display\strc_notes_set_style_color_display_yes + \fi} + +\def\strc_references_prepare_display_references_yes_text + {\edef\currentnoteinternal{\clf_noteinternal{\currentnote}\currentnotenumber}% + \ifcase\currentnoteinternal\relax + \strc_references_prepare_display_references_nop + \else + \strc_references_get_simple_reference{*\currentnoteinternal}% reference + \edef\strc_notes_set_reference_attribute_text{\c_attr_reference\currentreferenceattribute}% + \let\strc_notes_set_reference_attribute_number\donothing + \let\strc_notes_set_style_color_display\strc_notes_set_style_color_display_yes + \fi} + +\def\strc_references_prepare_display_references_yes_all + {\edef\currentnoteinternal{\clf_noteinternal{\currentnote}\currentnotenumber}% + \ifcase\currentnoteinternal\relax + \strc_references_prepare_display_references_nop + \else + \strc_references_get_simple_reference{*\currentnoteinternal}% reference + \edef\strc_notes_set_reference_attribute_text{\c_attr_reference\currentreferenceattribute}% + \strc_references_get_simple_reference{*\currentnoteinternal}% reference + \edef\strc_notes_set_reference_attribute_number{\c_attr_reference\currentreferenceattribute}% + \let\strc_notes_set_style_color_display\strc_notes_set_style_color_display_yes + \fi} + +\letvalue{\??noteinteractiondisplay\v!no }\strc_references_prepare_display_references_nop +\letvalue{\??noteinteractiondisplay\v!all }\strc_references_prepare_display_references_yes_all +\letvalue{\??noteinteractiondisplay\v!number}\strc_references_prepare_display_references_yes_number +\letvalue{\??noteinteractiondisplay\v!text }\strc_references_prepare_display_references_yes_text +\letvalue{\??noteinteractiondisplay\v!yes }\strc_references_prepare_display_references_yes_number + +\let\strc_notes_set_style_color_inline_nop \usenotestyleandcolor +\let\strc_notes_set_style_color_display_nop\usenotationstyleandcolor + +\protected\def\strc_notes_set_style_color_inline_yes#style#color% + {\usenotestyleandcolor#style#color% + \iflocation\strc_notes_set_style_color_special\fi} + +\protected\def\strc_notes_set_style_color_display_yes#style#color% + {\usenotationstyleandcolor#style#color% + \iflocation\strc_notes_set_style_color_special\fi} + +\def\strc_notes_set_style_color_special + {\iftrialtypesetting + % keep + \orelse\ifx\currentcolorparameter\empty + \scratchcounter\clf_notedeltapage{\currentnote}\currentnotenumber\relax % todo calculate once + \setlocationcolorspecified\scratchcounter + \fi} + +\setvalue{\??constructiontexthandler\v!notation}% + {\begingroup + % we need to retrigger the reference as otherwise it gets lost because we don't do nested + % references with the same id ... maybe some day if we can figure out a nice heuristic ... + % the problem is that normally it's no issue but here we lap into the margin, so maybe that's + % a criterium + % \strc_notes_interaction_check_display + \strc_notes_set_reference_attribute_number + \dotagsetnotation + \strc_notes_set_style_color_display\c!headstyle\c!headcolor + \strc_enumerations_text + \endgroup} + +% in mkii the pointer only showed up in pagewise notes + +\protected\def\strc_notes_inject_pointer % todo calculate once + {\ifcase\clf_notedeltapage{\currentnote}\currentnotenumber\relax\relax + % unknown + \or + % same page + \or + \noteparameter\c!symbolcommand{\symbol[\v!note:\v!nextpage]}% + \or + \noteparameter\c!symbolcommand{\symbol[\v!note:\v!previouspage]}% + \fi} + +\protected\def\strc_notes_inject_symbol_yes + {\strc_notes_inject_symbol_indeed\conditionaltrue} + +\protected\def\strc_notes_inject_symbol_nop + {\strc_notes_inject_symbol_indeed\conditionalfalse} + +\definemargindata + [strc_notes_destination_margin] + [\v!left] + [\c!margin=\zeropoint, + \c!width=\zeropoint, + \c!style=, + \c!color=] + +\protected\def\strc_notes_inject_symbol_indeed#synchronize% + {\ifconditional\c_strc_notations_anchored_next\else + \removeunwantedspaces + \doifelseitalic\/\donothing % Charles IV \footnote{the fourth} + \fi + \ifdim\lastkern=\notesignal + % \kern\noteparameter\c!distance % yes or no note font? or main text + \strc_notes_inject_separator + \fi + \nobreak + \begingroup + \strc_notes_interaction_check_inline + \strc_notes_set_style_color_inline\c!textstyle\c!textcolor + \hbox \strc_notes_get_reference_attribute_symbol \strc_notes_get_destination_attribute_symbol \bgroup + % \hbox \strc_notes_get_reference_attribute_symbol \bgroup \strc_notes_destination_hack + \strc_references_flush_destination_nodes % a bit late but ok + \dostarttagged\t!descriptionsymbol\currentnote + \dotagsetnotesymbol + \noteparameter\c!textcommand{\clf_noteprefixednumber{\currentnote}\currentnotenumber\relax}% + % the next one can cycle so we need to make sure it has no advance width + \doif{\noteparameter\c!indicator}\v!yes\strc_notes_inject_pointer + \dostoptagged + \egroup + \endgroup + \glet\lastnotesymbol\relax} + +\protected\def\strc_notes_inject_dummy % temp hack + {\removeunwantedspaces + \doifelseitalic\/\donothing % Charles IV \footnote{the fourth} + \ifdim\lastkern=\notesignal + % \kern\noteparameter\c!distance % yes or no note font? or main text + \strc_notes_inject_separator + \fi + \nobreak + \hpack to .5\emwidth{}% + \glet\lastnotesymbol\relax} + +\protected\def\strc_notes_inject_separator % patch by WS due to request on list + {\edef\p_textseparator{\noteparameter\c!textseparator}% + \ifx\p_textseparator\empty + \kern\noteparameter\c!distance + \else + % skip or kern + \nobreak + \hbox\bgroup + \strc_notes_interaction_check_inline + \strc_notes_set_style_color_inline\c!textstyle\c!textcolor + \noteparameter\c!textcommand{\p_textseparator}% + \kern\noteparameter\c!distance + \egroup + \nobreak + \fi} + +% this needs a further cleanup ... soon as it's a slow mechanism +% +% -- set breakpoint in descriptions +% -- reset after trialtypesetting +% -- that way we can trick the symbol space + +% removed: +% +% \pushsomestates +% +% core-ins -> obsolete +% +% saveinsertiondata +% restoreinsertiondata +% saveinsertionbox +% eraseinsertionbackup +% restoreinsertionbackup + +\def\savenotedata {} % \writestatus{todo}{save note data}} +\def\restorenotedata {} % \writestatus{todo}{restore note data}} +\def\savenotecontent {} % \writestatus{todo}{save note content}} +\def\restorenotecontent{} % \writestatus{todo}{restore note content}} +\def\erasenotebackup {} % \writestatus{todo}{erase note backup}} + +% page-set: + +\def\enablenotes {\writestatus{todo}{enable notes}} +\def\disablenotes {\writestatus{todo}{disable notes}} +\def\savenotes {\writestatus{todo}{save notes}} +\def\flushsavednotes{\writestatus{todo}{flush notes}} + +% experiment: (compare scope=text and scope=page) +% +% \definenote[mynote][way=bytext,location=text,width=\leftmarginwidth,scope=page,rule=,before=,after=,factor=0] +% \setuptexttexts[margin][\vbox to \textheight{\placenotes[mynote]\vfill}][] + +%D Footnotes are can be characterized by three components: +%D +%D \startitemize[packed] +%D \item a small number \footnote {a footnote number} or symbol {\setupfootnotes +%D [conversion=set 2]\footnote {a footnote}} +%D \item and a similar mark at the bottom of the page +%D \item followed by some additional text +%D \stopitemize +%D +%D Because footnotes are declared at the location of their reference they can be +%D seen as a special kind of floating bodies. Their placement is postponed but has +%D to be taken into account in the pagebreak calculations. This kind of calculations +%D are forced by using \type{\insert}s and dealing with all cases is not trivial. + +%D \macros +%D {notesenabled} +%D +%D We need a couple of states because at some moments we don't want to mess around +%D with inserts at all. Take for instance a table of contents. And so we can +%D temporary disable footnotes by saying +%D +%D \starttyping +%D \notesenabledfalse +%D \stoptyping + +\newif\ifnotesenabled \notesenabledtrue + +% better mark a note .. once flushed no more flushing + +%appendtoks \notesenabledfalse \to \everymarking +\appendtoks \notesenabledfalse \to \everybeforepagebody +\appendtoks \notesenabledfalse \to \everystructurelist % quick hack +\appendtoks \notesenabledfalse \to \everysimplifycommands % quick hack +\appendtoks \notesenabledfalse \to \everypreroll % quick hack + +%D Often we need to process the whole set of notes and to make that fast, we use a +%D token register: + +% we have several synchronizers: +% +% - after a definition +% - after a specific setup +% - after a general setup (inheritance of dimensions) +% - just before a note is typeset + +\newtoks\t_strc_notes + +\let\strc_notes_process_list\gobbleoneargument + +\protected\def\strc_notes_process#action% argument is a \macro that uses \currentnote + {\def\strc_notes_process_list##1{\edef\currentnote{##1}\let\currentdescription\currentnote#action}% + \the\t_strc_notes} + +\newtoks\everychecknote % just before a note is typeset +\newtoks\everysynchronizenote % after a general setup has happened + +\appendtoks + \ifx\currentnote\empty \else + \setupnotations[\currentnote][]% also a synchronize + \fi +\to \everysynchronizenote + +\def\strc_notes_synchronize + {\the\everysynchronizenote} % we can speed this one up if needed by avoiding the commalist + +\appendtoks + \strc_notes_process\strc_notes_synchronize +\to \everysetupnoteroot + +\appendtoks + \the\everysynchronizenote +\to \everydefinenote + +% \starttext +% text \startfootnote Test.\stopfootnote +% test \footnote{xxxx} \subfootnote{xxxx} +% test \footnote{xxxx} \subfootnote{xxxx} +% \stoptext + +\installcorenamespace{notecommand} +\installcorenamespace{notealign} +\installcorenamespace{notepenalty} +\installcorenamespace{noterule} + +\permanent\protected\def\currentnoterulecommand{\begincsname\??notecommand\currentnote\endcsname} +\permanent\protected\def\currentnoterulealign {\begincsname\??notealign \currentnote\endcsname} + +\permanent\protected\def\currentnoterulecommandcommand{\noteparameter\c!rulecommand} +\permanent\protected\def\currentnoterulecommandnormal {\normalnoterule} % no let as it can be changed afterwards + +\permanent\protected\def\letcurrentnoterulecommand{\enforced\expandafter\let\csname\??notecommand\currentnote\endcsname} +\permanent\protected\def\letcurrentnoterulealign {\enforced\expandafter\let\csname\??notealign \currentnote\endcsname} + +\appendtoks + \enforced\expandafter\let\csname\??notecommand\currentnote\endcsname\currentnoterulecommandnormal + \enforced\expandafter\let\csname\??notealign \currentnote\endcsname\lefttoright +\to \everysynchronizenote + +\def\strc_notes_set_rule + {\letcurrentnoterulecommand\relax % so we default to nothing + \letcurrentnoterulealign \relax + \processcommacommand[\noteparameter\c!rule]\strc_notes_set_rule_step} + +\def\strc_notes_set_rule_step#alternative% + {\begincsname\??noterule#alternative\endcsname} + +\def\strc_notes_set_rule_autodir + {\doifelserighttoleftinbox\currentnoteinsertionnumber\righttoleft\lefttoright} + +\setvalue{\??noterule \v!command}{\letcurrentnoterulecommand\currentnoterulecommandcommand} +\setvalue{\??noterule \v!on}{\letcurrentnoterulecommand\currentnoterulecommandnormal} +\setvalue{\??noterule \v!normal}{\letcurrentnoterulecommand\currentnoterulecommandnormal} +\setvalue{\??noterule \v!left}{\letcurrentnoterulecommand\currentnoterulecommandnormal + \letcurrentnoterulealign \lefttoright} +\setvalue{\??noterule \v!right}{\letcurrentnoterulecommand\currentnoterulecommandnormal + \letcurrentnoterulealign \righttoleft} +\setvalue{\??noterule\v!paragraph}{\letcurrentnoterulecommand\currentnoterulecommandnormal + \letcurrentnoterulealign \strc_notes_set_rule_autodir} +\setvalue{\??noterule \v!off}{\letcurrentnoterulecommand\relax} + +\appendtoks + \strc_notes_set_rule +\to \everysynchronizenote + +\permanent\def\currentnotepenalty + {\ifcsname\??notepenalty\noteparameter\c!split\endcsname + \lastnamedcs + \else + \numexpr\noteparameter\c!split\relax + \fi} + +\setnewconstant\notepenaltytolerant \zerocount +\setnewconstant\notepenaltystrict 9999 +\setnewconstant\notepenaltyverystrict\maxdimen + +\letvalue{\??notepenalty\v!tolerant }\notepenaltytolerant +\letvalue{\??notepenalty\v!strict }\notepenaltystrict +\letvalue{\??notepenalty\v!verystrict}\notepenaltyverystrict +\letvalue{\??notepenalty }\notepenaltytolerant + +%D The following switch can be used to disable limiting the height of the footnote +%D area, something that is needed in multi column balancing. Use this switch with +%D care. + +\newif\ifnotelimit \notelimittrue % shared + +\def\strc_notes_set_factor + {\edef\p_factor{\noteparameter\c!factor}% + \ifx\p_factor\empty \else + \ifnum\p_factor<\zerocount \else +% \global + \count\currentnoteinsertionnumber\p_factor % new: global + \fi + \fi} + +\appendtoks + \strc_notes_set_factor +\to \everysynchronizenote + +% locations: + +\installcorenamespace{notelocationvariant} +\installcorenamespace{notepositionvariant} +\installcorenamespace{notedelayedvariant} +\installcorenamespace{notelocation} + +\newconditional\c_strc_notes_delayed + +\protected\def\strc_notes_set_delayed_yes{\settrue \c_strc_notes_delayed} +\protected\def\strc_notes_set_delayed_nop{\setfalse\c_strc_notes_delayed} + +\setvalue{\??notelocation\v!page }{\letvalue{\??notedelayedvariant \currentnote}\strc_notes_set_delayed_nop + \letvalue{\??notelocationvariant\currentnote}\strc_notes_set_location_page} +\setvalue{\??notelocation\v!columns }{\letvalue{\??notedelayedvariant \currentnote}\strc_notes_set_delayed_nop + \letvalue{\??notelocationvariant\currentnote}\strc_notes_set_location_columns} +\setvalue{\??notelocation\v!lastcolumn }{\letvalue{\??notedelayedvariant \currentnote}\strc_notes_set_delayed_nop + \letvalue{\??notelocationvariant\currentnote}\strc_notes_set_location_lastcolumn} +\setvalue{\??notelocation\v!firstcolumn}{\letvalue{\??notedelayedvariant \currentnote}\strc_notes_set_delayed_nop + \letvalue{\??notelocationvariant\currentnote}\strc_notes_set_location_firstcolumn} +\setvalue{\??notelocation\v!none }{\letvalue{\??notedelayedvariant \currentnote}\strc_notes_set_delayed_yes + \letvalue{\??notelocationvariant\currentnote}\strc_notes_set_location_none} +\setvalue{\??notelocation\v!text }{\letvalue{\??notedelayedvariant \currentnote}\strc_notes_set_delayed_yes + \letvalue{\??notelocationvariant\currentnote}\strc_notes_set_location_text} +\setvalue{\??notelocation\v!high }{\letvalue{\??notepositionvariant\currentnote}\strc_notes_set_position_high} +\setvalue{\??notelocation\v!bottom }{\letvalue{\??notepositionvariant\currentnote}\strc_notes_set_position_bottom} + +\setvalue{\??notedelayedvariant \??notedelayedvariant }{\strc_notes_set_delayed_nop} % not let +\setvalue{\??notepositionvariant\??notepositionvariant}{\strc_notes_set_position_bottom} % not let +\setvalue{\??notelocationvariant\??notelocationvariant}{\strc_notes_set_location_page} % not let + +\protected\def\strc_notes_set_delayed + {\csname\??notedelayedvariant + \ifcsname\??notedelayedvariant\currentnote\endcsname + \currentnote + \else + \??notedelayedvariant + \fi + \endcsname} + +\protected\def\strc_notes_set_position + {\csname\??notepositionvariant + \ifcsname\??notepositionvariant\currentnote\endcsname + \currentnote + \else + \??notepositionvariant + \fi + \endcsname} + +\protected\def\strc_notes_set_location + {\csname\??notelocationvariant + \ifcsname\??notelocationvariant\currentnote\endcsname + \currentnote + \else + \??notelocationvariant + \fi + \endcsname} + +\protected\def\strc_notes_set_variants + {\normalexpanded{\rawprocesscommalist[\noteparameter\c!location]\strc_notes_set_location_step}} + +\protected\def\strc_notes_set_location_step#alternative% the insert related one + {\begincsname\??notelocation#alternative\endcsname} + +\appendtoks + \strc_notes_set_variants + \strc_notes_set_delayed +\to \everysynchronizenote + +\newskip \s_strc_notes_distance % we need to implement stretch +\newcount\c_strc_notes_columns + +\newskip \s_strc_notes_before +\newskip \s_strc_notes_inbetween +\newconditional\c_strc_notes_first_flushed + +\appendtoks + \edef\p_spacebefore{\rootnoteparameter\c!spacebefore}% + \ifx\p_spacebefore\empty + \global\s_strc_notes_before\zeropoint + \else + \setbox\scratchbox\vbox{\blank[\p_spacebefore]\global\s_strc_notes_before\lastskip}% + \fi + \edef\p_spaceinbetween{\rootnoteparameter\c!spaceinbetween}% + \ifx\p_spaceinbetween\empty + \global\s_strc_notes_inbetween\zeropoint + \else + \setbox\scratchbox\vbox{\blank[\p_spaceinbetween]\global\s_strc_notes_inbetween\lastskip}% + \fi +\to \everysynchronizenote + +\def\strc_notes_set_distance + {\begingroup + \restoreglobalbodyfont + \setbox\scratchbox\vbox % no reuse as it can mirror + {\forgetall + \dontcomplain + \noteparameter\c!before + \placenoterule + \strut + \noteparameter\c!after}% + % also dp now + \scratchdimen\dimexpr\htdp\scratchbox-\lineheight\relax + \ifgridsnapping + \getnoflines\scratchdimen + \scratchdimen\noflines\lineheight + \fi + \expandafter\endgroup\expandafter + \s_strc_notes_distance\the\scratchdimen\relax} + +\def\strc_notes_set_columns + {\c_strc_notes_columns\noteparameter\c!n\relax + \ifcase\c_strc_notes_columns + \c_strc_notes_columns\plusone + \fi} + +\def\strc_notes_set_location_page + {\setfalse\c_strc_notes_delayed + \strc_notes_set_distance + \strc_notes_set_columns + \page_inserts_set_location\currentnoteinsertion\v!page % \setupinsertion[\currentnote][\c!location=\v!page]% + \global\count\currentnoteinsertionnumber\numexpr(\plusthousand/\c_strc_notes_columns)*\nofmulticolumns\relax + \global\dimen\currentnoteinsertionnumber\ifnotelimit\dimexpr\noteparameter\c!height*\c_strc_notes_columns\relax\else\maxdimen\fi + \global\skip \currentnoteinsertionnumber\s_strc_notes_distance} + +\def\strc_notes_set_location_columns + {\setfalse\c_strc_notes_delayed + \strc_notes_set_distance + \strc_notes_set_columns + \ifnum\currentnofcolumns=\zerocount + \c_strc_notes_columns\plusone + \fi + \page_inserts_set_location\currentnoteinsertion\v!columns % \setupinsertion[\currentnote][\c!location=\v!columns]% + \global\count\currentnoteinsertionnumber\numexpr\plusthousand/\c_strc_notes_columns\relax + \global\dimen\currentnoteinsertionnumber\ifnotelimit\dimexpr\noteparameter\c!height*\c_strc_notes_columns\relax\else\maxdimen\fi + \global\skip \currentnoteinsertionnumber\s_strc_notes_distance} + +\def\strc_notes_set_location_somecolumn#whatcolumn% + {\setfalse\c_strc_notes_delayed + \strc_notes_set_distance + \strc_notes_set_columns + \page_inserts_set_location\currentnoteinsertion#whatcolumn% \setupinsertion[\currentnote][\c!location=#whatcolumn]% + \global\count\currentnoteinsertionnumber\plusthousand + \global\dimen\currentnoteinsertionnumber\ifnotelimit\noteparameter\c!height\else\maxdimen\fi + \global\skip \currentnoteinsertionnumber\s_strc_notes_distance} + +\def\strc_notes_set_location_firstcolumn{\strc_notes_set_location_somecolumn\v!firstcolumn} +\def\strc_notes_set_location_lastcolumn {\strc_notes_set_location_somecolumn\v!lastcolumn } + +\def\strc_notes_set_location_text % we don't use inserts anyway (e.g. endnotes) + {\settrue\c_strc_notes_delayed + \clf_setnotestate{\currentnote}{store}% + \page_inserts_set_location\currentnoteinsertion\v!text % \setupinsertion[\currentnote][\c!location=\v!text]% + \global\count\currentnoteinsertionnumber\zerocount + \global\dimen\currentnoteinsertionnumber\maxdimen + \global\skip \currentnoteinsertionnumber\zeropoint} + +\let\strc_notes_set_location_none\strc_notes_set_location_text + +\def\strc_notes_set_properties + {\strc_notes_set_columns + \strc_notes_set_distance + \strc_notes_set_location + \strc_notes_set_delayed} + +\let\strc_notes_set_position_high\relax + +\def\strc_notes_set_position_bottom + {\settrue\c_notes_bottom_present} + +\appendtoks + \strc_notes_set_properties +\to \everysynchronizenote + +%D A fast checker for bottom notes being used: + +\newconditional\c_notes_bottom_present + +\def\strc_notes_check_if_bottom_present_indeed % in otr ! + {\ifvoid\currentnoteinsertionnumber\else + \strc_notes_set_position + \fi} + +\def\strc_notes_check_if_bottom_present_step + {\ifconditional\c_notes_bottom_present\else\strc_notes_check_if_bottom_present_indeed\fi} + +\def\strc_notes_check_if_bottom_present + {\setfalse\c_notes_bottom_present + \strc_notes_process\strc_notes_check_if_bottom_present_step} + +% Example of using factor: +% +% \definenote[mynote][way=bypage,location=text,width=\marginwidth,rule=,before=,factor=0] +% \setuplayout[backspace=5cm,margin=3cm,margindistance=.5cm,width=middle] +% \setuptexttexts[margin][\vbox to \textheight{\placenotes[mynote]\vfill}][] +% \starttext +% \dorecurse{10}{test \mynote{one one one one one one} \input zapf \mynote{one one one one one one} } +% \stoptext + +%D The noterule can be a graphic and therefore calling this setup macro at every +%D skipswitch is tricky (many many MP runs). Let's just reserve a few points, that +%D probably match those of the stretch component. A bit messy: + +\permanent\protected\def\placenoterule + {\begingroup + \currentnoterulealign + \currentnoterulecommand + \par + \endgroup} + +\permanent\protected\def\normalnoterule + {\ifvmode + \dontleavehmode \blackrule + [\c!color=\noteparameter\c!rulecolor, + \c!width=.2\hsize, + \c!height=\noteparameter\c!rulethickness, + \c!depth=\zeropoint]% + \endgraf + \kern\strutdepth + \fi} + +%D The formatting depends on the width of the table, so we have to set \type {n} to +%D zero. +%D +%D \starttyping +%D \startbuffer +%D \bTABLE +%D \bTR \bTD one \footnote{\dorecurse{10}{abcd }} \eTD \bTD two \eTD \eTR +%D \bTR \bTD three fout five six seven eight nine \eTD \bTD ten \eTD \eTR +%D \eTABLE +%D \stopbuffer +%D +%D \startlocalfootnotes[n=0,location={text,none}] +%D \placelegend[n=2]{\getbuffer}{\placelocalfootnotes} +%D \stoplocalfootnotes +%D \stoptyping + +%D \macros +%D {footnote} +%D +%D A footnote can have a reference as optional argument and therefore its formal +%D specification looks like: +%D +%D \showsetup{footnote} +%D +%D This command has one optional command: the reference. By saying \type{[-]} the +%D number is omitted. The footnote command is not that sensitive to spacing, so it's +%D quite legal to say: +%D +%D \startbuffer +%D Users of \CONTEXT\ must keep both feet \footnote {Given they have two.} on the +%D ground and not get confused \footnote {Or even crazy.} by all those obscure +%D \footnote {But fortunately readable.} parameters. +%D \stopbuffer +%D +%D \typebuffer +%D +%D When setting the \type{conversion} to \type{set 2} we get +%D something like: +%D +%D \bgroup +%D \startnarrower +%D \setupfootnotes[conversion=set 1] +%D \getbuffer +%D \stopnarrower +%D \egroup +%D +%D Typesetting footnotes is, at least for the moment, disabled when reshaping boxes. +%D The additional macro \type {\footnotetext} and the associated \type {\note} macro +%D were implemented at request of users on the mailing list and a suggestion by taco +%D to split of the symbol placement. I decided to merge this functionality with the +%D existing \type {\note} functionality. + +\newconditional\c_strc_notes_symbol \settrue\c_strc_notes_symbol % not used +\newconditional\c_strc_notes_skip + +\permanent\protected\def\setnote [#tag]{\csname#tag\endcsname} +\permanent\protected\def\setnotetext[#tag]{\global\settrue\c_strc_notes_skip\csname#tag\endcsname} + +\permanent\protected\def\handlenoteinsert#tag#id% + {\begingroup + \edef\currentnote{#tag}% + \strc_constructions_initialize{#tag}% + \strc_notes_synchronize + \the\everybeforenoteinsert + \insert\currentnoteinsertionnumber\bgroup + \the\everyinsidenoteinsert\relax + \usesetupsparameter\noteparameter % experimental + \useinterlinespaceparameter\noteparameter + \doifelse{\noteparameter\c!paragraph}\v!yes + {\nointerlineskip + \startvboxtohboxseparator + \noteparameter\c!inbetween + \stopvboxtohboxseparator + \startvboxtohbox + \handlenoteitself{#tag}{#id}% + \stopvboxtohbox} + {\handlenoteitself{#tag}{#id}}% + \egroup + \the\everyafternoteinsert + \endgroup} + +\permanent\protected\def\betweennoteitself#tag% used ? + {\edef\currentnote{#tag}% + \doif{\noteparameter\c!paragraph}\v!yes{\noteparameter\c!inbetween}} + +\permanent\protected\def\handlenoteitself#tag#id% + {\edef\currentnotenumber{#id}% + \edef\currentnote{#tag}% + \strc_constructions_initialize{#tag}% + \strc_notes_synchronize + \edef\currentconstructionlistentry{\clf_notelistindex{\currentnote}#id}% index in list cache + % as we can have collected notes (e.g. in tables) we need to recover + % \currentdescriptionattribute and \currentdescriptionsynchronize + % + \reinstatecachedconstructionnumberentry\currentconstructionlistentry % we could store the number in the entry (e.g. needed when local notes in table) + % + \dontcomplain + %begingroup + \strc_notes_interaction_check_display + \strc_notes_set_reference_attribute_text + \strc_constructions_stored_start + \begstrut + \strc_references_flush_destination_nodes + \strc_notes_set_destination_attribute_text + \strc_notes_inject_text\relax + \ifvmode\obeydepth\else\endstrut\fi % \obeydepth is new per 2015-01-10 + \strc_constructions_stored_stop + %endgroup + } + +\protected\def\strc_notes_inject_text % hm main? + {\clf_savedlisttitle{\currentconstructionmain}\currentconstructionlistentry\relax} + +\let\startpushnote\relax +\let\stoppushnote \relax + +\newsignal\notesignal + +\newconditional\processingnote +\newconditional\postponednote + +\newtoks\everybeforenoteinsert +\newtoks\everyinsidenoteinsert +\newtoks\everyafternoteinsert + +\permanent\protected\def\doifelseinnote + {\ifconditional\processingnote + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\appendtoks + \enforced\let\flushnotes \relax + \enforced\let\postponenotes\relax + \forgetall + \resetallattributes % new, we don't want color bleed into notes + \inheritmaintextcolor % but we do want to obey the textcolor +\to \everybeforenoteinsert + +\def\strc_notes_set_penalties + {% stored in insert node + \floatingpenalty \currentnotepenalty + % used when typesetting + \interlinepenalty\plushundred % plain value + % used when we need to split in columns + \ifnum\noteparameter\c!n>\plusone + \penalty\zerocount % otherwise no split in columns, maybe just always (tex just adds it to accumulated) + \fi} + +\appendtoks + \strc_notes_set_penalties + \forgetall % again + \strc_notes_set_bodyfont + \redoconvertfont % to undo \undo calls in in headings etc + \splittopskip\strutht % not actually needed here + \splitmaxdepth\strutdp % not actually needed here + % + % not: + % + % \leftmargindistance \noteparameter\c!margindistance + % \rightmargindistance\leftmargindistance + % \ifnum\noteparameter\c!n=\zerocount % no ifcase new 31-07-99 ; always ? + % \doifnotinset{\noteparameter\c!width}{\v!fit,\v!broad}\setnotehsize % ? + % \fi + % + \pickupattributes +\to \everyinsidenoteinsert + +%D Nasty, the might be more: + +\appendtoks \strc_itemgroups_push \to \everybeforenoteinsert +\appendtoks \strc_itemgroups_pop \to \everyafternoteinsert + +% maybe but better use [scope=local] here +% +% \appendtoks +% \setfalse\inhibitmargindata +% \to \everyinsidenoteinsert + +\setupnotes + [\c!width=\v!auto] + +\permanent\protected\def\setnotehsize + {\ifinsidemulticolumns + \setnoteparameter\c!width{\makeupwidth}% + \else + \edef\p_width{\noteparameter\c!width}% + \ifx\p_width\v!auto + % \ifinsidecolumns + \setnoteparameter\c!width{\ifdim\hsize<\makeupwidth\hsize\else\makeupwidth\fi}% + % \else + % \setnoteparameter\c!width{\makeupwidth}% + % \fi + \orelse\ifx\p_width\empty + \setnoteparameter\c!width{\hsize}% + \fi + \fi + \hsize\noteparameter\c!width\relax} + +\appendtoks + % only needed when columns (could be three \set...) + \setnotehsize + \setsimplecolumnshsize[\c!distance=\noteparameter\c!columndistance,\c!n=\noteparameter\c!n,\c!width=\noteparameter\c!width]% +\to \everyinsidenoteinsert + +%D Normally footnotes are saved as inserts that are called upon as soon as the +%D pagebody is constructed. The footnote insertion routine looks just like the +%D \PLAIN\ \TEX\ one, except that we check for the end note state. + +% testcase for split bottom alignment see (a) below +% +% \dorecurse{6}{\input tufte\footnote{\input ward \input tufte \relax}} + +\newconditional\c_strc_notes_first_placed + +\permanent\protected\def\placenoteinserts + {\setfalse\c_strc_notes_first_placed + \strc_notes_process\strc_notes_place_inserts} + +\def\strc_notes_place_inserts + {\strc_notes_set_delayed % \strc_notes_synchronize % we need to know if it's delayed + \ifconditional\c_strc_notes_delayed \else + \ifdim\ht\currentnoteinsertionnumber>\zeropoint % or a faster delayed test + \strc_notes_place_inserts_indeed + \settrue\c_strc_notes_first_placed + \fi + \fi} + +\def\strc_notes_place_inserts_indeed + {\relax + \ifdim\ht\currentnoteinsertionnumber>\zeropoint + \endgraf + \ifvmode + \whitespace + \ifconditional\c_strc_notes_first_placed + \edef\p_spaceinbetween{\noteparameter\c!spaceinbetween}% + \ifx\p_spaceinbetween\empty\else + \blank[\p_spaceinbetween]% + \fi + \else + \edef\p_spacebefore{\noteparameter\c!spacebefore}% + \ifx\p_spacebefore\empty\else + \blank[\p_spacebefore]% + \fi + \fi + \noteparameter\c!before + \fi + \placenoterule + \bgroup + \strc_notes_set_bodyfont + \setbox\scratchbox\hbox + {\strc_notes_flush_inserts}% + \page_postprocessors_linenumbers_deepbox\scratchbox + \setbox\scratchbox\hbox + {\setupcurrentnote + [\c!location=, + \c!width=\v!fit, + \c!height=\v!fit, + \c!strut=\v!no, + \c!offset=\v!overlay]% + \inheritednoteframed + {\ifzeropt\dp\scratchbox % this hack is needed because \vadjust + \hpack{\lower\strutdp\box\scratchbox}% % in margin number placement + \else % hides the (always) present depth + \box\scratchbox + \fi}}% + \setbox\scratchbox\hpack{\lower\strutdepth\box\scratchbox}% + \dp\scratchbox\strutdepth % so we know that it has the note bodyfont depth + \ifvmode + \nointerlineskip % else sometimes empty line + \fi + \box\scratchbox + \egroup + \endgraf + \ifvmode + \noteparameter\c!after + \fi + \fi} + +\def\strc_notes_flush_inserts + {\ifcase\noteparameter\c!n\relax + % should not happen + \or + \strc_notes_flush_inserts_normal + \else + \strc_notes_flush_inserts_columns + \fi} + +\def\strc_notes_flush_inserts_normal + {\strc_notes_flush_global + \obeydepth} % (a) added , since split footnotes will not align properly + +\def\strc_notes_flush_inserts_columns + {\begingroup + \setnotehsize % probably still not ok for columns + \startsimplecolumns[\c!distance=\noteparameter\c!columndistance,\c!n=\noteparameter\c!n,\c!width=\noteparameter\c!width]% + \strc_notes_flush_global + \stopsimplecolumns + \endgroup} + +% idea: tag with attr and then just flush them again + +\def\strc_notes_flush_global + {\begingroup + \useinterlinespaceparameter\noteparameter + \doifelse{\noteparameter\c!paragraph}\v!yes + {\leftorrightvbox % cf mail from ws to list + {\starthboxestohbox + \iftrialtypesetting\unvcopy\else\unvbox\fi\currentnoteinsertionnumber + \stophboxestohbox}} + {\iftrialtypesetting\unvcopied\else\unvboxed\fi\currentnoteinsertionnumber}% + \endgroup} + +%D Supporting end notes is surprisingly easy. Even better, we can combine this +%D feature with solving the common \TEX\ problem of disappearing inserts when +%D they're called for in deeply nested boxes. The general case looks like: +%D +%D \starttyping +%D \postponenotes +%D \.box{whatever we want with footnotes} +%D \flushnotes +%D \stoptyping +%D +%D This alternative can be used in headings, captions, tables etc. The latter one +%D sometimes calls for notes local to the table, which can be realized by saying +%D +%D \starttyping +%D \setlocalfootnotes +%D some kind of table with local footnotes +%D \placelocalfootnotes +%D \stoptyping +%D +%D Postponing is accomplished by simply redefining the (local) insert operation. A +%D not too robust method uses the \type{\insert} primitive when possible. This +%D method fails in situations where it's not entirely clear in what mode \TEX\ is. +%D Therefore the auto method can is to be overruled when needed. + +\newconditional\postponingnotes + +% we need a proper state: normal, postponing, flushing + +\permanent\protected\def\postponenotes % will be locally overloaded + {\ifcase\insertionmigrationmode + \ifconditional\postponingnotes\else + \global\settrue\postponingnotes + \glet\flushnotes\doflushnotes + \clf_postponenotes + \fi + \fi} + +\let\flushnotes\relax + +% also \ifcase\insertionmigrationmode here, needs testing: + +\permanent\protected\def\startpostponingnotes % experimental, page-mix + {\ifconditional\postponingnotes\else + \global\settrue\postponingnotes + %\glet\flushnotes\doflushnotes + \clf_postponenotes + \fi} + +\permanent\protected\def\stoppostponingnotes % experimental, page-mix + {\doflushnotes} + +\permanent\protected\def\doflushnotes + {\ifconditional\postponingnotes + \begingroup + \enforced\let\flushnotes \relax + \enforced\let\postponenotes\relax + \ifconditional\postponednote + \ifhmode + % needed for tagging ... otherwise we get some weird node free error + \signalcharacter + \fi + \fi + \clf_flushpostponednotes% this also resets the states ! + \global\setfalse\postponednote + \global\setfalse\postponingnotes + \glet\flushnotes\relax + \endgroup + \fi} + +%D \macros +%D {startlocalfootnotes,placelocalfootnotes} +%D +%D The next two macros can be used in for instance tables, as we'll demonstrate +%D later on. +%D +%D \showsetup{startlocalfootnotes} +%D \showsetup{placelocalfootnotes} + +% todo: compatibility mode: when first arg is assignment or missing, then all + +\newtoks\everyplacelocalnotes + +\appendtoks + \enforced\let\flushnotes \relax + \enforced\let\postponenotes\relax +\to \everyplacelocalnotes + +\newconditional\inlocalnotes + +\permanent\tolerant\protected\def\startlocalnotes[#list]% grouping ? (we used to have a second argument ... settings) + {\def\localnoteslist{#list}% + \settrue\inlocalnotes + \processcommacommand[\localnoteslist]\strc_notes_local_start_step} + +\permanent\protected\def\stoplocalnotes + {\processcommacommand[\localnoteslist]\strc_notes_local_stop_step + \setfalse\inlocalnotes} + +\let\p_strc_notes_continue\empty + +\def\strc_notes_local_start_step#tag% + {\p_strc_notes_continue{\noteparameter\c!continue}% + \ifx\p_strc_notes_continue\v!yes \else + \strc_counters_save{#tag}% + \strc_counters_reset{#tag}% + \fi + \clf_savenote{#tag}{store}} + +\def\strc_notes_local_stop_step#tag% + {\p_strc_notes_continue{\noteparameter\c!continue}% + \ifx\p_strc_notes_continue\v!yes \else + \strc_counters_restore{#tag}% + \fi + \clf_restorenote{#tag}} + +\permanent\tolerant\protected\def\placelocalnotes[#tag]#spacer[#settings]% + {\doif{\clf_getnotestate{#tag}}{store}{\strc_notes_local_place_indeed{#settings}{#tag}}} + +\def\strc_notes_local_place_indeed#settings#tag% + {\begingroup + \edef\currentnote{#tag}% is already set? + \the\everyplacelocalnotes + % beware, we cannot trust setting \currentnote here + \setupcurrentnote[#settings]% later we set height etc for framed + \strc_notes_place_local_alternative + \strc_notes_set_properties % restore globals (if needed) + \endgroup + }% TODO: just restore properties \the\everychecknote} % we need to restore the old state + +%D These commands can be used like: +%D +%D \startbuffer +%D \startlocalnotes[footnote] +%D \placetable +%D {Some Table} +%D \placeontopofeachother +%D {\starttable[|l|r|] +%D \HL +%D \VL Nota\footnote{Bene} \VL Bene\footnote{Nota} \VL\SR +%D \VL Bene\footnote{Nota} \VL Nota\footnote{Bene} \VL\SR +%D \HL +%D \stoptable} +%D {\setupnotation[footnote][alternative={serried},distance=.5em,after=\hskip1em]% +%D \placelocalnotes[footnote]} +%D \stoplocalnotes +%D \stopbuffer +%D +%D \typebuffer +%D +%D Because this table placement macro expect box content, and thanks to the grouping +%D of the local footnotes, we don't need additional braces. +%D +%D \getbuffer + +%D \macros +%D {placefootnotes} +%D +%D We still have no decent command for placing footnotes somewhere else than at the +%D bottom of the page (for which no user action is needed). Footnotes (endnotes) can +%D be placed by using +%D +%D \showsetup{placefootnotes} + +\permanent\protected\def\placebottomnotes + {\strc_notes_process\strc_notes_place_inserts} + +\permanent\tolerant\protected\def\placenotes[#list]#spacer[#settings]% + {\processcommalist[#list]{\strc_notes_place_indeed{#settings}}} + +\def\strc_notes_place_indeed#settings#tag% settings note + {\edef\currentnote{#tag}% grouping ? + \doifelse{\clf_getnotestate{#tag}}{store} + \strc_notes_local_place_indeed + \strc_notes_global_place_indeed + {#settings}{#tag}} + +\def\strc_notes_global_place_indeed#settings#tag% + {\begingroup + \setupnote[#tag][#settings]% + \strc_notes_place_inserts + \endgroup + \the\everysetupnote} % to be checked .. synchronize + +%D Placement + +\installcorenamespace{notealternative} + +\permanent\protected\def\installnotealternative#alternative#command% + {\setvalue{\??notealternative#alternative}{#command}} + +\permanent\protected\def\doifnotescollected#tag% + {\clf_doifnotecontent{#tag}} + +\def\strc_notes_place_local_alternative % will be a setup (wrapper) + {\doifnotescollected\currentnote + {\endgraf + \ifvmode + \whitespace + \noteparameter\c!before + \fi + \begingroup + \strc_notes_set_bodyfont + \csname\??notealternative\noteparameter\c!alternative\endcsname + \endgroup + \ifvmode + \noteparameter\c!after + \fi}} + +%D A stupid alternative is also provided: +%D +%D \starttyping +%D \setupfootnotes[location=text,alternative=none] +%D \stoptyping + +% setups ? + +\permanent\def\flushlocalnotes#tag{\clf_flushnotes{#tag}{store}{\noteparameter\c!criterium}} + +\installnotealternative \v!none + {\flushlocalnotes\currentnote} + +\installnotealternative \empty + {\flushlocalnotes\currentnote} + +\installnotealternative \v!grid % test if n > 0 + {\begingroup + \setupcurrentnote[\c!location=]% + \snaptogrid\hbox + {\inheritednoteframed + {\flushlocalnotes\currentnote}}% + \endgroup} + +\installnotealternative \v!fixed % test if n > 0 + {\begingroup + \setupcurrentnote[\c!location=]% + \inheritednoteframed + {\flushlocalnotes\currentnote}% + \endgroup} + +\installnotealternative \v!columns % redundant + {\begingroup + \setupcurrentnote[\c!location=]% + \inheritednoteframed + {\edef\currentnotewidth{\noteparameter\c!width}% + \doifelsedimension\currentnotewidth\donothing + {\edef\currentnotewidth{\the\hsize}}% + \startsimplecolumns[\c!distance=\noteparameter\c!columndistance,\c!n=\noteparameter\c!n,\c!width=\currentnotewidth]% + \flushlocalnotes\currentnote + \stopsimplecolumns}% + \endgroup} + +% 0:page 1:firstcolumn 2:lastcolumn + +\newconstant\c_strc_notes_page_location + +\protected\def\strc_notes_check_locations + {\edef\p_strc_notes_location{\rootnoteparameter\c!location}% + \c_strc_notes_page_location + \ifx\p_strc_notes_location\v!firstcolumn\plusone \else + \ifx\p_strc_notes_location\v!lastcolumn \plustwo \else + \zerocount\fi\fi} + +\appendtoks + \strc_notes_check_locations +\to \everysynchronizenote + +% still semi public (but will change) + +\newif\ifnotespresent + +\permanent\protected\def\checknotepresence + {\notespresentfalse + \strc_notes_process\strc_notes_check_presence} + +\def\strc_notes_check_presence + {\ifdim\ht\currentnoteinsertionnumber>\zeropoint + \notespresenttrue + \fi} + +%D \macros +%D {fakenotes} + + % used in page-mul + + \ifdefined\currentnofcolumns\else \def\currentnofcolumns{\nofcolumns} \fi + + \protected\def\fakenotes + {\ifhmode\endgraf\fi\ifvmode + \calculatetotalclevernoteheight + \ifdim\totalnoteheight>\zeropoint \kern\totalnoteheight \fi + \fi} + + \protected\def\fakepagenotes + {\ifhmode\endgraf\fi\ifvmode + \calculatetotalpagenoteheight + \ifdim\totalnoteheight>\zeropoint \kern\totalnoteheight \fi + \fi} + + % used in page-not but not yet ok + + \newdimen\totalnoteheight + + \protected\def\additionaltotalnoteheight#insert% temp hacks anyway + {\dimexpr + \ifdim\ht#insert>\zeropoint + \ifcase\count#insert % + \zeropoint + \else % todo: divide by count + \ht#insert+\skip#insert% hm, no stretch but a dimen anyway + \fi + \else + \zeropoint + \fi + \relax} + + \def\docalculatetotalnoteheight + {\ifcase\c_strc_notes_page_location % tricky here ! ! ! to be sorted out ! ! ! + \advance\totalnoteheight\normalexpanded{\additionaltotalnoteheight\currentnoteinsertionnumber}% + \fi} + + \def\docalculatetotalclevernoteheight + {\ifcase\c_strc_notes_page_location \else % tricky here ! ! ! to be sorted out ! ! ! + \advance\totalnoteheight\normalexpanded{\additionaltotalnoteheight\currentnoteinsertionnumber}% + \fi} + + \def\docalculatetotalpagenoteheight + {\advance\totalnoteheight\normalexpanded{\additionaltotalnoteheight\currentnoteinsertionnumber}} + + \def\calculatetotalnoteheight {\totalnoteheight\zeropoint\strc_notes_process\docalculatetotalnoteheight} + \def\calculatetotalclevernoteheight{\totalnoteheight\zeropoint\strc_notes_process\docalculatetotalclevernoteheight} + \def\calculatetotalpagenoteheight {\totalnoteheight\zeropoint\strc_notes_process\docalculatetotalpagenoteheight} + +%D Now how can this mechanism be hooked into \CONTEXT\ without explictly postponing +%D footnotes? The solution turned out to be rather simple: +%D +%D \starttyping +%D \everypar {...\flushnotes...} +%D \neverypar {...\postponenotes} +%D \stoptyping +%D +%D We can use \type {\neverypar} because in most commands sensitive to footnote +%D gobbling we disable \type {\everypar} in favor for \type {\neverypar}. In fact, +%D this footnote implementation is the first to use this scheme. + +%D This is a nasty and new secondary footnote flusher. It can be hooked into \type +%D {\everypar} like: +%D +%D \starttyping +%D \appendtoks \synchronizenotes \to \everypar +%D \stoptyping + +\let\synchronizenotes\relax + +%D When typesetting footnotes, we have to return to the footnote specific bodyfont +%D size, which is in most cases derived from the global document bodyfont size. In +%D the previous macros we already used a footnote specific font setting macro. + +\def\strc_notes_set_bodyfont + {\let\strc_notes_set_bodyfont\relax + \restoreglobalbodyfont + \usebodyfontparameter\noteparameter + \usealignparameter\noteparameter} + +%D The footnote mechanism defaults to a traditional one column way of showing them. +%D By default we precede them by a small line. + +% end notes in the margin: +% +% \setuptexttexts +% [margin] +% [] [{\directsetup{notabene}}] +% +% \startsetups notabene +% \vbox to \textheight \bgroup +% \setupalign[tolerant] +% \topskipcorrection +% \placenotes[endnote][before=,after=] +% \vfilll +% \egroup +% \stopsetups + +\definenote [\v!footnote] +\definenote [\v!endnote ] [\c!location=\v!none] % else no break + +%D Compatibility macros: + +\permanent\protected\def\setupfootnotedefinition{\setupnotation [\v!footnote]} +\permanent\protected\def\setupfootnotes {\setupnote [\v!footnote]} +\permanent \def\footnotetext {\setnotetext [\v!footnote]} +\permanent\protected\def\placefootnotes {\dodoubleempty\strc_notes_place_footnotes [\v!footnote]} +\permanent\protected\def\placelocalfootnotes {\dodoubleempty\strc_notes_place_local_footnotes[\v!footnote]} +\permanent\protected\def\startlocalfootnotes {\startlocalnotes [\v!footnote]} % alleen footnote +\permanent\protected\def\stoplocalfootnotes {\stoplocalnotes } + +\def\strc_notes_place_footnotes[#list][#settings]% + {\ifsecondargument + \placenotes[#list][#settings,\c!height=\textheight]% + \else + \placenotes[#list][\c!height=\textheight]% + \fi} + +\def\strc_notes_place_local_footnotes[#list][#settings]% + {\ifsecondargument + \placelocalnotes[#list][#settings,\c!height=\textheight]% + \else + \placelocalnotes[#list][\c!height=\textheight]% + \fi} + +%D Goodies: +%D +%D \starttyping +%D \dorecurse {100} { +%D test \footnote{\doifnoteonsamepageelse[footnote]{ibidem}{aaa}} +%D } +%D \stoptyping + +\permanent\def\doifelsenoteonsamepage#tag{\clf_doifnoteonsamepageasprevious{#tag}} + +\aliased\let\doifnoteonsamepageelse\doifelsenoteonsamepage + +%D New trickery: + +%D \macros +%D {note} +%D +%D Refering to a note is accomplished by the rather short command: +%D +%D \showsetup{note} +%D +%D This command is implemented rather straightforward as: + +\installcorenamespace{notesymbol} + +\let\lastnotesymbol\relax % todo: per class + +\permanent\tolerant\protected\def\notesymbol[#tag]#spacer[#reference]% + {\ifnotesenabled + \dontleavehmode + \begingroup + \edef\currentnote{#tag}% + \usenotestyleandcolor\c!textstyle\c!textcolor + \iftok{#reference}\emptytoks + \noteparameter\c!textcommand\lastnotesymbol % check if command double + \else + \unskip + \noteparameter\c!textcommand{\in[#reference]}% command here? + \fi + \endgroup + \fi} + +\permanent\tolerant\protected\def\note[#tag]#spacer[#reference]% + {\iftok{#reference}\emptytoks + \notesymbol[\v!footnote][#tag]% + \else + \notesymbol[#tag][#reference]% + \fi} + +% will be redone if needed +% +% \def\ownnotesymbol#1% #1 gets number passed +% {\executeifdefined{\??notesymbol\currentnote}\empty} +% +% \protected\def\setnotesymbol[#1]#2#3% +% {\prewordbreak % prevent lookback +% \setgvalue{\??notesymbol#1}{#3} +% \strc_notes_inject_symbol} +% +% \protected\def\ownnote[#1]#2#3#4% +% {\setnotesymbol[#1]{#2}{#3}% +% \setnotetext [#1]{#4}} +% +% \defineconversion +% [ownnote] +% [\ownnotesymbol] + +% tricky: +% +% \enabletrackers[nodes.areas] +% \enabletrackers[nodes.references] +% \enabletrackers[nodes.destinations] +% +% \setupnotes[interaction=all,rule=no] +% \setupinteraction[state=start,focus=standard] +% +% \starttext +% \goto{\input tufte\relax}[page(2)] \par +% \ruledhbox{\gotobox{\vtop{\input tufte\relax}}[page(2)]} \par +% \ruledhbox{\gotobox{\vbox{\input tufte\relax}}[page(2)]} \par +% % \completecontent +% % \chapter{Chapter} +% % \dorecurse{5}{\input knuth} +% a\footnote{\input tufte\par\input ward\relax} +% \stoptext + +%D Bonus: + +\appendtoks + \setsystemmode\currentnote +\to \everysynchronizenote + +\protect \endinput |