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?
David Carlisle
  • 757,742
  • Crosslink: Related questions on the topic of verbatim inside tabularx: 1 2 3 4 5 6 7 8 (remark: last one has my answer using a "general" approach using my cprotectinside package) – user202729 Jan 11 '23 at 10:02

2 Answers2

12

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.

David Carlisle
  • 757,742
Leo Liu
  • 77,365
11
  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} 
    
David Carlisle
  • 757,742
Martin Scharrer
  • 262,582