原始答案

原始答案

有没有办法将TikZcdexternal一起使用?
这不起作用:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{cd, external}
\tikzexternalize

\begin{document}

\begin{tikzcd}
  A \arrow[rd] \arrow[r, "\varphi"] & B \\ & C
\end{tikzcd}

\end{document}

错误:

Runaway argument?

! File ended while scanning use of \tikzexternal@laTeX@collect@until@end@tikzpicture.

我正在使用TikZ/PGF版本 3.0.0 和tikz-cd版本 0.9b。

答案1

这个问题和环境扩展和 Tikz 外部库的问题。因为 TeX 看不到\end{tikzpicture}内部\end{tikzcd}。解决方案环境扩展和 Tikz 外部库的问题。是将所有内容打包在宏中,以确保在 TeX 开始吞噬之前扩展自定义的环境结束,从而\end{tikzpicture}显示隐藏的内容。 上面问题中的改编并不相同,因为它添加了一个额外的内容\end{tikzpicture}而不是解压隐藏的内容,这会导致 TikZ 图片嵌套,这不是一个好主意。

(尽管如此,仅仅因为某件事不是一个好主意,并不意味着它不是最好的主意,只是应该极其谨慎地使用它。)

如果您的所有图片都是tikzcd环境,那么似乎正确的解决方案可能是告诉 TeX 查找tikzcd而不是tikzpicture。这是一个合理的尝试,因为第一件事\begin{tikzcd}是启动一个tikzpicture,最后一件事是结束它。但是,我尝试将外部化代码中的\end{tikzcd}所有 s 更改为 的实验没有成功,所以我暂时放弃了这个(最好是对适用于 的外部化库进行改编tikzpicturetikzcd任何环境,而不仅仅是tikzpictures)。

这是您对我对链接问题的回答的改编,它不是将环境包装tikzcd在 中,而是tikzpicture简单地暴露内部tikzpicture。好吧,除了它没有,因为内部tikzpicture写为\tikzpicture ... \endtikzpicture不匹配,所以我们必须重新定义tikzcd环境以将\tikzpicture\endtikzpicture变成\begin{tikzpicture}\end{tikzpicture}。它并不优雅,但它确实避免了嵌套问题。

\documentclass{article}
%\url{https://tex.stackexchange.com/q/171931/86}
\usepackage{tikz}
\usepackage{environ}
\usetikzlibrary{cd,external}
\tikzexternalize

\makeatletter
\def\tikzcd@[#1]{%
  \begin{tikzpicture}[/tikz/commutative diagrams/.cd,every diagram,#1]%
  \ifx\arrow\tikzcd@arrow%
    \pgfutil@packageerror{tikz-cd}{Diagrams cannot be nested}{}
  \fi%
  \let\arrow\tikzcd@arrow%
  \let\ar\tikzcd@arrow%
  \def\rar{\tikzcd@xar{r}}%
  \def\lar{\tikzcd@xar{l}}%
  \def\dar{\tikzcd@xar{d}}%
  \def\uar{\tikzcd@xar{u}}%
  \def\urar{\tikzcd@xar{ur}}%
  \def\ular{\tikzcd@xar{ul}}%
  \def\drar{\tikzcd@xar{dr}}%
  \def\dlar{\tikzcd@xar{dl}}%
  \global\let\tikzcd@savedpaths\pgfutil@empty%
  \matrix[/tikz/matrix of \iftikzcd@mathmode math \fi nodes,
          /tikz/every cell/.append code={\tikzcdset{every cell}},
          /tikz/commutative diagrams/.cd,every matrix]%
  \bgroup}

\def\endtikzcd{%
  \pgfmatrixendrow\egroup%
  \pgfextra{\global\let\tikzcdmatrixname\tikzlastnode};%
  \tikzcdset{\the\pgfmatrixcurrentrow-row diagram/.try}%
  \begingroup%
    \tikzcd@enablequotes%
    \tikzcd@patcherrmsg%
    \tikzcd@savedpaths%
  \endgroup%
  \end{tikzpicture}%
  \ifnum0=`{}\fi}


\NewEnviron{mytikzcd}[1][]{%
  \def\@temp{\tikzcd@[#1]\BODY}%
  \expandafter\@temp\endtikzcd
}
\makeatother

\def\temp{&} \catcode`&=\active \let&=\temp
\begin{document}

\begin{mytikzcd}
  A \arrow{rd} \arrow{r}{\phi} & B \\ & C
\end{mytikzcd}

\begin{mytikzcd}
  A \arrow{rd} \arrow{r}{\phi} & B \\ & C
\end{mytikzcd}


\end{document}

答案2

当我最初回答这个问题时,external是唯一可用的选项。幸运的是,现在情况不再如此。您附近的 CTAN 镜像现在提供两个新的外部化选项:memoizerobust-externalize

这是一个使用的解决方案memoizetikzcd设置得益于memoize的作者

\documentclass{article}
\usepackage{memoize}
\mmzset{%
  path={dir=memos},
  mkdir,
  % Sašo Živanović: https://chat.stackexchange.com/transcript/message/64689784#64689784
  auto={tikzcd}{memoize,verbatim},
}
\usepackage{tikz}
\usetikzlibrary{cd}

\begin{document}

\begin{tikzpicture}
    \node at (0,0) {node};
\end{tikzpicture}

\begin{tikzcd}
    A \arrow[rd] \arrow[r, "\varphi"] & B \\ & C
\end{tikzcd}

\end{document}

经过一次编译后,图像将成memoized为主 PDF 制作的一部分。此时,它们除了在文档中的适当位置生成外,还显示为额外页面。

单次编译结果

在第二次编辑中,外部人员被提取到单独的 PDF 文件中,现在包含在主 PDF 中,无需重新编译。只有当图像代码发生变化或满足某些进一步条件时,才会重新编译图像代码。(例如,如果您删除 PDF 或指示重新memoize编译或其他。)

使用记忆图像的第二次编译的结果

原始答案

此解决方案不允许您外部化使用tikzcd环境生成的图表,但允许您外部化其他 tikz图片在您的文档中。它基于tikz手册第 50.8.2 节(第 627-8 页)中提到的解决方法。为了使其使用更方便,etoolbox用于修补tikzcd环境。本质上,这会在环境开始时关闭外部化tikzcd,然后在环境结束时将其重新打开。

\documentclass{article}

\usepackage{etoolbox,tikz}

\usetikzlibrary{external}
  \tikzexternalize
\usetikzlibrary{cd}

\AtBeginEnvironment{tikzcd}{\tikzexternaldisable}
\AtEndEnvironment{tikzcd}{\tikzexternalenable}

\begin{document}

\begin{tikzpicture}
    \node at (0,0) {node};
\end{tikzpicture}

\begin{tikzcd}
    A \arrow[rd] \arrow[r, "\varphi"] & B \\ & C
\end{tikzcd}

\end{document}

第一次运行时,pdflatex --shell-escape <filename>.tex包括以下输出:

===== 'mode=convert with system call': Invoking 'pdflatex -shell-escape -halt-o
n-error -interaction=batchmode -jobname "<filename>-figure0" "\def\tikzexternalreal
job{<filename>}\input{<filename>}"' ========

<filename>-figure0.pdf看起来像这样:

外化图像

后续运行包括输出:

===== Image '<filename>-figure0' is up-to-date. ======

PDF 将外部化的图像与动态<filename>-figure0.pdf生成的图像结合在一起:tikzcd

一幅图像外化;一幅不外化

这有多大帮助取决于你的图片所占的比例tikzcd。如果答案是 100%,那显然毫无用处。另一方面,如果答案低于 100%,那可能还是有用的。

答案3

以下是一个与external库配合使用的解决方案,我之前从未想到过。
我们可以将tikzcd环境放在 的节点内tizkpicture

\begin{tikzpicture}
  \node {\begin{tikzcd}
    A \arrow[rd] \arrow[r, "\varphi"] & B \\ & C
  \end{tikzcd}};
\end{tikzpicture}

为了获得正确的间距和对齐,以下选项似乎有效:

\begin{tikzpicture}[baseline=(current bounding box.west)]
  \node[inner sep=0, outer sep=0] {\begin{tikzcd}
    A \arrow[rd] \arrow[r, "\varphi"] & B \\ & C
  \end{tikzcd}};
\end{tikzpicture}

因此结合安德鲁·史黛西非常棒回答对于相关问题,我们得到:

\documentclass{article}

\usepackage{tikz, environ}
\usetikzlibrary{cd, external}
\tikzexternalize

\def\temp{&} \catcode`&=\active \let&=\temp

\NewEnviron{mycd}[1][]{%
  \begin{tikzpicture}[baseline=(current bounding box.west)]
    \node[inner sep=0, outer sep=0] {\begin{tikzcd}[#1]
      \BODY
    \end{tikzcd}};
  \end{tikzpicture}}

\begin{document}

\begin{equation}
\begin{mycd}[row sep=huge]
  A \arrow[rd] \arrow[r, "\varphi"] & B \\ & C
\end{mycd}
\end{equation}

\end{document}

我仍然觉得这很卑鄙。有没有更好的解决方案?

答案4

我必须调整马可·瓦里斯科的答案,以便在更改时自动重建图形。此外,我让人造 tikzpicture 的基线位于 tikzcd 基线的高度上。

\documentclass{article}

\usepackage{tikz, environ, etoolbox}
\usetikzlibrary{cd, external}
\tikzexternalize
% activate the following such that you can check the macro expansion in
% *-figure0.md5 manually
%\tikzset{external/up to date check=diff}


\def\temp{&} \catcode`&=\active \let&=\temp

\newcommand{\mytikzcdcontext}[2]{
  \begin{tikzpicture}[baseline=(maintikzcdnode.base)]
    \node (maintikzcdnode) [inner sep=0, outer sep=0] {\begin{tikzcd}[#2]
        #1
    \end{tikzcd}};
  \end{tikzpicture}}

\NewEnviron{mytikzcd}[1][]{%
% In the following, we need \BODY to expanded before \mytikzcdcontext
% such that the md5 function gets the tikzcd content with \BODY expanded.
% Howerver, expand it only once, because the \tikz-macros aren't
% defined at this point yet. The same thing holds for the arguments to
% the tikzcd-environment.
\def\myargs{#1}%
\edef\mydiagram{\noexpand\mytikzcdcontext{\expandonce\BODY}{\expandonce\myargs}}%
\mydiagram%
}

\begin{document}

\begin{equation}
\begin{mytikzcd}[row sep=huge,baseline = (B.base)]
  A \arrow[rd] \arrow[r, "\varphi"] & |[alias=B]| B \\ & C
\end{mytikzcd}
\hbox{sharing a baseline with } B
\end{equation}

\end{document}

相关内容