2

I'm trying to define my own version (\CLINE) of \cline, such that
\CLINE{1-3,5-7} is equivalent to
\cline{1-3}\cline{5-7}.
I want therefore call \cline with a non-literal argument, like so:

\def\arg{1-3}
...
\cline{\arg}

But this leads to an error message:

Runaway argument?
\xx \@nil \cline {5-7} 1&2&3&4&5&6&7\\ \end {tabular} \end document}\ETC.
! File ended while scanning use of \@cline.

Is there a better way to do this? Here is what I have sofar:

\documentclass{article}
\usepackage[papersize={60mm,30mm},margin=5mm,noheadfoot]{geometry}
\usepackage{xstring}
\pagestyle{empty}
\parindent0pt

\def\CLINE#1{%
  \def\arg{#1}% \arg -> 1-3,5-7
  \loop%
    \iftrue%
    \StrCut{\arg}{,}{\X}{\arg}% first cycle: \X → 1-3 \arg → 5-7
                              % secnd cycle: \X → 5-7 \arg → empty
    \typeout{cline argument: \X}%
    \cline{\X}% first cycle: \cline{1-3}
              % secnd cycle: \cline{5-7}
    \ifx\arg\empty\let\iterate\relax\fi%
  \repeat%
}
\begin{document}
\begin{tabular}{ccccccc}\hline
1&2&3&4&5&6&7\\\cline{1-3}\cline{5-7}
1&2&3&4&5&6&7\\\CLINE{1-3,5-7}
1&2&3&4&5&6&7\\
\end{tabular}
\end{document}
  • \expandafter\cline\expandafter{\arg} – Manuel Nov 5 '15 at 16:12
  • In the above test file this results in ` ! Misplaced \omit....` – Wybo Dekker Nov 5 '15 at 19:40
  • Okey, then the wrong part is not in \cline{\arg}, the rest of the code doesn't work. – Manuel Nov 5 '15 at 20:35
1

You have to use a macro based on expansion; assignments won't do. When evaluating \cline, TeX is in a particularly unstable state: any non expandable token would end the search for \omit or \noalign and start a new alignment cell.

\documentclass{article}

\def\CLINE#1{\CLINEA#1,,}
\def\CLINEA#1,{\ifx,#1,\else \cline{#1}\expandafter\CLINEA\fi}

\begin{document}
\begin{tabular}{ccccccc}\hline
1&2&3&4&5&6&7\\\cline{1-3}\cline{5-7}
1&2&3&4&5&6&7\\\CLINE{1-3,5-7}
1&2&3&4&5&6&7\\
\end{tabular}
\end{document}

(Code borrowed from wipet)

enter image description here

If you want to perform a loop, you have to do it inside \noalign, for instance

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\CLINE}{m}
 {
  \noalign{\CLINE_split:n { #1 } }
 }

\cs_new_protected:Nn \CLINE_split:n
 {
  \tl_gclear:N \g_tmpa_tl
  \clist_map_inline:nn { #1 }
   {
    \tl_gput_right:Nn \g_tmpa_tl { \cline{##1} }
   }
  \group_insert_after:N \g_tmpa_tl
 }
\ExplSyntaxOff

\begin{document}
\begin{tabular}{ccccccc}\hline
1&2&3&4&5&6&7\\\cline{1-3}\cline{5-7}
1&2&3&4&5&6&7\\\CLINE{1-3,5-7}
1&2&3&4&5&6&7\\
\end{tabular}
\end{document}

Your approach is too complicated, in my opinion; splitting a comma separated list of arguments can be done more easily, as you see in the two examples.

  • What a nice simplification! Makes me feel stupid, but thanks! – Wybo Dekker Nov 5 '15 at 21:37
  • @WyboDekker Alignments are a very hairy subject. Getting the timing right is the most important thing and is not easy. Consider that LaTeX tables are the realm of things like {\ifnum0=`}\fi and \ifnum`{=0\fi} ;-) – egreg Nov 5 '15 at 21:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.