4

I want to use a macro to write a line of a tabular. As part of this macro, there is an argument that isn't set in the tabular, but is saved for later use. This unused argument should be allowed to contain \par. But as the following example shows, the tabular breaks when it encounters the \par (or in this case, the two newlines.)

\documentclass{article}
\usepackage{xparse,expl3}
\ExplSyntaxOn
\NewDocumentCommand{\AddTalk}{mmm}{
  \tl_new:c {l_#1_title_tl}
  \tl_set:cn {l_#1_title_tl} {#2}
  \tl_new:c {l_#1_abstract_tl} 
  \tl_set:cn {l_#1_abstract_tl} {#3}
  #2 & #1 \\
}
\ExplSyntaxOff
\begin{document}

\begin{tabular}{ll}
  \AddTalk{foo}{This is the title}{This is the abstract}
  \AddTalk{bar}{Another title}{Another abstract}
  \AddTalk{spock}{A breakage}{This abstract
%
  contains a paragraph break.}
\end{tabular}

\end{document}

(Remove the commented out linebreak to see the failure.)

So my question is this: How can I "hide" the contents of the unused argument of \AddTalk from the tabular? Or more generally, is there a better way to achieve what I want to achieve?

  • 2
    Just make the argument of \AddTalk long: \NewDocumentCommand{\AddTalk}{mm+m}{ ... } – cgnieder May 9 '13 at 12:44
  • @cgnieder Aha! I totally missed that paragraph in the xparse doc. Could you turn your comment into an answer and I'll accept it. – Seamus May 9 '13 at 12:46
  • Ah no wait. When I later "use" the unused argument, the linebreak has gone and has been replaced by "par. I guess I also want to make the unused argument unexpanded... – Seamus May 9 '13 at 12:49
  • that seems unrelated to the MWE. If I simply use \l_spock_abstract_tl from your example the paragraph break is where it's supposed to be. – cgnieder May 9 '13 at 12:55
  • 1
    Semantically better would be \tl_use:c – cgnieder May 9 '13 at 13:07
6

The problem is not the {tabular}. The arguments of a command defined with \NewDocumentCommand (and with the other xparse commands) are short per default and hence choking on \par. One needs to make them long explicitly by preceding the argument identifier with +:

\NewDocumentCommand{\AddTalk}{mm+m}{ ... }
4

Apart from the problem of long arguments, your code has a big weakness: your assignments to token list variables are local, so they'll disappear as soon as the next & is scanned, that is, almost immediately.

You should do global assignments and probably building property list variables is better:

\documentclass{article}
\usepackage{xparse,expl3}
\ExplSyntaxOn
\NewDocumentCommand{\AddTalk}{ m m +m }
 {
  \prop_new:c { g_talks_#1_prop }
  \prop_gput:cnn { g_talks_#1_prop } { title } { #2 }
  \prop_gput:cnn { g_talks_#1_prop } { abstract } { #3 }
  #2 & #1 \\
 }
\NewDocumentCommand{\gettitle} { m }
 {
  \prop_get:cn { g_talks_#1_prop } { title }
 }
\NewDocumentCommand{\getabstract} { m }
 {
  \prop_get:cn { g_talks_#1_prop } { abstract }
 }
\ExplSyntaxOff
\begin{document}

\begin{tabular}{ll}
  \AddTalk{foo}{This is the title}{This is the abstract}
  \AddTalk{bar}{Another title}{Another abstract}
  \AddTalk{spock}{A breakage}{This abstract

  contains a paragraph break.}
\end{tabular}

\bigskip

\noindent\textbf{\gettitle{spock}:} \getabstract{spock}

\end{document}
  • I'd already noticed the local thing. I didn't know about property lists. I will explore. Thanks! – Seamus May 10 '13 at 15:00
  • \prop_get:cnN puts it in a token list. So the \gettitle macro needs to use something like \l_tmpa_tl and then \tl_use:N \l_tmpa_tl, right? – Seamus May 13 '13 at 9:45
  • @Seamus My macros use \prop_get:cn, not \prop_get:cnN – egreg May 13 '13 at 9:50
  • Yes, I hadn't noticed the \prop_get:cn macro in the candidate additions section of interface3... – Seamus May 13 '13 at 10:33

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.