Tikz Externalize:手动检查最新情况

Tikz Externalize:手动检查最新情况

我正在使用这个宏将我的 pgfplots 缩放到所需的大小:

\newsavebox{\measuredSize}
\newcounter{int}
\newcommand{\resizeToMeasure}[3]{%
    \pgfmathsetmacro{\pgfplotswidthtarget}{#2}%
    \pgfmathsetmacro{\pgfplotswidth}{#2}%
    \pgfmathsetmacro{\pgfplotsheighttarget}{#3}%
    \pgfmathsetmacro{\pgfplotsheight}{#3}%
    \setcounter{int}{1}%
    \loop%
    \addtocounter{int}{1}%
    \begin{lrbox}{\measuredSize}%
    \tikzset{external/export next=false,external/optimize=false}%
    \input{#1}%
    \end{lrbox}%
    \pgfmathsetmacro{\pgfplotswidth}{\pgfplotswidth+\pgfplotswidthtarget-\wd\measuredSize}%
    \pgfmathsetmacro{\pgfplotsheight}{\pgfplotsheight+\pgfplotsheighttarget-\ht\measuredSize}%
    \ifnum \value{int}<\nIter
    \repeat
    \filename@parse{#1}
    \tikzsetnextfilename{\filename@base}
    \input{#1}}

但是,在重新编译而不更改文件时,pgfplots我不想再次循环该文件,而只是使用库中创建的 pdf external。所以我认为手动检查该文件并在文件更新后省略循环是一个好主意。在库源代码中,我发现\def\tikzexternal@externalizefig@systemcall@uptodatecheck#1进行该检查并将其内容tikzpicture作为参数 #1。现在我的问题是,我找不到库如何读取 tikzpicture 并将其放入该函数中。

以下是 MWE:

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepackage{filecontents}
\usetikzlibrary{external}

\makeatletter
\newsavebox{\measuredSize}
\newcounter{int}
\newcommand{\resizeToMeasure}[3]{%
    \pgfmathsetmacro{\pgfplotswidthtarget}{#2}%
    \pgfmathsetmacro{\pgfplotswidth}{#2}%
    \pgfmathsetmacro{\pgfplotsheighttarget}{#3}%
    \pgfmathsetmacro{\pgfplotsheight}{#3}%
    \setcounter{int}{1}%
    \loop%
    \addtocounter{int}{1}%
    \begin{lrbox}{\measuredSize}%
    \tikzset{external/export next=false,external/optimize=false}%
    \input{#1}%
    \end{lrbox}%
    \pgfmathsetmacro{\pgfplotswidth}{\pgfplotswidth+\pgfplotswidthtarget-\wd\measuredSize}%
    \pgfmathsetmacro{\pgfplotsheight}{\pgfplotsheight+\pgfplotsheighttarget-\ht\measuredSize}%
    \ifnum \value{int}<5
    \repeat
    \filename@parse{#1}
    \tikzsetnextfilename{\filename@base}
    \input{#1}}
\makeatother

\begin{document}

\begin{filecontents*}{tikzpicture01.tikz}
\begin{tikzpicture}
\begin{axis}[
height=\pgfplotsheight,
width=\pgfplotswidth
]
\addplot coordinates {
    ( 1.5, 1.28 )
    ( 1.75, 1.43 )
    ( 2.0, 1.59 )
    ( 2.25, 1.75 )
    ( 2.5, 1.91 )
    ( 2.75, 2.07 )
    ( 3.0, 2.23 )
};
\end{axis}
\end{tikzpicture}
\end{filecontents*}

\resizeToMeasure{tikzpicture01.tikz}{7cm}{7cm}

\end{document}

答案1

好的,我找到了一个解决方案,可以进行手动最新检查。不幸的是,我找不到使用库中的内部宏的方法external,因此我编写了自己的宏\make@uptodate@check,它与包中使用的宏非常相似。

    \def\make@uptodate@check#1{
    \def\scanText{}%
    \def\name@tikzpicture{tikzpicture}%
    \CatchFileDef{\myTikz}{#1}{}%
    \long\def\collect@tikz@from@begin##1\begin##2{%
        \def\name@environment@begin{##2}%
        \ifx\name@environment@begin\name@tikzpicture%
            \expandafter\collect@tikz@after@begin%
        \else%
            \expandafter\collect@tikz@from@begin%
        \fi%
    }
    \long\def\collect@tikz@after@begin##1\end##2{%
        \def\name@environment@end{##2}%
        \ifx\name@tikzpicture\name@environment@end%
            \g@addto@macro\scanText{##1}
        \else%
            \g@addto@macro\scanText{##1\end{##2}}%
            \expandafter\collect@tikz@after@begin%
        \fi%
    }
    \expandafter\collect@tikz@from@begin\myTikz
    \filename@parse{#1}%
    \tikzsetnextfilename{\filename@base}%
    \expandafter\tikzexternal@check@uptodate@mode\expandafter{\scanText}%
    }

为了检查图片是否需要更新,它从环境中提取内容tikzpicture并将其传递\tikzexternal@check@uptodate@modeexternal库,该库也会更新\tikzexternal@file@isuptodate。然后resizeToMeasure检查文件是否是最新的,以跳过 for 循环并直接插入 pdf 文件。

以下是完整的 MWE:

    \documentclass{article}
    \usepackage{tikz}
    \usepackage{catchfile}
    \usepackage{pgfplots}
    \usetikzlibrary{external} %
    \tikzexternalize
    
    \makeatletter
    \def\make@uptodate@check#1{
        \def\scanText{}%
        \def\name@tikzpicture{tikzpicture}%
        \CatchFileDef{\myTikz}{#1}{}%
        \long\def\collect@tikz@from@begin##1\begin##2{%
            \def\name@environment@begin{##2}%
            \ifx\name@environment@begin\name@tikzpicture%
                \expandafter\collect@tikz@after@begin%
            \else%
                \expandafter\collect@tikz@from@begin%
            \fi%
        }
        \long\def\collect@tikz@after@begin##1\end##2{%
            \def\name@environment@end{##2}%
            \ifx\name@tikzpicture\name@environment@end%
                \g@addto@macro\scanText{##1}
            \else%
                \g@addto@macro\scanText{##1\end{##2}}%
                \expandafter\collect@tikz@after@begin%
            \fi%
        }
        \expandafter\collect@tikz@from@begin\myTikz
        \filename@parse{#1}%
        \def\tikzexternal@curfilename{\tikzexternal@filenameprefix\filename@base}%
    \expandafter\tikzexternal@check@uptodate@mode\expandafter{\scanText}%
    }
    
    \def\pgfmathsetglobalmacro#1#2{\pgfmathparse{#2}%
    \global\let#1\pgfmathresult}
    
    \newsavebox{\measuredSize}
    \newcounter{int}
    \newcommand{\resizeToMeasure}[3]{%
    \pgfmathsetglobalmacro{\pgfplotswidthtarget}{#2}%
             \pgfmathsetglobalmacro{\pgfplotswidth}{#2}%
             \pgfmathsetglobalmacro{\pgfplotsheighttarget}{#3}%
             \pgfmathsetglobalmacro{\pgfplotsheight}{#3}%
        \make@uptodate@check{#1}%
        \filename@parse{#1}%
        \iftikzexternal@file@isuptodate%
            \typeout{File is up to date! No loop needed!}%
            \tikzsetnextfilename{\filename@base}
            \input{#1}%
        \else%
            \typeout{Update File!}%
             \setcounter{int}{1}
             \loop
             \typeout{1}
             \addtocounter{int}{1}
             \begin{lrbox}{\measuredSize}\tikzset{external/export next=false,external/optimize=false}\input{#1}\end{lrbox}%
             \typeout{2}
             \pgfmathsetglobalmacro{\pgfplotswidth}{\pgfplotswidth+\pgfplotswidthtarget-\wd\measuredSize}%
             \pgfmathsetglobalmacro{\pgfplotsheight}{\pgfplotsheight+\pgfplotsheighttarget-\ht\measuredSize}%
             \typeout{3}
             \ifnum \value{int}<3%
             \repeat%
             \tikzset{external/force remake}
             \tikzsetnextfilename{\filename@base}
             \input{#1}%
         \fi%
    }
    
    \makeatother
    \begin{document}
    
    \begin{filecontents*}{tikzpicture01.tikz}
    \begin{tikzpicture}
    \begin{axis}[
    height=\pgfplotsheight,
    width=\pgfplotswidth
    ]
    \addplot coordinates {
        ( 1.5, 1.28 )
        ( 1.75, 1.43 )
        ( 2.0, 1.59 )
        ( 2.25, 1.75 )
        ( 2.5, 1.91 )
        ( 2.75, 2.07 )
        ( 3.0, 2.23 )
    };
    \end{axis}
    \end{tikzpicture}
    \end{filecontents*}
    
    \resizeToMeasure{tikzpicture01.tikz}{7cm}{7cm}
    
    \end{document}

相关内容