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

tgkolda
  • 704

3 Answers3

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

Ulrich Diez
  • 28,770
  • Thanks, @UlrichDiez, for the solution! This is working well so far. I really appreciate the help. – tgkolda Dec 14 '20 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 '20 at 01:36
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.

egreg
  • 1,121,712
  • 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 '20 at 15:28
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

gernot
  • 49,614