9

I was wondering how to write a LaTeX3 variable to an aux file and read it in at the very beginning of a document. The motivation of this problem is that I would like to get rid of my LaTeX2 counters and implement them via LaTeX3 variables. A LaTeX2 counter I can write out as follows

\AtEndDocument{%
  \immediate\write\@auxout{%
    \string\setcounter{foo}{\number\value{bar}}}
}

But something similar

\AtEndDocument{%
  \immediate\write\@auxout{\string\int_set:Nn\l__foo{\l__bar}}
}

does not work.

Is there something similar defined for LaTeX3? Or is this already to early to ask for?

  • The problem is in the category codes; only @ is made into a letter when the aux file is being read. – egreg Mar 11 '16 at 14:26
7

Let's assume you have two integer variables \g_maxmaier_foo_int and \l_maxmaier_bar_int and that, at end document, you want to save the setting

\int_gset:Nn \g_maxmaier_foo_int { \int_eval:n { \l_maxmaier_bar_int } }

in the aux file, so that the value of the foo variable is set at the beginning of the next run.

You have to surround this in \ExplSyntaxOn and \ExplSyntaxOff, otherwise the commands would not be interpreted correctly. Note also that the setting to the foo variable must be global, because the aux file is read inside a group.

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\int_new:N \g_maxmaier_foo_int
\int_new:N \l_maxmaier_bar_int

\NewDocumentCommand{\setbar}{m}
 {
  \int_set:Nn \l_maxmaier_bar_int { #1 }
 }
\NewDocumentCommand{\showfoo}{}
 {
  \int_to_arabic:n { \g_maxmaier_foo_int }
 }

\AtEndDocument
 {
  \iow_now:cx { @auxout }
   {
    \token_to_str:N \ExplSyntaxOn
    ^^J
    \int_gset:Nn \g_maxmaier_foo_int { \int_eval:n { \l_maxmaier_bar_int } }
    ^^J
    \token_to_str:N \ExplSyntaxOff
   }
 }
\ExplSyntaxOff

\begin{document}

The value of \texttt{foo} is \showfoo

\setbar{42}

\end{document}

enter image description here

Contents of the aux file

\relax 
\ExplSyntaxOn
\int_gset:Nn \g_maxmaier_foo_int {42}
\ExplSyntaxOff

Some comments.

  1. Adding \int_eval:n (or its synonym \int_use:n) is essential, otherwise LaTeX would write

    \int_gset:Nn \g_maxmaier_foo_int { \l_maxmaier_bar_int }
    

    which would be completely useless, because it would assign the value of \l_maxmaier_bar_int current at execution time, that is, when the .aux file is being read; we want instead to fix the value of the variable at writing time (in the previous LaTeX run).

  2. For the same reason above, it's important to use \iow_now:cx (a variant for \iow_now:Nx) so its argument is fully expanded at writing time.

  3. The token ^^J makes a new line when a list of tokens is written in the .aux file. It's the analog of \n in other programming languages.

  • I've been playing around with your solution and have a couple of questions. 1) Why do you make use of int_eval:n while setting the variable in the aux file instead of int_use:N? Wouldn't it be enough to write \int_gset:Nn \g_maxmaier_foo_int { \l_maxmaier_bar_int } }? According to source3.pdf if an integer is expected one can omit \int_use:N. Therefore my conclusion was to omit the eval, too. 2) What are the tokens '^^J` for? Thank you very much for your solution so far! – Max Maier Mar 14 '16 at 8:04
  • @MaxMaier I added a final comment; let me know if you have other doubts. – egreg Mar 14 '16 at 8:51
1

I don't recommend replacing LaTeX2e counters with \int... variables (although they are \count registers anyway) since this needs \ExplSyntaxOn ... in the .aux file already.

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\int_new:N \l_foo_int

\int_new:N \l_bar_int
\int_set:Nn \l_bar_int {100}


\begin{document}
The~value~of~foo~is~\int_use:N \l_foo_int
\makeatletter
\immediate\write\@auxout{\string\int_set:Nn \l_foo_int\expandafter{\int_use:N \l_bar_int}}
\makeatother




\end{document}
  • I haven't thought about putting ExplSyntaxOn/Off into the aux file. Does this have any side effects if I put it only around my commands and nothing else? – Max Maier Mar 12 '16 at 8:22
  • @MaxMaier: If you don't write ExplSyntaxOn/Off into the .aux file LaTeX2 will not understand your code, that's the backdraw! – user31729 Mar 12 '16 at 9:30

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.