5

I'd like to insert a block of code in an enumerate list, but I don't want the natural indent from enumerate with the block. For example,

\begin{enumerate}
    \item Primitive Version
    \begin{enumerate}
        \item Implementation
        \paragraph{} The key segment of code is:
\begin{lstlisting}[style=ccode]
int main()
{
    cout << "hello world" << endl;
}
\end{lstlisting}
    \end{enumerate}
\end{enumerate}

I've checked several solutions such as No indentation for non-item within itemize but all of them resulted in errors as I cannot use lstlisting as a parameter.

! Illegal parameter number in definition of \lst@insertargs.

How should I achieve this? Thanks in advance.

  • While code snippets are useful in explanations, it is always best to compose a fully compilable MWE that illustrates the problem including the \documentclass and the appropriate packages so that those trying to help don't have to recreate it. – Peter Grill Sep 21 '16 at 05:48

2 Answers2

8

You can adjust the left margin of the lstlisting using the xleftmargin key-value. Setting it to a combination of the list depths from each respective level (-\leftmargini for the first, an additional -\leftmarginii for the second, -\leftmarginiii for the third, etc.), you can push the listing back to the original left margin of the text as if it were set without the list indentations:

enter image description here

\documentclass{article}

\usepackage{listings}

\begin{document}

\noindent
X \dotfill X

\begin{enumerate}
  \item Y \dotfill Y
  \begin{enumerate}
    \item Z \dotfill Z

\begin{lstlisting}[language=C,xleftmargin=\dimexpr-\leftmarginii-\leftmargini]
int main()
{
    cout << "hello world" << endl;
}
\end{lstlisting}

    \item Z\dotfill Z
  \end{enumerate}

\begin{lstlisting}[language=C,xleftmargin=-\leftmargini]
int main()
{
    cout << "hello world" << endl;
}
\end{lstlisting}
  \item Y \dotfill Y
\end{enumerate}

\noindent
X \dotfill X

\end{document}

The total left margin at any depth is given by \@totalleftmargin. We can utilise this by adjusting xleftmargin in the following way:

<list above>

\begin{lstlisting}[language=C,xleftmargin=\dimexpr-\csname @totalleftmargin\endcsname]
  <code>
\end{lstlisting}

<list below>
Werner
  • 603,163
  • 1
    You could use xleftmargin=\dimexpr-\csname @totalleftmargin\endcsname to avoid to have two different versions depending on the level. – Ulrike Fischer Sep 22 '16 at 08:47
3

An alternative approach which needs no manual adjustments depending on current list depth.

enter image description here

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{listings}

\makeatletter
% command \NOINDENT to be used in a group   
\newcommand*\NOINDENT{\@@par   % clear parshape parameters
% fool list-awareness code (as supposedly in lstlisting, not checked)
      \@totalleftmargin\z@ \@listdepth\z@ \rightmargin\z@
}
\makeatother

\begin{document}

\noindent
X \dotfill X

\begin{enumerate}
  \item Y \dotfill Y
  \begin{enumerate}
    \item Z \dotfill Z

{\NOINDENT\begin{lstlisting}[language=C]
int main()
{
    cout << "hello world" << endl;
}
\end{lstlisting}}
% the whole \NOINDENT\begin...\end must be enclosed in braces!
    \item Z\dotfill Z
      \begin{enumerate}
      \item W\dotfill W

{\NOINDENT\begin{lstlisting}[language=C]
int main()
{
    cout << "hello world" << endl;
}
\end{lstlisting}}

      \end{enumerate}
  \end{enumerate}

  \item Y \dotfill Y

{\NOINDENT\begin{lstlisting}[language=C]
int main()
{
    cout << "hello world" << endl;
}
\end{lstlisting}}
\end{enumerate}

\noindent
X \dotfill X

\end{document}