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?

1
  • Welcome to TeX.SX! Could you already share a minimal working example (MWE) with what you have so far? So do you already have code that calculates something in Lua. Because up to now it is not totally clear how and where the calculation is happening/should happen. Jun 6, 2019 at 14:19

2 Answers 2

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

3
  • 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? :-) Jun 6, 2019 at 16:11
  • @DavidCarlisle Not to my knowledge. I'm just an insignificant apprentice ;-)
    – frougon
    Jun 6, 2019 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, 2019 at 19:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .