编辑

编辑

我使用 tikzexternalize 来保存不同的 tikz 图像,如果我让 tikz 命名图片或者我需要为下一张图片命名,我都没有问题。

\documentclass{article}

\usepackage{tikz}

\usetikzlibrary{external}

\tikzexternalize[prefix=figures-tikz/]

\begin{document}

%\tikzsetnextfilename{circle}
\begin{tikzpicture}
  \draw (0,0) circle [radius=1];
\end{tikzpicture}
\end{document}

由于我包含许多文件,我希望可以使用包含的文件名而不是源文件名来命名图片。

我使用 currfile 包来检索导入文件当前的名称,并使用以下配置:

\documentclass{article}

\usepackage{tikz}

\usepackage{currfile}
\usetikzlibrary{external}

\tikzexternalize[prefix=figures-tikz/]
\tikzsetfigurename{\currfilename-}

\begin{document}

\begin{tikzpicture}
  \draw (0,0) circle [radius=1];
\end{tikzpicture}
\end{document}

此配置不适用于我的电脑(Windows 10、miketx2.9、texworks 0.61、xelatex 或 pdflatex)

当然我像图片一样配置了texworks(我对shell-escape或write18有问题)

在此处输入图片描述

答案1

为了实现此功能,图片代码必须位于外部文件中。否则,文件名与主文件的名称相同,则无法正常工作。

.tex您可以通过使用filecontents环境预先创建此类文件,以便代码位于主文件中\documentclass

\begin{filecontents}{myfig.tex}
\begin{tikzpicture}
  \draw (0,0) circle [radius=1];
\end{tikzpicture}
\end{filecontents}

然而,我发现这在工作流程中很烦人,并且只将它用于 MWE。

下一个问题是\currentfilename包含.tex扩展名,这充其量是令人困惑的。 更好\currentfilebase。 但这需要在设置图形名称时进行扩展。

\expandafter\tikzsetfigurename\expandafter{\currfilebase-}

但是,如果我们只是在前言中这样做,那么名称将被设置为主文档的名称,.tex并且不起作用。所以我们需要在外部文件内部使用图片的代码来执行此操作。为了方便,我们可以定义一个包装器宏。

\newcommand*\setmyname{%\
  \expandafter\tikzsetfigurename\expandafter{\currfilebase-}%
}

现在我们可以\setmyname在外部文件中的每张图片之前使用它。但如果不必这样做会更方便。

如果你所有的 TiZ 图片位于外部文件中,并且不会包含在内,tikzpicture然后您可以使用将设置添加到环境中etoolbox

\AtBeginEnvironment{tikzpicture}{\setmyname}

然而,如果你定义了任何 Ti,则不能这样做主文件中内联的 Z 图片

绘制圆形的完整代码:

\begin{filecontents}{myfig.tex}
\begin{tikzpicture}
  \draw (0,0) circle [radius=1];
\end{tikzpicture}
\end{filecontents}

\documentclass{article}
\usepackage{tikz}
\usepackage{currfile}
\usepackage{etoolbox}
\usetikzlibrary{external}
\tikzexternalize[prefix=ffigurau/]
\newcommand*\setmyname{%\
  \expandafter\tikzsetfigurename\expandafter{\currfilebase-}%
}
\AtBeginEnvironment{tikzpicture}{\setmyname}
\begin{document}
\input{myfig}
\end{document}

编辑

此版本取消了所有外部化图像必须位于外部文件的要求。然而,document外部文件中的外部化图像仅当被包装在环境中时才会根据文件名命名。 此外,每个外部文件必须包含\documentclass。这些情况是由于代码通过修改standalone的修改document环境来限制命名更改的效果而导致的。

由于代码使用了standalone,如果需要,外部图像文件还可以包含完整的前导码,这便于在开发过程中单独编译它们。但是,完整的前导码不是必需的。例如,如果前导码未加载而只是在 之前tikz有 ,那就没关系了。(显然,这样的文件不会自行编译,但可以包含在主文件中。)\documentclass{article}\begin{document}.tex

这依赖于 PGF/Ti 第 611 页所示的分组效应Z 手册。

\begin{filecontents}{myfig.tex}
\documentclass[tikz]{standalone}% or article of something, if preferred
\begin{document}
\begin{tikzpicture}
  \filldraw [magenta] (0,0) circle [radius=1];
\end{tikzpicture}
\end{document}
\end{filecontents}
\begin{filecontents}{myfig2.tex}
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
  \filldraw [blue] (0,0) circle (1);
\end{tikzpicture}
\end{document}
\end{filecontents}

\documentclass{article}
\usepackage{standalone}
\usepackage{tikz}
\usepackage{currfile}
\usepackage{etoolbox}
\usetikzlibrary{external}
\tikzexternalize[prefix=ffigurau/]
\tikzsetfigurename{figure-}
\newcommand*\setmyname{%
  \expandafter\tikzsetfigurename\expandafter{\currfilebase-}%
}
\makeatletter
\apptocmd{\sa@document}{\setmyname}{\typeout{Append to document: OK!}}{\typeout{Append to document: Oh, no!}}
\makeatother
\begin{document}
\begin{tikzpicture}
  \draw [green] (0,0) -- (1,0);
\end{tikzpicture}
\input{myfig}
\begin{tikzpicture}
  \draw [red] (0,0) -- (1,0);
\end{tikzpicture}
\input{myfig2}
\end{document}

这将生成ffigurau/如下的图像:figure-0figure-1和。也就是说,两个内联图片获得名称,而外部文件中的两个myfig-0图片也相应地命名。myfig2-0figure-

如果外部文件包含多幅图像,则可以检查它是否正常工作。

\begin{filecontents}{myfig.tex}
\documentclass[tikz]{article}
\begin{document}
\begin{tikzpicture}
  \filldraw [magenta] (0,0) circle (1);
\end{tikzpicture}
\end{document}
\end{filecontents}
\begin{filecontents}{myfig2.tex}
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
  \filldraw [inner color=magenta, outer color=blue] (0,0) circle (1);
\end{tikzpicture}
\begin{tikzpicture}
  \filldraw [inner color=blue, outer color=magenta] (0,0) circle (1);
\end{tikzpicture}
\end{document}
\end{filecontents}
\begin{filecontents}{myfig3.tex}
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
  \filldraw [blue] (0,0) circle (1);
\end{tikzpicture}
\end{document}
\end{filecontents}

\documentclass{article}
\usepackage{standalone}
\usepackage{tikz}
\usepackage{currfile}
\usepackage{etoolbox}
\usetikzlibrary{external}
\tikzexternalize[prefix=ffigurau/]
\tikzsetfigurename{figure-}
\newcommand*\setmyname{%
  \expandafter\tikzsetfigurename\expandafter{\currfilebase-}%
}
\makeatletter
\apptocmd{\sa@document}{\setmyname}{\typeout{Append to document: OK!}}{\typeout{Append to document: Oh, no!}}
\makeatother
\begin{document}
\input{myfig}
\begin{tikzpicture}
  \draw [green] (0,0) -- (1,0);
\end{tikzpicture}
\input{myfig2}
\begin{tikzpicture}
  \draw [red] (0,0) -- (1,0);
\end{tikzpicture}
\input{myfig3}
\end{document}

正如预期的那样,这将生成ffigurau/如下图像:figure-0figure-1myfig-0,和。myfig2-0myfig2-1myfig3-0

编辑 编辑

此版本使用expl3、 以及和。它受以下版本的相同条件约束standaloneetoolboxcurrfile编辑即,外部文件中的所有外部化图像都必须包含\documentclass环境document

但是,与以前的版本不同,这个版本允许您以标准方式覆盖下一个外部化图像的名称。

为了做到这一点,它修改了一个 TiZ 用户命令 ( \tikzsetnextfilename) 和一个内部 TiZ 宏(\tikzexternal@getnextfilename@resetglobals),以及standalone的替代品document。这意味着更新有更多方法可以破坏代码。代码会在控制台和文件中生成警告,.log提醒用户内容已被修改或尚未修改。

\begin{filecontents}{myfig.tex}
\documentclass[tikz]{article}
\begin{document}
\begin{tikzpicture}
  \filldraw [magenta] (0,0) circle (1);
\end{tikzpicture}
\end{document}
\end{filecontents}
\begin{filecontents}{myfig2.tex}
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
  \filldraw [inner color=magenta, outer color=blue] (0,0) circle (1);
\end{tikzpicture}
\begin{tikzpicture}
  \filldraw [inner color=blue, outer color=magenta] (0,0) circle (1);
\end{tikzpicture}
\end{document}
\end{filecontents}
\begin{filecontents}{myfig3.tex}
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
  \filldraw [blue] (0,0) circle (1);
\end{tikzpicture}
\end{document}
\end{filecontents}

\documentclass{article}
\usepackage{standalone}
\usepackage{tikz}
\usepackage{currfile}
\usepackage{etoolbox}
\usepackage{xparse}
\usetikzlibrary{external}
\tikzexternalize[prefix=ffigurau/]
\tikzsetfigurename{figure-}
\ExplSyntaxOn
\tl_new:N \g_enext_figurename_tl
\cs_new_protected_nopar:Nn \enext_settofilename:
{
  \enext_tikzsetfigurename:x { \currfilebase- }
}
\cs_new_protected_nopar:Nn \enext_tikzsetfigurename:n
{
  \tikzsetfigurename { #1 }
}
\cs_generate_variant:Nn \enext_tikzsetfigurename:n { x }
\cs_new_protected_nopar:Nn \enext_tikzsetnextfilename:n
{
  \tikzsetnextfilename { #1 }
}
\cs_generate_variant:Nn \enext_tikzsetnextfilename:n { V }
\cs_new_protected_nopar:Nn \enext_setfigurename:
{
  \enext_settofilename:
  \enext_tikzsetnextfilename:V \g_enext_figurename_tl
}
\msg_new:nnnn { enext } { append ~ failed }
{
  \msg_warning_text:n { enext } ~ :: ~ Append ~ to ~ #1 ~ failed ~ \msg_line_context: !
}
{
  This ~ is ~ probably ~ not ~ your ~ fault ~ unless ~ you ~ redefined ~ the ~ modified ~ functions. ~
  Either ~ fix ~ the ~ code ~ yourself ~ or ~ ask ~ for ~ help. ~
  Apologies ~ for ~ any ~ inconvenience. ~
  All ~ code ~ provided ~ as-is ~ for ~ use ~ at ~ your ~ own ~ risk! ~
  As ~ a ~ goodwill ~ gesture, ~ a ~ full ~ refund ~ will ~ be ~ provided ~ on ~ request, ~ less ~ a ~ small ~ fee ~ to ~ cover ~ administration.
}
\msg_new:nnn { enext } { append ~ succeeded }
{
  \msg_warning_text:n { enext } ~ :: ~ Modified ~ #1 ~ \msg_line_context: !
}
\makeatletter
\apptocmd \sa@document
{
  \enext_setfigurename:
}{
  \msg_warning:nnn { enext } { append ~ succeeded } { document ~ environment }
}{
  \msg_warning:nnn { enext } { append ~ failed } { document ~ environment }
}
\apptocmd \tikzsetnextfilename
{
  \tl_gset:Nn \g_enext_figurename_tl { #1 }
}{
  \msg_warning:nnn { enext } { append ~ succeeded } { \tikzsetnextfilename }
}{
  \msg_warning:nnn { enext } { append ~ failed } { \tikzsetnextfilename }
}
\apptocmd \tikzexternal@getnextfilename@resetglobals
{
  \tl_gclear:N \g_enext_figurename_tl
}{
  \msg_warning:nnn { enext } { append ~ succeeded } { \tikzexternal@getnextfilename@resetglobals }
}{
  \msg_warning:nnn { enext } { append ~ failed } { \tikzexternal@getnextfilename@resetglobals }
}
\makeatother
\ExplSyntaxOff
\begin{document}
\input{myfig}
\tikzsetnextfilename{bill}
\begin{tikzpicture}
  \draw [green] (0,0) -- (1,0) circle (1);
\end{tikzpicture}
\tikzsetnextfilename{flowerpotmen}
\input{myfig2}
\begin{tikzpicture}
  \draw [red] (0,0) -- (1,0);
\end{tikzpicture}
\tikzsetnextfilename{ben}
\input{myfig3}
\end{document}

这将生成ffigurau名为benbillfigure-0flowerpotmenmyfig-0的外部化图像myfig2-0。也就是说,第一个内联图像被命名bill为 而不是figure-0(因此第二个是figure-0而不是figure-1),而第二个外部文件中的两个图像中的第一个被命名flowerpotmen为 而不是myfig2-0(因此第二个是myfig2-0而不是myfig2-1),而来自外部文件的最后一个图像被命名为ben而不是myfig3-0。我认为这是这里所期望的。

编辑 编辑 编辑

用这个仅当standalone必须避免使用包裹时。如果不能使用standalone包,那么创建包含代码的包装器的另一种方法是定义一个合适的包装器\input

例如,以下定义\extinput{}非常相似\input{},只是它适当地设置了包含的图形的名称。在这种情况下,您甚至不需要currfile

当然,缺点是只有使用\extinput而不是输入的文件\input才会得到特殊处理,因此只有它们才会根据其文件的名称进行命名。此外,该命令的当前版本非常简单,不会尝试以任何方式检查文件名。因此,除非可以仅使用文件的基本名称输入文件,而不是使用包括封闭目录的相对或绝对路径,否则不应使用此命令。

\begin{filecontents}{myfig4.tex}
\begin{tikzpicture}
  \filldraw [green] (0,0) circle (1);
\end{tikzpicture}
\end{filecontents}
\begin{filecontents}{myfig5.tex}
\begin{tikzpicture}
  \filldraw [inner color=green, outer color=purple] (0,0) circle (1);
\end{tikzpicture}
\begin{tikzpicture}
  \filldraw [inner color=purple, outer color=green] (0,0) circle (1);
\end{tikzpicture}
\end{filecontents}
\begin{filecontents}{myfig6.tex}
\begin{tikzpicture}
  \filldraw [purple] (0,0) circle (1);
\end{tikzpicture}
\end{filecontents}

\documentclass{article}
\usepackage{tikz}
\usepackage{etoolbox}
\usepackage{xparse}
\usetikzlibrary{external}
\tikzexternalize[prefix=ffigurau/]
\tikzsetfigurename{figure-}
\ExplSyntaxOn
\tl_new:N \g_enext_figurename_tl
\cs_new_protected_nopar:Nn \enext_tikzsetfigurename:n
{
  \tikzsetfigurename { #1 }
}
\cs_new_protected_nopar:Nn \enext_tikzsetnextfilename:n
{
  \tikzsetnextfilename { #1 }
}
\cs_generate_variant:Nn \enext_tikzsetnextfilename:n { V }
\cs_new_protected_nopar:Nn \enext_setfigurename:n
{
  \enext_tikzsetfigurename:n { #1 }
  \enext_tikzsetnextfilename:V \g_enext_figurename_tl
}
\msg_new:nnnn { enext } { append ~ failed }
{
  \msg_warning_text:n { enext } ~ :: ~ Append ~ to ~ #1 ~ failed ~ \msg_line_context: !
}
{
  This ~ is ~ probably ~ not ~ your ~ fault ~ unless ~ you ~ redefined ~ the ~ modified ~ functions. ~
  Either ~ fix ~ the ~ code ~ yourself ~ or ~ ask ~ for ~ help. ~
  Apologies ~ for ~ any ~ inconvenience. ~
  All ~ code ~ provided ~ as-is ~ for ~ use ~ at ~ your ~ own ~ risk! ~
  As ~ a ~ goodwill ~ gesture, ~ a ~ full ~ refund ~ will ~ be ~ provided ~ on ~ request, ~ less ~ a ~ small ~ fee ~ to ~ cover ~ administration.
}
\msg_new:nnn { enext } { append ~ succeeded }
{
  \msg_warning_text:n { enext } ~ :: ~ Modified ~ #1 ~ \msg_line_context: !
}
\NewDocumentCommand \extinput { m }
{
  \group_begin:
    \enext_setfigurename:n { #1 - }
    \file_input:n { #1 }
  \group_end:
}
\makeatletter
\apptocmd \tikzsetnextfilename
{
  \tl_gset:Nn \g_enext_figurename_tl { #1 }
}{
  \msg_warning:nnn { enext } { append ~ succeeded } { \tikzsetnextfilename }
}{
  \msg_warning:nnn { enext } { append ~ failed } { \tikzsetnextfilename }
}
\apptocmd \tikzexternal@getnextfilename@resetglobals
{
  \tl_gclear:N \g_enext_figurename_tl
}{
  \msg_warning:nnn { enext } { append ~ succeeded } { \tikzexternal@getnextfilename@resetglobals }
}{
  \msg_warning:nnn { enext } { append ~ failed } { \tikzexternal@getnextfilename@resetglobals }
}
\makeatother
\ExplSyntaxOff
\begin{document}
\extinput{myfig4}
\begin{tikzpicture}
  \draw [green] (0,0) -- (1,0) circle (1);
\end{tikzpicture}
\tikzsetnextfilename{circ}
\extinput{myfig5}
\begin{tikzpicture}
  \draw [red] (0,0) -- (1,0);
\end{tikzpicture}
\extinput{myfig6}
\end{document}

相关内容