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
5
  • 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, 2013 at 9: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? Aug 27, 2013 at 10:07
  • @wasteofspace Probably you're right, as karlkoeller's answers shows. However, I find VerbatimOut much more flexible.
    – egreg
    Aug 27, 2013 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. Aug 27, 2013 at 10:12
  • I see... I guess I just have misunderstood how newenvironment works :)
    – FloDD
    Aug 27, 2013 at 10:31

2 Answers 2

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}
3
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.

1
  • +1 This solution seems very good ... despite the comments of egreg. ;-) Jan 1, 2014 at 23:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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