Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Could not find anything in the TeXBook, but this could be just me.

I guess it is always possible to open the file for reading, copy its content to another file, and then continue writing to that file. Finally, you could escape to shell to remove the original file and rename the newly generated file to the file you have just created.

share|improve this question
4  
I've wondered about this, and concluded that the only way is as you say to read everything in. The TeX \openout primitive simply does not allow appending. (Of course, LuaTeX is a different case). –  Joseph Wright Feb 23 '11 at 7:37
    
@Joseph: if you write this as an answer, I could mark it is as correct, just to tidy this up and close that question. –  Yossi Gil Feb 24 '11 at 0:08
1  
Related question: "File copy without expansion" –  Martin Scharrer Mar 1 '11 at 17:00

3 Answers 3

up vote 8 down vote accepted

I agree with Joseph that TeX doesn't support appending to an existing file. However it is possible to read the existing content and write it together with the new content back to the file. This is of course much less efficient than simply appending content, but the only possible way in TeX.

The catchfile makes the reading of the existing content quite easy:

\documentclass{article}

\usepackage{catchfile}

\newwrite\appendwrite
\newcommand*\appendtofile[2]{%
    \begingroup
    \IfFileExists{#1}%
      {\CatchFileDef{\filecontent}{#1}{\endlinechar=`^^J\catcode\endlinechar=12\relax}}% keep existing end-of-lines
      {\let\filecontent\empty}%
    \immediate\openout\appendwrite=#1\relax
    \immediate\write\appendwrite{\filecontent #2}%
    \immediate\closeout\appendwrite
    \endgroup
}

\begin{document}

\appendtofile{\jobname.test}{First line}

First:\\\fbox{\input{\jobname.test}}

\appendtofile{\jobname.test}{Second line}

Second:\\\fbox{\input{\jobname.test}}

\end{document}

See also the answers to the question "File copy without expansion".

share|improve this answer

I've wondered about this, and concluded that the only way is as you say to read everything in. The TeX \openout primitive simply does not allow appending. (Of course, LuaTeX is a different case). If you are going to read everything in, the e-TeX \readline primitive might be useful, as it reads everything detokenized.

share|improve this answer

You could write what you want to append into a new file, and rewrite both files together at the end of the run. Something like the following.

\documentclass{minimal}
\newwrite\mywrite
\newcount\mycount

\makeatletter
\newcommand{\makeallother}{%
  \mycount0\relax
  \loop\ifnum\mycount<255\relax
  \catcode\mycount12\relax
  \advance\mycount by 1\relax
  \repeat
}
\newcommand*{\VerbatimFile}[2]{%
  \begingroup
  \newlinechar\endlinechar
  \makeallother
  \everyeof{\noexpand}%
  \immediate\openout\mywrite #1\relax
  \def\from##1{\immediate\write\mywrite{\@@input ##1 }}%
  #2\relax
  \immediate\closeout\mywrite
  \endgroup
}
\makeatother

\AtBeginDocument{\immediate\openout\mywrite\jobname.append\relax}
\AtEndDocument{%
  \immediate\closeout\mywrite
  \VerbatimFile{\jobname.output}{%
    \from{\jobname.tex}%
    \from{\jobname.append}%
  }%
}

\begin{document}

\newcommand{\test}[1]{\immediate\write\mywrite{#1}}
\test{abc}
\test{cde}

\end{document}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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