12

Within a custom command, I'm doing the following to write to a file:

\newcommand\mycommand[1]{
  \newwrite\file
  \immediate\openout\file=foobar.tex
  \immediate\write\file{
    foo
    bar
    #1
    blarg
  }
  \immediate\closeout\file
}

Of course when I invoke it as \mycommand{baz}, I get the following contents in foobar.tex:

foo bar baz blarg

with all new lines turned into spaces by LaTeX. My question is, is there a way to output these lines into the file "as expected", i.e. with real new lines at the end of each line instead of a space? I'm thinking some \catcode wizardry should do the trick, but I'm not sure which character I need to redefine and to what category code.

Update

The solution in cmhughes' answer works perfectly. The only problem is when #1 contains embedded newlines. I can of course send it to mycommand with its own slew of ^^J, I was wondering if there is a way to avoid this.

  • you could use ^^J – cmhughes Jan 5 '14 at 1:52
  • @cmhughes that looks like an answer to me:-) – David Carlisle Jan 5 '14 at 2:20
7

I assume you're missing a \newcommand before \mycommand and a [1] after it.

First of all, it should be, at least,

\newwrite\file
\newcommand\mycommand[1]{
  \immediate\openout\file=foobar.tex
  \immediate\write\file{
    foo
    bar
    #1
    blarg
  }
  \immediate\closeout\file
}

or every call to \mycommand would allocate a new output stream. Now, let's see how to cope with the newlines. As others have observed, ^^J is set as the \newlinechar in LaTeX, so we can use it. But, if you want that a write respects new lines also in calls such as

\mycommand{a
  b
  c}

you have to work harder. Here's a possibility, by changing the category code of ^^M:

%\newlinechar`^^J % LaTeX already does this
\newwrite\file
\def\mycommand{\begingroup\obeylines\mycommandaux}
\begingroup\obeylines
\gdef\mycommandaux#1{%
  \obeylines%
  \def^^M{^^J}%
  \immediate\openout\file=foobar.tex%
  \immediate\write\file{%
    foo
    bar
    #1
    blarg% <- no new line at the end
  }%
  \immediate\closeout\file%
  \endgroup%
}
\endgroup


\mycommand{a
b
c}

Here's the contents of foobar.tex

foo
bar
a
b
c
blarg

There is an obvious limitation: \mycommand cannot be an argument to another command.

  • "I assume..." D'oh! Sorry, I posted the question at 3 AM after a long day. Thanks for the answer: it's exactly what I was looking for. Every day I see more value to learning the TeX internals... – Joseph R. Jan 5 '14 at 15:23
15

You can use ^^J as follows

\mycommand{%
  \newwrite\file
  \immediate\openout\file=foobar.tex
  \immediate\write\file{%
    foo^^J%
    bar^^J%
    #1^^J%
    blarg^^J%
  }%
  \immediate\closeout\file%
}%
  • +1 This works and I have tried it already. Sorry I failed to mention this. The problem is when #1 itself has newlines. I'll update my question to reflect this info. – Joseph R. Jan 5 '14 at 11:21
  • Sorry, I had to accept egreg's answer as it does exactly what I want. My bad for failing to be more specific earlier. – Joseph R. Jan 5 '14 at 15:24
  • Is it also possible to write space using that way somehow? – koppor Apr 19 '17 at 0:28

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.