The problem is the same as that in Problem with environment expansion and the Tikz external library. in that TeX does not see the \end{tikzpicture}
inside the \end{tikzcd}
. The solution in Problem with environment expansion and the Tikz external library. is to pack everything inside a macro to ensure that the customised end-of-environment is expanded before TeX starts gobbling so that the hidden \end{tikzpicture}
is revealed. The adaptation of that in the question above is not the same because it adds an extra \end{tikzpicture}
instead of unpacking the hidden one, and this leads to nesting of TikZ pictures which is Not A Good Idea.
(Nonetheless, just because something is not a good idea doesn't mean that it isn't the best idea, just that it should be used with extreme caution.)
If all your pictures are tikzcd
environments then it seems that the right solution might be to tell TeX to look for tikzcd
instead of tikzpicture
. This is a reasonable thing to try to do because the first thing that \begin{tikzcd}
does is to start a tikzpicture
and the last thing that \end{tikzcd}
does is to end it. However, my experiments at trying to change all tikzpicture
s in the externalisation code to tikzcd
didn't work so I'm abandoning this for the time being (what would be nice would be an adaptation of the externalisation library that worked for any environment, not just tikzpicture
s).
Here's an adaptation of your adaptation of my answer to the linked question which instead of wrapping the tikzcd
environment in a tikzpicture
simply exposes the inner tikzpicture
. Well, except that it doesn't since the inner tikzpicture
is written as \tikzpicture ... \endtikzpicture
which wouldn't match so we have to redefine the tikzcd
environment to make the \tikzpicture
and \endtikzpicture
into \begin{tikzpicture}
and \end{tikzpicture}
. Elegant, it ain't, but it does avoid the nesting issue.
\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}
Check the location of your personal texmf tree: tlmgr conf texmf TEXMFHOME
. Usually the result will be ~/texmf
. The rest of the answer assumes this is the case. If the directory does not exist, you can create it. You might as well call mkdir -p ~/texmf/tex/generic/pgf
right away, which will create a directory tree conforming to TeX Directory Structure (TDS). Without a proper structure, files will not be found during compilation.
Go to the newly created directory: cd ~/texmf/tex/generic/pgf
. Then clone the GitHub repository containing the required PGF library: git clone https://github.com/Qrrbrbirlbel/pgf.git qrr
. If the command is successful, the files will be found in a subdirectory called qrr
. The directory can be named freely. I found the location of the repository by following a chain of links starting from the question and ending in this answer by Qrrbrbirlbel.
The example document should then compile. The instructions assume a Unix / Linux system. Some modifications would be required for Windows. On Mac OS X, only the default value of TEXMFHOME
would be different, but the rest of the procedure should be the same.
Best Answer
Summary
Here's the list of libraries, and a brief summary of the purpose of each (any code supplied is for LaTeX and/or Plain TeX, not ConTeXt):
\usetikzlibrary{arrows.meta}
(\usetikzlibrary{arrows}
is deprecated). See details below.\usetikzlibrary{automata}
, and is used for drawing "finite state automata and Turing Machines". To draw these graphs, each node, its name and relative position is defined, as well as the types of path between each.\usetikzlibrary{backgrounds}
, and "defines background for pictures". To use this in a Tikzpicture, an option is passed, e.g.\begin{tikzpicture}[show background rectangle]
, with a background rectangle style defined before the picture. (e.g.\tikzset{background rectangle/.style={<define background rectangle style here>}}
\usetikzlibrary{calc}
to make complex coordinate calculations. See details below.\usetikzlibrary{calendar}
. This library is used to display calendars (I guess it's a Ronseal thing). You define a calendar as\calendar[
display options and date options](
Name (optional))
.\usetikzlibrary{er}
, as in the automata drawing library, each node is defined, as is each edge between each node, as well as any attributes. As a note of warning, underlining should be used for attributes, but this is not used as it is both ugly and difficult to implement. Italics are used instead.\usetikzlibrary{intersections}
, to calculate intersections of paths. See details below.\usetikzlibrary{mindmap}
. See details below.\usetikzlibrary{matrix}
. Matrices are defined in the same way as in maths mode, however, each item in the matrix as assigned a value as a node, starting from 1. Each node can then be identified and manipulated. Delimiters can also be selected in the matrix options and can be "any delimiter that is acceptable to TeX’s\left
command".\usetikzlibrary{folding}
. See details below.\usetikzlibrary{patterns}
. This package "defines patterns for filling areas". In the documentation, each pattern is named and an example given.\usetikzlibrary{plothandlers}
. TikZ loads this library automatically. Each point is defined (as a node) for the plot and the each point has a curve placed\usetikzlibrary{plotmarks}
is used to define additional styles for plots as used above. Each point is defined as\pgfuseplotmark{
Plot description}
.\usetikzlibrary{shapes}
or\usetikzlibrary{shapes.
shape type}
. The following additional types are available: geometric shapes, either named shapes (star, diamond, etc.) or polygons of specified side numbers; symbol shapes, e.g. "forbidden sign" as used in No Smoking signs; "multipart" shapes, with "multiple (text) parts"; and finally, "misc" shapes which "do not fit in the previous categories", such as strike-through crosses. See details below.\usetikzlibrary{snakes}
and can be best described as curved lines, and are used either between nodes or as a border to a shape , or as independent shapes.\usetikzlibrary{topaths}
. This library is used to define paths between two points, and is loaded automatically. Additionally, it can take the form of curved lines between two shapes or as a loop back to a node.\usetikzlibrary{trees}
. Each point on the tree is defined as a node, with children, and each child can have its own children. The tree's direction can also be specified, as well as the angle at which children emerge, however, when left to its own devices, the results are acceptable.Sources: Anything in inverted commas has been lifted from the tikzpgfmanual, as well as the calendar sample.