Discussion:
\begin{lstlisting} ... \end{lstlisting} inside a macro
(too old to reply)
Andrei Alexandrescu (See Website For Email)
2007-06-01 14:14:26 UTC
Permalink
I am trying to use the listings environment inside a macro, and this
doesn't work:

\documentclass{article}
\usepackage{listings}

\begin{document}

\newcommand\macro{
some text

\begin{lstlisting}
some code
\end{lstlisting}

some more text
}

\macro

\end{document}

I thought there would be complications when various special characters
are inside the listing, but it turns out even this simple example
doesn't work.

Any help would be appreciated!


Andrei
Joseph Wright
2007-06-01 15:02:49 UTC
Permalink
On Jun 1, 3:14 pm, "Andrei Alexandrescu (See Website For Email)"
Post by Andrei Alexandrescu (See Website For Email)
I am trying to use the listings environment inside a macro, and this
\documentclass{article}
\usepackage{listings}
\begin{document}
\newcommand\macro{
some text
\begin{lstlisting}
some code
\end{lstlisting}
some more text
}
\macro
\end{document}
I thought there would be complications when various special characters
are inside the listing, but it turns out even this simple example
doesn't work.
Any help would be appreciated!
Andrei
I have a feeling (I'm no expert) that this is to do with the need to
change catcodes. In that sense, I think the problem closely resembles
the limitations on using verbatim in macros and environments, as
discussed at:

http://www.tex.ac.uk/cgi-bin/texfaq2html?label=verbwithin

I think you may be out of luck.

Joseph Wright
Joseph Wright
2007-06-01 15:09:12 UTC
Permalink
Post by Joseph Wright
On Jun 1, 3:14 pm, "Andrei Alexandrescu (See Website For Email)"
Post by Andrei Alexandrescu (See Website For Email)
I am trying to use the listings environment inside a macro, and this
\documentclass{article}
\usepackage{listings}
\begin{document}
\newcommand\macro{
some text
\begin{lstlisting}
some code
\end{lstlisting}
some more text
}
\macro
\end{document}
I thought there would be complications when various special characters
are inside the listing, but it turns out even this simple example
doesn't work.
Any help would be appreciated!
Andrei
I have a feeling (I'm no expert) that this is to do with the need to
change catcodes. In that sense, I think the problem closely resembles
the limitations on using verbatim in macros and environments, as
http://www.tex.ac.uk/cgi-bin/texfaq2html?label=verbwithin
I think you may be out of luck.
Joseph Wright
Quickly looking through the docs for listings, I am pretty sure I'm
right. Section 4.16 of listings.pdf does mention a way of generating
a customised environment, but there is no mention of macros. Looking
though the source, there are various catcode changes, which I think
are the underlying problem.

Joseph Wright
Ulrich Diez
2007-06-01 18:06:48 UTC
Permalink
Post by Andrei Alexandrescu (See Website For Email)
I am trying to use the listings environment inside a macro, and this
How about working around this:

How about using the verbatimwrite-environment for writing your listing
verbatim to an external file?

Afterwards you can use \input or \lstinputlisting for repeated inclusion.

If you want repeated inclusion also of text which surrounds the listing, use the
verbatimwrite-environment for creating an external file which also contains the
lstlisting-environment. Use \input for importing it into your document.

If you only want the listing to be repeated, but no surrounding text, use the
verbatimwrite-environment for creating an external file which only contains
the listing but no surrounding lstlisting-environment.
Use \lstinputlisting for importing it into your document.

You can put the call to \input/lstinputlisting into a macro if you like.

You can also use Scott Pakin's attachfile-package for attaching the external file
with the code-listing to the pdf. This way you can have nicely formatted listings
with line-numbers etc when reading the pdf.
But for testing/compiling/playing around, the user can extract the listing to
hard-disk without the need of manually removing the formatting or the
line-numbers as might be the case when using some pdf-viewer's fancy
edit-copy-edit-paste-features.

Ulrich

\documentclass{article}
\usepackage{verbatim, listings}

%Define the verbatimwrite-environment:

\makeatletter
\@ifdefinable\***@out{%
\newwrite\***@out
}%
\newcommand*\verbatimwrite[1]{%
\@bsphack
\immediate\openout\***@out#1\relax
\let\do\@makeother\dospecials
\catcode`\^^M\active
\***@startline
\***@addtoline
\***@finish
\def\***@processline{%
\immediate\write\***@out{\the\***@line}%
}%
\***@start
}%
% This is the ending-part of the environment:
\@ifundefined{endverbatimwrite}%
{\def\endverbatimwrite{%
\immediate\closeout\***@out
\@esphack
}%
}%
{{\def\***@a{endverbatimwrite}\@notdefinable}}%
\makeatother

% Use the verbatim-environment for creating an external file
% which contains your listing:

\begin{verbatimwrite}{surround.tex}
some surrounding text

\begin{lstlisting}
some code ^@#&$§+-\/{}[]
\end{lstlisting}

some more surrounding text
\end{verbatimwrite}

\begin{verbatimwrite}{purelist.tex}
some code ^@#&$§+-\/{}[]
\end{verbatimwrite}

\newcommand*\othersurround{%
some surrounding text

\lstinputlisting{purelist.tex}

some more surrounding text
}%

\begin{document}

\textbf{The listing with text which surrounds it:}

\input{surround.tex}

\input{surround.tex}

\textbf{The pure listing:}

\lstinputlisting{purelist.tex}

\input{surround.tex}

\textbf{Again the listing with text which surrounds it:}

\othersurround

\othersurround

\end{document}
Andrei Alexandrescu (See Website For Email)
2007-06-02 16:38:57 UTC
Permalink
Post by Ulrich Diez
Post by Andrei Alexandrescu (See Website For Email)
I am trying to use the listings environment inside a macro, and this
How about using the verbatimwrite-environment for writing your listing
verbatim to an external file?
[snip]

Great, thanks! The lingering problem is the spurious newline when using
\input, but I guess I'll have to live with that.

Andrei
Ulrich Diez
2007-06-02 21:40:12 UTC
Permalink
Post by Andrei Alexandrescu (See Website For Email)
Great, thanks! The lingering problem is the spurious newline when using
\input, but I guess I'll have to live with that.
On my system I don't get spurious newline.
Perhaps you can provide a minimal example exhibiting this?

By the way: Instead of the verbatimwrite-environment, you can
also use the filecontents*-environment which comes along
with the LaTeX2e-kernel for creating your external files.

Usually you can use that environment only in the preamble.
But in case you wish to use that environment in the
document-body also, you can load the package pkgindoc
which makes it possible to use preamble-macros within in the
document-environment also.
pkgindoc.sty is implemented in the LaTeX2e-kernel,
file L: ltclassclass.dtx, Section 71: After Preamble .

Ulrich

\documentclass{article}
\usepackage{pkgindoc, listings}

\begin{filecontents*}{surround.tex}
\noindent some surrounding text
\begin{lstlisting}
some code ^@#&$§+-\/{}[]
\end{lstlisting}
some more surrounding text
\end{filecontents*}

\newcommand*\othersurround{%
\noindent some surrounding text
\lstinputlisting{purelist.tex}
some more surrounding text
}%

\begin{document}

\begin{filecontents*}{purelist.tex}
some code ^@#&$§+-\/{}[]
\end{filecontents*}

\textbf{The listing with text which surrounds it:}

\input{surround.tex}

\input{surround.tex}

\textbf{The pure listing:}

\lstinputlisting{purelist.tex}

\lstinputlisting{purelist.tex}

\textbf{Again the listing with text which surrounds it:}

\othersurround

\othersurround

\end{document}
Andrei Alexandrescu (See Website For Email)
2007-06-02 22:07:29 UTC
Permalink
Post by Ulrich Diez
Post by Andrei Alexandrescu (See Website For Email)
Great, thanks! The lingering problem is the spurious newline when using
\input, but I guess I'll have to live with that.
On my system I don't get spurious newline.
Perhaps you can provide a minimal example exhibiting this?
Actually it's only a spurious space, but I need precise inputting of the
file. Here's a short sample:

\documentclass{article}
\begin{document}
ab\input{data.txt}de
\end{document}

Say the content of data.txt is only one byte: "c". I'd want the output
to be "abcde". Instead it is "abc de". I have no idea on how to get rid
of that darn space. I'd be most grateful if you did...
Post by Ulrich Diez
By the way: Instead of the verbatimwrite-environment, you can
also use the filecontents*-environment which comes along
with the LaTeX2e-kernel for creating your external files.
Usually you can use that environment only in the preamble.
But in case you wish to use that environment in the
document-body also, you can load the package pkgindoc
which makes it possible to use preamble-macros within in the
document-environment also.
pkgindoc.sty is implemented in the LaTeX2e-kernel,
file L: ltclassclass.dtx, Section 71: After Preamble .
Thanks! I've also found the package filecontents written by Scott Pakin
(http://ctan.org/tex-archive/macros/latex/contrib/filecontents/) which
seems to lift those restrictions too. I'll give both a try.


Andrei
Ulrich Diez
2007-06-03 06:59:33 UTC
Permalink
Post by Andrei Alexandrescu (See Website For Email)
Actually it's only a spurious space, but I need precise inputting of the
\documentclass{article}
\begin{document}
ab\input{data.txt}de
\end{document}
Say the content of data.txt is only one byte: "c". I'd want the output
to be "abcde". Instead it is "abc de". I have no idea on how to get rid
of that darn space. I'd be most grateful if you did...
TeX more or less reads input line by line.
If a line does not end by a comment, TeX will usually
attach the character whose ASCII-number corresponds
to the integer-parameter \endlinechar.
Usually \endlinechar is ASCII-13.
Usually one ASCII-13-char will be treated as a space...

Thus you can make data.txt two bytes: "c%"
Or you let it end by a control-word like \endinput or \empty as
spaces do not count after control-words: "c\endinput"
or "c\empty"
The point is: You need to do this with the _last_ line of your file.

If your input-file does not have multiple lines, you can instead
temporarily set \endlinechar to -1 before inputting that file
so that no \endlinechar will be attached at all:

\documentclass{article}
\begin{document}
\endlinechar=-1ab\input{data.txt}de\endlinechar=13
\end{document}

If your input-file does not have multiple lines, you could also
make the endlinechar active and let it equal to \empty.
(^^M is ASCII-char-13 in TeX's ^^-notation for input.)
Thus endlinechar will still get attached but will be expanded
like a macro which yields emptiness:

\documentclass{article}
\begin{document}
{%
\catcode13=13\let^^M=\empty
ab\input{data.txt}de
}%
\end{document}


Ulrich

Stephan Hennig
2007-06-01 16:55:52 UTC
Permalink
Post by Andrei Alexandrescu (See Website For Email)
I am trying to use the listings environment inside a macro, and this
[...]
Any help would be appreciated!
The listings package provides an experimental feature that is described
in section 5.1 of the manual:

\documentclass{article}
\usepackage{listings}
\begin{document}
\newcommand\macro{
some text\par
\begin{lstlisting}^^J
some code^^J
\end{lstlisting}
some more text
}
\macro
\end{document}


Another option is to typeset the listing into an lrbox and then call
\usebox{\mylistingbox} in the macro definition.

Best regards,
Stephan Hennig
Loading...