# What is wrong with this TeX macro

Still soldiering on with trying to learn these macros. Can someone tell me why this isn't working?

The macro \mycline{n-n} is supposed to expand to \cmidrule{1-1} ... \cmidrule{n-n}, but in my code below I get multiple errors..

\documentclass{article}
\usepackage{pgfplotstable}
\usepackage{booktabs}

\def\mycline(#1-#2){
\xdef\MC{}%
\foreach \a in {#1,...,#2}{%
\toks0=\expandafter{\MC}%
\def\temp{\cmidrule\expandafter{\a\expandafter-\a}}%
\xdef\MC{\the\toks0 \temp}%
}
\MC
}

\begin{document}
\begin{tabular}{llll}
1&2&3&4\\ \mycline{1-3}
5&6&7&8\\
\end{tabular}
\end{document}

-
There are various things up here, but before tackling them what is wrong with simply \cmidrule{1-3}? –  Joseph Wright Oct 31 '12 at 14:06
hi @JosephWright as per egreg's answer I'm looking for a shortened \cmidrule. As a newbie I've been using \setlength{\extracolsep} to get the intercolumn gaps. –  Tahnoon Pasha Oct 31 '12 at 14:24
Related Question: Wrapping \cmidrule in a macro. –  Peter Grill Oct 31 '12 at 18:09

As Joseph comments, there's no point in saying

\cmidrule{1-1}\cmidrule{2-2}\cmidrule{3-3}


because the effect is the same as saying

\cmidrule{1-3}


If you want to use the "shortening" feature of \cmidrule and generate

\cmidrule(lr){1-1}\cmidrule(lr){2-2}\cmidrule(lr){3-3}


then you can do the computations in a \noalign and then deliver the result:

\documentclass{article}
\usepackage{pgffor}
\usepackage{booktabs}
\makeatletter
\def\mycline(#1-#2){\noalign{
\gdef\@mycline{}%
\foreach \a in {#1,...,#2}{%
\edef\@tempa{\noexpand\cmidrule(lr){\a-\a}}%
}}
\@mycline
}

% the macro
\begin{document}
\begin{tabular}{llll}
1&2&3&4\\ \mycline(1-3)
5&6&7&8\\
\end{tabular}
\end{document}


Notice some points:

1. You have to say \noexpand\cmidrule in the \edef

2. Using \g@addto@macro is a more economic way to add tokens to a parameterless macro

3. Using a @-command such as \@mycline is better than \MC that could clobber some already existing macro

4. Using \noalign ensures that the work is done "outside any alignment cell"

-
thanks @egreg exactly what I needed. –  Tahnoon Pasha Oct 31 '12 at 14:26

After \\ (which expands amongst other things to the primitive \cr that ends a table row, TeX looks ahead using expansion only to see if the table cell needs special treatment, specifically it looks for \noalign \span or omit. As soon as it finds a non-expandable token that is not one of these it stops and processes the cell normally.

so if you put \mycline at the start of a row it is expanded one level and then the next token that is seen is the \xdef which is not expandable so after that it is not possible to have any spanning entries (which are needed for \cline \cmidrule \multicolumn and other similar constructs).

If you look how these things are coded in table packages you will see that either they have to work purely by expansion (so no \xdef or foreach etc) or they have to start a \noalign, do all the computation in the local scope of \noalign and then globally insert the expandable commands to span the columns after the \noalign has finished.

-