# Full width code listing within two column text

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

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:

-
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? –  Yiannis Lazarides Dec 17 '11 at 12:03
@YiannisLazarides: I would guess but I have no idea? Sorry ;-) –  Marco Daniel Dec 17 '11 at 12:12
thanks, everything now works. Traced the error back to \DefineShortVerb{\|}, strange:( –  Yiannis Lazarides Dec 17 '11 at 12:42
@YiannisLazarides: Some time ago I had the same problem with this shortverb and pstricks ;-) –  Marco Daniel Dec 17 '11 at 12:51

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.

-
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. –  Yiannis Lazarides Dec 17 '11 at 12:43