9

I have a tabularx environment where I want to put an lstlisting into. But Latex fails to compile it. Testcase:

\documentclass[a4paper,12pt]{scrreprt}
\usepackage[utf8x]{inputenc}

\usepackage{tabularx}
\usepackage{listings}

\begin{document}
\begin{tabularx}{\textwidth}{lX}
 First column &
 \begin{lstlisting}
  Sample text
 \end{lstlisting} \\
\end{tabularx}

\end{document} 

I always get a ! Argument of \lst@next has an extra }. Two questions:

  1. What's causing it?
  2. How can I fix it?

2 Answers 2

11

You can use:

\begin{tabularx}{\textwidth}{lX}
 First column &
\begin{lstlisting}^^J
  Sample text^^J
\end{lstlisting} \\
\end{tabularx}

Generally speaking, all verbatim-like commands and environments cannot be directly used in parameters of other commands. In tabularx environments, X columntype works actually as macro arguments(it reads the cell contents into boxes first). listings package partially fixes it, but still has some limits. See "5.1 Listings inside arguments" of manual of listings for more information.

5
  • Oh thanks. I read the listings doc at the end, but I forgot to put "^^J" also after the first brace! Feb 10, 2011 at 20:30
  • 2
    What does the ^^J literal you appended do? It fixed my custom command to have code listings inside bclogo text boxes. Thanks!
    – Cloud
    Aug 11, 2016 at 15:35
  • What is that ^^J ? Is this a symbol ?
    – nowox
    Aug 11, 2019 at 11:09
  • @nowox ^^J is a line feed May 2, 2020 at 12:51
  • This does work, but it also adds additional empty lines before and after the listings' contents, thereby breaking the vertical alignment in the table cells. Any ideas if this can be avoided?
    – Stefan
    Jul 7, 2021 at 11:00
10
  1. tabularx has to read its content before the macros are executed, so it doesn't support verbatim code.

  2. Do the listing outside tabularx

    a) Use an external file with \lstinputlisting. This can be done in combination with filecontents to generate this file automatically:

    \documentclass[a4paper,12pt]{scrreprt}
    \usepackage[utf8x]{inputenc}
    
    \usepackage{tabularx}
    \usepackage{listings}
    \usepackage{filecontents}
    
    \newsavebox\mybox
    \begin{document}
    % Writes content to temp file
    \begin{filecontents*}{\jobname.abc}
     Sample text
    \end{filecontents*}
    % Or just add the 'listings' environment here
    % and use `\input` instead.
    
    \begin{tabularx}{\textwidth}{lX}
     First column &
     \lstinputlisting{\jobname.abc} \\
    \end{tabularx}
    
    \end{document} 
    

    b) Store the listing in a box and use the box inside tabularx:

    \documentclass[a4paper,12pt]{scrreprt}
    \usepackage[utf8x]{inputenc}
    
    \usepackage{tabularx}
    \usepackage{listings}
    
    \newsavebox\mybox
    \begin{document}
    \begin{lrbox}{\mybox}
     \begin{lstlisting}
       Sample text
     \end{lstlisting}
    \end{lrbox}
    
    \begin{tabularx}{\textwidth}{lX}
     First column &
      \usebox\mybox \\
    \end{tabularx}
    
    \end{document} 
    
3
  • I see now what the advantage of putting listings in separate files are. I had no idea :) I tried using a box to put it outside, but sadly the width of the box will be wrong when the listing is rendered into the box :) Feb 10, 2011 at 20:29
  • @Johannes: this might be fixable by using some of the many options of listings or surrounding listings with a minipage environment with a suitable width. Feb 10, 2011 at 20:34
  • I don't know the width of the X table in advance :( Feb 10, 2011 at 20:39

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.