9

I am using multicols to create two columns for body text. For code typesetting I am using the listings package. For the latter I have created an environment using \lstnewenvironment command, used as \begin{Code}..\end{Code}. I would like the code to be typeset as full width.

\begin{multicols}{2}
  ... two column text
  \begin{Code}...\end{Code}
  ... two column text
\end{multicols}

What I am after is to redefine the Code environment in such a way as to end the multicols, before it starts typesetting and re-start it at the end.

\documentclass{article}
\usepackage{listings,lipsum,xcolor}
\usepackage{multicol}
\renewcommand{\ttdefault}{cmtt}         % prefer old tt font
\newcommand\emphasis[2][red]{\lstset{emph={write,void,writeln,#2},
   emphstyle={\ttfamily\textcolor{#1}}}}%
\lstnewenvironment{Code}[1][]
  {\lstset{language=[LaTeX]TeX}\lstset{%
      escapeinside={{(*@}{@*)}},
      breaklines=true,
      framesep=5pt,
      basicstyle=\ttfamily,
      showstringspaces=false,
      keywordstyle=\ttfamily\textcolor{blue},
      stringstyle=\color{orange},
     commentstyle=\color{black},
     rulecolor=\color{gray!10},
      breakatwhitespace=true,
     showspaces=false,  % shows spacing symbol
     xleftmargin=0pt,
     xrightmargin=5pt,
     aboveskip=0pt, % compact the code looks ugly in type
     belowskip=0pt,  % user responsible to insert any skips
      backgroundcolor=\color{gray!15}, #1
}}
{}
\begin{document}
\begin{multicols}{2}
\lipsum[1]
\begin{Code}
  \def\somelongcommand{This is a test to demonstrate the problem}
\end{Code}
\lipsum[3]
\end{multicols}

Preferably,

\begin{Code}
  \def\somelongcommand{This is a test to demonstrate the problem}
\end{Code}

\end{document}

2 Answers 2

6

You can use the package etoolbox with the special hooks.

\documentclass{article}
\usepackage{listings,lipsum,xcolor}
\usepackage{multicol}
\renewcommand{\ttdefault}{cmtt}         % prefer old tt font
\newcommand\emphasis[2][red]{\lstset{emph={write,void,writeln,#2},
   emphstyle={\ttfamily\textcolor{#1}}}}%
\lstnewenvironment{Code}[1][]
  {\lstset{language=[LaTeX]TeX}\lstset{%
      escapeinside={{(*@}{@*)}},
      breaklines=true,
      framesep=5pt,
      basicstyle=\ttfamily,
      showstringspaces=false,
      keywordstyle=\ttfamily\textcolor{blue},
      stringstyle=\color{orange},
     commentstyle=\color{black},
     rulecolor=\color{gray!10},
      breakatwhitespace=true,
     showspaces=false,  % shows spacing symbol
     xleftmargin=0pt,
     xrightmargin=5pt,
     aboveskip=0pt, % compact the code looks ugly in type
     belowskip=0pt,  % user responsible to insert any skips
      backgroundcolor=\color{gray!15}, #1
}}
{}
\usepackage{etoolbox}
\makeatletter
\newtoggle{test:multicols}
\newcounter{savecolnum}
\AtBeginEnvironment{multicols}{%
   \global\toggletrue{test:multicols}
   }
\AtEndEnvironment{multicols}{%
 \global\setcounter{savecolnum}{\number\col@number}
 \global\togglefalse{test:multicols}
}


\BeforeBeginEnvironment{Code}{
   \iftoggle{test:multicols}%
      {\def\reserveda{\end{multicols}\global\toggletrue{test:multicols}}}
      {\let\reserveda\relax}
   \reserveda
}
\AfterEndEnvironment{Code}{%
   \iftoggle{test:multicols}%
      {\def\reserveda{\begin{multicols}{\thesavecolnum}}}
      {\let\reserveda\relax}
   \reserveda
}
\makeatother
\begin{document}
\begin{multicols}{2}
\lipsum[1]
\begin{Code}
  \def\somelongcommand{This is a test to demonstrate the problem}
\end{Code}
\lipsum[3]
\end{multicols}

Preferably,

\begin{Code}
  \def\somelongcommand{This is a test to demonstrate the problem}
\end{Code}

\end{document}

The result:

4
  • Thanks. This worked very well with the minimal, but fails in the main document with no error. It typesets the code with no error, but still in two columns. You want to take a guess?
    – yannisl
    Dec 17, 2011 at 12:03
  • @YiannisLazarides: I would guess but I have no idea? Sorry ;-) Dec 17, 2011 at 12:12
  • thanks, everything now works. Traced the error back to \DefineShortVerb{\|}, strange:(
    – yannisl
    Dec 17, 2011 at 12:42
  • @YiannisLazarides: Some time ago I had the same problem with this shortverb and pstricks ;-) Dec 17, 2011 at 12:51
5

The package etoolbox comes to rescue: we have to evaluate the current environment before \begin{Code} is completely processed:

\usepackage{etoolbox}
\makeatletter
\def\multicols@string{multicols}
\BeforeBeginEnvironment{Code}{%
  \ifx\@currenvir\multicols@string
    \xdef\resume@multicols{\noexpand\begin{multicols}{\number\col@number}}%
    \end{multicols}%
  \else
    \global\let\resume@multicols\@empty
  \fi}
\AfterEndEnvironment{Code}{\resume@multicols}
\makeatother

Of course you have to ensure that you don't issue \begin{Code} in the middle of another environment. Such a test might be implemented inside the \BeforeBeginEnvironment code, by issuing a warning.

1
  • Thanks for the code. I have accepted Marco's as he went out of his way with a minimal. In the end I used a bit of combination from both.
    – yannisl
    Dec 17, 2011 at 12:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .