3 of 8
added 181 characters in body
Phelype Oleinik
  • 70.5k
  • 19
  • 150
  • 227

The LaTeX kernel provides the filecontents environment to write to external files without having to worry about catcodes and such. The filecontents package does minimal changes to this environment allowing it to be used anywhere in the document (LaTeX's version can only be used in the preamble, for some reason; and allowing it to overwrite existing files, which is also disabled in LaTeX's version.

To produce

To be or not to be,
that is % the question

you use:

\documentclass{article}
\usepackage{filecontents}
\begin{document}
\begin{filecontents*}{tmp.txt}
To be or not to be,
that is % the question
\end{filecontents*}
\end{document}

The starred version (filecontents*) omits the heading that is printed in the standard version of the environment:

%% LaTeX2e file `tmp.txt'
%% generated by the `filecontents' environment
%% from source `test' on 2018/11/20.
%%
To be or not to be,
that is % the question

An addendum on my (admittedly lazy) answer:

If you should want to persist on reinventing the wheel (which is much more fun, I must admit), then you can create a command to take care of the \catcodeing for you. Here I provide an ad hoc implementation of a \verbwrite command which does the job for you.

The command syntax is somewhat like LaTeX's \verb: you can use either as \verbwrite\file{<stuff>} or \verbwrite\file|<stuff>|. For the latter syntax, any character other than { can be used to delimit the contents. This character, obviously, can't appear in <stuff>. The advantage of the second syntax is that you don't have any restriction in balancing { and } inside the contents of the command.

\documentclass{article}

\makeatletter
\def\verbwrite#1{%
  \begingroup
    \verbwrite@grab{#1}%
}
\def\verbwrite@grab#1{%
    \catcode`\^^M=13
    \newlinechar`\^^M
    \@ifnextchar\bgroup
      {%
        \let\do\@makeother \dospecials
        \catcode`{=1
        \catcode`}=2
        \verbwrite@brace{#1}
      }%
      {%
        \let\do\@makeother \dospecials
        \verbwrite@other{#1}
      }%
}
\def\verbwrite@brace#1#2{%
    \immediate\write#1{\unexpanded{#2}}%
  \endgroup
}
\def\verbwrite@other#1#2{%
  \def\verbwrite@delim##1##2#2{%
    \immediate\write##1{\unexpanded{##2}}%
    \endgroup
  }%
  \verbwrite@delim#1%
}
\makeatother

\begin{document}
\newwrite\file
\immediate\openout\file=tmp.txt
\verbwrite\file{To be or not to be,
that is % the question}
\verbwrite\file|To be or not to be,
that is } the {question|
\verbwrite\file=être ou ne pas être,
вот в чем вопрос=
\closeout\file
\end{document}

Please beware that I took 38 minutes to write this command, so it is certainly not what you can call robust. Proceed with care :)

Fix: Prevent expansion of the text using ε-TeX's \unexpanded (thanks to jfbu :)

Phelype Oleinik
  • 70.5k
  • 19
  • 150
  • 227