2

I want to refer to particular items in my document, which I call "Action Points". I created a counter for them, and I want to create a "list of Action Points", in the same way the list of figures is created. BUT, here is the catch, I want a table instead of a list, and I want these Action Points to contain more information, as a caption (in particular, the label assigned and three more arguments).

First, the counter and the references

\newcounter{ap}
\newcommand{\apref}[1]{A\ref{ap:#1}}
\newcommand{\ap}[1]{\refstepcounter{ap}\label{ap:#1}\apref{#1}}

Then I dived into latex.ltx, and I looked into many SE answers, and I defined these functions.

\makeatletter

\long\def\newwritefile#1#2{%
  \@ifundefined{tf@#1}\relax
    {%
      \add@percent@to@temptokena
        \@empty#2\protected@file@percent
        \add@percent@to@temptokena
     \immediate\write\csname tf@#1\endcsname{\the\@temptokena}%
    }%
}

\def\@newstarttoc#1{%
  \begingroup
    \makeatletter
    \@input{\jobname.#1}%
    \if@filesw
      \expandafter\newwrite\csname tf@#1\endcsname
      \immediate\openout \csname tf@#1\endcsname \jobname.#1\relax
    \fi
    \@nobreakfalse
  \endgroup}

% passes argument to write file
\def\newaddcontentsline#1#2{%
\newaddtocontents{#1}{\protect\newcontentsline#2
                     \protected@file@percent}}

% basically, it writes to file
\long\def\newaddtocontents#1#2{%
  \protected@write\@auxout
  {\let\label\@gobble \let\index\@gobble \let\glossary\@gobble}%
  {\string\newwritefile{#1}{#2}}}

% Rendering of the line read in the file.

\def\newcontentsline#1{\shortcut{#1} \par}

\newcommand{\shortcut}[1]{%
  \@tempswafalse
  \@for\next:=#1\do
    {\if@tempswa{ + }\else\@tempswatrue\fi\next}%
}    

% What happens when we define an action point.

\def\actionpoint#1#2#3#4{
\refstepcounter{ap}\label{ap:#1}\apref{#1}
\newaddcontentsline{lap}{{{\apref{#1}},{#2},{#3},{#4}}}
}


% The list of action points.
\newcommand\tableofaps{
\@newstarttoc{lap}
}

\makeatother

So, until now, my minimal experiment looks like

\documentclass[a4paper]{article}

[ALL THAT CODE ABOVE]

\begin{document}

\tableofaps

\actionpoint{a1}{b1}{c1}{d1}
\actionpoint{a2}{b2}{c2}{d2}

\end{document}

with the output

enter image description here

These are the fields, separated by "+" as defined in the function "shortcut". Now, this is not a table, so I tought to modify \tableofaps and encapsulate \newstarttoc in a tabular, and replace the "+" by "&",

\newcommand{\shortcut}[1]{%
  \@tempswafalse
  \@for\next:=#1\do
    {\if@tempswa{ & }\else\@tempswatrue\fi\next}%
}

\newcommand\tableofaps{
\begin{tabular}{llll}
\@newstarttoc{lap}
\end{tabular}
}

This solution give me a lot of errors, the first of which is "Missing } inserted" at line 1, so not very helpful.

I'd like to know how to achieve what I want without resorting to obscure packages.

1 Answer 1

2

[January 17, 2020: With all examples in the previous version of this answer I made a big mistake:

I had the macro \tableofaps write the beginning and the ending of the tabular-environment via\newaddtocontents/ \addtocontents.
This way the order in which the corresponding \newwritefile-/\@writefile-entries appear in the .aux-file and thus the order in which lines appear in the .lap-file will be wrong in case \tableofaps is not placed at the beginning of the document but somewehere behind a call to \actionpoint, e.g., in the middle or at the end of the document.

With this edit the beginning and the ending of the tabular-environment is not written to file at all. Instead \tableofaps locally patches \@input to wrap the call to \@@input (\@@input is the LaTeX 2e-name of the TeX-primitive \input) into \begin{tabular}...\end{tabular}.]



Using \@for or whatever for iterating on a list of tablecell-contents is interesting only in case you need flexibility regarding the amount of table-cells of a table-row.

If you always have exactly four table-cells, you can easily do without iteration/recursion/loops and just define macros that process four arguments:

\documentclass[a4paper]{article}

%\usepackage{hyperref}

\makeatletter

\newcounter{ap}
% The starred variant of \apref is always without hyperlink.
% The non-starred variant of \apref is without hyperlink only
% in case hyperref is not loaded.
\@ifdefinable\apref{%
   \DeclareRobustCommand{\apref}{\@ifstar\apref@star\apref@nostar}%
}%
\@ifpackageloaded{hyperref}{%
  \newcommand{\apref@nostar}[1]{\hyperref[{ap:#1}]{A\ref*{ap:#1}}}%
  \newcommand{\apref@star}[1]{A\ref*{ap:#1}}%
}{%
  \newcommand{\apref@nostar}[1]{A\ref{ap:#1}}%
  \newcommand{\apref@star}[1]{A\ref{ap:#1}}%
}%

% What happens when we define an action point.
\newcommand\actionpoint[4]{%
  \ifvmode\leavevmode\fi
  \refstepcounter{ap}%
  \apref*{#1}%
  \label{ap:#1}%
  \addtocontents{lap}{%
    \string\MakeMyDayByMakingMyTableline{\string\apref{#1}}{#2}{#3}{#4}\string\protected@file@percent
  }% 
}

\newcommand\MakeMyDayByMakingMyTableline[4]{\hline#1&#2&#3&#4\\}%

% The list of action points.
\newcommand\tableofaps{%
  \begingroup
  % Patch \@input to wrap the call to \@@input (which is the LaTeX-name
  % of the TeX-primitive \input) into \begin{tabular}..\end{tabular}%
  \patch@input
  \@starttoc{lap}%
  \endgroup
}

\newcommand\patch@input{%
  \let\saved@input=\@input
  \def\@input##1{%
    \let\@input=\saved@input
    \IfFileExists{##1}{%
      \begin{tabular}{|c|c|c|c|}%
      \hline
      heading1&heading2&heading3&heading4\\
      \@@input\@filef@und
      \hline
      \end{tabular}%
    }{\typeout{No file ##1.}}%
  }%
}%

% Just to make sure it is not already defined...
\newcommand\saved@input{}%

\makeatother

\begin{document}

\tableofaps

\actionpoint{a1}{b1}{c1}{d1}
\actionpoint{a2}{b2}{c2}{d2}

\end{document}

Here the resulting .aux-file:

\relax 
\newlabel{ap:a1}{{1}{1}}
\@writefile{lap}{\MakeMyDayByMakingMyTableline{\apref{a1}}{b1}{c1}{d1}\protected@file@percent}
\newlabel{ap:a2}{{2}{1}}
\@writefile{lap}{\MakeMyDayByMakingMyTableline{\apref{a2}}{b2}{c2}{d2}\protected@file@percent}

Here the resulting .lap-file:

\MakeMyDayByMakingMyTableline {\apref {a1}}{b1}{c1}{d1}% 
\MakeMyDayByMakingMyTableline {\apref {a2}}{b2}{c2}{d2}% 

Here a picture of the resulting .pdf-output-file:

enter image description here



The sequence \if@tempswa{ & }\else\@tempswatrue\fi\next is a problem:

In case the condition is true, the braces that surround & will not be stripped off.
\if../\else/\fi-matching is independent from group matching and from brace-matching and from the &-matching of the align-mechanisms that underlie tabular-environments.
The braces surrounding the & will disturb the align-mechanisms that underlie tabular-environments.
& being wrapped into \if..\else..\fi will within table-environments disturb \if..\else..\fi-matching.

Besides this things that form the content of a table-cell will be processed within a group/local scope.
Thus \next after & will not end up in the local scope of that table-cell wherein \@for defined it, and therefore will be undefined at the time when LaTeX attempts to carry it out.

You can hide & within a macro and use some \expandafter-trickery for having LaTeX carry out \next before closing the local scope of the current table-cell.

With \addtocontents in some situations I prefer \string to \protect in order to avoid the writing of a trailing space behind the characters that form the name of the control-word-token that is to be written unexpanded.

Performing as few changes as possible to your code, you can get a table by omitting these braces, doing some \expandafter-trickery and having \tableofaps locally patch \@input to wrap \@@input into commands for beginning and ending some tabular-environment:

\documentclass[a4paper]{article}

%\usepackage{hyperref}

\makeatletter

\newcounter{ap}
% The starred variant of \apref is always without hyperlink.
% The non-starred variant of \apref is without hyperlink only
% in case hyperref is not loaded.
\@ifdefinable\apref{%
   \DeclareRobustCommand{\apref}{\@ifstar\apref@star\apref@nostar}%
}%
\@ifpackageloaded{hyperref}{%
  \newcommand{\apref@nostar}[1]{\hyperref[{ap:#1}]{A\ref*{ap:#1}}}%
  \newcommand{\apref@star}[1]{A\ref*{ap:#1}}%
}{%
  \newcommand{\apref@nostar}[1]{A\ref{ap:#1}}%
  \newcommand{\apref@star}[1]{A\ref{ap:#1}}%
}%
% \ap is not used anywhere, therefore it is commented out:
%\newcommand{\ap}[1]{\refstepcounter{ap}\label{ap:#1}\apref{#1}}

\long\def\newwritefile#1#2{%
  \@ifundefined{tf@#1}\relax
    {%
      \add@percent@to@temptokena
        \@empty#2\protected@file@percent
        \add@percent@to@temptokena
     \immediate\write\csname tf@#1\endcsname{\the\@temptokena}%
    }%
}

\def\@newstarttoc#1{%
  \begingroup
    \makeatletter
    \@input{\jobname.#1}%
    \if@filesw
      \expandafter\newwrite\csname tf@#1\endcsname
      \immediate\openout \csname tf@#1\endcsname \jobname.#1\relax
    \fi
    \@nobreakfalse
  \endgroup}

% passes argument to write file
\def\newaddcontentsline#1#2{%
\newaddtocontents{#1}{\string\newcontentsline{#2}%%%%%%%%% braces now surround #2.
                     \string\protected@file@percent}}

% basically, it writes to file
\long\def\newaddtocontents#1#2{%
  \protected@write\@auxout
  {\let\label\@gobble \let\index\@gobble \let\glossary\@gobble}%
  {\string\newwritefile{#1}{#2}}}%

% Rendering of the line read in the file.

\def\newcontentsline#1{\shortcut{#1}\par}

\def\AndHiddenFomAlignMechanisms{&}

\newcommand{\shortcut}[1]{%
  \hline
  \global\@tempswatrue
  \@for\next:=#1\do{%
    \if@tempswa
      \global\@tempswafalse
    \else
      \expandafter\expandafter\expandafter\AndHiddenFomAlignMechanisms
    \fi
    \next
  }%
  \\% <- End the table-row.
}    

% What happens when we define an action point.

\def\actionpoint#1#2#3#4{%
  \ifvmode\leavevmode\fi
  \refstepcounter{ap}%
  \apref*{#1}%
  \label{ap:#1}%
  %%% One pair of braces removed because that will now be added by
  %%% \newaddcontentsline. \newaddcontentsline is safer this way.
  \newaddcontentsline{lap}{{\string\apref{#1}},{#2},{#3},{#4}}% 
}

% The list of action points.
\newcommand\tableofaps{%
  \begingroup
  % Patch \@input to wrap the call to \@@input (which is the LaTeX-name
  % of the TeX-primitive \input) into \begin{tabular}..\end{tabular}%
  \patch@input
  \@newstarttoc{lap}%
  \endgroup
}

\newcommand\patch@input{%
  \let\saved@input=\@input
  \def\@input##1{%
    \let\@input=\saved@input
    \IfFileExists{##1}{%
      \begin{tabular}{|c|c|c|c|}%
      \hline
      heading1&heading2&heading3&heading4\\
      \@@input\@filef@und
      \hline
      \end{tabular}%
    }{\typeout{No file ##1.}}%
  }%
}%

% Just to make sure it is not already defined...
\newcommand\saved@input{}%

\makeatother

\begin{document}

\tableofaps

\actionpoint{a1}{b1}{c1}{d1}
\actionpoint{a2}{b2}{c2}{d2}

\end{document}

Here the resulting .aux-file:

\relax 
\newlabel{ap:a1}{{1}{1}}
\newwritefile{lap}{\newcontentsline{{\apref{a1}},{b1},{c1},{d1}}\protected@file@percent}
\newlabel{ap:a2}{{2}{1}}
\newwritefile{lap}{\newcontentsline{{\apref{a2}},{b2},{c2},{d2}}\protected@file@percent}

Here the resulting .lap-file:

\newcontentsline {{\apref {a1}},{b1},{c1},{d1}}% 
\newcontentsline {{\apref {a2}},{b2},{c2},{d2}}% 

Here a picture of the resulting .pdf-output-file:

enter image description here



As I like expansion-trickery I'd prefer a full expandable \romannumeral0-expansion-based tail-recursive loop for recursively iterating the list of cell-contents and hereby accumulating the tokens that form a table-row.


I think \romannumeral0-expansion needs some explanation.

Usually \romannumeral⟨number⟩ is applied for obtaining the representation of a number in roman notation.

Due to the subtle ways in which \romannumeral works, the sequence \romannumeral0 can nicely be (ab)used for triggering expansion without the need of writing a bunch of \expandafter:

The sequence \ronmannumeral0 triggers searching for more digits that belong to the digit-sequence that forms the ⟨number⟩ or for something that terminates the digit-sequence that forms the ⟨number⟩

During that search expansion of expandable things is triggered.
If a space-token is found, that space is discarded silently and terminates the process of searching for more digits.
If the digits gathered form a non-positive number, e.g., the number 0, \romannumeral will just silently swallow that number without delivering any token in return.

Therefore \romannumeral's expansion of things while searching for more digits or a terminator of the digit-sequence can nicely be abused for triggering a lot of expansion-work and flipping around of macro-arguments as long as it is ensured that after all that expansion-work the first things \romannumeral "finds" in the token-stream form a non-positive number, as is the case, e.g., with the sequence 0⟨space token⟩.


I suggest providing as argument to LaTeX's \addtocontents a sequence of tokens which consists of

  • the call to a macro \FormTableRowFromNonDelimitedArgList.
  • a non-delimited/brace-nested argument which in turn consists of a list of non-delimited/brace-nested arguments whereof each holds the content of one of the table row's table cells.
    Henceforth this argument is called the "list of tablecell-contents".

These things will end up in the .lap-file.

When the .lap-file is processed, the calls to \FormTableRowFromNonDelimitedArgList with their lists of tablecell-contents appended will be carried out.

At this stage \FormTableRowFromNonDelimitedArgList can initiate a full expandable \romannumeral0-expansion-driven tail-recursive loop for iterating on the list of tablecell-contents for accumulating the tokens for a table-row:

\FormTableRowFromNonDelimitedArgList just prepends to the list of tablecell-contents a token-sequence which consists of \romannumeral0\FormTableRowFromNonDelimitedArgListLoop⟨some more arguments⟩.

\FormTableRowFromNonDelimitedArgListLoop in turn processes some arguments:

  1. The tokens of the table-row accumulated so far.
  2. The remaining list of tablecell-contents.
  3. Tokens that shall precede each table-row. Something like \hline.
  4. Tokens that shall trail each table-row. Something like \\.
  5. Separator between table-cells. Something like &.

\FormTableRowFromNonDelimitedArgListLoop is to process these arguments as follows:

If the remaining list of tablecell-contents is empty:

Terminate \romannumeral0-expansion by delivering a space (yielding that \romannumeral finds a non-positive number...) and the tokens of the table-row accumulated so far and hereby—in case the argument holding the tokens of the table-row accumulated so far is not empty—prepend to the tokens of the table-row accumulated so far the tokens from the argument for \hline and append to the tokens of the table-row accumulated so far the tokens from the argument for \\.

If the remaining list of tablecell-contents is not empty:

Call the tail-recusrsive loop-macro again, with its arguments modified as follows:
In case the argument holding the tokens of the table-row accumulated so far is not empty, have the tokens from the argument for & appended to it. Have the first element of the remaining list of tablecell-contents appended to it.
Have the first element removed from the argument holding the remaining list of tablecell-contents.

\documentclass[a4paper]{article}

%\usepackage{hyperref}

\makeatletter

%%=============================================================================
%% Expandable handling of lists of non-delimited arguments:
%%-----------------------------------------------------------------------------
%% Pass first argument to second argument; Exchange two arguments:
%%.............................................................................
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
\newcommand\UD@Exchange[2]{#2#1}%
%%-----------------------------------------------------------------------------
%% %% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
%%
%% I explained this macro in my answer to the question
%% "Expandable test for an empty token list—methods, performance, and robustness"
%% at TeX-LaTeX-StackExchange: <https://tex.stackexchange.com/a/522506/118714>
%%
\newcommand\UD@CheckWhetherNull[1]{%
  \romannumeral0\expandafter\@secondoftwo\string{\expandafter
  \@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \@secondoftwo\string}\expandafter\@firstoftwo\expandafter{\expandafter
  \@secondoftwo\string}\@firstoftwo\expandafter{} \@secondoftwo}%
  {\@firstoftwo\expandafter{} \@firstoftwo}%
}%
%% With e-TeX-extensions' \detokenize available you can do:
%\newcommand\UD@CheckWhetherNull[1]{%
%  \romannumeral0\if\relax\detokenize{#1}\relax
%  \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
%  {\@firstoftwo\expandafter{} \@firstoftwo}%
%  {\@firstoftwo\expandafter{} \@secondoftwo}%
%}%
%%-----------------------------------------------------------------------------
%% Extract first inner undelimited argument:
%%
%%   \romannumeral0\UD@ExtractFirstArgLoop{<list of non-delimited arguments>\UD@SelDOm} 
%%
%%   yields the first non-delimited argument of the <list of non-delimited arguments>
%%
%%   \romannumeral0\UD@ExtractFirstArgLoop{ABCDE\UD@SelDOm} yields  A
%%   \romannumeral0\UD@ExtractFirstArgLoop{{AB}CDE\UD@SelDOm} yields  AB
%%
%%  <list of non-delimited arguments> may contain the token \UD@SelDOm.
%%  <list of non-delimited arguments> must not be empty.
%%  Emptiness/non-emptiness of <list of non-delimited arguments> can be
%%  checked via \UD@CheckWhetherNull.
%%-----------------------------------------------------------------------------
\newcommand\UD@RemoveTillUD@SelDOm{}%
\long\def\UD@RemoveTillUD@SelDOm#1#2\UD@SelDOm{{#1}}%
\newcommand\UD@ExtractFirstArgLoop[1]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\@firstoftwo{}#1}%
  {\@firstoftwo\expandafter{} \@secondoftwo{}#1}%
  {\expandafter\UD@ExtractFirstArgLoop\expandafter{\UD@RemoveTillUD@SelDOm#1}}%
}%
%%=============================================================================

\newcounter{ap}
% The starred variant of \apref is always without hyperlink.
% The non-starred variant of \apref is without hyperlink only
% in case hyperref is not loaded.
\@ifdefinable\apref{%
   \DeclareRobustCommand{\apref}{\@ifstar\apref@star\apref@nostar}%
}%
\@ifpackageloaded{hyperref}{%
  \newcommand{\apref@nostar}[1]{\hyperref[{ap:#1}]{A\ref*{ap:#1}}}%
  \newcommand{\apref@star}[1]{A\ref*{ap:#1}}%
}{%
  \newcommand{\apref@nostar}[1]{A\ref{ap:#1}}%
  \newcommand{\apref@star}[1]{A\ref{ap:#1}}%
}%
% \ap is not used anywhere, therefore it is commented out:
%\newcommand{\ap}[1]{\refstepcounter{ap}\label{ap:#1}\apref{#1}}

\newcommand\FormTableRowFromNonDelimitedArgList{%
  \romannumeral0\FormTableRowFromNonDelimitedArgListLoop{\hline}{\\}{&}{}%
}%
\newcommand\FormTableRowFromNonDelimitedArgListLoop[5]{%
  % #1 = tokens to prepend to each table-row (\hline)
  % #2 = tokens to append to each table-row (\\)
  % #3 = tokens that separate contents of single cells (&)
  % #4 = tokens of the table-row accumulated so far
  % #5 = remaining list of tablecell-contents
  \UD@CheckWhetherNull{#5}{%
    \UD@CheckWhetherNull{#4}{ }{ #1#4#2}% <- the trailing spaces in \UD@CheckWhetherNull's
                                        %    2nd/3rd argument terminate \romannumeral0-expansion
                                        %    started by \FormTableRowFromNonDelimitedArgList
  }{%
    \expandafter\UD@PassFirstToSecond\expandafter{\@gobble#5}{%
      \expandafter\UD@PassFirstToSecond\expandafter{%
        \romannumeral0%
        \expandafter\UD@Exchange\expandafter{%
          \romannumeral0\UD@ExtractFirstArgLoop{#5\UD@SelDOm}%
        }{%
          \UD@CheckWhetherNull{#4}{ }{ #4#3}%
        }%
      }{%
        \FormTableRowFromNonDelimitedArgListLoop{#1}{#2}{#3}%
      }%
    }%
  }%
}%
% What happens when an action point gets defined:
\newcommand\actionpoint[4]{%
  \ifvmode\leavevmode\fi
  \refstepcounter{ap}%
  \apref*{#1}%
  \label{ap:#1}%
  \addtocontents{lap}{%
    \string\FormTableRowFromNonDelimitedArgList{%
      {\string\apref{#1}}{#2}{#3}{#4}%
    }\string\protected@file@percent
  }%
}

% The list of action points.
\newcommand\tableofaps{%
  \begingroup
  % Patch \@input to wrap the call to \@@input (which is the LaTeX-name
  % of the TeX-primitive \input) into \begin{tabular}..\end{tabular}%
  \patch@input
  \@starttoc{lap}%
  \endgroup
}

\newcommand\patch@input{%
  \let\saved@input=\@input
  \def\@input##1{%
    \let\@input=\saved@input
    \IfFileExists{##1}{%
      \begin{tabular}{|c|c|c|c|}%
      \hline
      heading1&heading2&heading3&heading4\\
      \@@input\@filef@und
      \hline
      \end{tabular}%
    }{\typeout{No file ##1.}}%
  }%
}%

% Just to make sure it is not already defined...
\newcommand\saved@input{}%

\makeatother

\begin{document}

\tableofaps

\actionpoint{a1}{b1}{c1}{d1}
\actionpoint{a2}{b2}{c2}{d2}

\end{document}

Here the resulting .aux-file:

\relax 
\newlabel{ap:a1}{{1}{1}}
\@writefile{lap}{\FormTableRowFromNonDelimitedArgList{{\apref{a1}}{b1}{c1}{d1}}\protected@file@percent}
\newlabel{ap:a2}{{2}{1}}
\@writefile{lap}{\FormTableRowFromNonDelimitedArgList{{\apref{a2}}{b2}{c2}{d2}}\protected@file@percent}

Here the resulting .lap-file:

\FormTableRowFromNonDelimitedArgList {{\apref {a1}}{b1}{c1}{d1}}% 
\FormTableRowFromNonDelimitedArgList {{\apref {a2}}{b2}{c2}{d2}}% 

Here a picture of the resulting .pdf-output-file:

enter image description here

4
  • Wow, this is an extremely detailed set of solutions, I need a bit of time to process it :) thanks!
    – chuse
    Jan 17, 2020 at 9:55
  • I was experimenting indeed with \string and \expandafter, but I think that the 1st solution is exactly what I needed, and it works. I'll check with more time later the other two
    – chuse
    Jan 17, 2020 at 14:16
  • 1
    @chuse I just edited my answer as the design was flawed: I had the macro \tableofaps write the beginning and the end of the tabular-environment via \newaddtocontents/\addtocontents. This way the order in which \newwritefile-/\@writefile-entries appear in the .aux-file and thus in which lines appear in the .lap-file may be wrong. \tableofaps now locally patches \@input to wrap the call to \@@input (= the LaTeX 2e-name of the \input-primitive) into \begin{tabular}...\end{tabular}.This way \tableofaps should also work when called in the middle or at the end of the document. Jan 17, 2020 at 14:27
  • 1
    @chuse You experimented with \expandafter? In my answer to the question How can I know the number of expandafters when appending to a csname macro? I tried to explain \expandafter and also how to avoid it / how to reduce the amount of \expandafter needed. ;-) Jan 17, 2020 at 15:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .