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

\unprotect

% Spacing is kind of complicated and eventually we might move so more to the engine:
%
% [global spacebefore]     % force flexible
%
% [before][rule 1][after]  % force fixed
% [local spacebefore 1]    % force fixed
% [notes 1.1]
% [local spaceinbetween 1] % force fixed
% [notes 1.2]
%
% [global spaceinbetween]  % force fixed
%
% [before][rule 2][after]  % force fixed
% [local spacebefore 2]    % force fixed
% [notes 2.1]
% [local spaceinbetween 2] % force fixed
% [notes 2.2]
%
% [global spaceinbetween]  % force fixed
%
% [before][rule 2][after]  % force fixed
% [local spacebefore 3]    % force fixed
% [notes 3.1]
% [local spaceinbetween 3] % force fixed
% [notes 3.2]

\newgluespec \s_strc_notes_global_before
\newgluespec \s_strc_notes_global_inbetween
\newgluespec \s_strc_notes_local_before
\newgluespec \s_strc_notes_local_inbetween

% These are accessed in:

\registerctxluafile{strc-not}{autosuffix}

% 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 \aliased\let\dotagsetnotesymbol      \relax              \fi
\ifdefined\dotagsetnotation         \else \aliased\let\dotagsetnotation        \relax              \fi
\ifdefined\dotagsetdescriptionindex \else \aliased\let\dotagsetdescriptionindex\gobbletwoarguments \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}

\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%
  {\ifempty{#parent}%
     \expanded{\defineconstruction[#tag][\s!handler=\v!notation,\c!level=#level]}%
     \edefcsname\??notation#tag:\s!parent\endcsname{\??notation}%
   \else
     \expanded{\defineconstruction[#tag][#parent][\s!handler=\v!notation,\c!level=#level]}%
     \edefcsname\??note    #tag:\s!parent\endcsname{\??note#parent}% see later for \s!note
     \edefcsname\??notation#tag:\s!parent\endcsname{\??notation#parent}%
   \fi
   \protected\instance\edefcsname\e!next #tag\endcsname{\strc_notations_next{#tag}{\number#level}}% obsolete
   \protected\instance\edefcsname\c!reset#tag\endcsname{\strc_notations_reset{#tag}{\number#level}}% obsolete
   \protected\instance\edefcsname        #tag\endcsname{\strc_notations_command[#tag]}%
   \protected\instance\edefcsname\e!start#tag\endcsname{\strc_notations_start[#tag]}%
   \protected\instance\edefcsname\e!stop #tag\endcsname{\strc_notations_stop}}

\lettonothing\m_strc_notation_sub

\appendtoks
    \lettonothing\m_strc_notation_sub
    \ifempty\currentnotationparent
       % clone => parent | subclone => clone | subsubclone => subclone
       \strc_define_commands_notation
         {\m_strc_notation_sub\currentnotation}%
         \plusone
         \empty
       \edef\p_levels{\notationparameter\c!levels}%
       \dostepwiserecurse\plustwo\p_levels\plusone
         {\strc_define_commands_notation
            {\v!sub\m_strc_notation_sub\currentnotation}%
            \recurselevel
            {\m_strc_notation_sub\currentnotation}%
          \edef\m_strc_notation_sub{\v!sub\m_strc_notation_sub}}%
        \definelist[\currentnotation]% goodie
   \else
       % clone => parent | subclone => subparent | subsubclone => subsubparent
       \edef\p_levels{\notationparameter\c!levels}%
       \dorecurse\p_levels
         {\strc_define_commands_notation
            {\m_strc_notation_sub\currentnotation}%
            \recurselevel
            {\m_strc_notation_sub\currentnotationparent}%
          \edef\m_strc_notation_sub{\v!sub\m_strc_notation_sub}}%
        \definelist[\currentnotation][\currentnotationparent]% goodie
   \fi
   \edef\p_counter{\notationparameter\s!counter}% can inherit from parent
   \ifempty\p_counter
       \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

\lettonothing\p_strc_constructions_title
\lettonothing\p_strc_constructions_number

\protected\defcsname\??constructioninitializer\v!notation\endcsname
  {\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
     \c_strc_constructions_number_state\conditionaltrue
     \iftrialtypesetting
       \strc_counters_save\currentconstructionnumber
     \fi
    %\strc_counters_increment_sub\currentconstructionnumber\currentconstructionlevel
   \else
     \c_strc_constructions_number_state\conditionalfalse
   \fi
   \edef\p_strc_constructions_title{\constructionparameter\c!title}%
   \ifx\p_strc_constructions_title\v!yes
     \c_strc_constructions_title_state\conditionaltrue
   \else
     \c_strc_constructions_title_state\conditionalfalse
   \fi}

\protected\defcsname\??constructionfinalizer\v!notation\endcsname
  {\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
  {\expanded{\endgroup\noteparameter\c!next}}

\def\strc_notations_finalize_next
  {\endgroup\ignorespaces}

\tolerant\protected\def\strc_notations_command[#1]#*[#S#2]%
  {\begingroup
   \cdef\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
     \c_strc_notations_anchored_next\conditionaltrue
   \else
     \c_strc_notations_anchored_next\conditionalfalse
   \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[#S#1]%
  {\strc_constructions_register[][\c!delay={\noteparameter\c!location},\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,\c!referencetext=,#1]%
   \strc_notations_wrapup}

\tolerant\def\strc_notations_command_reference[#1]#*#=%
  {\strc_constructions_register[][\c!delay={\noteparameter\c!location},\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=,\c!referencetext=]%
   \strc_notations_wrapup}

\def\strc_notations_wrapup
  {\csname\??constructionnotehandler\currentconstructionhandler\endcsname
   \strc_constructions_finalize
  %\strc_constructions_discard % yes or no, for now disabled
   \strc_notations_finalize}

\tolerant\protected\def\strc_notations_start
  {\strc_notations_start_indeed{\csname\e!stop\currentnotation\endcsname}}

\tolerant\protected\defcsname\e!start\e!namednotation\endcsname
  {\strc_notations_start_indeed{\csname\e!stop\e!namednotation\endcsname}}

\ifdefined\startnamednotation
    % we're in the english interface
\else
    \tolerant\protected\def\startnamednotation
      {\strc_notations_start_indeed\stopnamednotation}
\fi

\tolerant\protected\def\strc_notations_start_indeed#1#*[#2]#*[#S#3]%
  {\begingroup
   \cdef\currentnote{#2}%
   \strc_constructions_initialize{#2}%
   \strc_notes_synchronize
   \ifnotesenabled
     \strc_counters_increment_sub\currentconstructionnumber\currentconstructionlevel
   \fi
   \ifhastok={#3}%
     \expandafter\strc_notations_start_setups
   \else
     \expandafter\strc_notations_start_reference
   \fi#1[#3]}

\let\strc_notations_pickup_yes\relax

\protected\def\strc_notations_start_setups#1[#S#2]%
  {\expanded{\def\noexpand\strc_notations_pickup_yes##/#1{\strc_notations_start_setups_indeed[#2]{##1}}}%
   \strc_notations_pickup_yes}

\protected\def\strc_notations_start_setups_indeed[#S#1]#*#2%
  {\strc_constructions_register[][\c!delay={\noteparameter\c!location},\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#2},\c!bookmark=,\c!list=,\c!referencetext=,#1]%
   \strc_notations_wrapup}

\protected\def\strc_notations_start_reference#1[#S#2]%
  {\expanded{\def\noexpand\strc_notations_pickup_yes##/#1{\strc_notations_start_reference_indeed[#2]{##1}}}%
   \strc_notations_pickup_yes}

\protected\def\strc_notations_start_reference_indeed[#1]#*#2%
  {\strc_constructions_register[][\c!delay={\noteparameter\c!location},\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=,\c!referencetext=]%
   \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\defcsname\??constructionnotehandler\v!notation\endcsname
  {\csname\??constructionnotehandler\currentconstructionhandler:\constructionparameter\c!type\endcsname}

\protected\defcsname\??constructionnotehandler\v!notation:\endcsname % 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\kern{\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!before=\blank,
  %\c!before=,
  %\c!after=,
   \c!spacebefore=\v!line,
   \c!spaceinbetween=\v!halfline,
   \c!bodyfont=\v!small,
   \c!anchor=, % can also be v!next
  %\c!style=,
  %\c!color=,
  %\c!rulecolor=,
  %\c!rulecommand=,
   \c!rule=\v!on,
   \c!rulethickness=\linewidth,
   \c!rulewidth=.2\hsize,
   \c!ruledistance=\zeropoint,
   \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=]

\appendtoks
   \resetnoteparameter\c!spacebefore
   \resetnoteparameter\c!spaceinbetween
\to \everydefinenote

% What keyword to use for this: max ? \insertmaxplaced\namedinsertionnumber{footnote} 4

%D Insertions are part of notes.c!delay

%D Insertions are part of notes.

% \installcorenamespace{noteinsertion}

\permanent\def\currentnoteinsertion      {\noteparameter\s!insert}
\permanent\def\currentnoteinsertionnumber{\namedinsertionnumber{\noteparameter\s!insert}}

\appendtoks
    \ifempty\currentnoteparent
        \doifelseinsertion\currentnote
          \donothing
          {\defineinsertion[\currentnote]% could be an option
           \xtoksapp\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

%letcsname\??constructionstarthandler  \v!notation\expandafter\endcsname\csname\??constructionstarthandler  \v!enumeration\endcsname
\letcsname\??constructionstarthandler  \v!notation\expandafter\endcsname\csname\??constructionstarthandler  \v!construction\endcsname % no par mess
\letcsname\??constructionstophandler   \v!notation\expandafter\endcsname\csname\??constructionstophandler   \v!enumeration \endcsname
\letcsname\??constructioncommandhandler\v!notation\expandafter\endcsname\csname\??constructioncommandhandler\v!enumeration \endcsname
\letcsname\??constructiontexthandler   \v!notation\expandafter\endcsname\csname\??constructiontexthandler   \v!enumeration \endcsname

\protected\defcsname\??constructionmainhandler\v!notation\endcsname#following%
  {\iftrialtypesetting \else
     \begingroup
     \currentconstructionsynchronize
     \c_attr_destination\currentconstructionattribute\relax % todo, whole text
     \signalcharacter
     \endgroup
   \fi
   \ifconditional\c_strc_notes_flushed\else
     #following\relax
   \fi}

\newmarks\c_strc_notes_insert_mark

\protected\defcsname\??constructionnotehandler\v!notation:\v!note\endcsname % 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}%
       \processingnote\conditionaltrue
       \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\postponednote\conditionaltrue
       \orelse\ifconditional\inlocalnotes % todo: per note class
         \global\postponednote\conditionaltrue
       \orelse\ifconditional\c_strc_notes_flushed
         \handlenoteitself\currentnote\currentnotenumber
       \orelse\ifconditional\c_strc_notes_delayed
         % probably end notes
       \else
         \handlenoteinsert\currentnote\currentnotenumber % either an insert or just delayed
       \fi
       \endgroup
     \fi
   \fi
   %
   \ifcstok{\noteparameter\c!range}\v!yes
     \expanded{\marks\c_strc_notes_insert_mark{\the\c_strc_notes_n}}%
   \fi
   %
   \ifconditional\c_strc_notes_skip
     \global\c_strc_notes_skip\conditionalfalse
   \else
     \boundary\noteboundary
   \fi}

%D New, for columnsets:

\permanent\protected\def\flushnoterange[#1]%
  {\begingroup
   \cdef\currentnote{#1}%
  %\clf_flushnoterange
  %   \numexpr\currentnoteinsertionnumber\relax
  %   \numexpr\firstmarks\c_strc_notes_insert_mark\relax
  %   \numexpr\botmarks\c_strc_notes_insert_mark\relax
  %\relax
   \clf_flushnoterange
      {\currentnoteinsertionnumber}%
      \c_strc_notes_insert_mark
   \relax
   \endgroup}

%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

\lettonothing\strc_notes_get_reference_attribute_symbol
\lettonothing\strc_notes_get_destination_attribute_symbol

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

\mutable\let\currentnotenumber\!!zerocount

\lettonothing\strc_notes_get_reference_attribute_symbol
\lettonothing\strc_notes_get_destination_attribute_symbol

\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_inline \relax
\let\strc_notes_set_style_color_display\relax

% inline

\lettonothing\m_strc_notes_internal

\def\strc_notes_prepare_inline_references_nop
  {\lettonothing\strc_notes_get_reference_attribute_symbol
   \lettonothing\strc_notes_get_destination_attribute_symbol
   \let\strc_notes_set_style_color_inline\strc_notes_set_style_color_inline_nop}

\def\strc_notes_prepare_inline_references_yes
  {\edef\m_strc_notes_internal{\clf_noteinternal{\currentnote}\currentnotenumber}%
   \strc_references_set_simple_reference{*\m_strc_notes_internal}% destination
   \strc_references_get_simple_reference{internal(\m_strc_notes_internal)}% reference
   \edef\strc_notes_get_destination_attribute_symbol{attr\destinationattribute\number\currentdestinationattribute}%
   \edef\strc_notes_get_reference_attribute_symbol  {attr\referenceattribute  \number\currentreferenceattribute  }%
   \let\strc_notes_set_style_color_inline\strc_notes_set_style_color_inline_yes}

\letcsname\??noteinteractioninline\v!no    \endcsname\strc_notes_prepare_inline_references_nop
\letcsname\??noteinteractioninline\v!all   \endcsname\strc_notes_prepare_inline_references_yes
\letcsname\??noteinteractioninline\v!number\endcsname\strc_notes_prepare_inline_references_yes
\letcsname\??noteinteractioninline\v!text  \endcsname\strc_notes_prepare_inline_references_yes
\letcsname\??noteinteractioninline\v!yes   \endcsname\strc_notes_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_notes_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_notes_prepare_display_references_yes_number
  {\edef\m_strc_notes_internal{\clf_noteinternal{\currentnote}\currentnotenumber}%
   \ifcase\m_strc_notes_internal\relax
     \strc_notes_prepare_display_references_nop
   \else
     \let\strc_notes_set_reference_attribute_text\donothing
     \strc_references_get_simple_reference{*\m_strc_notes_internal}% reference
     \edef\strc_notes_set_reference_attribute_number{\c_attr_reference\number\currentreferenceattribute}%
     \let\strc_notes_set_style_color_display\strc_notes_set_style_color_display_yes
   \fi}

\def\strc_notes_prepare_display_references_yes_text
  {\edef\m_strc_notes_internal{\clf_noteinternal{\currentnote}\currentnotenumber}%
   \ifcase\m_strc_notes_internal\relax
     \strc_notes_prepare_display_references_nop
   \else
     \strc_references_get_simple_reference{*\m_strc_notes_internal}% reference
     \edef\strc_notes_set_reference_attribute_text{\c_attr_reference\number\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_notes_prepare_display_references_yes_all
  {\edef\m_strc_notes_internal{\clf_noteinternal{\currentnote}\currentnotenumber}%
   \ifcase\m_strc_notes_internal\relax
     \strc_notes_prepare_display_references_nop
   \else
     \strc_references_get_simple_reference{*\m_strc_notes_internal}% reference
     \edef\strc_notes_set_reference_attribute_text{\c_attr_reference\number\currentreferenceattribute}%
     \strc_references_get_simple_reference{*\m_strc_notes_internal}% reference
     \edef\strc_notes_set_reference_attribute_number{\c_attr_reference\number\currentreferenceattribute}%
     \let\strc_notes_set_style_color_display\strc_notes_set_style_color_display_yes
   \fi}

\letcsname\??noteinteractiondisplay\v!no    \endcsname\strc_notes_prepare_display_references_nop
\letcsname\??noteinteractiondisplay\v!all   \endcsname\strc_notes_prepare_display_references_yes_all
\letcsname\??noteinteractiondisplay\v!number\endcsname\strc_notes_prepare_display_references_yes_number
\letcsname\??noteinteractiondisplay\v!text  \endcsname\strc_notes_prepare_display_references_yes_text
\letcsname\??noteinteractiondisplay\v!yes   \endcsname\strc_notes_prepare_display_references_yes_number

\mutable\let\strc_notes_set_style_color_inline_nop \usenotestyleandcolor
\mutable\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\ifempty\currentcolorparameter
     \scratchcounter\clf_notedeltapage{\currentnote}\currentnotenumber\relax % todo calculate once
     \setlocationcolorspecified\scratchcounter
   \fi}

\defcsname\??constructiontexthandler\v!notation\endcsname
  {\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
   \ifnum\lastboundary=\noteboundary
     \unboundary
   % \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
     \s!keepspacing
     \strc_notes_get_reference_attribute_symbol
     \strc_notes_get_destination_attribute_symbol
   \bgroup
     \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
     \ifcstok{\noteparameter\c!indicator}\v!yes
       \strc_notes_inject_pointer
     \fi
     \dostoptagged
   \egroup
   \endgroup
   \glettonothing\lastnotesymbol}

\protected\def\strc_notes_inject_dummy % temp hack
  {\removeunwantedspaces
   \doifelseitalic\/\donothing % Charles IV \footnote{the fourth}
   \ifnum\lastboundary=\noteboundary
     \unboundary
   % \kern\noteparameter\c!distance % yes or no note font? or main text
     \strc_notes_inject_separator
   \fi
   \nobreak
   \hpack to .5\emwidth{}%
   \glettonothing\lastnotesymbol}

\protected\def\strc_notes_inject_separator % patch by WS due to request on list
  {\edef\p_textseparator{\noteparameter\c!textseparator}%
   \ifempty\p_textseparator
     \kern{\noteparameter\c!distance}%
   \else
     % skip or kern
     \nobreak
     \hbox\bgroup
       \usenotestyleandcolor\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{\cdef\currentnote{##1}\let\currentdescription\currentnote#action}%
   \expand\t_strc_notes}

\newtoks\everychecknote                % just before a note is typeset
\newtoks\everysynchronizenote          % after a general setup has happened
\newtoks\everysynchronizenoteinbetween % during collecting just before packaging

\appendtoks
    \ifempty\currentnote \else
        \setupnotations[\currentnote][]% also a synchronize
    \fi
\to \everysynchronizenote

\def\strc_notes_synchronize
  {\expand\everysynchronizenote} % we can speed this one up if needed by avoiding the commalist

\appendtoks
    \strc_notes_process\strc_notes_synchronize
\to \everysetupnoteroot

\appendtoks
    \expand\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\letcsname\??notecommand\currentnote\endcsname}
\permanent\protected\def\letcurrentnoterulealign  {\enforced\letcsname\??notealign  \currentnote\endcsname}

\appendtoks
    \enforced\letcsname\??notecommand\currentnote\endcsname\currentnoterulecommandnormal
    \enforced\letcsname\??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
  {\ifcase\insertdirection\currentnoteinsertionnumber
     \lefttoright
   \else
     \righttoleft
   \fi}

\defcsname\??noterule  \v!command\endcsname{\letcurrentnoterulecommand\currentnoterulecommandcommand}
\defcsname\??noterule       \v!on\endcsname{\letcurrentnoterulecommand\currentnoterulecommandnormal}
\defcsname\??noterule   \v!normal\endcsname{\letcurrentnoterulecommand\currentnoterulecommandnormal}
\defcsname\??noterule     \v!left\endcsname{\letcurrentnoterulecommand\currentnoterulecommandnormal
                                            \letcurrentnoterulealign  \lefttoright}
\defcsname\??noterule    \v!right\endcsname{\letcurrentnoterulecommand\currentnoterulecommandnormal
                                            \letcurrentnoterulealign  \righttoleft}
\defcsname\??noterule\v!paragraph\endcsname{\letcurrentnoterulecommand\currentnoterulecommandnormal
                                            \letcurrentnoterulealign  \strc_notes_set_rule_autodir}
\defcsname\??noterule      \v!off\endcsname{\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

\letcsname\??notepenalty\v!tolerant  \endcsname\notepenaltytolerant
\letcsname\??notepenalty\v!strict    \endcsname\notepenaltystrict
\letcsname\??notepenalty\v!verystrict\endcsname\notepenaltyverystrict
\letcsname\??notepenalty             \endcsname\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}%
   \ifempty\p_factor \else
     \ifnum\p_factor<\zerocount \else
%        \global
       \insertmultiplier\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
\newconditional\c_strc_notes_flushed

\protected\def\strc_notes_set_delayed_yes{\c_strc_notes_delayed\conditionaltrue \c_strc_notes_flushed\conditionalfalse}
\protected\def\strc_notes_set_delayed_nop{\c_strc_notes_delayed\conditionalfalse\c_strc_notes_flushed\conditionalfalse}
\protected\def\strc_notes_set_delayed_lst{\c_strc_notes_delayed\conditionaltrue \c_strc_notes_flushed\conditionaltrue }

\defcsname\??notelocation\v!page\endcsname
  {\letcsname\??notedelayedvariant \currentnote\endcsname\strc_notes_set_delayed_nop
   \letcsname\??notelocationvariant\currentnote\endcsname\strc_notes_set_location_page}

\defcsname\??notelocation\v!columns\endcsname
  {\letcsname\??notedelayedvariant \currentnote\endcsname\strc_notes_set_delayed_nop
   \letcsname\??notelocationvariant\currentnote\endcsname\strc_notes_set_location_columns}

\defcsname\??notelocation\v!lastcolumn\endcsname
  {\letcsname\??notedelayedvariant \currentnote\endcsname\strc_notes_set_delayed_nop
   \letcsname\??notelocationvariant\currentnote\endcsname\strc_notes_set_location_lastcolumn}

\defcsname\??notelocation\v!firstcolumn\endcsname
  {\letcsname\??notedelayedvariant \currentnote\endcsname\strc_notes_set_delayed_nop
   \letcsname\??notelocationvariant\currentnote\endcsname\strc_notes_set_location_firstcolumn}

\defcsname\??notelocation\v!none\endcsname
  {\letcsname\??notedelayedvariant \currentnote\endcsname\strc_notes_set_delayed_yes
   \letcsname\??notelocationvariant\currentnote\endcsname\strc_notes_set_location_none}

\defcsname\??notelocation\v!list\endcsname
  {\letcsname\??notedelayedvariant \currentnote\endcsname\strc_notes_set_delayed_lst
   \letcsname\??notelocationvariant\currentnote\endcsname\strc_notes_set_location_none}

\defcsname\??notelocation\v!text\endcsname
  {\letcsname\??notedelayedvariant \currentnote\endcsname\strc_notes_set_delayed_yes
   \letcsname\??notelocationvariant\currentnote\endcsname\strc_notes_set_location_text}

\defcsname\??notelocation\v!high\endcsname
  {\letcsname\??notepositionvariant\currentnote\endcsname\strc_notes_set_position_high}

\defcsname\??notelocation\v!bottom\endcsname
  {\letcsname\??notepositionvariant\currentnote\endcsname\strc_notes_set_position_bottom}

\defcsname\??notedelayedvariant \??notedelayedvariant \endcsname{\strc_notes_set_delayed_nop    } % not \let
\defcsname\??notepositionvariant\??notepositionvariant\endcsname{\strc_notes_set_position_bottom} % not \let
\defcsname\??notelocationvariant\??notelocationvariant\endcsname{\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
  {\expanded{\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

\newgluespec   \s_strc_notes_distance % we need to implement stretch
\newinteger    \c_strc_notes_columns
\newconditional\c_strc_notes_first_flushed

% we can store them per insert so so real need to redo it

\def\strc_notes_set_distance % basically only wrapper and rule
  {\begingroup
   \restoreglobalbodyfont
 % \expand\everysynchronizenote
 % \resetgridsnapping \gridsnappingfalse \strc_notes_set_bodyfont
   \setbox\scratchbox\vbox % no reuse as it can mirror
     {\forgetall
      \dontcomplain
      \noteparameter\c!before
      \ifvmode
        \nointerlineskip
      \fi
      \placenoterule
      \noteparameter\c!after
      }%
   \scratchdimen\htdp\scratchbox
 % \ifconditional\c_page_mvl_active
 %   % quick hack, columnsets already handle the grid .. maybe an option
 % \orelse\ifgridlinesnapping
 %   % gridlinesnapping: to be decided
 % \orelse\ifgridsnapping
 %   \getnoflines\scratchdimen
 %   \scratchdimen\noflines\lineheight
 % \fi
   \expanded{%
     \endgroup
     \s_strc_notes_distance\the\scratchdimen\relax
     % this will / has to / might become a plug
     \ifconditional\c_page_mvl_split_inserts
       \insertlineheight\currentnoteinsertionnumber\relaxedspace\the\strutht\relax
       \insertlinedepth \currentnoteinsertionnumber\relaxedspace\the\strutdp\relax
     \fi}}

\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
  {\c_strc_notes_delayed\conditionalfalse
   \strc_notes_set_distance
   \strc_notes_set_columns
   \page_inserts_set_location\currentnoteinsertion\v!page % \setupinsertion[\currentnote][\c!location=\v!page]%
   \insertcategory  \currentnoteinsertionnumber\pageinsertcategorycode
   \insertmultiplier\currentnoteinsertionnumber{(\plusthousand/\c_strc_notes_columns)*\nofmulticolumns}%
   \insertlimit     \currentnoteinsertionnumber\ifnotelimit{(\noteparameter\c!height)*\c_strc_notes_columns}\else\maxdimen\fi
   \insertdistance  \currentnoteinsertionnumber\s_strc_notes_distance}

\def\strc_notes_set_location_columns
  {\c_strc_notes_delayed\conditionalfalse
   \strc_notes_set_distance
   \strc_notes_set_columns
 % \ifnum\currentnofcolumns=\zerocount
   \ifnum\nofcolumns=\zerocount
     \c_strc_notes_columns\plusone
   \fi
   \page_inserts_set_location\currentnoteinsertion\v!columns % \setupinsertion[\currentnote][\c!location=\v!columns]%
   \insertcategory  \currentnoteinsertionnumber\pageinsertcategorycode
   \insertmultiplier\currentnoteinsertionnumber{\plusthousand/\c_strc_notes_columns}%
   \insertlimit     \currentnoteinsertionnumber\ifnotelimit{(\noteparameter\c!height)*\c_strc_notes_columns}\else\maxdimen\fi
   \insertdistance  \currentnoteinsertionnumber\s_strc_notes_distance}

\def\strc_notes_set_location_somecolumn#whatcolumn%
  {\c_strc_notes_delayed\conditionalfalse
   \strc_notes_set_distance
   \strc_notes_set_columns
   \page_inserts_set_location\currentnoteinsertion#whatcolumn% \setupinsertion[\currentnote][\c!location=#whatcolumn]%
   \insertmultiplier\currentnoteinsertionnumber\plusthousand
   \insertlimit     \currentnoteinsertionnumber\ifnotelimit{\noteparameter\c!height}\else\maxdimen\fi
   \insertdistance  \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)
  {\c_strc_notes_delayed\conditionaltrue
   \clf_setnotestate{\currentnote}{store}%
   \page_inserts_set_location\currentnoteinsertion\v!text % \setupinsertion[\currentnote][\c!location=\v!text]%
   \insertmultiplier\currentnoteinsertionnumber\zerocount
   \insertlimit     \currentnoteinsertionnumber\maxdimen
   \insertdistance  \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
   \strc_notes_set_factor}

\let\strc_notes_set_position_high\relax

\def\strc_notes_set_position_bottom
  {\c_notes_bottom_present\conditionaltrue}

\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_indeed % in otr !
  {\ifzeropt\insertheight\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
  {\c_notes_bottom_present\conditionalfalse
   \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\placenoterule
  {\begingroup
   \currentnoterulealign
 % \begingroup
 % \resetgridsnapping
 % \gridsnappingfalse
 % \strc_notes_set_bodyfont
   \setbox\scratchbox\hpack\bgroup
     \currentnoterulecommand
   \egroup
   \ifzeropt\htdp\scratchbox\else
     \box\scratchbox\par
     \ifvmode
       \vkern{\noteparameter\c!ruledistance}%
     \fi
     \par
   \fi
 % \endgroup
   \endgroup}

\permanent\protected\def\normalnoterule
  {\blackrule
     [\c!color=\noteparameter\c!rulecolor,
      \c!width={\noteparameter\c!rulewidth},
    % \c!height={\noteparameter\c!rulethickness-\strutdp},
    % \c!depth=\strutdp]}
      \c!height={\noteparameter\c!rulethickness},
      \c!depth=\zeropoint]}

%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 \c_strc_notes_symbol\conditionaltrue % not used
\newconditional\c_strc_notes_skip

\newcount\c_strc_notes_n

\permanent\protected\def\setnote    [#tag]{\csname#tag\endcsname}
\permanent\protected\def\setnotetext[#tag]{\global\c_strc_notes_skip\conditionaltrue\csname#tag\endcsname}

\permanent\protected\def\handlenoteinsert#tag#id%
  {\begingroup
   \cdef\currentnote{#tag}%
   \strc_constructions_initialize{#tag}%
   \strc_notes_synchronize
   \global\advanceby\c_strc_notes_n\plusone
   \expand\everybeforenoteinsert
  %\insert\currentnoteinsertionnumber
   \insert
     \s!index \currentnoteinsertionnumber
     \s!data  \c_strc_notes_n
   \bgroup
     \expand\everyinsidenoteinsert\relax
     \usesetupsparameter\noteparameter % experimental
     \useinterlinespaceparameter\noteparameter
     \ifcstok{\noteparameter\c!paragraph}\v!yes
       \nointerlineskip
       \startvboxtohboxseparator
         \noteparameter\c!inbetween
       \stopvboxtohboxseparator
       \startvboxtohbox
         \handlenoteitself{#tag}{#id}%
       \stopvboxtohbox
     \else
       \handlenoteitself{#tag}{#id}%
     \fi
   \egroup
   \expand\everyafternoteinsert
   \endgroup}

\permanent\protected\def\betweennoteitself#tag% used ?
  {\cdef\currentnote{#tag}%
   \ifcstok{\noteparameter\c!paragraph}\v!yes
     \noteparameter\c!inbetween
   \fi}

\def\strc_notes_save_indices
  {\dotagsetdescriptionindex
      \currentnotenumber
      \currentconstructionlistentry}

\permanent\protected\def\handlenoteitself#tag#id%
  {\edef\currentnotenumber{#id}%
   \cdef\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
   \ifconditional\c_strc_notes_flushed
   \else
       \strc_notes_save_indices % horrible hack (for tagging attachments)
       \strc_notes_inject_text
       \relax
   \fi
   \ifvmode\obeydepth\else\endstrut\fi % \obeydepth is new per 2015-01-10
   \strc_constructions_stored_stop
   %endgroup
   }

% see deeptextcommand-001.tex
%
% \starttexdefinition protected MyNoteCommand #1
%     \doifelsetaggednoteonsamepage {\currentnote} {\SomeTag} {
%         \color[darkblue]
%     } {
%         \color[darkred]
%     }
%     {#1}
% \stoptexdefinition
%
% \setupnotation[footnote][deeptextcommand=\MyNoteCommand]

% \protected\def\strc_notes_inject_text % hm main?
%   {\clf_savedlisttitle{\currentconstructionmain}\currentconstructionlistentry\relax}

\protected\def\strc_notes_inject_text % hm main?
  {\notationparameter\c!deeptextcommand
     {\clf_savedlisttitle{\currentconstructionmain}\currentconstructionlistentry\relax}}

\installstructurelistprocessor{construction}{\usestructurelistprocessor{section}}

\newboundary\noteboundary

\newconditional\processingnote
\newconditional\postponednote

\newtoks\everybeforenoteinsert
\newtoks\everyinsidenoteinsert
\newtoks\everyafternoteinsert

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

\appendtoks
   \enforced\lettonothing\flushnotes
   \enforced\lettonothing\postponenotes
   \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 % now per note
   \insertpenalty\currentnoteinsertionnumber\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 (plain has it)
    \splitmaxdepth\strutdp % not actually needed here (plain has it)
% \insertsplittop  \currentnoteinsertionnumber\strutht
\insertmaxdepth  \currentnoteinsertionnumber\strutdp
    %
    % 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
%     \inhibitmargindata\conditionalfalse
% \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\ifempty\p_width
%        \setnoteparameter\c!width{\hsize}%
%      \fi
%   \fi
%   \hsize\noteparameter\c!width\relax}
%
% We construct immediately and migrate so:

\permanent\protected\def\setnotehsize
  {\edef\p_width{\noteparameter\c!width}%
   \ifx\p_width\v!auto
     % intercept old value
     \let\p_width\makeupwidth
     \setnoteparameter\c!width{\makeupwidth}%
   \fi
   \hsize{\p_width}}

\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
  {\c_strc_notes_first_placed\conditionalfalse
   \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
     \ifcase\insertheight\currentnoteinsertionnumber\else
       \strc_notes_place_inserts_indeed
       \c_strc_notes_first_placed\conditionaltrue
     \fi
   \fi}

\newbox\b_strc_notes_inserts

\def\strc_notes_place_inserts_indeed_before
  {\endgraf
   \c_spac_whitespace_flexible\conditionalfalse
  %\gridsnappingfalse
   \ifvmode
     \begingroup % global or not
   % \whitespace % hm
     \ifconditional\c_strc_notes_first_placed
       \edef\p_space{\rootnoteparameter\c!spaceinbetween}%
       \ifempty\p_space\else
         \setbox\scratchbox\vbox{\blank[\p_space]}\vskip\htdp\scratchbox
       \fi
     \else
       \edef\p_space{\rootnoteparameter\c!spacebefore}%
       \ifempty\p_space\else
         \setbox\scratchbox\vbox{\blank[\p_space]}\vskip\htdp\scratchbox
       \fi
     \fi
%      \edef\p_space{\noteparameter\c!spacebefore}%
%      \ifempty\p_space\else
%        \setbox\scratchbox\vbox{\blank[\p_space]}\vskip\htdp\scratchbox
%      \fi
     \endgroup
   \fi
   \ifvmode
     \strc_notes_set_bodyfont
     \noteparameter\c!before % part of note, maybe inside
     \ifvmode
        \nointerlineskip % added, otherwise spacing between multiple classes
     \fi
   \fi
   \placenoterule
   \ifvmode
     \begingroup
       \edef\p_space{\noteparameter\c!spacebefore}%
       \ifempty\p_space\else
         \setbox\scratchbox\vbox{\blank[\p_space]}\vskip\htdp\scratchbox
       \fi
     \endgroup
  \fi}

\def\strc_notes_place_inserts_indeed_after
  {\endgraf
   \ifvmode
     \noteparameter\c!after % part of note, maybe inside
   \fi}

\def\strc_notes_place_inserts_indeed
  {\relax
   \ifcase\insertheight\currentnoteinsertionnumber\else
 % \ifzeropt\insertheight\currentnoteinsertionnumber\else
     \strc_notes_place_inserts_indeed_before
     \begingroup
\resetgridsnapping
\gridsnappingfalse
\strc_notes_set_bodyfont
     \setbox\b_strc_notes_inserts\hbox
       {\strc_notes_flush_inserts}%
     \page_postprocessors_linenumbers_deepbox\b_strc_notes_inserts
     \setbox\b_strc_notes_inserts\hbox
       {\setupcurrentnote
          [\c!location=,
           \c!width=\v!fit,
           \c!height=\v!fit,
           \c!strut=\v!no,
           \c!offset=\v!overlay]%
        \inheritednoteframed
          {\ifzeropt\dp\b_strc_notes_inserts                  % this hack is needed because \vadjust
             \hpack{\lower\strutdp\box\b_strc_notes_inserts}% % in margin number placement
           \else                                              % hides the (always) present depth
             \box\b_strc_notes_inserts
           \fi}}%
     \setbox\b_strc_notes_inserts\hpack{\lower\strutdepth\box\b_strc_notes_inserts}%
   % \dp\b_strc_notes_inserts\strutdepth % so we know that it has the note bodyfont depth
     \ifvmode
       \nointerlineskip % else sometimes empty line
     \fi
     \box\b_strc_notes_inserts
     \endgroup
     \strc_notes_place_inserts_indeed_after
   \fi}

% \def\strc_notes_place_inserts_very_indeed#1%
%   {\strc_notes_place_inserts_indeed_before
%    \bgroup
%    \strc_notes_set_bodyfont
%    #1% set the box here
%    \page_postprocessors_linenumbers_deepbox\b_strc_notes_inserts
%    \scratchheight\ht\b_strc_notes_inserts
%    \scratchdepth \dp\b_strc_notes_inserts
%    \setbox\b_strc_notes_inserts\hbox
%      {\setupcurrentnote
%         [\c!location=,
%          \c!width=\v!fit,
%          \c!height=\v!fit,
%          \c!strut=\v!no,
%          \c!offset=\v!overlay]%
%       \inheritednoteframed
%         {\box\b_strc_notes_inserts}}%
%    \ht\b_strc_notes_inserts\scratchheight
%   %\dp\b_strc_notes_inserts\scratchdepth
%    \dp\b_strc_notes_inserts\strutdepth % so we know that it has the note bodyfont depth
%    \ifvmode
%      \nointerlineskip % else sometimes empty line
%    \fi
%    \box\b_strc_notes_inserts
%    \egroup
%    \strc_notes_place_inserts_indeed_after}

\def\strc_notes_place_inserts_very_indeed#1%
  {\strc_notes_place_inserts_indeed_before
   \bgroup
\resetgridsnapping
\gridsnappingfalse
   \strc_notes_set_bodyfont
   #1% set the box here
   \page_postprocessors_linenumbers_deepbox\b_strc_notes_inserts
   \scratchheight\ht\b_strc_notes_inserts
   \scratchdepth \dp\b_strc_notes_inserts
   \setbox\b_strc_notes_inserts\hbox
     {\setupcurrentnote
        [\c!location=,
         \c!width=\v!fit,
         \c!height=\v!fit,
         \c!strut=\v!no,
         \c!offset=\v!overlay]%
      \inheritednoteframed
        {\box\b_strc_notes_inserts}}%
   \ht\b_strc_notes_inserts\scratchheight
  %\dp\b_strc_notes_inserts\scratchdepth
   \dp\b_strc_notes_inserts\strutdepth % so we know that it has the note bodyfont depth
   \ifvmode
     \nointerlineskip % else sometimes empty line
   \fi
   \box\b_strc_notes_inserts
   \egroup
   \strc_notes_place_inserts_indeed_after
   }

\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
   \ifcstok{\noteparameter\c!paragraph}\v!yes
     \leftorrightvbox % cf mail from ws to list
       {\starthboxestohbox
          \iftrialtypesetting
            \insertuncopy
          \else
            \insertunbox
          \fi
          \currentnoteinsertionnumber
        \stophboxestohbox}%
   \else
     \iftrialtypesetting
       \ifvmode\insertuncopy\else\insertcopy\fi
     \else
       \ifvmode\insertunbox \else\insertbox \fi
     \fi
     \currentnoteinsertionnumber
   \fi
   \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\postponingnotes\conditionaltrue
       \enforced\glet\flushnotes\doflushnotes
       \clf_postponenotes
     \fi
   \fi}

\permanent\lettonothing\flushnotes

% also \ifcase\insertionmigrationmode here, needs testing:

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

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

\permanent\protected\def\doflushnotes
  {\ifconditional\postponingnotes
     \begingroup
     \enforced\lettonothing\flushnotes
     \enforced\lettonothing\postponenotes
     \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\postponednote\conditionalfalse
     \global\postponingnotes\conditionalfalse
     \enforced\glettonothing\flushnotes
     \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\lettonothing\flushnotes
    \enforced\lettonothing\postponenotes
\to \everyplacelocalnotes

\newconditional\inlocalnotes

\mutable\lettonothing\localnoteslist

\permanent\tolerant\protected\def\startlocalnotes[#list]% grouping ? (we used to have a second argument ... settings)
  {\inlocalnotes\conditionaltrue
   \def\localnoteslist{#list}%
   \processcommacommand[\localnoteslist]\strc_notes_local_start_step}

\permanent\protected\def\stoplocalnotes
  {\processcommacommand[\localnoteslist]\strc_notes_local_stop_step
   \inlocalnotes\conditionalfalse}

\lettonothing\p_strc_notes_continue
\lettonothing\p_strc_notes_location

\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[#S#settings]%
  {\iftok{\clf_getnotestate{#tag}}{store}%
     \strc_notes_local_place_indeed{#settings}{#tag}%
   \fi}

\def\strc_notes_local_place_indeed#settings#tag%
  {\begingroup
   \cdef\currentnote{#tag}% is already set?
   \expand\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 \expand\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\protected\def\placebottomnotes
  {\vbox \s!yoffset -\usedlineskip \bgroup % TODO (normally 1pt), \lineskip is zero at this moment
     \strc_notes_process\strc_notes_place_inserts
     \vskip\strutdp
   \egroup}

\permanent\tolerant\protected\def\placenotes[#list]#spacer[#S#settings]%
  {\processcommalist[#list]{\strc_notes_place_indeed{#settings}}}

\def\strc_notes_place_indeed#settings#tag% settings note
  {\cdef\currentnote{#tag}% grouping ?
   \iftok{\clf_getnotestate{#tag}}{store}%
     \expandafter\strc_notes_local_place_indeed
   \else
     \expandafter\strc_notes_global_place_indeed
   \fi
   {#settings}{#tag}}

\def\strc_notes_global_place_indeed#settings#tag%
  {\begingroup
   \setupnote[#tag][#settings]%
   \strc_notes_place_inserts
   \endgroup
   \expand\everysetupnote} % to be checked .. synchronize

%D Placement

\installcorenamespace{notealternative}

\permanent\protected\def\installnotealternative#alternative#command%
  {\defcsname\??notealternative#alternative\endcsname{#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
      \begincsname\??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=]%
   \ifgridlinesnapping
     % gridlinesnapping: to be decided
     \expandafter\snaptogridline
   \orelse\ifgridsnapping
     \expandafter\snaptogrid
   \else
     % to be decided
   \fi
   \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
     {\ifchkdimension\noteparameter\c!width\or\else\setexpandednoteparameter\c!width{\the\hsize}\fi
      \startsimplecolumns[\c!distance=\noteparameter\c!columndistance,\c!n=\noteparameter\c!n,\c!width=\noteparameter\c!width]%
        \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\insertheight\currentnoteinsertionnumber>\zeropoint % not reliable
  {\ifcase\insertheight\currentnoteinsertionnumber\else
     \notespresenttrue
   \fi}

%D \macros
%D   {fakenotes}

    % used in page-mul

 %  \ifdefined\currentnofcolumns\else \def\currentnofcolumns{\nofcolumns} \fi

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

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

    \permanent\protected\def\additionaltotalnoteheight#insert% temp hacks anyway
      {\dimexpr
         \ifnum\insertheight#insert=\zeropoint
           \zeropoint
         \orelse\ifnum\insertmultiplier#insert=\zeropoint
           \zeropoint
         \else % todo: divide by count
           \insertheight  #insert
          +\insertdistance#insert% hm, no stretch but a dimen anyway
         \fi
      \relax}

    \permanent\def\docalculatetotalnoteheight
      {\ifcase\c_strc_notes_page_location % tricky here ! ! ! to be sorted out ! ! !
         \advanceby\totalnoteheight\expanded{\additionaltotalnoteheight\currentnoteinsertionnumber}%
       \fi}

    \permanent\def\docalculatetotalclevernoteheight
      {\ifcase\c_strc_notes_page_location \else % tricky here ! ! ! to be sorted out ! ! !
         \advanceby\totalnoteheight\expanded{\additionaltotalnoteheight\currentnoteinsertionnumber}%
       \fi}

    \permanent\def\docalculatetotalpagenoteheight
      {\advanceby\totalnoteheight\expanded{\additionaltotalnoteheight\currentnoteinsertionnumber}}

    \permanent\def\calculatetotalnoteheight      {\totalnoteheight\zeropoint\strc_notes_process\docalculatetotalnoteheight}
    \permanent\def\calculatetotalclevernoteheight{\totalnoteheight\zeropoint\strc_notes_process\docalculatetotalclevernoteheight}
    \permanent\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
\definenote [\v!mathnote] [\c!location=\v!none]

%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         {\strc_notes_place_footnotes      [\v!footnote]}
\permanent\protected\def\placelocalfootnotes    {\strc_notes_place_local_footnotes[\v!footnote]}
\permanent\protected\def\startlocalfootnotes    {\startlocalnotes                 [\v!footnote]} %  alleen footnote
\permanent\protected\def\stoplocalfootnotes     {\stoplocalnotes }

\tolerant\def\strc_notes_place_footnotes[#list]#spacer[#S#settings]%
  {\ifarguments\or
     \placenotes[#list][\c!height=\textheight]%
   \or
     \placenotes[#list][#settings,\c!height=\textheight]%
   \fi}

\tolerant\def\strc_notes_place_local_footnotes[#list]#spacer[#S#settings]%
  {\ifarguments\or
     \placelocalnotes[#list][\c!height=\textheight]%
   \or
     \placelocalnotes[#list][#settings,\c!height=\textheight]%
   \fi}

%D Goodies:
%D
%D \starttyping
%D \dorecurse {100} {
%D     test \footnote{\doifnoteonsamepageelse{footnote}{ibidem}{aaa}}
%D }
%D \stoptyping

% defined at lua end:

\aliased\let\doifnoteonsamepageelse      \doifelsenoteonsamepage
\aliased\let\doiftaggednoteonsamepageelse\doifelsetaggednoteonsamepage

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

\mutable\lettonothing\lastnotesymbol % todo: per class

\permanent\tolerant\protected\def\notesymbol[#tag]#keepspacer[#reference]%
  {\ifnotesenabled
     \dontleavehmode
     \begingroup
     \cdef\currentnote{#tag}%
     \usenotestyleandcolor\c!textstyle\c!textcolor
     \ifempty{#reference}%
       \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]#keepspacer[#reference]%
  {\ifempty{#reference}%
     \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
%    \gdefcsname\??notesymbol#1\endcsname{#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

\def\strc_notes_check_space#1#2#3%
  {\edef\p_space{#2#3}%
   \ifempty\p_space
     \global#1\zeropoint
   \else
     \setbox\scratchbox\vbox\bgroup
       \blank[\p_space]% so anyway fixed and force
       \global#1\lastskip
     \egroup
   \fi}

\appendtoks
    \begingroup
        \restoreglobalbodyfont
        \strc_notes_check_space\s_strc_notes_global_before   \rootnoteparameter\c!spacebefore
        \strc_notes_check_space\s_strc_notes_global_inbetween\rootnoteparameter\c!spaceinbetween
        \strc_notes_check_space\s_strc_notes_local_before    \noteparameter    \c!spacebefore
        \strc_notes_check_space\s_strc_notes_local_inbetween \noteparameter    \c!spaceinbetween
    \endgroup
\to \everysynchronizenote

\appendtoks
    \begingroup
        \restoreglobalbodyfont
        \strc_notes_check_space\s_strc_notes_local_inbetween \noteparameter \c!spaceinbetween
    \endgroup
\to \everysynchronizenoteinbetween

\protect \endinput
