diff options
Diffstat (limited to 'macros/plain/formats/lollipop/tex/lollipop-define.tex')
-rw-r--r-- | macros/plain/formats/lollipop/tex/lollipop-define.tex | 425 |
1 files changed, 425 insertions, 0 deletions
diff --git a/macros/plain/formats/lollipop/tex/lollipop-define.tex b/macros/plain/formats/lollipop/tex/lollipop-define.tex new file mode 100644 index 0000000000..6f805a2791 --- /dev/null +++ b/macros/plain/formats/lollipop/tex/lollipop-define.tex @@ -0,0 +1,425 @@ +% 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
\ No newline at end of file |