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