3

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}
3
  • \expandafter\cline\expandafter{\arg}
    – Manuel
    Nov 5, 2015 at 16:12
  • 1
    In the above test file this results in ` ! Misplaced \omit....` Nov 5, 2015 at 19:40
  • Okey, then the wrong part is not in \cline{\arg}, the rest of the code doesn't work.
    – Manuel
    Nov 5, 2015 at 20:35

1 Answer 1

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.

2
  • What a nice simplification! Makes me feel stupid, but thanks! Nov 5, 2015 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, 2015 at 21:48

You must log in to answer this question.

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