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 would like to add listings source as attachment to a PDF (created by pdflatex). For \lstinputlisting this is pretty easy:

\RequirePackage{listings}
\RequirePackage{embedfile}

\let\lstinputlistingO=\lstinputlisting
\renewcommand{\lstinputlisting}[2][]{\embedfile{\detokenize{#2}}\lstinputlistingO[#1]{#2}}

but how can I do the same with \begin{listing} ... \end{listing}? (referenced filename should be the something like listing 12)

share|improve this question
add comment

2 Answers 2

up vote 9 down vote accepted

As embedfile can only embed external files, you have to write the content of the environment to a file first. To do this, the capabilities of the listings package, namely the \lst@BeginAlsoWriteFile macro, can be used:

\usepackage{listings}
\usepackage{embedfile}

\makeatletter
\lst@RequireAspects{writefile}

\lstnewenvironment{lstembedlisting}[2][]{%
\bgroup%
\lstset{#1}%
\lst@BeginAlsoWriteFile{#2}%
}
{%
\lst@EndWriteFile%
\embedfile{#2}%
\egroup%
}
\makeatother

This code snippet creates a new environment called lstembedlisting, which can be used like the normal lstlisting, except that it expects an additional filename as a mandatory argument. The code inside the environment is typeset and written to that file at the same time. Afterwards, \embedfile is called to attach it to the PDF.

Full MWE:

\documentclass{article}

\usepackage{listings}
\usepackage{embedfile}

\makeatletter
\lst@RequireAspects{writefile}

\lstnewenvironment{lstembedlisting}[2][]{%
\bgroup%
\lstset{#1}%
\lst@BeginAlsoWriteFile{#2}%
}
{%
\lst@EndWriteFile%
\embedfile{#2}%
\egroup%
}
\makeatother

\begin{document}
\begin{lstembedlisting}[language=TeX]{listing_12.tex}
Hello world!
\bye
\end{lstembedlisting}
\end{document}
share|improve this answer
    
+1 nice solution! –  Jan Hlavacek Feb 11 '12 at 2:50
add comment

Since it is tricky working with verbatim content, which is the case when dealing with listings, there is no easy single-command way out in my opinion. A two-step process using the filecontents package, however, is easy. Not as clean as diabonas' answer though...

enter image description here

\documentclass{article}
\usepackage{listings}% http://ctan.org/pkg/listings
\usepackage{embedfile}% http://ctan.org/pkg/embedfile
\usepackage{filecontents}% http://ctan.org/pkg/filecontents

% Automatically embed listings file as attachment with \lstinputlisting
\let\lstinputlistingO=\lstinputlisting
\renewcommand{\lstinputlisting}[2][]{\embedfile{\detokenize{#2}}\lstinputlistingO[#1]{#2}}

\begin{document}

\lstinputlisting{A.tex} % Insert listing and embed in PDF

% Write listing to file
\begin{filecontents*}{B.tex}
Here is some more code
\end{filecontents*}
\lstinputlisting{B.tex} % Insert listing and embed in PDF
\end{document}

filecontents allows for using the filecontents (and filecontents*) environment outside the preamble of your document. If you don't like using filecontents* and would rather use something like \begin{listing}...\end{listing}, you could add the following to your document preamble:

\expandafter\let\expandafter\listing\csname filecontents*\endcsname
\expandafter\let\expandafter\endlisting\csname endfilecontents*\endcsname

However, adapting filecontents in general to accept an optional argument (which would include your listing formatting) is rather difficult, apart from rewriting the package (as far as I know).

This option saves the file first and then inputs it. The opposite approach of setting it first and then embedding it would be more difficult.

share|improve this answer
add comment

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.