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.

I have a macro \Content wich contains several occurence of a macro \comm. The latter increases a counter a displays the value of the counter. Calling \Content gives the correct output. But i want to write this \Content into a file, and i encounter a problem. I guess, this is because \write does not like \stepcounter. I would like to understand why, and to find a workaround.

\documentclass{article}     
\begin{document}

\newcounter{myCounter}

\newcommand{\comm}{%
    \stepcounter{myCounter}%
    var\arabic{myCounter} %
}
\def\Content{text \comm text \comm text \comm}

\Content %%%% This works

\newwrite\tempfile
\immediate\openout\tempfile=counter.txt
\immediate\write\tempfile{\Content}
\immediate\closeout\tempfile

\end{document}

PS : by the way, the error message is Missing \endcsname inserted. which i don'T really understand...

EDIT1 I formulate more precisely my question : the macro \Content is given, and i dont' want to modify it. I just know that it contains many occurences of \comm. And i want to write the content of \COntent into a file, but replacing each \comm by something like var1, var2 which increases with some counter.

share|improve this question
add comment

2 Answers

up vote 6 down vote accepted

\write is an expansion context like \edef so only expansion happens, no assignments, so no \def or counter assignments. You need to increment the counter before the write.

If (as noted in the comments) you really want to use expansion then you can't use \advance (or equivalently) \stepcounter but you could do:

\documentclass{article}     
\begin{document}

\newcounter{myCounter}

\def\Content{text \comm text \comm text \comm}

\newwrite\tempfile
\immediate\openout\tempfile=counter.txt
{%
\def\comm#1\expandcomm#2{var#2 #1\expandcomm}
\def\expandcomm#1\relax{}
\immediate\write\tempfile{\Content\expandcomm123456789\relax}%
}%
\immediate\closeout\tempfile

\end{document}

which writes:

text var1 text var2 text var3 
share|improve this answer
    
yes, ok, i understand this. But i can't see any way of expanding first completely \Content ( and therefore let the counter increase), and then write the result of this expansion into a file... On the other hand, i was always convinced of "with LaTeX, nothing is impossible" ... –  nicolas roy Jun 11 '12 at 8:09
    
You can't make the counter increase by expanding \Content You have to evaluate the assignments which happens "in the stomach" in the terminology of the TeXBook. So you have to do the assignments first save the tokens of each of the three values, and then build the content from that. In other words, do what @egreg says. –  David Carlisle Jun 11 '12 at 8:31
    
I can't do what @egreg says, because \Content is given to me in a tex file. I can only implement something in a documentclass and compile the tex-file with this class, but not modify \Content per hand. :( –  nicolas roy Jun 11 '12 at 8:45
    
well why do you need to increment \comm as the file is written? (which you can't do) rather than after you read it back? –  David Carlisle Jun 11 '12 at 8:55
    
I'm not sure whether i understood your question, but the output file is not intended to be read by TeX anymore. It is something like an XML file, if you want. Stupid question : is there an option of pdfLatex, which allows to produce a pure text file, instead of a pdf ? –  nicolas roy Jun 11 '12 at 9:00
show 2 more comments

Here's how one can do it in Plain TeX. It shouldn't be difficult to turn it into LaTeX.

\newcount\roycount

\def\writecontent{\buildcontent\immediate\write\tempfile{\commcontent}}
\def\buildcontent{\def\commcontent{\gobble}\step{text}{var}\step{text}{var}\step{text}{var}}
\def\step#1#2{\advance\roycount 1
  \edef\commcontent{\commcontent\space#1\space#2\number\roycount}}
\def\gobble#1{}

\newwrite\tempfile
\immediate\openout\tempfile=\jobname.out

\writecontent
\writecontent

\immediate\closeout\tempfile

\bye

As you see the string to write is build before the write (where assignments can't be performed).

The written file is

text var1 text var2 text var3
text var4 text var5 text var6
share|improve this answer
    
I don't see how i can easily adapt your solution to my problem, because in my case, \Content is defined somewhere else, and i have no control on it. I just know that it contains many occurences of some command \comm, which i want to redefine, in order to have this counter effect in the file. I don't know if i am clear... I edited the question. –  nicolas roy Jun 8 '12 at 21:35
1  
@nicolasroy You can't. Your \Content command contains instructions to generate the numbers, while \write needs the already generated numbers: it can't perform computations, only macro expansion. –  egreg Jun 8 '12 at 21:48
1  
@nicolasroy Note that adding any number of \expandafter won't cause the assignments to be performed: the primitive \advance, which \stepcounter ultimately relies on, is not expandable. –  egreg Jun 9 '12 at 9:59
1  
Thanks for the explanation. For me, it's hard to accept, that there is no way to perform what i wanted. What is the fundamental reason, why we don't have any version of def/edef which expands completely and also executes assignements ? –  nicolas roy Jun 11 '12 at 6:12
    
@nicolasroy Why? Because that's the way it is: macro expansion and assignments are performed at two distinct levels in TeX, so you can't have both at the same time. –  egreg Jun 11 '12 at 6:55
show 1 more comment

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.