12

I am trying to print a number at the beginning of my document, say x. The problem is, that this number gets computed at a later part of my document, for example x = 2 + 3.

How do I use the result of this calculation at the beginning of my document? Commands like \tableofcontents are also able to do similar things by multiple compile-steps, so i think this should be possible, but I am stuck here. Do you have any advice?

15

enter image description here

as in classic tex, you can use the aux file

\documentclass{article}


\gdef\mynumber{0}% first time
\begin{document}

The number will be \mynumber.

\makeatletter
\immediate\write\@auxout{\gdef\string\mynumber{\directlua{
n=1+2+3
tex.print(n)}}}
\makeatother

\end{document}
7

Welcome to TeX.SX! Here is a LaTeX3 implementation. It is independent of the TeX engine (LuaTeX, pdfTeX, XeTeX...). Moreover, as for LaTeX references, you will be warned if the result has changed since the last compilation run (meaning you should recompile to get correct output). The arithmetic expression passed to \writeresult uses the \int_eval:n function described in interface3.pdf (cf. part titled The l3int package).

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\str_new:N \g_lemonbonbon_result_str
\str_new:N \g_lemonbonbon_previous_result_str

\msg_new:nnn { lemonbonbon } { additional-compilation-run-may-be-needed }
  { The~computed~result~has~changed;~another~compilation~run~may~be~needed. }

\cs_new_protected:Npn \lemonbonbon_write_result_to_aux_file:n #1
  {
    \cs_set_eq:cN { lemonbonbon@set@result } \relax % will not expand

    \iow_now:cx { @auxout }
      { \use:c { lemonbonbon@set@result } { \int_eval:n {#1} } }
  }

\NewDocumentCommand \writeresult { m }
  {
    \lemonbonbon_write_result_to_aux_file:n {#1}
  }

\NewDocumentCommand \useresult { }
  {
    \str_use:N \g_lemonbonbon_result_str
  }

\AtBeginDocument
  {
    % Save the previous result (this is run after the .aux file has been read)
    \str_gset_eq:NN \g_lemonbonbon_previous_result_str \g_lemonbonbon_result_str
  }

% Command run when the .aux file is reread, after the \AtEndDocument hook.
\cs_new_protected:Npn \lemonbonbon_warn_if_result_changed:n #1
  {
    \str_if_eq:VnF \g_lemonbonbon_previous_result_str {#1}
      {
        \msg_warning:nn { lemonbonbon }
                        { additional-compilation-run-may-be-needed }
      }
  }

% Reading the .aux file at end of document triggers comparison with the
% previous result in order to warn the user if it has changed.
\AtEndDocument
  {
    \cs_gset_eq:cN { lemonbonbon@set@result }
                   \lemonbonbon_warn_if_result_changed:n
  }

\makeatletter
% Command used in the .aux file (uses LaTeX2e naming conventions)
\NewDocumentCommand \lemonbonbon@set@result { m }
  {
    \str_gset:Nn \g_lemonbonbon_result_str {#1}
  }
\makeatother

\ExplSyntaxOff

\begin{document}
  The result is \useresult.

  \writeresult{3+4*(5-3)}
\end{document}

Output after two compilation runs:

Screenshot

  • 2
    oh no, green square trying to steal my tick by application of expl3 code, you are not by any chance related to @egreg are you? :-) – David Carlisle Jun 6 at 16:11
  • @DavidCarlisle Not to my knowledge. I'm just an insignificant apprentice ;-) – frougon Jun 6 at 16:14
  • Note that this could be extended to store an arbitrary number of (key, value) pairs. Not sure anyone cares, though... – frougon Jun 6 at 19:55

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.