4

I want to save the value of a particular key (from pgfkeys) into the aux file for my LaTeX document. If it matters, I'm using LuaLaTeX, but the same problem is exhibited by XeLaTeX, pdfLaTeX, and the original LaTeX (producing dvi -> ps -> pdf).

Here is a minimal (non-)working example:

\documentclass{standalone}
\usepackage{pgfkeys}
\pgfkeys{/test key/.initial=0}
\begin{document}
\pgfkeysvalueof{/test key}
\makeatletter\protected@write\@auxout{}{\protect\pgfkeys{/test key=2}}\makeatother
\pgfkeysvalueof{/test key}
\end{document}

The resulting aux file shows that the write was successful:

\relax 
\pgfkeys {/test key=2}

However, no matter how many times I run (Lua|Xe|pdf|)LaTeX, the displayed values are "0" and "0"; I am trying to make them (after at least two runs) display "2" and "2".

How can I get my intended results? I would really like to stick with pgfkeys if at all possible; am I just going about this the wrong way?

3

First, let's look at latex.ltx and how it reads the .aux file. For that, we look at how \document is defined in the LaTeX kernel:

\def\document{%
  ...
  \begingroup\@floatplacement\@dblfloatplacement
    \makeatletter\let\@writefile\@gobbletwo
    \global \let \@multiplelabels \relax
    \@input{\jobname.aux}% Reading of the .aux file
  \endgroup
  \if@filesw
    \immediate\openout\@mainaux\jobname.aux
    \immediate\write\@mainaux{\relax}%
  \fi
  ...

Note how the .aux file is read within a \begingroup...\endgroup scope.

Second, since keys set through \pgfkeys as local by default, you have to find a means to make them global, or at least survive the current scope.

One possible way is to set the keys written to the .aux using the hook \@begindocumenthook:

\makeatletter
\protected@write\@auxout{}{%
  \protect\providecommand\protect\@begindocumenthook{}% Make sure \@begindocumenthook is defined
  \protect\g@addto@macro\protect\@begindocumenthook{\protect\pgfkeys{/test key=2}}
}
\makeatother

or perhaps \AfterGroup (from etextools):

\makeatletter
\protected@write\@auxout{}{%
  \protect\AfterGroup{\protect\pgfkeys{/test key=2}}
}
\makeatother

The former approach is similar to issuing \AtBeginDocument{\pgfkeys{..}} that ensures the key setting is local to the document environment. The latter ensures the same.

  • Thank you so much! This is much cleaner than just making everything implicitly global. – Ptharien's Flame Dec 26 '15 at 9:26
2

I found the related question Is there a way to set a *global* key value using `pgfkeys`?; the following works perfectly, both for the MWE and for my actual use case:

\documentclass{standalone}
\usepackage{pgfkeys}
\pgfkeys{/test key/.initial=0}
\begin{document}
\pgfkeysvalueof{/test key}
\makeatletter\protected@write\@auxout{}{{\globaldefs=1\relax\protect\pgfkeys{/test key=2}}}\makeatother
\pgfkeysvalueof{/test key}
\end{document}

I'd still be very interested in more elegant solutions, however.

2

You can exploit the fact that the .aux file is read in before the tokens saved with \AtBeginDocument are executed.

\documentclass[border=4]{standalone}
\usepackage{pgfkeys}
\pgfkeys{/test key/.initial=0}

\makeatletter
% at first reading, set the keys at begin document
\newcommand{\pgfkeysinaux}[1]{%
  \AtBeginDocument{\pgfkeys{#1}}%
}
% at end document the command should do nothing
\AtEndDocument{\let\pgfkeysinaux\@gobble}
% a handier interface for writing to the aux file
\newcommand{\writepgfkeys}[1]{%
  \write\@auxout{\unexpanded{\pgfkeysinaux{#1}}}%
}
\makeatother

\begin{document}
\pgfkeysvalueof{/test key}

\writepgfkeys{/test key=2}

\pgfkeysvalueof{/test key}
\end{document}

enter image description here

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.