# Edit for clarification:

I have a counter whose value I want to write to an aux file. The counter will later be used very dynamically so it has to be read back on subsequent runs or recalculated depending on the need.

The main aim of this question is to figure out how to simply write a counter which gets incremented in a macro to a file.

========

When I run the following MWE the \writeVerse command rightly displays the value of this counter in the PDF output, yet it also adds a bunch of code when I write that counter to a file. Why is this happening?

\documentclass[pagesize=pdftex, fontsize=10]{scrbook}

\newcounter{countVerse}

\newcommand{\writeVerse}{%
\stepcounter{countVerse}%
\thecountVerse%
}

% Write the position to file.
\def\msec@write@lines#1#2{%
\pdfsavepos%
\write\yposoutputfile{%
\string{#1\string}%
\string{#2\string}%
}%
}

\begin{document}
\newwrite\yposoutputfile%
\openout\yposoutputfile=\jobname.ypos.txt%

\writeVerse %this works
\msec@write@lines{1}{F}~Some test text for the first verse.
\msec@write@lines{\writeVerse}{F}~And some more text for the second verse. %this doesn't work EDIT: Added second variable {F}

\closeout\yposoutputfile%
\end{document}


produces this in the output file where the parts in bold should not be present:

{1}{F} {\global \advance \c@countVerse \@ne \relax \begingroup \let \@elt \global \c@ \csname\endcsname\z@ cl@countVerse\endcsname \endgroup 1}{\nobreakspace {}}

-
I think we might need to know what the wider plan is here to give more help, but the immediate issue is that \write carries out expansion and \writeVerse is not expandable. Try \msec@write@lines{\noexpand\writeVerse} to fix this (or at least to avoid the error: not sure what you want!). –  Joseph Wright Feb 13 '13 at 16:10
@JosephWright Thanks, but your solution produces {1}{F} {\writeVerse }{F} in the output file. Please see question for clarification. –  McGafter Feb 14 '13 at 10:35
add comment

## 1 Answer

You can't execute arithmetic computations during a write operation, so you need to do it before writing.

\documentclass{scrbook}

\newcounter{countVerse}

\makeatletter
% Write the position to file.
\newcommand\writelines[2][]{%
\if!#1!%
\stepcounter{countVerse}%
\msec@write@lines{\thecountVerse}{#2}%
\else
\msec@write@lines{#1}{#2}%
\fi
}
\def\msec@write@lines#1#2{%
\pdfsavepos
\write\yposoutputfile{%
\string{#1\string}%
\string{#2\string}%
}%
}
\makeatother

\begin{document}
\newwrite\yposoutputfile
\openout\yposoutputfile=\jobname.ypos.txt

\writelines[1]{F}~Some test text for the \emph{first} verse.

\writelines{F}~And some more text for the second verse.

\closeout\yposoutputfile
\end{document}


Of course this doesn't write the positions, for which you have to use \the\pdflastxpos and \the\pdflastypos.

It's up to you that the mandatory argument to \writelines contains only safe tokens for a \write; if it can contain arbitrary text, change the line with \write into

\protected@write\yposoutputfile{}{%


Note also that macros with @ in their name should be defined and used (explicitly) only between \makeatletter and \makeatother

-
Great this seems to solve the problem. I was not aware of the @ convention. Thanks. The pdflastxpos code was removed for the MWE. –  McGafter Feb 14 '13 at 11:01
@egreg You can do calculations: what you can't do is store the results in a count(er). –  Joseph Wright Feb 14 '13 at 11:31
@JosephWright Yes, with \numexpr; I was referring to \stepcounter which is not performed (correctly) in a \write. –  egreg Feb 14 '13 at 11:33
@egreg Yes, I understood that but thought it might be worth tightening up the answer to be clear on this for the less-experienced –  Joseph Wright Feb 14 '13 at 11:34
add comment