%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

%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}

\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}

\unexpanded\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}}%
   \setuevalue{\e!next #tag}{\strc_notations_next   {#tag}{\number#level}}% obsolete
   \setuevalue{\c!reset#tag}{\strc_notations_reset  {#tag}{\number#level}}% obsolete
   %setuevalue{\c!set  #tag}{\strc_notations_set    {#tag}{\number#level}}% obsolete
   \setuevalue        {#tag}{\strc_notations_command{#tag}}%
   \setuevalue{\e!start#tag}{\strc_notations_start  {#tag}{#tag}}% okay?
   \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

\unexpanded\setvalue{\??constructioninitializer\v!notation}%
  {\let\currentnotation                 \currentconstruction
   \let\constructionparameter           \notationparameter
   \let\constructionnamespace           \??notation
   \let\detokenizedconstructionparameter\detokenizednotationparameter
   \let\letconstructionparameter        \letnotationparameter
   \let\useconstructionstyleandcolor    \usenotationstyleandcolor
   \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}

\unexpanded\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

\unexpanded\def\strc_notations_next {\strc_constructions_next_indeed \namednotationparameter} % #1#2
\unexpanded\def\strc_notations_reset{\strc_constructions_reset_indeed\namednotationparameter} % #1#2
%unexpanded\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}

\unexpanded\def\strc_notations_command#tag%
  {\begingroup
   \edef\currentnote{#tag}%
   \strc_constructions_initialize{#tag}%
   \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
   \doifelsenextoptionalcs\strc_notations_command_yes\strc_notations_command_nop}

\unexpanded\def\strc_notations_command_nop#title%
  {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#title},\c!bookmark=,\c!list=]%
   \csname\??constructionnotehandler\currentconstructionhandler\endcsname
   \strc_constructions_finalize
   \strc_notations_finalize}

\unexpanded\def\strc_notations_command_yes[#optional]%
  {\doifelseassignment{#optional}\strc_notations_command_assignment\strc_notations_command_argument[#optional]}

\unexpanded\def\strc_notations_command_assignment[#settings]%
  {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,#settings]%
   \csname\??constructionnotehandler\currentconstructionhandler\endcsname
   \strc_constructions_finalize
   \strc_notations_finalize}

\unexpanded\def\strc_notations_command_argument[#reference]#title%
  {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#reference},\c!title={#title},\c!bookmark=,\c!list=]%
   \csname\??constructionnotehandler\currentconstructionhandler\endcsname
   \strc_constructions_finalize
   \strc_notations_finalize}

\unexpanded\def\strc_notations_start#tag#stoptag%
  {\begingroup
   \edef\currentnote{#tag}%
   \strc_constructions_initialize{#tag}%
   \strc_notes_synchronize
   \ifnotesenabled
     \strc_counters_increment_sub\currentconstructionnumber\currentconstructionlevel
   \fi
   \normalexpanded % not that efficient but also not that frequently used (\normaldef for parser)
     {\def\noexpand\strc_pickup_yes[#one]#two\csname\e!stop#stoptag\endcsname{\strc_notations_command_yes[#one]{#two}}%
      \def\noexpand\strc_pickup_nop      #one\csname\e!stop#stoptag\endcsname{\strc_notations_command_nop      {#one}}}%
   \doifelsenextoptionalcs\strc_pickup_yes\strc_pickup_nop}

\unexpanded\def\strc_notations_start_yes[#reference]#title%
  {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#reference},\c!title={#title},\c!bookmark=,\c!list=]%
   \csname\??constructionnotehandler\currentconstructionhandler\endcsname
   \strc_constructions_finalize
   \strc_notations_finalize}

\unexpanded\def\strc_notations_start_nop#title%
  {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#title},\c!bookmark=,\c!list=]%
   \csname\??constructionnotehandler\currentconstructionhandler\endcsname
   \strc_constructions_finalize
   \strc_notations_finalize}

\unexpanded\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.

\unexpanded\setvalue{\??constructionnotehandler\v!notation}%
  {\csname\??constructionnotehandler\currentconstructionhandler:\constructionparameter\c!type\endcsname}

\unexpanded\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}

\def\currentnoteinsertion      {\noteparameter\s!insert}
\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

\unexpanded\setvalue{\??constructionmainhandler\v!notation}#following%
  {\iftrialtypesetting \else
     \begingroup
     \currentconstructionsynchronize
     \c_attr_destination\currentconstructionattribute\relax % todo, whole text
     \signalcharacter
     \endgroup
   \fi#following}

\unexpanded\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
       \else\ifconditional\inlocalnotes % todo: per note class
         \global\settrue\postponednote
       \else\ifconditional\c_strc_notes_delayed
         % probably end notes
       \else
         \handlenoteinsert\currentnote\currentnotenumber % either an insert or just delayed
       \fi\fi\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

\unexpanded\def\strc_notes_set_style_color_inline_yes#style#color%
  {\usenotestyleandcolor#style#color%
   \iflocation\strc_notes_set_style_color_special\fi}

\unexpanded\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
   \else\ifx\currentcolorparameter\empty
     \scratchcounter\clf_notedeltapage{\currentnote}\currentnotenumber\relax % todo calculate once
     \setlocationcolorspecified\scratchcounter
   \fi\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

\unexpanded\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}

\unexpanded\def\strc_notes_inject_symbol_yes
  {\strc_notes_inject_symbol_indeed\conditionaltrue}

\unexpanded\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=]

% \unexpanded\def\strc_notes_destination_hack
%   {\ifx\strc_notes_get_destination_attribute_symbol\empty\else
%      \strc_notes_destination_hack_indeed
%    \fi}
%
% \unexpanded\def\strc_notes_destination_hack_indeed % can be a helper
%   {\strc_notes_destination_margin
%      {\setbox\scratchbox\hpack \strc_notes_get_destination_attribute_symbol{}%
%       \wd\scratchbox\makeupwidth
%       \ht\scratchbox\strutht
%       \dp\scratchbox\strutdp
%       \hpack to \zeropoint{\box\scratchbox\hss}}}

\unexpanded\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}

\unexpanded\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}

\unexpanded\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

\unexpanded\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}

\def\currentnoterulecommand{\begincsname\??notecommand\currentnote\endcsname}
\def\currentnoterulealign  {\begincsname\??notealign  \currentnote\endcsname}

\def\currentnoterulecommandcommand{\noteparameter\c!rulecommand}
\def\currentnoterulecommandnormal {\normalnoterule} % no let as it can be changed afterwards
%def\currentnoterulecommandunknown{\noteparameter\c!rule}

\def\letcurrentnoterulecommand{\expandafter\let\csname\??notecommand\currentnote\endcsname}
\def\letcurrentnoterulealign  {\expandafter\let\csname\??notealign  \currentnote\endcsname}

\appendtoks
    \letvalue{\??notecommand\currentnote}\currentnoterulecommandnormal
    \letvalue{\??notealign  \currentnote}\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

\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

\unexpanded\def\strc_notes_set_delayed_yes{\settrue \c_strc_notes_delayed}
\unexpanded\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

\unexpanded\def\strc_notes_set_delayed
  {\csname\??notedelayedvariant
     \ifcsname\??notedelayedvariant\currentnote\endcsname
       \currentnote
     \else
       \??notedelayedvariant
     \fi
   \endcsname}

% \let\strc_notes_set_delayed_yes\truecondition
% \let\strc_notes_set_delayed_nop\falsecondition
%
% \def\c_strc_notes_delayed
%   {\csname\??notedelayedvariant
%      \ifcsname\??notedelayedvariant\currentnote\endcsname
%        \currentnote
%      \else
%        \??notedelayedvariant
%      \fi
%    \endcsname}

\unexpanded\def\strc_notes_set_position
  {\csname\??notepositionvariant
     \ifcsname\??notepositionvariant\currentnote\endcsname
       \currentnote
     \else
       \??notepositionvariant
     \fi
   \endcsname}

\unexpanded\def\strc_notes_set_location
  {\csname\??notelocationvariant
     \ifcsname\??notelocationvariant\currentnote\endcsname
       \currentnote
     \else
       \??notelocationvariant
     \fi
   \endcsname}

\unexpanded\def\strc_notes_set_variants
  {\normalexpanded{\rawprocesscommalist[\noteparameter\c!location]\strc_notes_set_location_step}}

\unexpanded\def\strc_notes_set_location_step#alternative% the insert related one
 %{\ifcsname\??notelocation#alternative\endcsname\csname\??notelocation#alternative\endcsname\fi}
  {\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\relax
%    \global\dimen\currentnoteinsertionnumber\ifnotelimit\dimexpr\noteparameter\c!height*\c_strc_notes_columns\relax\else\maxdimen\fi
%    \global\skip \currentnoteinsertionnumber\s_strc_notes_distance\relax}

\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:

\unexpanded\def\placenoterule
  {\begingroup
   \currentnoterulealign
   \currentnoterulecommand
   \par
   \endgroup}

\unexpanded\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

\unexpanded\def\setnote    [#tag]{\csname#tag\endcsname}
\unexpanded\def\setnotetext[#tag]{\global\settrue\c_strc_notes_skip\csname#tag\endcsname}

\unexpanded\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}

\unexpanded\def\betweennoteitself#tag% used ?
  {\edef\currentnote{#tag}%
   \doif{\noteparameter\c!paragraph}\v!yes{\noteparameter\c!inbetween}}

\unexpanded\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
   }

\unexpanded\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

\unexpanded\def\doifelseinnote
  {\ifconditional\processingnote
     \expandafter\firstoftwoarguments
   \else
     \expandafter\secondoftwoarguments
   \fi}

\appendtoks
   \let\flushnotes\relax
   \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
%  {\doif{\noteparameter\c!scope}\v!page{\floatingpenalty\maxdimen}% experiment
%  %\interlinepenalty\maxdimen % todo
%   \penalty\currentnotepenalty}

\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]

\unexpanded\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
     \else\ifx\p_width\empty
       \setnoteparameter\c!width{\hsize}%
     \fi\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

\unexpanded\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
        \ifvmode\unvcopy\else\copy\fi
      \else
        \ifvmode\unvbox \else\box \fi
      \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

\unexpanded\def\postponenotes
  {\ifcase\insertionmigrationmode
     \ifconditional\postponingnotes\else
       \global\settrue\postponingnotes
       \glet\flushnotes\doflushnotes
       \clf_postponenotes
     \fi
   \fi}

\let\flushnotes\relax

% also \ifcase\insertionmigrationmode here, needs testing:

\unexpanded\def\startpostponingnotes % experimental, page-mix
  {\ifconditional\postponingnotes\else
     \global\settrue\postponingnotes
    %\glet\flushnotes\doflushnotes
     \clf_postponenotes
   \fi}

\unexpanded\def\stoppostponingnotes % experimental, page-mix
  {\doflushnotes}

\unexpanded\def\doflushnotes
  {\ifconditional\postponingnotes
     \begingroup
     \let\flushnotes   \relax
     \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
    \let\flushnotes   \relax
    \let\postponenotes\relax
\to \everyplacelocalnotes

\newconditional\inlocalnotes

\unexpanded\def\startlocalnotes
  {\dosingleempty\strc_notes_local_start}

\def\strc_notes_local_start[#list]% grouping ? (we used to have a second argument ... settings)
  {\def\localnoteslist{#list}%
   \settrue\inlocalnotes
   \processcommacommand[\localnoteslist]\strc_notes_local_start_step}

\unexpanded\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}}

\unexpanded\def\placelocalnotes
  {\dodoubleempty\strc_notes_local_place}

\def\strc_notes_local_place[#tag][#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}

\unexpanded\def\placebottomnotes
  {\strc_notes_process\strc_notes_place_inserts}

\unexpanded\def\placenotes
  {\dodoubleempty\strc_notes_place}

\def\strc_notes_place[#list][#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}

\unexpanded\def\installnotealternative#alternative#command%
  {\setvalue{\??notealternative#alternative}{#command}}

\unexpanded\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 ?

\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

\unexpanded\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

\unexpanded\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

    \unexpanded\def\fakenotes
      {\ifhmode\endgraf\fi\ifvmode
         \calculatetotalclevernoteheight
         \ifdim\totalnoteheight>\zeropoint \kern\totalnoteheight \fi
       \fi}

    \unexpanded\def\fakepagenotes
      {\ifhmode\endgraf\fi\ifvmode
         \calculatetotalpagenoteheight
         \ifdim\totalnoteheight>\zeropoint \kern\totalnoteheight \fi
       \fi}

    % used in page-not but not yet ok

    \newdimen\totalnoteheight

    \unexpanded\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

% \def\dosynchronizenotes
%   {\ifvoid\currentnoteinsertionnumber\else\insert\currentnoteinsertionnumber{\unvbox\currentnoteinsertionnumber}\fi}
%
% \def\synchronizenotes
%   {\strc_notes_process\dosynchronizenotes}

\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:

\unexpanded\def\setupfootnotedefinition{\setupnotation                                 [\v!footnote]}
\unexpanded\def\setupfootnotes         {\setupnote                                     [\v!footnote]}
           \def\footnotetext           {\setnotetext                                   [\v!footnote]}
\unexpanded\def\placefootnotes         {\dodoubleempty\strc_notes_place_footnotes      [\v!footnote]}
\unexpanded\def\placelocalfootnotes    {\dodoubleempty\strc_notes_place_local_footnotes[\v!footnote]}
\unexpanded\def\startlocalfootnotes    {\startlocalnotes                               [\v!footnote]} %  alleen footnote
\unexpanded\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

\def\doifelsenoteonsamepage#tag{\clf_doifnoteonsamepageasprevious{#tag}}

\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

\unexpanded\def\notesymbol
  {\dodoubleempty\strc_notes_symbol}

\def\strc_notes_symbol[#tag][#reference]%
  {\ifnotesenabled
     \dontleavehmode
     \begingroup
     \edef\currentnote{#tag}%
     \usenotestyleandcolor\c!textstyle\c!textcolor
     \ifsecondargument
       \unskip
       \noteparameter\c!textcommand{\in[#reference]}% command here?
     \else
       \noteparameter\c!textcommand\lastnotesymbol % check if command double
     \fi
     \endgroup
   \fi}

\unexpanded\def\note
  {\dodoubleempty\strc_notes_note}

\def\strc_notes_note[#tag][#reference]%
  {\ifsecondargument
     \strc_notes_symbol[#tag][#reference]%
   \else
     \secondargumenttrue
     \strc_notes_symbol[\v!footnote][#tag]%
   \fi}

% will be redone if needed
%
% \def\ownnotesymbol#1% #1 gets number passed
%   {\executeifdefined{\??notesymbol\currentnote}\empty}
%
% \unexpanded\def\setnotesymbol[#1]#2#3%
%   {\prewordbreak % prevent lookback
%    \setgvalue{\??notesymbol#1}{#3}
%    \strc_notes_inject_symbol}
%
% \unexpanded\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
