% The stuff in this file is kept solely for its historical value. % ---------------------------------------------------------------------- % \newcommand{\looplisttemplate}[4] % % % % Invoke as: % % % % \looplisttemplate{HANDLER_BIND}{TEMPLATE}{ELEM_0}{LIST} % % % % LIST must be of following form for n >= 0: {ELEM_1} ... {ELEM_n} % % TEMPLATE may contain #1 and #2. % % HANDLER_BIND may contain #1 and #2. % % Let RESULT be: TEMPLATE(ELEM_0,ELEM_1)...TEMPLATE(ELEM_{n-1},ELEM_n) % % % % The behavior is: % % % % \looplisttemplate{HANDLER_BIND}{TEMPLATE}{ELEM_0}{LIST} % % -> HANDLER_BIND(RESULT,ELEM_n) % % % {% #1 is HANDLER_BIND % % #2 is ELEM_TEMPLATE % % #3 is ELEM_0 % % #4 is {ELEM_1}...{ELEM_n} % % RESULT_0 is nothing % % RESULT_{i+1} is RESULT_i ELEM_TEMPLATE(ELEM_i,ELEM_{i+1}) % \def\jbwl@LoopListTemplateViaDoListCont##1##2{#1}% % \def\jbwl@LoopListTemplateViaDoListTemplate##1##2{{{#2}}}% % \dolist{#4} % {{#3}} % {% ##1 is ELEM_i % % ##2 is ELEM_{i-1} % % ##3 is RESULT_{i-1} % \expandafter % \usetemplate\jbwl@LoopListTemplateViaDoListTemplate{##2}{##1} % {% ####1 is TEMPLATE(ELEM_{i-1},ELEM_i) % \DLNext{{##1}{##3####1}}}} % {% ##2 is ELEM_n % % ##3 is RESULT_n % \jbwl@LoopListTemplateViaDoListCont{##3}{##2}}} % ---------------------------------------------------------------------- % \newcommand{\looplist}[4] % % #1 is the continuation, which will be applied to {RESULT}{ELEM_n} % % #2 is a command to place in front of {ELEM_{i-1}}{ELEM_i} for each i % % #3 is ELEM_0 % % #4 is a list of form {ELEM_1}...{ELEM_n} % {% #1 is CONTINUATION % % #2 is ELEM_CMD % % #3 is ELEM_0 % % #4 is {ELEM_1}...{ELEM_n} % % RESULT_0 is nothing % % RESULT_{i+1} is RESULT_i ELEM_CMD{ELEM_i}{ELEM_{i+1}} % \dolist{#4}{{#3}} % {% ##1 is ELEM_i % % ##2 is ELEM_{i-1} % % ##3 is RESULT_{i-1} % \DLNext{{##1}{##3#2{##2}{##1}}}} % {% ##2 is ELEM_n % % ##3 is RESULT_n % #1{##3}{##2}}} % ---------------------------------------------------------------------- % \DeclareRobustCommand{\looplisttemplate}[4] % % % % Invoke as: % % % % \looplisttemplate{HANDLER_BIND}{TEMPLATE}{ELEM_0}{LIST} % % % % LIST must be of following form for n >= 0: {ELEM_1} ... {ELEM_n} % % TEMPLATE may contain #1 and #2. % % HANDLER_BIND may contain #1 and #2. % % Let RESULT be: TEMPLATE(ELEM_0,ELEM_1)...TEMPLATE(ELEM_{n-1},ELEM_n) % % % % The behavior is: % % % % \looplisttemplate{HANDLER_BIND}{TEMPLATE}{ELEM_0}{LIST} % % -> HANDLER_BIND(RESULT,ELEM_n) % % % {% #1 is {HANDLER_BIND} % % #2 is {TEMPLATE} % % #3 is {ELEM_0} % % #4 is {LIST} % \def\jbwl@looplisttemplatehandlerbind##1##2{#1}% % \def\jbwl@looplisttemplateauxB##1##2##3##4{% % % ##1 will be ELEM_0 % % ##2 will be ELEM_1 % % ##3 will be RESULT % % ##4 will be {ELEM_2}...{ELEM_n} % \jbwl@looplisttemplateauxA % % #1 and #2 in TEMPLATE will be captured by nested binding. % % The #2 on next line will thus yield TEMPLATE(ELEM_0,ELEM_1). % {##3#2}% % {##2}% % {##4}}% % \jbwl@looplisttemplateauxA{}{#3}{#4}} % \newcommand{\jbwl@looplisttemplateauxA}[3] % % #1 is RESULT % % #2 is ELEM_0 % % #3 is {ELEM_1}...{ELEM_n} % {\listcase*{#3} % % #1,#2 in HANDLER_BIND replaced by #1,#2. % % This yields HANDLER_BIND(RESULT,ELEM_0). % {\jbwl@looplisttemplatehandlerbind{#1}{#2}} % {% ##1 is ELEM_1 % % ##2 is {ELEM_2}...{ELEM_n} % \jbwl@looplisttemplateauxB{#2}{##1}{#1}{##2}}} % ---------------------------------------------------------------------- % \newcommand{\looplist}[4] % % #1 is the continuation, which will be applied to {RESULT}{ELEM_n} % % #2 is a command to place in front of {ELEM_{i-1}}{ELEM_i} for each i % % #3 is ELEM_0 % % #4 is a list of form {ELEM_1}...{ELEM_n} % {\jbwl@looplistauxA{#1}{#2}{#3}{}{#4}} % \newcommand{\jbwl@looplistauxA}[5] % % #1 is the continuation, which will be applied to {RESULT}{ELEM_n} % % #2 is a command to place in front of {ELEM_{i-1}}{ELEM_i} for each i % % #3 is ELEM_{i-1} % % #4 is the accumulated result of applications of #2 % % #5 is a list of form {ELEM_i}...{ELEM_n} % {\listcase{#5} % {#1{#4}{#3}} % {\jbwl@looplistauxB{#1}{#2}{#3}{#4}}} % \newcommand{\jbwl@looplistauxB}[6] % % #1 is the continuation, which will be applied to {RESULT}{ELEM_n} % % #2 is a command to place in front of {ELEM_{i-1}}{ELEM_i} for each i % % #3 is ELEM_{i-1} % % #4 is the accumulated result of applications of #2 % % #5 is ELEM_i % % #6 is a list of form {ELEM_{i+1}}...{ELEM_n} % {\jbwl@looplistauxA{#1}{#2}{#5}{#4#2{#3}{#5}}{#6}} % ---------------------------------------------------------------------- % \DeclareRobustCommand{\listcase} % % % % Invoke as follows: % % % % \listcase{LIST}{NIL_CASE}{CONS_CASE} % % \listcase*{LIST}{NIL_CASE}{CONS_CASE_BIND} % % % % LIST must be a valid list. % % % % I think that NIL_CASE and CONS_CASE can be _any_ balanced token % % sequences. Tell me if I'm wrong. % % % % CONS_CASE_BIND is allowed to contain #1 and #2 (which will usually % % have to be written as ##1 and ##2 in the invocation). % % % % The behavior is as follows: % % % % \listcase {} {NIL_CASE}{CONS_CASE} -> NIL_CASE % % \listcase*{} {NIL_CASE}{CONS_CASE} -> NIL_CASE % % \listcase {{HEAD}TAIL}{NIL_CASE}{CONS_CASE} -> CONS_CASE{HEAD}{TAIL} % % \listcase*{{HEAD}TAIL}{NIL_CASE}{CONS_CASE_BIND} % % -> CONS_CASE_BIND(HEAD,TAIL) % % % {\@ifstar{\jbwl@listcaseauxC}{\jbwl@listcaseaux}} % \newcommand{\jbwl@listcaseauxC}[3] % % #1 is LIST % % #2 is NIL_CASE % % #3 is CONS_CASE_BIND % {\def\jbwl@listcasebindconscont##1##2{#3}% % \jbwl@listcaseaux{#1}{#2}{\jbwl@listcasebindconscont}} % \newcommand{\jbwl@listcaseaux}[3] % % #1 is LIST % % #2 is NIL_CASE % % #3 is CONS_CASE % {\stripleadingspaces{\jbwl@listcaseauxA}{#1}{#2}{#3}} % \newcommand{\jbwl@listcaseauxA}[3] % % #1 is LIST (with leading spaces removed) % % #2 is NIL_CASE % % #3 is CONS_CASE % {\def\jbwl@listdummy{#1}% % \ifx\jbwl@emptylistdummy\jbwl@listdummy % Test whether the list is empty. % % List empty; continuation will run #2. % \let\jbwl@listcasetemp=\jbwl@listcaseauxD % \else % % List non-empty; continuation will feed head and tail to #3. % \def\jbwl@listcasetemp{\jbwl@listcaseauxE#1;}% % \fi % \jbwl@listcasetemp{#1}{#2}{#3}}% Invoke continuation. % \newcommand{\jbwl@listcaseauxD}[3] % % #1 is JUNK_1 (an empty list, not used) % % #2 is NIL_CASE % % #3 is JUNK_2 (the cons case, not used) % {#2} % \def\jbwl@listcaseauxE#1#2;#3#4#5{% % % #1 is HEAD % % #2 is TAIL, if TAIL is not a list of length 1 % % is LAST, if TAIL is {LAST} % % #3 is {HEAD}TAIL % % #4 is JUNK (the nil case, not used) % % #5 is CONS_CASE % \def\jbwl@listdummy{#3}% % \def\jbwl@listdummyB{{#1}#2}% % \ifx\jbwl@listdummy\jbwl@listdummyB % Test whether braces stripped from tail. % % Braces were not stripped; set continuation to do CONS_CASE{HEAD}{TAIL}. % \def\jbwl@listcasetemp{\jbwl@listcaseauxF{#2}}% % \else % % Braces were stripped; set continuation to do CONS_CASE{HEAD}{{LAST}} % % (Restore the braces around the tail's only element.) % \def\jbwl@listcasetemp{\jbwl@listcaseauxF{{#2}}}% % \fi % \jbwl@listcasetemp{#1}{#5}}% Invoke continuation. % \newcommand{\jbwl@listcaseauxF}[3] % % #1 is TAIL % % #2 is HEAD % % #3 is CONS_CASE % {#3{#2}{#1}} % \def\jbwl@emptylistdummy{}% Macro with empty body for use with \ifx. % ---------------------------------------------------------------------- % OBSOLETE, NEEDS TO BE REWRITTEN %\newcommand{\listlast}[2] % % #1 is the command to apply to the result % % #2 is the list % {\listlastaux{#1}{\uglydeathduetoemptylist}{#2}} %\newcommand{\listlastaux}[3] % % #1 is the command to apply % % #2 is to be used instead of the last element if the list is empty % % #3 is the list % {\listcase{#3} % {#1{#2}} % {% this will be applied to {HEAD}{TAIL} % \listlastaux{#1}}} % ---------------------------------------------------------------------- % \newcommand{\jbwl@ziplistauxAold}[4] % % #1 is the accumulated zipped list % % #2 is the command to apply to the result % % #3 is the first list % % #4 is the second list % {\listcase{#3} % Test whether the first list is empty. % {#2{#1}} % If first list is empty, pass result to continuation. % {\jbwl@ziplistauxB{#1}{#2}{#4}}} % \newcommand{\jbwl@ziplistauxB}[5] % % #1 is the accumulated zipped list % % #2 is the command to apply to the result % % #3 is the second list % % #4 is the head of the first list % % #5 is the tail of the first list % {\listcase{#3} % Test whether the second list is empty. % {#2{#1}} % If second list is empty, pass result to continuation. % {\jbwl@ziplistauxC{#1}{#2}{#4}{#5}}} % \newcommand{\jbwl@ziplistauxC}[6] % % #1 is the accumulated zipped list % % #2 is the command to apply to the result % % #3 is the head of the first list % % #4 is the tail of the first list % % #5 is the head of the second list % % #6 is the tail of the second list % {% Append pair {{HEAD_1}{HEAD_2}} to end of result. % % Process the list tails recursively. % \jbwl@ziplistauxA{#1{{#3}{#5}}}{#2}{#4}{#6}}