14

I need to write some inlined code on an external file, then load it with listings. I would like to define a new environment, but if I do, filecontents does not save the first line of code (see MWE):

\documentclass[]{article}
\usepackage{listings}
\usepackage{filecontents}

\newenvironment{MyNewEnvironment}[2]{%
  \def\temp{#1}%
  \csname filecontents*\endcsname{\temp}%
  #2%
}%
{\csname endfilecontents*\endcsname%
 \lstinputlisting{\temp}%
}%


\begin{document}

\begin{MyNewEnvironment}{foo.txt}%
one
two
three
four
five

\end{MyNewEnvironment}

\end{document}

The resulting foo.txt contains:

two
three
four
five
Jonas Stein
  • 8,909
FloDD
  • 581
  • 2
    You can't use filecontents* like that; I suggest you to check fancyvrb that provides a way to write verbatim to another file. – egreg Aug 27 '13 at 09:34
  • 1
    @egreg i just skimmed the docs of the filecontents package, and i'm not sure what actually is wrong with flodd's use of the command. what is the rule that prevents such use? – wasteofspace Aug 27 '13 at 10:07
  • @wasteofspace Probably you're right, as karlkoeller's answers shows. However, I find VerbatimOut much more flexible. – egreg Aug 27 '13 at 10:12
  • 3
    What is the purpose of the second argument of environment MyNewEnvironment? It causes the trouble, because it is not read in the control of \filecontents* with its changed catcodes and line ends. Removing the second argument solves your problem as shown in karlkoeller's answer. – Heiko Oberdiek Aug 27 '13 at 10:12
  • I see... I guess I just have misunderstood how newenvironment works :) – FloDD Aug 27 '13 at 10:31

2 Answers2

14

Probably it's not the right way to use filecontents*, as egreg says in his comment.

Anyway, changing your MWE to

\documentclass[]{article}
\usepackage{listings}
\usepackage{filecontents}

\newenvironment{MyNewEnvironment}[1]{%
  \def\temp{#1}%
  \csname filecontents*\endcsname{\temp}%
}%
{\csname endfilecontents*\endcsname%
 \lstinputlisting{\temp}%
}%


\begin{document}

\begin{MyNewEnvironment}{foo.txt}
one
two
three
four
five
\end{MyNewEnvironment}

\end{document} 

works fine for me.

karlkoeller
  • 124,410
13

I suggest using fancyvrb and xparse, that allows also to pass options to \lstinputlisting:

\documentclass{article}
\usepackage{fancyvrb,xparse,listings}

\NewDocumentEnvironment{MyNewEnvironment}{O{}m}
  {\VerbatimOut{#2}}
  {\endVerbatimOut\lstinputlisting[#1]{#2}}

\begin{document}

\begin{MyNewEnvironment}[columns=fullflexible]{foo.txt}
one
two
three
four
five

\end{MyNewEnvironment}

\end{document}
egreg
  • 1,121,712