I am making a macro that will take user input of a grading scheme and place it into a tabular environment. I would like the syntax to be as simple as possible and decided on:
\tabulate{ eval1,%1 ; eval2,%2 ; ... ; evaln,%n}
as the input scheme, e.g.
\tabulate{Midterm 1,15\% ; Midterm 2,20\%}
Having asked question about building a table from a macro previously, I know that I should (need to?) use toks to build the rows of the table. My first attempt was the following:
\documentclass{article}
\usepackage{xparse}
\makeatletter
\newtoks\@tabtoks
\newcommand\addtabtoks[1]{\@tabtoks\expandafter{\the\@tabtoks#1}}
\newcommand*\resettabtoks{\@tabtoks{}}
\newcommand*\printtabtoks{\the\@tabtoks}
\makeatother
\DeclareDocumentCommand \tabulate%
{ > { \SplitList { ; } } m }%
{\ProcessList {#1} {\mycommand}}
\def\mycommand#1,#2{\addtabtoks{#1\\ }}
It took me a while to sort of figure out why this didn't work: the #1 is passed from ProcessList to mycommand as a single token and can't be read as individual tokens? Question: Is my understanding of why the above doesn't work reasonably correct? If not, could someone please clarify? Based on that fuzzy understanding, I came up with a solution that works but deviates from my desired input scheme (this is the almost working example):
\documentclass{article}
\usepackage{xparse}
\makeatletter
\newtoks\@tabtoks
\newcommand\addtabtoks[1]{\@tabtoks\expandafter{\the\@tabtoks#1}}
\newcommand*\resettabtoks{\@tabtoks{}}
\newcommand*\printtabtoks{\the\@tabtoks}
\makeatother
\DeclareDocumentCommand \tabulate%
{ > { \SplitList { ; } } m }%
{\ProcessList {#1} {\mycommand}}
\newcommand{\mycommand}[1]{
\def\temp{#1}
\expandafter\mycommandTwo\temp
}
\def\mycommandTwo#1,#2{\addtabtoks{#1\\ }}
%{\ProcessList {#1} {\mycommand}}
%\def\mycommand#1,#2{\addtabtoks{#1\\ }}
\begin{document}
\resettabtoks
\tabulate{Midterm 1,{15\%};Midterm 2,{20\%};Midterm 3,{25\%}}
\begin{tabular}{cc}
\printtabtoks
\end{tabular}
\end{document}
Again, based on my fuzzy understanding, I stored the argument from ProcessList in a macro that gets expanded and can therefore be read as individual tokens by mycommandTwo. Depending on whether I understood the initial problem correctly, this may not be the correct interpretation. My problem is that without grouping the percentages as above, ie. {15\%} rather than just 15\% I don't get the output that I want. I'm not sure why that is the case. Could anyone help me understand why the percentages need to be grouped and/or suggest a possible fix/improvement on what I currently have. My previous attempt involved parsing the csv eval,%, prepending each entry with an &, and then deleting the first & in the resulting list but I couldn't make it work. Thanks in advance!
Edit 1: Thinking about it now, I would prefer to insulate the user from even needing to enter the \ prior to the %'s, although I suspect that would require more knowledge than I have.
expl3– cgnieder May 08 '12 at 20:28\DeclareDocumentCommand{\tabulate}{m}{\tl_set:Nn \l_scott_tmpa_tl {#1} \tl_replace_all:Nnn \l_scott_tmpa_tl {;} {\\} \tl_replace_all:Nnn \l_scott_tmpa_tl {,} {&} \tl_use:N \l_scott_tmpa_tl}, to be used as\begin{tabular}{cc} \tabulate{a,b;c,d} \end{tabular}work? – Bruno Le Floch May 20 '12 at 22:31