8

I'm using a custom command to format all tables in a document. Some tables share properties other than style, such as column definitions and headers, which is why this answer inspired me to even more reduce repeated code.

Inserting header data into the table command did not cause any problems, while for inserting column definitions I had to find out how to expand the column definitions before insertion. \expandafter solved that problem.

Now, I'd like to combine parameters given as commands and others given as literals, e.g. the table's data. If the to-be-expanded command that contains the column definitions happens to be the first argument, this works fine. What do I need to do if conversely a literal is the first argument? How do I make \expandafter bypass a pair of curly braces instead of a command?

 

\documentclass{article}
\usepackage{booktabs}

\begin{document}

    \newcommand{\colDef}{{cc}}  
    \newcommand{\tableBody}{a & b\\}

    \newcommand{\myTabA}[2]{%
        \begin{tabular}{#1}
            1 & 2\\\midrule
            #2
        \end{tabular}       
    }

    %same command with #1 and #2 switched
    \newcommand{\myTabB}[2]{%
        \begin{tabular}{#2}
            1 & 2\\\midrule
            #1
        \end{tabular}       
    }       

    %draw table A
    \expandafter\myTabA\colDef{\tableBody}
    \expandafter\myTabA\colDef{c & d\\} 

    %draw table B
    \expandafter\myTabB\expandafter\tableBody\colDef

    %produces error
    %\expandafter\myTabB\expandafter{c & d\\}\colDef    

\end{document}
4
  • 1
    The answers to this question will help you out I think: tex.stackexchange.com/q/22288/14100
    – Scott H.
    Commented May 22, 2012 at 17:08
  • True, that's it. Thanks, Scott and Hendrik. Make it an answer and I'll accept it.
    – dgs
    Commented May 22, 2012 at 17:32
  • 2
    I wish etextools's documentation did not look like a geocities website! All that is missing is a <blink> tag.
    – Aditya
    Commented May 22, 2012 at 17:52
  • 1
    @Aditya Geocitied tex.stackexchange
    – Scott H.
    Commented May 22, 2012 at 18:25

3 Answers 3

8

The etextools package provides some tools for doing this, for example

\ExpandNextTwo{code}{arg 1}{arg 2}

as used below:

\documentclass{article}
\usepackage{booktabs}
\usepackage{etextools}

\begin{document}

   \newcommand{\colDef}{{cc}}  
   \newcommand{\tableBody}{a & b\\}

   \newcommand{\myTabA}[2]{%
    \begin{tabular}{#1}
        1 & 2\\\midrule
        #2
    \end{tabular}       
}

%same command with #1 and #2 switched
\newcommand{\myTabB}[2]{%
    \begin{tabular}{#2}
        1 & 2\\\midrule
        #1
    \end{tabular}       
}       

%draw table A
\expandafter\myTabA\colDef{\tableBody}
\expandafter\myTabA\colDef{c & d\\} 

%draw table B
\expandafter\myTabB\expandafter\tableBody\colDef

% no longer produces error
\ExpandNextTwo{\myTabB}{c & d\\} \colDef

\end{document}
10

It's simpler of you push the expansion control into the macro, so it always expands the first token of #2 once, then you don't need \expandafter in the document.

\documentclass{article}
\usepackage{booktabs}

\begin{document}

    \newcommand{\colDef}{{cc}}  
    \newcommand{\tableBody}{a & b\\}

    \newcommand{\myTabA}[2]{%
        \begin{tabular}{#1}
            1 & 2\\\midrule
            #2
        \end{tabular}       
    }

    %same command with #1 and #2 switched
    \newcommand{\myTabB}[2]{%
        \def\temp{\begin{tabular}}%
           \expandafter\temp\expandafter{#2}
            1 & 2\\\midrule
            #1
        \end{tabular}       
    }       

    %draw table A
    \expandafter\myTabA\colDef{\tableBody}
    \expandafter\myTabA\colDef{c & d\\} 

    %draw table B
    \myTabB\tableBody\colDef

    %produces error (not now!)
    \myTabB{c & d\\}\colDef    

\end{document}
1
  • Thanks David, that's less redundant and a lot more elegant.
    – dgs
    Commented May 22, 2012 at 22:01
2

I've ended up using an etextools command inside the tabular definition, thus drawing from both all answers.

\newcommand{\myTabB}[2]{%
    \expandnext{
    \begin{tabular}}{#2}
        1 & 2\\\midrule
        #1
    \end{tabular}       
}   

You must log in to answer this question.

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