4

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 5:48
8
+50

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>
  • 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 8: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}

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.