% lollipop-define.tex copyright 1992/3 Victor Eijkhout
%                  copyright 2014--2016     Vafa Khalighi
%
%
%    This program is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    This program is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with this program.  If not, see <http://www.gnu.org/licenses/>.
%
%
\NewTrace:ref
%%%%%%%%%%%%%%%% Symbolic references

% User command for labels.
% this is hardly ever necessary:
% most commands directly accept the label.
%
\def\label[#1]{\bsp@hack\@label{#1}\esp@hack}

% Automatic generation of labels.
% after \@Labelize{command}, it is possible to write \command[sym:ref]
% This is done for any generic construct that has a counter.
%
%\add@generic@stop@default{\ifhas@label \@Labelize{\@command}\fi}
\newif\ifhas@label
\add@generic@default{\has@labelno}
\@GenericOption{haslabel}{\global\has@labelyes}
\def\@Labelize#1{\edef\cs@e{\let\CSname{lab@#1}=\CSname{#1}}\cs@e
    \csarg\edef{#1}{\begingroup
         \aftergroup\CSname{lab@#1}\nxp\@referentiep}}
\def\@referentiep
 {\ifnextchar[%]
    \x@label{\ifNextChar<%>
               \x@o@label{\gdef\xx@label{}\endgroup}%
  }}

% if \command has a symbolic key,
% \x@label#1 =
%     \def\xx@label
%         \@label{#1}
%         \xx@label <- {}
% the \xx@label command is called at the start of every environment
% this delay is necessary, because the label is seen before
% the title, or before any counter is stepped.
%
\newif\ifcustom@label
\def\xx@label{}\def\RefLabel{}
\def\x@o@label<#1>{\global\custom@labeltrue
    \global\current@label{#1}\x@label}
\def\x@label[#1]{\gdef\RefLabel{#1}%
    \gdef\xx@label{\@label{#1}\global\custom@labelfalse
                   \gdef\xx@label{}}\endgroup}

% Label contents
%    mostly generated by \step@counter or so
%
\newtoks\current@label
\def\define@reference
 #1{\ifcustom@label\else
      \edef\cs@e{\global\current@label
          {\counter@@repr{#1}{\csarg\number{\counter@name{#1}}}}}%
      \cs@e
    \fi}

% Internal labeling command
% 1/ \current@label contains tokens describing the reference
%    do a twostep unwrap of that
% 2/ write out the result to the .aux file
% 3/ if the current file has been \InputeFile'd,
%    write out to the .aux of the input file.
%
% the string written out is for \@label{Key}:
% \refer@label{ref@Key}{label value}{page counter}
%
\def\@label@key#1{ref@#1}
\noeol
\def\@label#1{\Tmessage[ref]{Label definition: <#1>=\the
                              \current@label}
    \ifWriteExtern \begingroup
     \def\label[##1]{}\normalesc
     \def\cprotect{\xp\string}
     %\xp\xp\xp\string\FooCounter =>
     %\xp\string\Foo@R{\number\Foo@C} => \string\@arabic{123}
     \def\protect{\noexpand\protect\noexpand}
     %\test@defined@key{#1}
     \edef\cs@e{\edef\nxp\cs@e{\current@label={\the\current@label}}
                \nxp\cs@e}
     \cs@e
     %\Tmessage[ref]{Label as written: <\the\current@label>}
     \edef\cs@e{\the\current@label}
     \edef\cs@a##1{\nxp\csarg\write{##1@file}
           {\string\refer@label{\@label@key{#1}}
               {\macro@meaning\cs@e}{\noexpand\PageCounter}}}
     \cs@a{aux}
     \ifx\@invoernaam\@leeg 
         \else \ifLocalReferences \cs@a{incaux}\relax \fi\fi
    \endgroup\fi}
\newcount\duplicate@labels
\def\test@defined@key#1{\if\UndefinedCS{\@label@key{#1}}
    \Tmessage[ref]{First time definition of <#1>}
    \else\xp\xp\xp\xp\xp\xp\xp\ifx\xp\xp\xp
                \third@of@three\csn \@label@key{#1}\ecs\StaleRef
         \begingroup
           \edef\cs@e{\CSname{\@label@key{#1}}}
           \xp\xp\xp\def\xp\xp\xp\cs@e\xp\xp\xp{\cs@e}
           \temptoksa\xp\xp\xp{\xp\first@of@three\cs@e}
           \edef\cs@e{\CSname{\@label@key{#1}}}
           \xp\xp\xp\def\xp\xp\xp\cs@e\xp\xp\xp{\cs@e}
           \temptoksb\xp\xp\xp{\xp\second@of@three\cs@e}
           \edef\cs@e{\temptoksa
                {{\the\temptoksa}{\the\temptoksb}\nxp\FreshRef}}
           \cs@e
           \csarg\xdef{\@label@key{#1}}{\the\temptoksa}
         \endgroup
         \Tmessage[ref]{Refreshing definition of <#1>:\@space
              \xp\meaning\csn \@label@key{#1}\ecs}
    \else\Wmessage{Duplicate label: <#1>}%
         \advance\duplicate@labels\@ne\fi\fi}
\normaleol

% complete expandable exploding of token lists
\def\macro@meaning#1{\xp\strip@macro@meaning\meaning#1}
\def\toks@meaning#1{\edef\cs@e{\the#1}\macro@meaning\cs@e}
\begingroup\escapechar=-1
\xp\xp\xp\gdef\xp\xp\xp\strip@macro@meaning\xp\string
              \csname macro:->\endcsname{}
\endgroup

\NewDummy{StaleRef}\NewDummy{FreshRef}

% Referring and Page references.
% first of all, when the .aux file is read:
% \refer@label{ref@Key}{label}{page} =
%     \gdef\ref@Key{ {{label}} {{page}} }
% with extra braces for occurring fonts
%
\def\refer@label#1#2#3{\csarg\gdef{#1}{{{#2}}{{#3}}\StaleRef}}

% then   \ref[key] = \@ref\take@former[key]
%      \pgref[key] = \@ref\take@latter[key]
% and \@ref\cs[key] = \expandafter\cs\ref@key
%                   = \cs {{label}} {{page}}
%
\def\ref  {\ifnextchar(%)
   {\@ref\first@of@three}{\@ref\first@of@three()}}
\def\pgref{\ifnextchar(%)
   {\@ref\second@of@three}{\@ref\second@of@three()}}
\newcount\unknown@refs
\add@start@command{\unknown@refs\z@}
\def\@ref#1(#2)[#3]{%
    \if\UndefinedCS{\@label@key{#3}}%
      \message{Unknown #1{}{page}{}reference: <#3>}{\bf ??}%
      \global\advance\unknown@refs\@ne
    \else \@@ref{#1}{#2}{\@label@key{#3}}\fi}
\def\@@ref#1#2#3{\@@@ref#1{#3}%
    \if\IsEmptyList{#2}\else,\penalty200\ #2\fi}
\def\@@@ref#1#2{%
    \xp\xp\xp#1\csname#2\endcsname}
% for btxmac
\def\@printlabel#1{\@ref\first@of@three()[#1]}
%\@@@ref\first@of@three{\@label@key{#1}}}

% Test for changed references
% at the end of the job
%
\def\test@refer@label#1#2#3{
    \def\cs@a{{{#2}}{{#3}}\FreshRef}
    \def\cs@b{{{#2}}{{#3}}\StaleRef}
    \csarg\ifx{#1}\cs@a
    \else \csarg\ifx{#1}\cs@b 
          \else \labels@changedyes 
                \Tmessage[ref]{New definition for <#1>}
    \fi\fi}

% Citations.
% \cite[key] = [\ref[key]]
% \cite(string)[key] = [\ref[key], string]
%
%\def\cite{\ifnextchar(\y@cite\x@cite}
%\def\y@cite(#1)[#2]{[\ref[#2], #1]}
%\def\x@cite[#1]{[\ref[#1]]}

% External Generic Option
% use: external:extfile ... external:stop
% stores result in \extern@x/y/z@toks in a tricky way:
% 'x' stores expandable parts, 'y' stores protectable parts.
% this is inserted in \@outerstartcommands
%
\NewTrace:ext
\newif\ifin@external
\add@generic@default{\in@externalno}
\newtoks\extern@toks \newtoks\late@extern@toks
\newtoks\build@extern@toks
\newtoks\extern@x@toks \newtoks\extern@y@toks \newtoks\extern@z@toks
\adds@generic@default{
  \extern@toks\empty@toks \late@extern@toks\empty@toks
  \extern@x@toks\empty@toks\extern@y@toks\empty@toks}
\@GenericOption{external}{
  \switch {\if\EqualString{#1}}
  {stop}  {\external@stop{extern@toks}}
  {late}  {\external@stop{late@extern@toks}}
  {default}    {\external@start{#1}}
  \endswitch}
\def\external@start#1{\b@group[external]\in@externalyes 
  \build@extern@toks\empty@toks
  \switch@to@options@list{build@extern@toks}
  \if\UndefinedCS{\file@ext@name{#1}}
    \Wmessage{Unknown external file: <#1>
        while defining <\@name>}\def\@add@toks##1{}%
  \else \generate@extern{#1}% document: this writes the file name
    \Tmessage[ext]{External definition <#1>}
  \fi
  \extern@x@toks\empty@stack \extern@y@toks\empty@stack
  \extern@z@toks\empty@toks 
  \begingroup \switch@to@options@list{extern@z@toks}
  }
\def\external@handle@title#1{\seen@textyes
  \external@handle@expandable{#1}{\csn\@@@title{#1}\ecs}{title: <#1>}}
\def\external@handle@expandable#1#2#3{
  \extern@push@part{y}{\the\extern@z@toks}
  \extern@push@part{x}{#2}
  \Tmessage[ext]{External pushed #3}
  \extern@z@toks\empty@toks}  
\def\extern@push@part#1{\csarg{\let\xp\cs@a}{extern@#1@toks}
  \xp\push@onto@cs\xp\cs@a\xp}
\def\extern@pop@n@pop{}
\def\external@before@title{\in@externalyes\seen@textno
    \switch@to@options@list{e@before@toks}}
\def\in@ref@protect{\ifin@label\@add@toks{\protect}\fi}
\def\cs@in@ref@protect#1{%
  \ifin@label \title@count@no@protect{#1} \fi
  \ifin@external \title@count@no@protect{#1} \fi
}
\def\title@count@no@protect#1{%
  \if\has@no@count@string #1Counter? 
    \if\has@no@title@string #1Title?
      \@add@toks{\protect}\fi\fi}
\def\has@no@count@string #1Counter#2?
   {00\fi\if\IsEmptyList{#2}}
\def\has@no@title@string #1Title#2?
   {00\fi\if\IsEmptyList{#2}}
% wind up making an external: invert the stacks
% and append them
\def\external@stop#1{\extern@push@part{y}{\the\extern@z@toks}
    \invert@csstack\extern@x@toks \invert@csstack\extern@y@toks
    \xdef\cs@e{\nxp\@add@toks
          {{\the\extern@x@toks}{\the\extern@y@toks}}}
    \endgroup %revert to build@extern@toks
    \cs@e \@add@toks{\e@extern}
    \switch@to@options@list{#1}
    \edef\cs@e{\nxp\@add@toks{\the\build@extern@toks}}\cs@e
    \e@group[external]}
% how do we write stuff to the aux file?
% #1 is the x toks, #2 the y
\def\aux@write@external#1#2{%
  \extern@x@toks{#1}\extern@y@toks{#2}%
%  \let\\\relax
%\message{Expandables <\the\extern@y@toks>}
%  \edef\cs@e{\extern@y@toks{#2}}\cs@e
%\message{becomes <\the\extern@y@toks>}
  \length@of@csstack\extern@x@toks
  \tempcounta\z@ \extern@toks\empty@toks
  \loop\ifnum\tempcounta<\stack@length
    \pop@cs@into\extern@z@toks\extern@y@toks
    \append@cslist@to@cslist\extern@toks\extern@z@toks
    \pop@cs@into\extern@z@toks\extern@x@toks
    \extern@z@toks\xp\xp\xp{\the\extern@z@toks}%
    \append@cslist@to@cslist\extern@toks\extern@z@toks
    \advance\tempcounta\@ne\repeat
  \pop@cs@into\extern@z@toks\extern@y@toks
  \append@cslist@to@cslist\extern@toks\extern@z@toks
  \xp\def\xp\cs@e\xp{\the\extern@toks}\edef\cs@e
   {\write\aux@file{\real@meaning\cs@e}}\cs@e}
%
% Protection of expandable control sequences;
% value \nxp\protect\nxp is set during label definition and shipout
% \protect should be empty during execution
%
\def\protect{}

%%%%%%%%%%%%%%%% External references
% define explicitly the form a reference will take
% label:start ... label:stop
%
% Maybe this can be unified with the `external' option
%
\newif\ifin@label
\newif\iflabel@defined \newtoks\@labelcoms
\add@generic@default{\@labelcoms{} \label@definedno \in@labelno}
\@GenericOption{label}{
    \if\EqualString{#1}{stop}\e@group[label]
    \else \global\label@definedyes\global\has@labelyes
          \b@group[label] \in@labelyes
          \switch@to@options@list{@labelcoms}
    \fi}

%%%%%%%%%%%%%%%% Substitutions

% Long substitutions
% the style designer declares the existence of a substitution
%
% \DefineSubstitution:Foo = 
%                \def\Foo#1\par
%
\def\DefineSubstitution:#1
   {\Tmessage[def]{Substitution being defined: #1}
    \csarg\edef{#1}##1\par{\@@subdef{#1}}
    \edef\cs@e{\let\CSname{if#1Exists}=\CSname{iffalse}}
    \cs@e
    }
\def\@@subdef#1{\let\CSname{if#1Exists}=\CSname{iftrue}%
    \def\CSname{#1@text}{##1}}

% Short substitutions
% almost the same, but to end of line instead of to \par
%
\def\DefineShortSubstitution:#1
   {\@DefineShortSubstitution{#1}}
{\noeol 
\othercr
\gdef\@DefineShortSubstitution#1{
    \Tmessage[def]{Defining short substitution: #1}
    {\othercr
     \csarg\xdef{#1}{\noexpand\othercr \CSname{@#1}}
     \csarg\xdef{@#1}##1^^M{
         \@@subdef{#1}\noexpand\normalcr}}
    \global\csarg\let{ifExists#1}=\iffalse}}


% Substitute
% is then a command for both user and style designer.
% \Substitute:text=uppercase/lowercase is possible
% but these take more than just expansion.
%
\def\Substitute:#1 {\@substitute#1== }
\def\@substitute#1=#2=
   {\if\ifempty{#2}{\csname#1@text\endcsname}%
    \else\if\EqualString{#2}{uppercase}%
               \uppercase\xp\xp\xp{\csname#1@text\endcsname}%
         \else \lowercase\xp\xp\xp{\csname#1@text\endcsname}%
         \fi
    \fi}%why did this say \noesc\csname\string#1@text... ?

{\noeol 
\othercr
\gdef\variant{\bgroup\othercr \@variant}
\gdef\@variant:#1=#2^^M#3\variantstop{
     \csarg\gdef{#1}{\par\bgroup #3 \csname#2\endcsname}
     \csarg\xdef{#1stop}{\CSname{#2stop}\egroup}
     \egroup}
}

% Value
% this is analogous to \Distance (in file text)
%
\def\Value:#1=#2
   {\edef\cs@e{\if\UndefinedCS{#1}\noexpand\new@count
               \else \noexpand\set@value \fi
               {#1}%
               \if\UndefinedCS{#2}{#2}%
               \else \CSname{#2}\fi}
    \cs@e}

%%%%%%%%%%%%%%%% Tests
%
% Test user command
%
\def\DefineTest:#1
   {\Tmessage[def]{Defining test: #1}
    \csarg\newif{if#1}
    \csarg\def{#1}:##1 {\csname #1##1\endcsname}}

% Test generic option
%
% option test:Foo tests if \ifFoo is defined
%
% if not, \let\ifFoo=\iffalse, and
%         \StyleDefinitionStop performs a test 
%                              and warns if still undefined
%
% \let\hang@fi\@empty globally
% \def\hang@fi{\@add@toks{\fi}} is defined locally
% ==> check on unclosed test options.
%
\@GenericOption{test}{
    \switch {\if\EqualString{#1}}
    {otherwise}{\hang@else}
    {stop}{\hang@fi \e@group}
    {default}{\b@group
                \if\UndefinedCS{if#1}
                    \check@existence{if#1}
                    \edef\cs@e{\global\let\CSname{if#1}\CSname{iffalse}}
                    \cs@e
                \fi
                \hang@fi@define
                \edef\cs@e{\nxp\@add@toks{\CSname{if#1}}}\cs@e
                }
    \endswitch}

% The body of these macros has to be kept outside of conditionals
%
\def\hang@else{\@add@toks{\else}}
\def\hang@fi@define{\def\hang@fi{\@add@toks{\fi}}}
\add@generic@default{\let\hang@fi\@empty}
\add@generic@stop@default
   {\ifx\hang@fi\@empty\else
    \Emessage{There are tests open in \@name}\fi}

% voorgegeven tests uit TOOLS
\newif\ifVoortgang 
\def\Voortgang:#1 {\csname Voortgang#1\endcsname}
\DefineTest:Diagnose 

\endinput

% 92/11/26 ifcustom@label and attendant handling
% 92/12/05 \@label@key