4

I'm writing some documentation about some macros I've made up. (I know there will probably be comments about the macros too, but that's not what I'm asking about.) Ideally, I'd like to make a sort of table where each row lists the macro itself, the result, and a comment. Here is a MWE that shows what I'm currently doing and what I'd like to do:

\documentclass{article}
\usepackage[margin=1in]{geometry}
\usepackage{xparse}
\usepackage{lmodern}
\usepackage{listings}
\usepackage[most]{tcolorbox}

\DeclareTCBListing{macrobox}{s G{} }{IfBooleanTF={#1}{}{listing side text},title=#2,
  listing options={style=tcblatex,commentstyle=\color{red!70!black}}
}

% Funny macro - don't worry about this part
\NewDocumentCommand{\TnidxRoot}{m m m m m m m}{%
  {#1}_{1} #2 %
  \IfBooleanF{#5}{{#1}_{2} #2} % 
  \IfBooleanTF{#6}{ % 
    {#1}_{3} % 3D
    \IfBooleanT{#7}{#2 {#1}_{4} } % 4D
  }{ % 
    \IfBooleanTF{#3}{\cdots}{\dots} #2 {#1}_{#4} %
  }%
}
% Funny macro - don't worry about this part
\NewDocumentCommand{\Tnsz}{s s t! G{n} O{d}}{%
  \TnidxRoot{#4}{\times}{\BooleanTrue}{#5}{#3}{#1}{#2}%
}

\begin{document}

What I currently do is this:
\begin{macrobox}{Size commands}
$\Tnsz$          \\ % Default
$\Tnsz!$         \\ % Compact, no 2nd index
$\Tnsz{m}$        % Change main letter
\end{macrobox}


But I'd like a nice macro to generate rows of the following table, where the macro for row 1 might be something like \verb|\ExampleRow{\Tnsz}{Default}|.

\begin{tabular}{|l|l|l|}
  \hline
  \LaTeX\ Command & Result & Description \\ \hline
  \verb|\Tnsz| & $\Tnsz$ & Default \\ \hline
  \verb|\Tnsz!| & $\Tnsz!$ & Compact, no second index \\ \hline
  \verb|\Tnsz{m}| & $\Tnsz{m}$ & Change main letter \\ \hline
\end{tabular}

\end{document}

MWE output

3 Answers 3

4

Not so different from Ulrich's proposal, but with a simpler coding. The macro has a *-variant for material to be printed in math mode.

\documentclass{article}
\usepackage{amsmath}
\usepackage{booktabs}
%\usepackage{xparse} % uncomment if using LaTeX prior to 2020-10-01

\ExplSyntaxOn

\NewDocumentCommand{\ExampleRow}{svm}
 {
  \texttt{#2} &
  \IfBooleanT{#1}{$} \tl_rescan:nn { } { #2 } \IfBooleanT{#1}{$} &
  #3 \\
 }

\ExplSyntaxOff

\begin{document}

\begin{tabular}{lll}
\toprule
\ExampleRow{\fbox{a}}{Make a framed box}
\ExampleRow{\framebox[2cm][l]{a}}{Make a framed box}
\ExampleRow*{\sin}{Sine function}
\ExampleRow*{\xrightarrow{f}}{Extendable arrow}
\ExampleRow*{\xrightarrow[g]{}}{Extendable arrow}
\bottomrule
\end{tabular}

\end{document}

enter image description here

The first argument is absorbed verbatim, but then it is rescanned in order to be used for the second column, possibly in between $ characters.

1
  • Thanks, @egreg. This works too! I've accepted it as the solution because it is indeed simpler. I am curious if you have a suggested reference to learn more about the ExplSyntax and tl_rescan functions. Thanks.
    – tgkolda
    Dec 14, 2020 at 15:28
4

I have edited my example and—following egreg's example—added an asterisk argument:
With \ExampleRow*{... the code is executed in math mode.
With \ExampleRow{... the code is only executed in math mode if the code itself contains directives for switching to math mode.

Unlike egreg, however, I do not use \tl_rescan:nn, but still use \scantokens, because when using \scantokens, things like \verb|...|, which switch to verbatim mode, also work. With \tl_rescan:nn such things do not work.

The subtle but crucial differences between \scantokens and \tl_rescan:nn are dealt with in the questions
What is the essential/crucial difference between \scantokens/\tex_scantokens:D and \tl_rescan:nn?
and
expl3 - how can you pass the content of a token-list-variable as argument to another "function"?


As xparse is in use, you can probably have \ExampleRow

  • read an argument of type v (verbatim),
  • print it with \verbatim@font in effect for showing the coding
  • feed it to \scantokens, nested in $ and trailed by % (\scantokens does insert \endlinechar...) for showing the result.

 

\documentclass{article}
\usepackage[margin=1in]{geometry}
\usepackage{xparse}
\usepackage{lmodern}
\usepackage{listings}
\usepackage[most]{tcolorbox}

\DeclareTCBListing{macrobox}{s G{} }{IfBooleanTF={#1}{}{listing side text},title=#2,
  listing options={style=tcblatex,commentstyle=\color{red!70!black}}
}

% Funny macro - don't worry about this part
\NewDocumentCommand{\TnidxRoot}{m m m m m m m}{%
  {#1}_{1} #2 %
  \IfBooleanF{#5}{{#1}_{2} #2} % 
  \IfBooleanTF{#6}{ % 
    {#1}_{3} % 3D
    \IfBooleanT{#7}{#2 {#1}_{4} } % 4D
  }{ % 
    \IfBooleanTF{#3}{\cdots}{\dots} #2 {#1}_{#4} %
  }%
}
% Funny macro - don't worry about this part
\NewDocumentCommand{\Tnsz}{s s t! G{n} O{d}}{%
  \TnidxRoot{#4}{\times}{\BooleanTrue}{#5}{#3}{#1}{#2}%
}

%--------------------------------------------------------------------------
% This is what I would probably do:
%--------------------------------------------------------------------------
\begingroup
\makeatletter
% Let's use ^^A instead of %.
% Make % other so it can be "fed" to \scantokens to handle \scantokens'
% insertion of \endlinechar;
\catcode`\^^A=14\relax
\catcode`\%=12\relax
\@firstofone{^^A
  \endgroup
  \NewDocumentCommand\ExampleRow{svm}{^^A
    {\verbatim@font#2}&^^A
    {\IfBooleanT{#1}{$}\scantokens{#2%}\IfBooleanT{#1}{$}}&^^A
    {#3}\\\hline^^A
  }^^A
}%
%--------------------------------------------------------------------------

\begin{document}

What I currently do is this:
\begin{macrobox}{Size commands}
$\Tnsz$          \\ % Default
$\Tnsz!$         \\ % Compact, no 2nd index
$\Tnsz{m}$        % Change main letter
\end{macrobox}


But I'd like a nice macro to generate rows of the following table, where the macro for row 1 might be something like \verb|\ExampleRow{\Tnsz}{Default}|.

\begin{tabular}{|l|l|l|}
  \hline
  \LaTeX\ Command & Result & Description \\ \hline
  \verb|\Tnsz| & $\Tnsz$ & Default \\ \hline
  \verb|\Tnsz!| & $\Tnsz!$ & Compact, no second index \\ \hline
  \verb|\Tnsz{m}| & $\Tnsz{m}$ & Change main letter \\ \hline
  \verb+\verb|verbatim stuff|+ & \verb|verbatim stuff| & verbatim material \\ \hline
\end{tabular}

\bigskip

Here it is:

\bigskip

\begin{tabular}{|l|l|l|}
  \hline
  \LaTeX\ Command & Result & Description \\ \hline
  \ExampleRow*{\Tnsz}{Default}%
  \ExampleRow*{\Tnsz!}{Compact, no second index}%
  \ExampleRow*{\Tnsz{m}}{Change main letter}%
  \ExampleRow{\verb|verbatim stuff|}{verbatim material}%
\end{tabular}

\end{document}

enter image description here

2
  • Thanks, @UlrichDiez, for the solution! This is working well so far. I really appreciate the help.
    – tgkolda
    Dec 14, 2020 at 15:21
  • Ah! This is really interesting. Thank you for the tweak. I didn't realize the differences. I will check it out.
    – tgkolda
    Dec 16, 2020 at 1:36
2

Maybe something like the following? (this time no extra spaces after macro names)

\makeatletter
\newcommand\strings[1]{\@tfor\sss:=#1\do{\expandafter\string\sss}}
\makeatother
\newcommand\ExampleRow[2]{\texttt{\strings{#1}} & $#1$ & #2 \\}

enter image description here

\documentclass{article}
\makeatletter
\newcommand\strings[1]{\@tfor\sss:=#1\do{\expandafter\string\sss}}
\makeatother
\newcommand\ExampleRow[2]{\texttt{\strings{#1}} & $#1$ & #2 \\}
\begin{document}
\begin{tabular}{lll}
  \ExampleRow{\times!\times}{binary product}
  \ExampleRow{\prod}{generic product}
\end{tabular}
\end{document}

Old solution (macro names will be followed by spaces)

Maybe something like

\newcommand\ExampleRow[2]{\texttt{\detokenize{#1}} & $#1$ & #2 \\}

is sufficient for your purpose?

\documentclass{article}
\newcommand\ExampleRow[2]{\texttt{\detokenize{#1}} & $#1$ & #2 \\}
\begin{document}
\begin{tabular}{lll}
  \ExampleRow{\times}{binary product}
  \ExampleRow{\prod}{generic product}
\end{tabular}
\end{document}

enter image description here

5
  • Thank you for the comment, @gernot! The main problem with detokenize that I can see if that it adds spaces, which are a problem for some of the commands I need to demo.
    – tgkolda
    Dec 12, 2020 at 1:43
  • @tgkolda I've added another solution that does not introduce spaces.
    – gernot
    Dec 12, 2020 at 14:22
  • Thank you so much. I've accepted your solution. Appreciate the help.
    – tgkolda
    Dec 12, 2020 at 16:22
  • I had trouble with the following: \ExampleRow{x \text{ and } y}{Example math}
    – tgkolda
    Dec 12, 2020 at 19:32
  • @tgkolda Try Ulrich's solution, seems to handle all cases.
    – gernot
    Dec 13, 2020 at 22:05

You must log in to answer this question.

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