3

I would like to write a programme code to a file, so that it can be later on executed. The language requires to keep line breaks.

\begin{myCode}
one
two
three
\end{myCode}

In my macro I have following

\obeylines

which produces this output:

one^^Mtwo^^Mthree

Is there a simple way how to replace ^^M by a line ending character that would by recognized by a Unix system? I understood that verbatim environment processes text line by line, but in this case it's probably not necessary.

Update:

Here's the minimal working code:

\documentclass{minimal}
\usepackage{environ}

\newwrite\myOutput
\makeatletter

\def\my@writeToFile#1{
  \immediate\openout\myOutput=output.txt%
  \immediate\write\myOutput{#1}
  \immediate\closeout\myOutput
}

\newenvironment{myCode} {
    \obeylines
    \Collect@Body\my@writeToFile %macro from the environ package
}{%
}
\makeatother

\begin{document}
  \begin{myCode}
  one
  two
  three
  \end{myCode}
\end{document}
4
  • 2
    Please, provide a minimal working example with the code that gives the problem.
    – egreg
    Feb 27, 2012 at 23:05
  • 1
    If you want to write the code to a file as ASCII text you should consider using the filecontents package. Feb 27, 2012 at 23:05
  • 1
    How is the MyCode environment defined? In particular, what is the \dospecials macro supposed to achieve?
    – Mico
    Feb 28, 2012 at 0:57
  • sure, I've added a minimal working code. \dospecials is useless there, I guess. I'll have a look at the filecontents package
    – Tombart
    Feb 28, 2012 at 14:49

4 Answers 4

4
\newlinechar`\^^J

will make it put unix line end control J at the ends instead of control M,

1
  • where should be this defined? I wasn't able to make it work
    – Tombart
    Feb 28, 2012 at 15:47
1

You should be aware of an important fact: \write expands its argument during the writing operation. So (leaving out, for the moment, the line termination problem) if your environment is

\begin{myCode}
\emph{x}
\end{myCode}

the result in output.txt will be the not very amusing

^^M\protect \unhbox \voidb@x \bgroup \def myCode{x}\let \futurelet \@let@token \let \protect \relax \protect \relax \protect \edef n{it}\protect \xdef \OT1/cmr/m/n/10 {\OT1/cmr/m/n/10 }\OT1/cmr/m/n/10 \size@update \enc@update x\egroup ^^M

Verbatim writes to files is available, for example, with the package fancyvrb:

\documentclass{article}
\usepackage{fancyvrb}

\begin{document}
\begin{VerbatimOut}{output.txt}
one
two
three
\emph{x}
\end{VerbatimOut}
\end{document}
1
  • yes, I understand it's not very universal solution
    – Tombart
    Feb 28, 2012 at 16:20
1

Inspired by David's answer, using \newlinechar to let ^^M be interpreted as a new line character in your new environment seems to work.

\documentclass{minimal}
\usepackage{environ}

\newwrite\myOutput
\makeatletter

\def\my@writeToFile#1{
  \immediate\openout\myOutput=output.txt%
  \immediate\write\myOutput{#1}%
  \immediate\closeout\myOutput%
}

\newenvironment{myCode} {
    \newlinechar`\^^M%
    \obeylines%
    \Collect@Body\my@writeToFile% %macro from the environ package
}{%
}
\makeatother

\begin{document}
\begin{myCode}
one
two
three
\end{myCode}
\end{document}
2
  • 1
    Welcome to TeX.SX!
    – Bobyandbob
    May 6, 2018 at 15:20
  • I now realise that David probably ment to replace \obeylines with \endlinechar=\^^J%`. This works as well (and is simpler)
    – Jelmervdl
    May 8, 2018 at 9:00
0

based on Peter Grill's advice I've tried filecontents package. I came up with following solution:

\documentclass{minimal}
\usepackage{filecontents}
\makeatletter

\newenvironment{myCode}[1] {
    \filec@ntents{#1}
}{%
}
\makeatother 

\begin{document}
\begin{myCode}{myFile.txt}
one
two
\emph{txt}
\\ dangerous $ code %@# 
\end{myCode}
\end{document}

The output looks like this:

%% LaTeX2e file `myFile.txt'
%% generated by the `myCode' environment
%% from source `test' on 2012/02/28.
%%
one
two
\emph{txt}
\\ dangerous $ code %@#

It's minimalistic, but it does pretty much what I wanted (just remove those comments and it will be perfect).

4
  • \@tempswafalse\filec@ntents{#1} will remove the comments. There are also spurious spaces in your code.
    – egreg
    Feb 28, 2012 at 16:44
  • 1
    @egreg those comments go away if you use filecontents* of standard LaTeX, so no need for lowlevel hackery here ;-) Feb 28, 2012 at 17:14
  • @FrankMittelbach Yes, but the OP wants to define a differently named environment. I really don't know why using myCode would be better than filecontents*, nor why the more powerful facilities of fancyvrb are not exploited.
    – egreg
    Feb 28, 2012 at 17:18
  • hmm, I just wonder why we made those filecontents environments preamble-only. So that is why Scott wrote the package. Maybe not a good idea to have this restriction. Feb 28, 2012 at 17:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .