2

Is it possible to update global variables from within externalized tikz picture?

I would like for global modifiers(in this case \tl_gput_right:Nn) to outlast the scope of tikz picture.

Here is the MWE:

\documentclass{article}

\usepackage [utf8] {inputenc}
\usepackage {tikz}
\usepackage {xparse}

% Setup externalization.
\usetikzlibrary{external}
\tikzexternalize[prefix=images/]
\tikzset{png export/.style={external/system call/.add={}{; convert -density 300 "\image.pdf" "\image.png"}}}
\tikzset{png export}

% Declare global variable.
\ExplSyntaxOn
    \tl_clear_new:N \something
\ExplSyntaxOff

\begin {document}
    \ExplSyntaxOn

        % Draw a picture and update global variable.
        \begin{tikzpicture}
            \draw node {aaa};
            \tl_gput_right:Nn \something {AAA}
            \tl_log:N \something % Value is "AAA".
        \end{tikzpicture}

        % Print global variable afterwards.
        \tl_log:N \something % Value is "".

    \ExplSyntaxOff
\end {document}

I would like for last \tl_log:N to show value AAA just like it does if externalization part is commented-out.

  • 3
    The contents of the tikzpicture are executed in a separate document, so the main one has no “memory” of it. You'd probably need some auxiliary file which will keep the value of \something while the tikzpicture job is being executed and will be read back by the main job once that picture is finished. What exactly do you want to achieve? Perhaps knowing the goal someone might know a better option. – Phelype Oleinik May 15 '19 at 0:50
  • 1
    I am wondering about the same thing as @PhelypeOleinik and feel that your goal defeats the purpose of externalize. You may roughly think of externalize as "create a pdf in the first run and just include the pdf in the subsequent runs". Why would you want to define some new macro that gets broadcasted outside the externalized picture? – user121799 May 15 '19 at 0:58
  • I am writing a small simulator for my C++ library. The idea is to generate several similar pictures representing the work of the library. Each picture is drawn based on the current library state and the provided input. Input is provided through function arguments, but I wanted the internal state of the library(which changes while drawing a picture) to be updated while the picture is drawn and used by the next picture. It is possible to separate drawing from variable updates, but it would duplicate a lot of same if statements in both places. Hope this clears my intention. – Iskustvo May 15 '19 at 5:35
  • To be honest, it doesn't. You use externalize to "freeze" a tikzpicture. So why don't you just compile the first run without externalize, get all the dimensions out, and then externalize things? – user121799 May 15 '19 at 12:11
  • Sorry, can you explain how to do the 2-pass compilation in a bit more details? Just to clarify, I can't just calculate all and then draw. Every picture needs to draw some intermediate state. – Iskustvo May 15 '19 at 19:30
1

As Phelype Oleinik suggested in comment, I ended up writing the data from tikzpicture environment to external file and then reading it back when tikzpicture ended.

One way of doing it:

\documentclass{article}

\usepackage [utf8] {inputenc}
\usepackage {tikz}
\usepackage {xparse}

% Setup externalization.
\usetikzlibrary{external}
\tikzexternalize[prefix=images/]
\tikzset{png export/.style={external/system call/.add={}{; convert -density 300 "\image.pdf" "\image.png"}}}
\tikzset{png export}

% Declare global variables.
\ExplSyntaxOn
    % Streams for reading and writing to file.
    \iow_new:N \output_stream
    \ior_new:N \input_stream

    \tl_clear_new:N \something
\ExplSyntaxOff

\begin {document}
    \ExplSyntaxOn

        % Draw a picture and update global variable.
        \begin{tikzpicture}
            \draw node {aaa};
            \tl_gput_right:Nn \something {AAA}
            \tl_log:N \something % Value is "AAA".

            % Store data in file to use it outside of tikzpicture.
            \iow_open:Nn \output_stream {stored_data}
            \iow_now:Nx \output_stream {\something} % You can generate \iow_now:NV variant instead of \iow_now:Nx
            \iow_close:N \output_stream
        \end{tikzpicture}

        % Read stored data from file.
        \ior_open:Nn \input_stream {stored_data}
        \ior_get:NN \input_stream \something
        \ior_close:N \input_stream

        % Print global variable afterwards.
        \tl_log:N \something % Value is now "AAA".

    \ExplSyntaxOff
\end {document}

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.