Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I'm trying to use this answer to put my lstlistings environments inside a tikz node. So I want to define a new listings environment, with \lstnewenvironment.

My final goal, to be precise, is to ensure the proper framing of two-column listings generated through the multicol package using the multicols option of listings (§5.8 of the listings manual). Tikz comes in because 2-columns framing is ugly with the frame argument of listings, see the end of this pdf for an example.

But I also have single-column listings in my document that I'd like to decorate with tikz, and I'd love to have a single command to typeset both 2-columns and single-column listings. Fortunately, the listings manual suggests something: simply copying an optional argument of the new listings environment inside an lstset command (p.41).

That's what I tried to do:

\documentclass{minimal}

\usepackage{listings}
\usepackage{tikz}
\usepackage{multicol}

\tikzstyle{sourcecodebox} = [
 fill=white, draw=black, inner sep=1em, rectangle
]

\makeatletter
\lstnewenvironment{lstfigurelisting}[1][]{%
  \lstset{frame=none,#1}%
  \setbox\@tempboxa=\hbox\bgroup\color@setgroup
}%
{%
    \color@endgroup\egroup
    \begin{tikzpicture}
        \node[sourcecodebox] (box)
            {\makebox[.75\linewidth][l]{\box\@tempboxa}};
    \end{tikzpicture}
}
\makeatother

\begin{document}

Some code here:
\begin{lstfigurelisting}[multicols=2]
  #!/usr/bin/env python
  def main():
  print "Hello, World!"
  if __name__ == '__main__':
  main()
\end{lstfigurelisting}

\end{document}

Unfortunately, I get a Something's wrong--perhaps a missing \item pointing at multicols=2.

If I remove that optional argument, or change it to something innocuous (e.g. breaklines=true, everything works (so at least I get the framing for single-column listings). I've read the FAQ on the missing \item error, but I don't understand how this would apply, here. I do understand that the plain TeX \setbox is used to save the whole environment content in a TeX box register, but I don't see how the multi-column environment, specifically, would insert a list inside that box.

Does anybody have an idea of what's going on ? Any other alternatives to suggest as to reaching my final goal (1 and 2-column listings inside a tiks node) ?

share|improve this question

1 Answer 1

up vote 5 down vote accepted

I don't really know anything about listings or multicol and particularly haven't a clue as to why they complain so much about being put in a box (presumably to do with how multicol works its magic). So I went back to the original specification: to get a listings listing in a columnar setup within a TikZ node. I came up with the following solution. What seemed to be the key was to avoid precisely that situation that your code lands in: that something reads in the listing ahead of time and then resets it somewhere else. Several of the commands that I chose to use had a "read ahead" version, and I found that the code did not work if I chose that one. For example, I had to use a minipage instead of a \parbox.

Anyway, this will need tweaking I'm sure - particularly with regard to line widths - but it does seem to do the basic "put a 2-column listing in a TikZ node".

\documentclass{article}

\usepackage{listings}
\usepackage{tikz}
\usepackage{multicol}

\tikzstyle{sourcecodebox} = [
 fill=white, draw=black, inner sep=1em, rectangle
]

\makeatletter
\lstnewenvironment{lstfigurelisting}[1][]{%
  \tikzpicture
  \node[sourcecodebox] (box)
  \bgroup
  \minipage{.75\textwidth}
  \lstset{frame=none,#1}
}
{
\endminipage
\egroup;
\endtikzpicture
}
\makeatother

\begin{document}

Some code here:

\begin{lstfigurelisting}[multicols=2]
#!/usr/bin/env python
  def main():
  print "Hello, World!"
  if __name__ == '__main__':
  main()
\end{lstfigurelisting}
\end{document}

Result:

listings in a node

share|improve this answer
    
Very insightful, thanks ! –  huitseeker Sep 13 '11 at 9:09

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.