summaryrefslogtreecommitdiff
path: root/graphics/pgf
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-02-22 03:01:54 +0000
committerNorbert Preining <norbert@preining.info>2021-02-22 03:01:54 +0000
commit1c74c0d7614ec471bea05b5919b68e67a05dd6c1 (patch)
tree8631538e81cccc6ba01275553fc571cb4d02e349 /graphics/pgf
parentf35565737733e319e7293a9fafe1b78e87f8a14e (diff)
CTAN sync 202102220301
Diffstat (limited to 'graphics/pgf')
-rw-r--r--graphics/pgf/contrib/spath3/calligraphy.pdfbin259702 -> 259536 bytes
-rw-r--r--graphics/pgf/contrib/spath3/knots.pdfbin341151 -> 341621 bytes
-rw-r--r--graphics/pgf/contrib/spath3/spath3.pdfbin353909 -> 388662 bytes
-rw-r--r--graphics/pgf/contrib/spath3/spath3.tex272
-rw-r--r--graphics/pgf/contrib/spath3/spath3_code.dtx1261
-rw-r--r--graphics/pgf/contrib/spath3/spath3_code.pdfbin576597 -> 571802 bytes
-rw-r--r--graphics/pgf/contrib/tikzmark/tikzmark.dtx134
-rw-r--r--graphics/pgf/contrib/tikzmark/tikzmark.pdfbin419430 -> 423477 bytes
8 files changed, 1266 insertions, 401 deletions
diff --git a/graphics/pgf/contrib/spath3/calligraphy.pdf b/graphics/pgf/contrib/spath3/calligraphy.pdf
index 6896a3b289..a700b4fc0e 100644
--- a/graphics/pgf/contrib/spath3/calligraphy.pdf
+++ b/graphics/pgf/contrib/spath3/calligraphy.pdf
Binary files differ
diff --git a/graphics/pgf/contrib/spath3/knots.pdf b/graphics/pgf/contrib/spath3/knots.pdf
index 1a2afd39db..39067dee2e 100644
--- a/graphics/pgf/contrib/spath3/knots.pdf
+++ b/graphics/pgf/contrib/spath3/knots.pdf
Binary files differ
diff --git a/graphics/pgf/contrib/spath3/spath3.pdf b/graphics/pgf/contrib/spath3/spath3.pdf
index 466b71e7e5..ebbefefa1a 100644
--- a/graphics/pgf/contrib/spath3/spath3.pdf
+++ b/graphics/pgf/contrib/spath3/spath3.pdf
Binary files differ
diff --git a/graphics/pgf/contrib/spath3/spath3.tex b/graphics/pgf/contrib/spath3/spath3.tex
index 49b897c481..7621db4a28 100644
--- a/graphics/pgf/contrib/spath3/spath3.tex
+++ b/graphics/pgf/contrib/spath3/spath3.tex
@@ -56,6 +56,8 @@
\maketitle
+\tableofcontents
+
\section{Introduction}
The \texttt{spath3} package was originally designed as a low-level package for manipulating the \emph{soft paths} defined by PGF/TikZ.
@@ -124,59 +126,61 @@ Clones one soft path into another.
In the second, the clone is global (the original need not be).
\end{function}
-\begin{function}{restore, restore reverse}
+\begin{function}{use}
\begin{syntax}
-|restore=|\meta{name}
-|restore reverse=|\meta{name}
+|use=|\meta{name}
+|use=|\marg{name, options}
\end{syntax}
-Restores a previously saved soft path to the current path.
-The \Verb+reverse+ version reverses the soft path first.
-This happens immediately so can be issued in the options to the main command and then the path can be extended with normal drawing commands.
-Any keys that affect the soft path directly should be applied \emph{before} this one.
+This uses a previously saved soft path at the current juncture in the path declaration.
+If before the path has begun, it is the initial part of the new path.
+If during the path construction then it is stuck in at the current place.
+Note that any keys that affect the soft path directly should be applied \emph{before} this one.
+
+The path can be modified first by using the second form -- note that as far as the \Verb+use+ key is concerned, the whole thing is a single argument.
+The options is a comma separated list and can include:
+%
+\begin{itemize}
+\item |reverse| reverses the inserted path first.
+\item |weld|, |no weld| determines whether to weld the inserted path to the current path.
+Welding means that the |move to| at the start of the inserted path is removed.
+Note that this doesn't \emph{move} the inserted path so this will usually modify the first segment of the inserted path, possibly in unexpected ways.
+\item |move|, |no move| determines whether the inserted path is translated so that it starts where the current path ends.
+\item |transform=|\marg{transformations} applies the specified transformations to the inserted path.
+See the |transform| key in Section~\ref{sec:transform}
+\item Any other key is taken as the name of the path (so it doesn't have to be specified first) with the last one winning.
+\end{itemize}
One thing should be noted about transformations.
By the time a soft path is built, all available transformations have been applied.
This means that when re-inserting a soft path back into a high level command (such as |\draw|), the effect of existing transformations might produce some confusing effects.
When restoring a path then the library tries to set up various internals of TikZ correctly, but there may be some things I've overlooked or not accounted for particularly with regard to existing transformations; if you spot anything working oddly then please report it to me.
-Restoring a path also sets things right for positioning nodes along the path.
+In particular, restoring a path should sets things right for positioning nodes along the path.
Using the \Verb+pos=D+ key on a node positions that node at a particular point on the path.
Exactly how the parameter is interpreted is the same as for the \Verb+spath+ coordinate system described in Section~\ref{sec:coordinates}.
\end{function}
\begin{function}{
+ restore,
+ restore reverse
+ insert,
+ insert reverse,
append,
append reverse,
append no move,
append reverse no move
}
-\begin{syntax}
-|append=|\meta{name}
-|append reverse=|\meta{name}
-|append no move=|\meta{name}
-|append reverse no move=|\meta{name}
-\end{syntax}
-
-This inserts a soft path, or its reverse, into the path at the current point, it is therefore more suited to being used part way through a path construction.
-In a sense, it is a little like a \texttt{pic} in that it enables the user to construct a path segment early to be reused at various places.
-The path is \emph{welded} on to the current path, meaning that the intervening \Verb+move+ is removed.
-This is particularly useful for creating filled regions.
-The first two versions translate the path so that it starts at the last point on the existing path, the second two versions don't do this translation (the intention being that in such a case the translation is omitted because it is \emph{unnecessary} rather than simply not wanted because the effect of removing the intervening move will adjust the initial segment of the appended path otherwise).
+These are all aliases to various versions of \Verb+use+ (they originally existed as separate code before I united them all as variants of \Verb+use+).
+The equivalences are:
-As with restoring a path, the last point and node positioning machinery is established.
-The positioning is relative to the appended part of the path, not the full path.
-\end{function}
-
-\begin{function}{insert, insert reverse}
-\begin{syntax}
-|insert=|\meta{name}
-|insert reverse=|\meta{name}
-\end{syntax}
-
-Like \Verb+append+ except that it doesn't remove the intervening \Verb+move+ and doesn't translate the inserted path.
-The \Verb+reverse+ version reverses the path first.
+\begin{itemize}
+\item |restore| and |insert| are aliases for |use|.
+\item |append| sets the |move| and |weld| keys.
+\item |append no move| just sets the |weld| key.
+\item |reverse| sets the |reverse| key.
+\end{itemize}
\end{function}
\begin{function}{to}
@@ -191,6 +195,7 @@ The path is transformed by rotation, translation, and uniform scaling so that it
\subsection{Transformation Routines}
+\label{sec:transform}
The following keys all apply some sort of transformation to the soft path.
They do not render the path, but simply adjust it.
@@ -236,40 +241,6 @@ This transforms the named path so that it goes from the start point to the end p
As with the \Verb+to+ path construction and the \Verb+splice+ method, this won't work if the path ends very close to where it starts.
\end{function}
-\begin{function}{splice, splice global}
-\begin{syntax}
-|splice=|\marg{initial path}\marg{splice path}\marg{final path}
-|splice globally=|\marg{initial path}\marg{splice path}\marg{final path}
-\end{syntax}
-
-This splices the middle path into the gap between the initial and final paths.
-The middle path is transformed to fit (don't try this with a path whose starting and ending points are close together) and the paths are joined so that the last component of the initial path and the first component of the splice path become a single component, and similarly at the other end.
-\end{function}
-
-\begin{function}{join components with, join components globally with}
-\begin{syntax}
-|join components with=|\marg{path}\marg{splice path}
-|join components globally with=|\marg{path}\marg{splice path}
-\end{syntax}
-
-This inserts the |splice path| in the gaps between components of |path|.
-A \emph{spot weld} is performed first to join any components where the end of one is the start of the next.
-The result is a single component path.
-This does \emph{not} close the resulting path, for that see the key |close with|.
-\end{function}
-
-\begin{function}{close, close globally, close with, close globally with}
-\begin{syntax}
-|close=|\marg{path}
-|close globally=|\marg{path}
-|close with=|\marg{path}\marg{splice path}
-|close globally with=|\marg{path}\marg{splice path}
-\end{syntax}
-
-These all close the last component of the given path.
-The first two will insert a line segment if the initial and final points of the component are not sufficiently close.
-The latter two allow you to specify another path to insert.
-\end{function}
\subsection{Intersection Routines}
@@ -317,6 +288,20 @@ The second path is not changed.
This inserts breaks into a pair of paths at their mutual intersections.
\end{function}
+\begin{function}{
+ replace lines,
+ replace lines globally
+}
+\begin{syntax}
+|replace lines=|\meta{path}
+|replace lines globally=|\meta{path}
+\end{syntax}
+
+The PGF intersection routines have difficulties with parallel, or near parallel, lines.
+One way to counter this is to replace all line segments by ``curves''.
+This is done so that the parametrisation of the curve matches that of the line segment that it is replacing.
+\end{function}
+
\subsection{Working with Components}
\begin{function}{
@@ -335,7 +320,7 @@ The macro can be used in a |\foreach|.
The macro consists of a comma separated list of names of the components (the actual names used are of the form \Verb+anonymous_N+).
To access an individual component, use the command \Verb+\getComponentOf+.
-This can be used directly in place of a path name in any other key, such as \Verb+restore+, (it is just the \LaTeX3 command \Verb+\clist_item:Nn+).
+This can be used directly in place of a path name in any other key, such as \Verb+use+, (it is just the \LaTeX3 command \Verb+\clist_item:Nn+).
Note that these are \emph{copies} of the components of the original path.
Changing a component doesn't update the original path.
@@ -365,11 +350,14 @@ It applies the following styles (in this order):
}
\begin{syntax}
|insert gaps after components=|\marg{path}\marg{gap}\marg{components}
+|insert gaps after components=|\marg{path}\marg{gap}
|insert gaps globally after components=|\marg{path}\marg{gap}\marg{components}
+|insert gaps globally after components=|\marg{path}\marg{gap}
\end{syntax}
This inserts a gap between components of a path by shortening the end of the specified component and start of the next one.
The list of components is passed through a |\foreach| loop so that syntax like |2,4,...,16| can be used.
+If the list of components is not given the gaps are inserted between all components.
\end{function}
\begin{function}{
@@ -386,6 +374,31 @@ The list of components is processed by |\foreach|.
If the component is the first one then it is joined to the last component.
\end{function}
+\begin{function}{join components with, join components globally with, join components upright with, join components globally upright with}
+\begin{syntax}
+|join components with=|\marg{path}\marg{splice path}
+|join components with=|\marg{path}\marg{splice path}\marg{list}
+|join components upright with=|\marg{path}\marg{splice path}
+|join components upright with=|\marg{path}\marg{splice path}\marg{list}
+|join components globally with=|\marg{path}\marg{splice path}
+|join components globally with=|\marg{path}\marg{splice path}\marg{list}
+|join components globally upright with=|\marg{path}\marg{splice path}
+|join components globally upright with=|\marg{path}\marg{splice path}\marg{list}
+\end{syntax}
+
+This inserts the |splice path| in the gaps between components of |path| specified by a comma separated list.
+The splice is inserted between each specified component and the next one.
+If the \marg{list} is not given (or is empty) then the splice is inserted between every component except that a \emph{spot weld} is performed first to join any components where the end of one is the start of the next.
+The spot weld is only performed if the list of components is empty.
+
+This does \emph{not} close the resulting path, even if the last component is specified in the list, for that see the key |close with|.
+
+Note that because there is an optional third argument to this key, the second argument must always be enclosed in braces unless it is a single token.
+
+The |upright| versions do a little test to see if the gap is oriented upside-down and if so then they insert the reflection of the splice path.
+\end{function}
+
+
\begin{function}{
spot weld,
spot weld globally
@@ -423,6 +436,31 @@ This removes the listed components of the path.
As with other list routines, the list is parsed via |foreach| first.
\end{function}
+
+\begin{function}{close, close globally, close with, close globally with}
+\begin{syntax}
+|close=|\marg{path}
+|close globally=|\marg{path}
+|close with=|\marg{path}\marg{splice path}
+|close globally with=|\marg{path}\marg{splice path}
+\end{syntax}
+
+These all close the last component of the given path.
+The first two will insert a line segment if the initial and final points of the component are not sufficiently close.
+The latter two allow you to specify another path to insert.
+\end{function}
+
+\begin{function}{splice, splice global}
+\begin{syntax}
+|splice=|\marg{initial path}\marg{splice path}\marg{final path}
+|splice globally=|\marg{initial path}\marg{splice path}\marg{final path}
+\end{syntax}
+
+This splices the middle path into the gap between the initial and final paths.
+The middle path is transformed to fit (don't try this with a path whose starting and ending points are close together) and the paths are joined so that the last component of the initial path and the first component of the splice path become a single component, and similarly at the other end.
+\end{function}
+
+
\subsection{Shortening Paths}
\begin{function}{
@@ -473,8 +511,8 @@ Saves the path to the file \texttt{path.svg} as an SVG document.
\subsection{Knots}
\begin{function}{
- global knot,
knot,
+ global knot,
draft mode
}
\begin{syntax}
@@ -544,7 +582,7 @@ The intention with the second key is that it is similar to what happens with the
\section{Examples}
\begin{enumerate}
-\item Saving, restoring, inserting, and appending.
+\item Saving and re-using.
\begin{example}
\begin{tikzpicture}
@@ -554,10 +592,10 @@ The intention with the second key is that it is similar to what happens with the
\node[above left] at (spath cs:rpath 0.\k) {\(0.\k\)};
}
\fill[green] (2,2) circle[radius=3pt];
-\draw[blue, spath/transform={rpath}{shift={(2,2)}}, spath/restore=rpath] node[right] {transform};
-\draw[orange] (3,0) [spath/insert=rpath] node[right] {insert};
+\draw[blue, spath/transform={rpath}{shift={(2,2)}}, spath/use=rpath] node[right] {transform};
+\draw[orange] (3,0) [spath/use={rpath, move}] node[right] {moving};
\draw[red] (3,-1) -- +(0,2) [spath/append=rpath] node[above] {append};
-\draw[spath/restore=rpath] node[right] {restore};
+\draw[spath/use=rpath] node[right] {use};
\end{tikzpicture}
\end{example}
@@ -570,8 +608,8 @@ The intention with the second key is that it is similar to what happens with the
green,
draw=black,
ultra thick,
- spath/restore=apath
-] -- ++(0,-4) [spath/append reverse=apath] -- cycle;
+ spath/use=apath
+] -- ++(0,-4) [spath/use={apath, reverse, move, weld}] -- cycle;
\end{tikzpicture}
\end{example}
@@ -583,7 +621,7 @@ The intention with the second key is that it is similar to what happens with the
\draw[rotate=45, xscale=2, yscale=3, ultra thick, red] (0,0) rectangle +(1,1);
\draw[
spath/transform={tpath}{rotate=45, xscale=2, yscale=3},
- spath/restore={tpath}];
+ spath/use={tpath}];
\end{tikzpicture}
\end{example}
@@ -615,7 +653,7 @@ The intention with the second key is that it is similar to what happens with the
(7,1) circle[radius=3pt]
;
-\draw[spath/restore=a];
+\draw[spath/use=a];
\end{tikzpicture}
\end{example}
@@ -653,9 +691,9 @@ The intention with the second key is that it is similar to what happens with the
shorten at end={apath}{7pt},
shorten at start={apath}{9pt},
translate={apath}{0pt}{1pt},
- restore=apath,
+ use=apath,
];
-\draw (0,0) circle[radius=9pt] [spath/insert=apath] circle[radius=7pt];
+\draw (0,0) circle[radius=9pt] [spath/use=apath] circle[radius=7pt];
\end{tikzpicture}
\end{example}
@@ -670,9 +708,9 @@ The intention with the second key is that it is similar to what happens with the
shorten at end={apath}{7pt},
shorten at start={apath}{9pt},
translate={apath}{0pt}{1pt},
- restore=apath,
+ use=apath,
];
-\draw (0,0) circle[radius=9pt] [spath/insert=apath] circle[radius=7pt];
+\draw (0,0) circle[radius=9pt] [spath/use=apath] circle[radius=7pt];
\end{tikzpicture}
\end{example}
@@ -699,7 +737,7 @@ The intention with the second key is that it is similar to what happens with the
path \k/.try,
spath/.cd,
translate=\cpt{0pt}{\k pt},
- restore=\cpt,
+ use=\cpt,
] +(0,3pt) -- +(0,-3pt);
\node[text=red] at (spath cs:{\cpt} .5) {\(\k\)};
}
@@ -734,12 +772,12 @@ One of the main motivations for implementing the intersection routines was to pr
}
\foreach[count=\k] \cpt in \pathAcomponents {
- \draw[spath/restore=\cpt,-Circle];
+ \draw[spath/use=\cpt,-Circle];
\node[fill=white, fill opacity=.5, circle, text opacity=1] at (spath cs:{\cpt} .5) {\(\k\)};
}
\foreach[count=\k] \cpt in \pathBcomponents {
- \draw[spath/restore=\cpt,-Circle];
+ \draw[spath/use=\cpt,-Circle];
\node[fill=white, fill opacity=.5, circle, text opacity=1] at (spath cs:{\cpt} .5) {\(\k\)};
}
\end{tikzpicture}
@@ -766,12 +804,12 @@ Although the paths were defined globally, the splitting in the previous example
\fill[pattern=bricks, pattern color=white] (-.5,-.5) rectangle (8.5,1.5);
\foreach[count=\k] \cpt in \pathAcomponents {
- \draw[blue, line width=2pt,spath/restore=\cpt];
+ \draw[blue, line width=2pt,spath/use=\cpt];
\node[fill=cyan, fill opacity=.5, circle, text opacity=1] at (spath cs:{\cpt} .3) {\(\k\)};
}
\foreach[count=\k] \cpt in \pathBcomponents {
- \draw[green, line width=2pt,spath/restore=\cpt];
+ \draw[green, line width=2pt,spath/use=\cpt];
\node[fill=green!50, fill opacity=.5, circle, text opacity=1] at (spath cs:{\cpt} .3) {\(\k\)};
}
\end{tikzpicture}
@@ -807,7 +845,7 @@ arc[radius=.5cm,start angle=90, delta angle=-180]
}
\foreach[count=\k] \cpt in \pathcomponents {
- \draw[spath/restore=\cpt,-|];
+ \draw[spath/use=\cpt,-|];
\node[fill=white, fill opacity=.5, circle, text opacity=1] at (spath cs:{\cpt} .5) {\(\k\)};
}
\end{tikzpicture}
@@ -826,7 +864,7 @@ arc[radius=.5cm,start angle=90, delta angle=-180]
}
\foreach[count=\k] \cpt in \pathcomponents {
- \draw[blue, line width=2pt,spath/restore=\cpt];
+ \draw[blue, line width=2pt,spath/use=\cpt];
}
\end{tikzpicture}
\end{example}
@@ -843,5 +881,65 @@ arc[radius=.5cm,start angle=90, delta angle=-180]
\tikzset{spath/knot={trefoil}{8pt}{1,3,5}}
\end{tikzpicture}
\end{example}
+
+\item Here's how to mark intersections of paths with ``bridges''.
+\begin{example}
+\begin{tikzpicture}
+\coordinate (a) at (-1,0.5);
+\coordinate (b) at (8,0.5);
+\coordinate (c) at (3,-0.5);
+\path[spath/save=sine]
+(-1.57,-1)
+cos ++(1.57,1)
+sin ++(1.57,1)
+cos ++(1.57,-1)
+sin ++(1.57,-1)
+cos ++(1.57,1)
+sin ++(1.57,1);
+\path[spath/save=over] (a) -- (c) |- (b);
+
+\path[spath/save=arc] (0,0) arc[radius=1cm, start angle=180, delta angle=-180];
+
+\tikzset{
+ spath/split at intersections with={over}{sine},
+ spath/insert gaps after components={over}{8pt},
+ spath/join components upright with={over}{arc},
+ spath/split at intersections with={sine}{over},
+ spath/insert gaps after components={sine}{4pt},
+}
+
+\draw[spath/use=sine];
+\draw[spath/use=over];
+\end{tikzpicture}
+\end{example}
+
+\item If there are lots of paths like the previous example, here's a convenient style to put them together.
+\begin{example}
+\tikzset{
+ bridging path/.initial=arc,
+ bridging span/.initial=8pt,
+ bridging gap/.initial=4pt,
+ bridge/.style 2 args={
+ spath/split at intersections with={#1}{#2},
+ spath/insert gaps after components={#1}{\pgfkeysvalueof{/tikz/bridging span}},
+ spath/join components upright with={#1}{\pgfkeysvalueof{/tikz/bridging path}},
+ spath/split at intersections with={#2}{#1},
+ spath/insert gaps after components={#2}{\pgfkeysvalueof{/tikz/bridging gap}},
+ }
+}
+
+% If used in the preamble, this needs surrounding in \AtBeginDocument
+%\AtBeginDocument{
+\tikz[overlay] \path[spath/save=arc] (0,0) arc[radius=1cm, start angle=180, delta angle=-180];
+%}
+\begin{tikzpicture}
+\path[spath/save=over] (0,0) -| ++(1,1) -| ++(-1,1) -| ++(1,1) -| ++(-1,1);
+\path[spath/save=under] (.5,-.5) -- ++(0,4);
+\tikzset{bridge={over}{under}}
+\draw[spath/use=over];
+\draw[spath/use=under];
+\end{tikzpicture}
+\end{example}
+
\end{enumerate}
\end{document}
diff --git a/graphics/pgf/contrib/spath3/spath3_code.dtx b/graphics/pgf/contrib/spath3/spath3_code.dtx
index 621ab942f7..afd132938c 100644
--- a/graphics/pgf/contrib/spath3/spath3_code.dtx
+++ b/graphics/pgf/contrib/spath3/spath3_code.dtx
@@ -143,7 +143,7 @@ and the derived files spath3.ins,
%</driver>
% \fi
%
-% \CheckSum{8404}
+% \CheckSum{8929}
%
% \CharacterTable
% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
@@ -168,6 +168,7 @@ and the derived files spath3.ins,
% \changes{1.4}{2020/12/18}{A fair amount of code reimplementation and reorganisation, together with defining TikZ keys to make functions available for use.}
% \changes{2.0}{2021/01/19}{Refactored the code to remove the OO approach and make it functional, introduced the spath3 TikZ library to provide a user interface.}
% \changes{2.2}{2021/02/05}{Bugfixes and improvements, mainly with regard to the intersection and splitting routines.}
+% \changes{2.4}{2021/02/21}{Rejigged how the routines for using paths were implemented, added some more routines for joining paths.}
%
% \DoNotIndex{\newcommand,\newenvironment}
%
@@ -256,7 +257,7 @@ and the derived files spath3.ins,
\NeedsTeXFormat{LaTeX2e}
\RequirePackage{expl3}
\RequirePackage{pgf}
-\ProvidesExplPackage {spath3} {2021/02/05} {2.2} {Functions for
+\ProvidesExplPackage {spath3} {2021/02/21} {2.4} {Functions for
manipulating PGF soft paths}
\RequirePackage{xparse}
% \end{macrocode}
@@ -1756,7 +1757,7 @@ manipulating PGF soft paths}
{
\spath_splice_between:NVnn #1#1{#2}{#3}
}
-\cs_generate_variant:Nn \spath_splice_between:Nnn {NVV, cnn, cvv, Nvn}
+\cs_generate_variant:Nn \spath_splice_between:Nnn {NVV, cnn, cvv, Nvn, NVn}
\cs_new_protected_nopar:Npn \spath_gsplice_between:Nnnn #1#2#3#4
{
\@@_splice_between:nnn {#2}{#3}{#4}
@@ -1768,7 +1769,7 @@ manipulating PGF soft paths}
{
\spath_gsplice_between:NVnn #1#1{#2}{#3}
}
-\cs_generate_variant:Nn \spath_gsplice_between:Nnn {NVV, cnn, cvv}
+\cs_generate_variant:Nn \spath_gsplice_between:Nnn {NVV, cnn, cvv, Nvn, NVn}
% \end{macrocode}
% \end{macro}
%
@@ -1919,7 +1920,7 @@ manipulating PGF soft paths}
{
\spath_append_no_move:NVn #1#1{#2}
}
-\cs_generate_variant:Nn \spath_append_no_move:Nn {NV, cv, Nv}
+\cs_generate_variant:Nn \spath_append_no_move:Nn {NV, cv, Nv, cV}
\cs_new_protected_nopar:Npn \spath_gappend_no_move:Nnn #1#2#3
{
\@@_append_no_move:nn {#2}{#3}
@@ -1931,7 +1932,7 @@ manipulating PGF soft paths}
{
\spath_gappend_no_move:NVn #1#1{#2}
}
-\cs_generate_variant:Nn \spath_gappend_no_move:Nn {NV, cv, Nv}
+\cs_generate_variant:Nn \spath_gappend_no_move:Nn {NV, cv, Nv, cV}
% \end{macrocode}
% \end{macro}
%
@@ -1953,7 +1954,7 @@ manipulating PGF soft paths}
{
\spath_append:NVn #1#1{#2}
}
-\cs_generate_variant:Nn \spath_append:Nn {NV, Nv, cv}
+\cs_generate_variant:Nn \spath_append:Nn {NV, Nv, cv, cV}
\cs_new_protected_nopar:Npn \spath_gappend:Nnn #1#2#3
{
\tl_gset:Nn #1 {#2}
@@ -1964,7 +1965,7 @@ manipulating PGF soft paths}
{
\spath_gappend:NVn #1#1{#2}
}
-\cs_generate_variant:Nn \spath_gappend:Nn {NV, Nv, cv}
+\cs_generate_variant:Nn \spath_gappend:Nn {NV, Nv, cv, cV}
% \end{macrocode}
% \end{macro}
%
@@ -2235,6 +2236,128 @@ manipulating PGF soft paths}
% \end{macro}
%
% \begin{macro}[internal]{
+% \spath_replace_lines:Nn,
+% \spath_replace_lines:Nn,
+% \spath_replace_lines:Nn,
+% \spath_replace_lines:Nn,
+% }
+% Replace any line segments by B\'ezier curves.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_replace_lines:n #1
+{
+ \group_begin:
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_clear:N \l_@@_tmpb_tl
+ \dim_set:Nn \l_@@_tmpa_dim {0pt}
+ \dim_set:Nn \l_@@_tmpb_dim {0pt}
+
+ \bool_do_until:nn
+ {
+ \tl_if_empty_p:N \l_@@_tmpa_tl
+ }
+ {
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_item:Nn \l_@@_tmpa_tl {1}}
+ \tl_set:Nx \l_@@_tmpd_tl {\tl_item:Nn \l_@@_tmpa_tl {2}}
+ \tl_set:Nx \l_@@_tmpe_tl {\tl_item:Nn \l_@@_tmpa_tl {3}}
+
+ \tl_if_eq:NNTF \l_@@_tmpc_tl \c_spath_lineto_tl
+ {
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetoa_tl
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {
+ \fp_to_dim:n
+ {
+ 2/3 * (\l_@@_tmpa_dim)
+ +
+ 1/3 * (\l_@@_tmpd_tl)
+ }
+ }
+ }
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {
+ \fp_to_dim:n
+ {
+ 2/3 * (\l_@@_tmpb_dim)
+ +
+ 1/3 * (\l_@@_tmpe_tl)
+ }
+ }
+ }
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetob_tl
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {
+ \fp_to_dim:n
+ {
+ 1/3 * (\l_@@_tmpa_dim)
+ +
+ 2/3 * (\l_@@_tmpd_tl)
+ }
+ }
+ }
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ {
+ \fp_to_dim:n
+ {
+ 1/3 * (\l_@@_tmpb_dim)
+ +
+ 2/3 * (\l_@@_tmpe_tl)
+ }
+ }
+ }
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curveto_tl
+ \@@_tl_put_right_braced:NV \l_@@_tmpb_tl \l_@@_tmpd_tl
+ \@@_tl_put_right_braced:NV \l_@@_tmpb_tl \l_@@_tmpe_tl
+ }
+ {
+ \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpc_tl
+ \@@_tl_put_right_braced:NV \l_@@_tmpb_tl \l_@@_tmpd_tl
+ \@@_tl_put_right_braced:NV \l_@@_tmpb_tl \l_@@_tmpe_tl
+ }
+
+ \dim_set:Nn \l_@@_tmpa_dim {\l_@@_tmpd_tl}
+ \dim_set:Nn \l_@@_tmpb_dim {\l_@@_tmpe_tl}
+
+ \prg_replicate:nn {3}
+ {
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ }
+ }
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl
+ \group_end:
+}
+\cs_generate_variant:Nn \@@_replace_lines:n {V}
+\cs_new_protected_nopar:Npn \spath_replace_lines:Nn #1#2
+{
+ \@@_replace_lines:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_replace_lines:Nn {NV, cV, cv, Nv}
+\cs_new_protected_nopar:Npn \spath_replace_lines:N #1
+{
+ \spath_replace_lines:NV #1#1
+}
+\cs_generate_variant:Nn \spath_replace_lines:N {c}
+\cs_new_protected_nopar:Npn \spath_greplace_lines:Nn #1#2
+{
+ \@@_replace_lines:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_greplace_lines:Nn {NV, cV, cv, Nv}
+\cs_new_protected_nopar:Npn \spath_greplace_lines:N #1
+{
+ \spath_greplace_lines:NV #1#1
+}
+\cs_generate_variant:Nn \spath_greplace_lines:N {c}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{
% \spath_remove_empty_components:Nn,
% \spath_remove_empty_components:N,
% \spath_gremove_empty_components:Nn,
@@ -4709,8 +4832,8 @@ manipulating PGF soft paths}
\cs_generate_variant:Nn \spath_show:n {V, v}
% \end{macrocode}
% \end{macro}
-
-% \subsubsection{PGF and TikZ Interface Functions}
+%
+% \subsection{PGF and TikZ Interface Functions}
%
% Spaths come from PGF so we need some functions that get and set spaths from the pgf system.
%
@@ -4845,6 +4968,7 @@ manipulating PGF soft paths}
\tl_clear_new:c {tikz@timer}
\tl_set:cn {tikz@timer}
{
+ \pgftransformreset
\spath_reallength:Nn \l_@@_tmpa_int {#1}
\tl_set_eq:Nc \l_@@_tmpb_tl {tikz@time}
\tl_set:Nx \l_@@_tmpb_tl
@@ -4927,7 +5051,10 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
\msg_new:nnn { spath3 } { missing soft path } { Soft~ path~ #1~ doesn't~ exist }
-\msg_new:nnn { spath3 } { empty soft path } { Soft~ path~ #1~ is~ empty }
+\msg_new:nnnn { spath3 } { empty soft path } { Soft~ path~ #1~ is~ empty}
+{If~ it~ was~ defined~ inside~ a~ group,~ try~ using~ "save~ global". }
+\msg_new:nnn { spath3 } { load intersections }
+{ You~ need~ to~ load~ the~ "intersections"~ library~ to~ work~ with~ intersections }
% \end{macrocode}
%
% When saving a soft path, by default we use a naming convention that is compatible with the intersections library so that paths saved here and paths saved by the \texttt{name path} facility of the intersections library are mutually exchangeable.
@@ -4990,6 +5117,73 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}[internal]{
+% \@@_tikzset:n
+% }
+% Wrapper around \Verb+\tikzset+ for expansion.
+% \begin{macrocode}
+\cs_set_eq:NN \@@_tikzset:n \tikzset
+\cs_generate_variant:Nn \@@_tikzset:n {V, v}
+% \end{macrocode}
+% \end{macro}
+%
+% When joining two paths we provide a set of options for how to process the second path.
+%
+% \begin{macrocode}
+\bool_new:N \l_@@_reverse_bool
+\bool_new:N \l_@@_weld_bool
+\bool_new:N \l_@@_move_bool
+\bool_new:N \l_@@_global_bool
+\tl_new:N \l_@@_joinpath_tl
+\tl_new:N \l_@@_transformation_tl
+
+\cs_new_protected_nopar:Npn \@@_set_bool:Nn #1#2
+{
+ \tl_if_eq:nnTF {#2}{false}
+ {
+ \bool_set_false:N #1
+ }
+ {
+ \bool_set_true:N #1
+ }
+}
+\tikzset {
+ spath/join/.is~ family,
+ spath/join/.cd,
+ reverse/.code = {
+ \@@_set_bool:Nn \l_@@_reverse_bool {#1}
+ },
+ reverse/.default = true,
+ weld/.code = {
+ \@@_set_bool:Nn \l_@@_weld_bool {#1}
+ },
+ weld/.default = true,
+ no~ weld/.code = {
+ \@@_set_bool:Nn \l_@@_weld_bool {#1}
+ \bool_set:Nn \l_@@_weld_bool {! \l_@@_weld_bool}
+ },
+ no~ weld/.default = true,
+ move/.code = {
+ \@@_set_bool:Nn \l_@@_move_bool {#1}
+ },
+ move/.default = true,
+ no~ move/.code = {
+ \@@_set_bool:Nn \l_@@_move_bool {#1}
+ \bool_set:Nn \l_@@_move_bool {! \l_@@_move_bool}
+ },
+ no~ move/.default = true,
+ global/.code = {
+ \@@_set_bool:Nn \l_@@_global_bool {#1}
+ },
+ global/.default = true,
+ transform/.store~in=\l_@@_transformation_tl,
+ .unknown/.code = {
+ \tl_set_eq:NN \l_@@_joinpath_tl \pgfkeyscurrentname
+ }
+}
+% \end{macrocode}
+%
+%
% When we split a soft path into components, we make it a comma separated list so that it can be fed into a \Verb+\foreach+ loop.
% This can also make it possible to extract a single component, but to do this we need a wrapper around \Verb+\clist_item:Nn+ (there doesn't appear to be a PGF way of getting an item of a CS list).
%
@@ -5042,6 +5236,15 @@ manipulating PGF soft paths}
\l_@@_tmpa_tl
}
},
+ save~ global/.code={
+ \tikz@addmode{
+ \spath_get_current_path:N \l_@@_tmpa_tl
+ \spath_bake_round:NV \l_@@_tmpa_tl \l_@@_tmpa_tl
+ \spath_gsave_path:cV
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \l_@@_tmpa_tl
+ }
+ },
clone/.code~ 2~ args={
\tl_if_exist:cTF
{\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
@@ -5070,15 +5273,6 @@ manipulating PGF soft paths}
\msg_warning:nnn { spath3 } { missing soft path } { #2 }
}
},
- save~ global/.code={
- \tikz@addmode{
- \spath_get_current_path:N \l_@@_tmpa_tl
- \spath_bake_round:NV \l_@@_tmpa_tl \l_@@_tmpa_tl
- \spath_gsave_path:cV
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- \l_@@_tmpa_tl
- }
- },
% \end{macrocode}
%
% Saves a soft path to the aux file.
@@ -5097,77 +5291,152 @@ manipulating PGF soft paths}
},
% \end{macrocode}
%
-% Restores a soft path to the current path.
+% Exports the path as an SVG file.
%
% \begin{macrocode}
- restore/.code={
+ export~ to~ svg/.code={
\tl_if_exist:cTF
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
- \tl_if_empty:cTF
+ \spath_export_to_svg:nv {#1}
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- {
- \tl_clear:N \l_@@_tmpa_tl
- \tl_put_right:NV \l_@@_tmpa_tl \c_spath_moveto_tl
- \tl_put_right:Nn \l_@@_tmpa_tl {{0pt}{0pt}}
- \spath_set_current_path:V \l_@@_tmpa_tl
- \spath_set_tikz_data:V \l_@@_tmpa_tl
- \msg_warning:nnn { spath3 } { empty soft path } { #1 }
- }
- {
- \spath_set_current_path:c
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- \spath_set_tikz_data:v
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- }
}
{
- \tl_clear:N \l_@@_tmpa_tl
- \tl_put_right:NV \l_@@_tmpa_tl \c_spath_moveto_tl
- \tl_put_right:Nn \l_@@_tmpa_tl {{0pt}{0pt}}
- \spath_set_current_path:V \l_@@_tmpa_tl
- \spath_set_tikz_data:V \l_@@_tmpa_tl
\msg_warning:nnn { spath3 } { missing soft path } { #1 }
}
},
% \end{macrocode}
%
-% Restores the reverse of a soft path to the current path.
+% Inserts the named path at the current point in the path, with options for how this is accomplished.
+% The inserted path can be transformed, reversed, moved to the current point, and welded to the current path.
+% If this is used before the path has been started then it becomes the start of the path (and the ``current point'' is taken as the origin).
+%
%
% \begin{macrocode}
- restore~ reverse/.code={
+ use/.code={
+ \bool_set_false:N \l_@@_reverse_bool
+ \bool_set_false:N \l_@@_weld_bool
+ \bool_set_false:N \l_@@_move_bool
+ \tl_clear:N \l_@@_joinpath_tl
+ \tl_clear:N \l_@@_transformation_tl
+ \tikzset{
+ spath/join/.cd,
+ #1
+ }
+
\tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
- \tl_if_empty:cTF
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_use:N \l_@@_prefix_tl
+ \tl_use:N \l_@@_joinpath_tl
+ \tl_use:N \l_@@_suffix_tl
+ }
+ {
+ \tl_if_empty:cT
+ {
+ \tl_use:N \l_@@_prefix_tl
+ \tl_use:N \l_@@_joinpath_tl
+ \tl_use:N \l_@@_suffix_tl
+ }
{
- \tl_clear:N \l_@@_tmpa_tl
- \tl_put_right:NV \l_@@_tmpa_tl \c_spath_moveto_tl
- \tl_put_right:Nn \l_@@_tmpa_tl {{0pt}{0pt}}
- \spath_set_current_path:V \l_@@_tmpa_tl
- \spath_set_tikz_data:V \l_@@_tmpa_tl
\msg_warning:nnn { spath3 } { empty soft path } { #1 }
}
+ \tl_set_eq:Nc \l_@@_joinpath_tl
{
- \spath_reverse:Nv
- \l_@@_reverse_tl
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- \spath_set_current_path:N \l_@@_reverse_tl
- \spath_set_tikz_data:V \l_@@_reverse_tl
+ \tl_use:N \l_@@_prefix_tl
+ \tl_use:N \l_@@_joinpath_tl
+ \tl_use:N \l_@@_suffix_tl
+ }
+ \spath_get_current_path:N \l_@@_current_tl
+
+ \bool_if:NT \l_@@_reverse_bool
+ {
+ \spath_reverse:N \l_@@_joinpath_tl
+ }
+
+ \tl_if_empty:NF \l_@@_transformation_tl
+ {
+ \group_begin:
+ \pgftransformreset
+ \@@_tikzset:V \l_@@_transformation_tl
+ \pgfgettransform \l_@@_tmpa_tl
+ \tl_gset:Nn \g_@@_smuggle_tl
+ {
+ \spath_transform:Nnnnnnn
+ \l_@@_joinpath_tl
+ }
+ \tl_gput_right:NV \g_@@_smuggle_tl \l_@@_tmpa_tl
+ \group_end:
+ \tl_use:N \g_@@_smuggle_tl
+ }
+
+ \bool_if:NT \l_@@_move_bool
+ {
+ \tl_if_empty:NTF \l_@@_current_tl
+ {
+ \tl_set:Nn \l_@@_tmpc_tl { {0pt} {0pt} }
+ }
+ {
+ \spath_finalpoint:NV
+ \l_@@_tmpc_tl
+ \l_@@_current_tl
+ }
+ \spath_translate_to:NV \l_@@_joinpath_tl \l_@@_tmpc_tl
+ }
+
+ \tl_if_empty:NTF \l_@@_current_tl
+ {
+ \tl_if_empty:NTF \l_@@_joinpath_tl
+ {
+ \tl_set_eq:NN \l_@@_current_tl \c_spath_moveto_tl
+ \tl_put_right:Nn \l_@@_current_tl {{0pt}{0pt}}
+ }
+ {
+ \tl_set_eq:NN \l_@@_current_tl \l_@@_joinpath_tl
+ }
+ }
+ {
+
+ \tl_clear:N \l_@@_tmpa_tl
+ \tl_set:Nn \l_@@_tmpa_tl {spath_}
+
+ \tl_put_right:Nn \l_@@_tmpa_tl {append}
+
+ \bool_if:NT \l_@@_weld_bool
+ {
+ \tl_put_right:Nn \l_@@_tmpa_tl {_no_move}
+ }
+ \tl_put_right:Nn \l_@@_tmpa_tl {:NV}
+
+ \use:c {\tl_use:N \l_@@_tmpa_tl }
+ \l_@@_current_tl
+ \l_@@_joinpath_tl
}
+
+ \spath_set_current_path:N \l_@@_current_tl
+ \spath_set_tikz_data:V \l_@@_joinpath_tl
}
{
- \tl_clear:N \l_@@_tmpa_tl
- \tl_put_right:NV \l_@@_tmpa_tl \c_spath_moveto_tl
- \tl_put_right:Nn \l_@@_tmpa_tl {{0pt}{0pt}}
- \spath_set_current_path:V \l_@@_tmpa_tl
- \spath_set_tikz_data:V \l_@@_tmpa_tl
- \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ \msg_warning:nnx
+ { spath3 }
+ { missing soft path }
+ {\tl_use:N \l_@@_joinpath_tl }
}
},
% \end{macrocode}
%
+% Some aliases for the above.
+%
+% \begin{macrocode}
+ restore/.style={/tikz/spath/use={#1}},
+ restore~ reverse/.style={/tikz/spath/use={reverse, #1}},
+ append/.style={/tikz/spath/use={move, weld, #1}},
+ append~ no~ move/.style={/tikz/spath/use={weld, #1}},
+ append~ reverse/.style={/tikz/spath/use={move, weld, reverse, #1}},
+ append~ reverse~ no~ move/.style={/tikz/spath/use={weld, reverse, #1}},
+ insert/.style={/tikz/spath/use={#1}},
+ insert~ reverse/.style={/tikz/spath/use={reverse, #1}},
+% \end{macrocode}
+%
% Diagnostic, show the current path in the terminal and log.
%
% \begin{macrocode}
@@ -5204,45 +5473,99 @@ manipulating PGF soft paths}
},
% \end{macrocode}
%
-% Appends the named path to the current path with a weld.
-%
-% \begin{macrocode}
- append/.code={
- \tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- {
- \spath_get_current_path:N \l_@@_current_tl
- \spath_finalpoint:NV \l_@@_tmpa_tl \l_@@_current_tl
- \tl_set_eq:Nc
- \l_@@_tmpb_tl
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- \spath_translate_to:NV \l_@@_tmpb_tl \l_@@_tmpa_tl
- \spath_append_no_move:NV \l_@@_current_tl \l_@@_tmpb_tl
- \spath_set_current_path:N \l_@@_current_tl
- \spath_set_tikz_data:V \l_@@_tmpb_tl
- }
- {
- \msg_warning:nnn { spath3 } { missing soft path } { #1 }
- }
- },
-% \end{macrocode}
-%
-% Joins the second named path to the first.
+% This joins a path on to an existing path, possibly modifying it first.
+% The possible options are the same as those for \Verb+use+.
+% It is possible to specify the same path both for the initial and the joining path as a copy is made internally first.
%
% \begin{macrocode}
join~ with/.code~ 2~ args={
\tl_if_exist:cTF
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
+ \bool_set_false:N \l_@@_reverse_bool
+ \bool_set_false:N \l_@@_weld_bool
+ \bool_set_false:N \l_@@_move_bool
+ \bool_set_false:N \l_@@_global_bool
+ \tl_clear:N \l_@@_joinpath_tl
+ \tl_clear:N \l_@@_transformation_tl
+ \tikzset{
+ spath/join/.cd,
+ #2
+ }
+
\tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
{
- \spath_append:cv
+ \tl_use:N \l_@@_prefix_tl
+ \tl_use:N \l_@@_joinpath_tl
+ \tl_use:N \l_@@_suffix_tl
+ }
+ {
+ \tl_set_eq:Nc \l_@@_joinpath_tl
+ {
+ \tl_use:N \l_@@_prefix_tl
+ \tl_use:N \l_@@_joinpath_tl
+ \tl_use:N \l_@@_suffix_tl
+ }
+
+ \bool_if:NT \l_@@_reverse_bool
+ {
+ \spath_reverse:N \l_@@_joinpath_tl
+ }
+
+ \tl_if_empty:NF \l_@@_transformation_tl
+ {
+ \group_begin:
+ \pgftransformreset
+ \@@_tikzset:V \l_@@_transformation_tl
+ \pgfgettransform \l_@@_tmpa_tl
+ \tl_gset:Nn \g_@@_smuggle_tl
+ {
+ \spath_transform:Nnnnnnn
+ \l_@@_joinpath_tl
+ }
+ \tl_gput_right:NV \g_@@_smuggle_tl \l_@@_tmpa_tl
+ \group_end:
+ \tl_use:N \g_@@_smuggle_tl
+ }
+
+ \bool_if:NT \l_@@_move_bool
+ {
+ \spath_finalpoint:Nv
+ \l_@@_tmpc_tl
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \spath_translate_to:NV \l_@@_joinpath_tl \l_@@_tmpc_tl
+ }
+
+ \tl_clear:N \l_@@_tmpa_tl
+ \tl_set:Nn \l_@@_tmpa_tl {spath_}
+
+ \bool_if:NT \l_@@_global_bool
+ {
+ \tl_put_right:Nn \l_@@_tmpa_tl {g}
+ }
+
+ \tl_put_right:Nn \l_@@_tmpa_tl {append}
+
+ \bool_if:NT \l_@@_weld_bool
+ {
+ \tl_put_right:Nn \l_@@_tmpa_tl {_no_move}
+ }
+ \tl_put_right:Nn \l_@@_tmpa_tl {:cV}
+
+ \cs_if_exist:cF {\tl_use:N \l_@@_tmpa_tl}
+ {
+ \tl_show:N \l_@@_tmpa_tl
+ }
+
+ \use:c {\tl_use:N \l_@@_tmpa_tl }
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ \l_@@_joinpath_tl
}
{
- \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ \msg_warning:nnx
+ { spath3 }
+ { missing soft path }
+ {\tl_use:N \l_@@_joinpath_tl }
}
}
{
@@ -5305,113 +5628,6 @@ manipulating PGF soft paths}
},
% \end{macrocode}
%
-% Appends the reversal of the path to the current path.
-%
-% \begin{macrocode}
- append~ reverse/.code={
- \tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- {
- \spath_reverse:Nv
- \l_@@_reverse_tl
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- \spath_get_current_path:N \l_@@_current_tl
- \spath_finalpoint:NV \l_@@_tmpa_tl \l_@@_current_tl
- \spath_translate_to:NV \l_@@_reverse_tl \l_@@_tmpa_tl
- \spath_append_no_move:NV \l_@@_current_tl \l_@@_reverse_tl
- \spath_set_current_path:N \l_@@_current_tl
- \spath_set_tikz_data:V \l_@@_reverse_tl
- }
- {
- \msg_warning:nnn { spath3 } { missing soft path } { #1 }
- }
- },
-% \end{macrocode}
-%
-% Inserts the named path into the current path as-is, meaning without transforming or welding it.
-%
-% \begin{macrocode}
- insert/.code={
- \tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- {
- \spath_get_current_path:N \l_@@_current_tl
- \spath_append:Nv
- \l_@@_current_tl
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- \spath_set_current_path:N \l_@@_current_tl
- \spath_set_tikz_data:v
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- }
- {
- \msg_warning:nnn { spath3 } { missing soft path } { #1 }
- }
- },
-% \end{macrocode}
-%
-% Inserts the reverse of the named path.
-%
-% \begin{macrocode}
- insert~ reverse/.code={
- \tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- {
- \spath_reverse:Nv
- \l_@@_reverse_tl
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- \spath_get_current_path:N \l_@@_current_tl
- \spath_append:NV \l_@@_current_tl \l_@@_reverse_tl
- \spath_set_current_path:N \l_@@_current_tl
- \spath_set_tikz_data:V \l_@@_reverse_tl
- }
- {
- \msg_warning:nnn { spath3 } { missing soft path } { #1 }
- }
- },
-% \end{macrocode}
-%
-% Appends the named path to the current path without translating it.
-%
-% \begin{macrocode}
- append~ no~ move/.code={
- \tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- {
- \spath_get_current_path:N \l_@@_current_tl
- \spath_append_no_move:Nv
- \l_@@_current_tl
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- \spath_set_current_path:N \l_@@_current_tl
- \spath_set_tikz_data:v
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- }
- {
- \msg_warning:nnn { spath3 } { missing soft path } { #1 }
- }
- },
-% \end{macrocode}
-%
-% Appends the reverse of the named path without translating it.
-%
-% \begin{macrocode}
- append~ reverse~ no~ move/.code={
- \tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- {
- \spath_reverse:Nv
- \l_@@_reverse_tl
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- \spath_get_current_path:N \l_@@_current_tl
- \spath_append_no_move:NV \l_@@_current_tl \l_@@_reverse_tl
- \spath_set_current_path:N \l_@@_current_tl
- \spath_set_tikz_data:V \l_@@_reverse_tl
- }
- {
- \msg_warning:nnn { spath3 } { missing soft path } { #1 }
- }
- },
-% \end{macrocode}
-%
% Adjust a path to span between two points.
%
% \begin{macrocode}
@@ -5519,36 +5735,99 @@ manipulating PGF soft paths}
% \end{macrocode}
%
% Join the components of a path by splicing in the second path whenever the components are sufficiently far apart.
+% The third argument is a list of components to splice after, if it is empty then all components are used and a spot weld is done first so that the splicing only happens if there is an actual gap.
+%
+% The \Verb+upright+ versions will join with the reflection of the splice path if it detects that the gap is ``upside-down''.
+%
%
% \begin{macrocode}
join~ components~ with/.code~2~args={
\tl_if_exist:cTF
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
+ \tl_if_head_is_group:nTF {#2}
+ {
+ \tl_set:Nx \l_@@_tmpc_tl { \tl_item:nn {#2} {1} }
+ \tl_set:Nx \l_@@_tmpd_tl { \tl_item:nn {#2} {2} }
+ }
+ {
+ \tl_set:Nn \l_@@_tmpc_tl {#2}
+ \tl_clear:N \l_@@_tmpd_tl
+ }
\tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
{
- \spath_spot_weld_components:c
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_use:N \l_@@_prefix_tl
+ \tl_use:N \l_@@_tmpc_tl
+ \tl_use:N \l_@@_suffix_tl
+ }
+ {
+ \tl_if_empty:NT \l_@@_tmpd_tl
+ {
+ \spath_spot_weld_components:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
\spath_components_to_seq:Nv
\l_@@_tmpa_seq
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \seq_gclear:N \g_@@_tmpa_seq
+
+ \tl_if_empty:NTF \l_@@_tmpd_tl
+ {
+ \int_step_inline:nnnn {1}{1} {\seq_count:N \l_@@_tmpa_seq}
+ {
+ \seq_gput_right:Nn \g_@@_tmpa_seq {##1}
+ }
+ }
+ {
+ \foreach \l_@@_tmpa_tl in \l_@@_tmpd_tl
+ {
+ \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl
+ }
+ \seq_gsort:Nn \g_@@_tmpa_seq
+ {
+ \int_compare:nNnTF {##1} < {##2}
+ { \sort_return_same: }
+ { \sort_return_swapped: }
+ }
+ }
+
\seq_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpa_tl
-
- \seq_map_inline:Nn \l_@@_tmpa_seq
+ \seq_gpop_left:NN \g_@@_tmpa_seq \l_@@_tmpb_tl
+
+ \seq_map_indexed_inline:Nn \l_@@_tmpa_seq
{
- \spath_splice_between:Nvn \l_@@_tmpa_tl
- {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
- {##1}
+ \int_compare:nTF
+ {
+ ##1 == \l_@@_tmpb_tl
+ }
+ {
+ \seq_gpop_left:NNF \g_@@_tmpa_seq \l_@@_tmpb_tl
+ {
+ \tl_set:Nn \l_@@_tmpb_tl {-1}
+ }
+ \spath_splice_between:Nvn \l_@@_tmpa_tl
+ {
+ \tl_use:N \l_@@_prefix_tl
+ \tl_use:N \l_@@_tmpc_tl
+ \tl_use:N \l_@@_suffix_tl
+ }
+ {##2}
+ }
+ {
+ \tl_put_right:Nn \l_@@_tmpa_tl {##2}
+ }
}
\tl_set_eq:cN
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
\l_@@_tmpa_tl
}
{
- \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ \msg_warning:nnx
+ { spath3 }
+ { missing soft path }
+ { \tl_use:N \l_@@_tmpc_tl }
}
}
{
@@ -5559,30 +5838,319 @@ manipulating PGF soft paths}
\tl_if_exist:cTF
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
+ \tl_if_head_is_group:nTF {#2}
+ {
+ \tl_set:Nx \l_@@_tmpc_tl { \tl_item:nn {#2} {1} }
+ \tl_set:Nx \l_@@_tmpd_tl { \tl_item:nn {#2} {2} }
+ }
+ {
+ \tl_set:Nn \l_@@_tmpc_tl {#2}
+ \tl_clear:N \l_@@_tmpd_tl
+ }
\tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
{
- \spath_spot_gweld_components:c
+ \tl_use:N \l_@@_prefix_tl
+ \tl_use:N \l_@@_tmpc_tl
+ \tl_use:N \l_@@_suffix_tl
+ }
+ {
+ \tl_if_empty:NT \l_@@_tmpd_tl
+ {
+ \spath_spot_weld_components:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+
+ \spath_components_to_seq:Nv
+ \l_@@_tmpa_seq
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+
+ \seq_gclear:N \g_@@_tmpa_seq
+ \tl_if_empty:NTF \l_@@_tmpd_tl
+ {
+ \int_step_inline:nnnn {1}{1} {\seq_count:N \l_@@_tmpa_seq}
+ {
+ \seq_gput_right:Nn \g_@@_tmpa_seq {##1}
+ }
+ }
+ {
+ \foreach \l_@@_tmpa_tl in \l_@@_tmpd_tl
+ {
+ \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl
+ }
+ \seq_gsort:Nn \g_@@_tmpa_seq
+ {
+ \int_compare:nNnTF {##1} < {##2}
+ { \sort_return_same: }
+ { \sort_return_swapped: }
+ }
+ }
+
+ \seq_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpa_tl
+ \seq_gpop_left:NN \g_@@_tmpa_seq \l_@@_tmpb_tl
+
+ \seq_map_indexed_inline:Nn \l_@@_tmpa_seq
+ {
+ \int_compare:nTF
+ {
+ ##1 == \l_@@_tmpb_tl
+ }
+ {
+ \seq_gpop_left:NNF \g_@@_tmpa_seq \l_@@_tmpb_tl
+ {
+ \tl_set:Nn \l_@@_tmpb_tl {-1}
+ }
+ \spath_splice_between:Nvn \l_@@_tmpa_tl
+ {
+ \tl_use:N \l_@@_prefix_tl
+ \tl_use:N \l_@@_tmpc_tl
+ \tl_use:N \l_@@_suffix_tl
+ }
+ {##2}
+ }
+ {
+ \tl_put_right:Nn \l_@@_tmpa_tl {##2}
+ }
+ }
+ \tl_gset_eq:cN
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \l_@@_tmpa_tl
+ }
+ {
+ \msg_warning:nnx
+ { spath3 }
+ { missing soft path }
+ { \tl_use:N \l_@@_tmpc_tl }
+ }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ join~ components~ upright~ with/.code~2~args={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_if_head_is_group:nTF {#2}
+ {
+ \tl_set:Nx \l_@@_tmpc_tl { \tl_item:nn {#2} {1} }
+ \tl_set:Nx \l_@@_tmpd_tl { \tl_item:nn {#2} {2} }
+ }
+ {
+ \tl_set:Nn \l_@@_tmpc_tl {#2}
+ \tl_clear:N \l_@@_tmpd_tl
+ }
+ \tl_if_exist:cTF
+ {
+ \tl_use:N \l_@@_prefix_tl
+ \tl_use:N \l_@@_tmpc_tl
+ \tl_use:N \l_@@_suffix_tl
+ }
+ {
+ \tl_if_empty:NT \l_@@_tmpd_tl
+ {
+ \spath_spot_weld_components:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+
\spath_components_to_seq:Nv
\l_@@_tmpa_seq
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \seq_gclear:N \g_@@_tmpa_seq
+
+ \tl_if_empty:NTF \l_@@_tmpd_tl
+ {
+ \int_step_inline:nnnn {1}{1} {\seq_count:N \l_@@_tmpa_seq}
+ {
+ \seq_gput_right:Nn \g_@@_tmpa_seq {##1}
+ }
+ }
+ {
+ \foreach \l_@@_tmpa_tl in \l_@@_tmpd_tl
+ {
+ \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl
+ }
+ \seq_gsort:Nn \g_@@_tmpa_seq
+ {
+ \int_compare:nNnTF {##1} < {##2}
+ { \sort_return_same: }
+ { \sort_return_swapped: }
+ }
+ }
+
\seq_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpa_tl
-
- \seq_map_inline:Nn \l_@@_tmpa_seq
+ \seq_gpop_left:NN \g_@@_tmpa_seq \l_@@_tmpb_tl
+
+ \tl_set_eq:Nc \l_@@_tmpc_tl
{
- \spath_gsplice_between:Nvn \l_@@_tmpa_tl
- {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
- {##1}
+ \tl_use:N \l_@@_prefix_tl
+ \tl_use:N \l_@@_tmpc_tl
+ \tl_use:N \l_@@_suffix_tl
+ }
+ \spath_transform:NVnnnnnn \l_@@_tmpd_tl \l_@@_tmpc_tl {1}{0}{0}{-1}{0pt}{0pt}
+
+ \seq_map_indexed_inline:Nn \l_@@_tmpa_seq
+ {
+ \int_compare:nTF
+ {
+ ##1 == \l_@@_tmpb_tl
+ }
+ {
+ \seq_gpop_left:NNF \g_@@_tmpa_seq \l_@@_tmpb_tl
+ {
+ \tl_set:Nn \l_@@_tmpb_tl {-1}
+ }
+ \spath_finalpoint:NV \l_@@_tmpe_tl \l_@@_tmpa_tl
+ \spath_initialpoint:Nn \l_@@_tmpf_tl {##2}
+
+ \dim_compare:nTF
+ {
+ \tl_item:Nn \l_@@_tmpe_tl {1}
+ >
+ \tl_item:Nn \l_@@_tmpf_tl {1}
+ }
+ {
+ \spath_splice_between:NVn
+ \l_@@_tmpa_tl
+ \l_@@_tmpd_tl
+ {##2}
+ }
+ {
+ \spath_splice_between:NVn
+ \l_@@_tmpa_tl
+ \l_@@_tmpc_tl
+ {##2}
+ }
+ }
+ {
+ \tl_put_right:Nn \l_@@_tmpa_tl {##2}
+ }
}
\tl_set_eq:cN
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
\l_@@_tmpa_tl
}
{
- \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ \msg_warning:nnx
+ { spath3 }
+ { missing soft path }
+ { \tl_use:N \l_@@_tmpc_tl }
+ }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ join~ components~ globally~ upright~ with/.code~2~args={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_if_head_is_group:nTF {#2}
+ {
+ \tl_set:Nx \l_@@_tmpc_tl { \tl_item:nn {#2} {1} }
+ \tl_set:Nx \l_@@_tmpd_tl { \tl_item:nn {#2} {2} }
+ }
+ {
+ \tl_set:Nn \l_@@_tmpc_tl {#2}
+ \tl_clear:N \l_@@_tmpd_tl
+ }
+ \tl_if_exist:cTF
+ {
+ \tl_use:N \l_@@_prefix_tl
+ \tl_use:N \l_@@_tmpc_tl
+ \tl_use:N \l_@@_suffix_tl
+ }
+ {
+ \tl_if_empty:NT \l_@@_tmpd_tl
+ {
+ \spath_spot_weld_components:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+
+ \spath_components_to_seq:Nv
+ \l_@@_tmpa_seq
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+
+ \seq_gclear:N \g_@@_tmpa_seq
+
+ \tl_if_empty:NTF \l_@@_tmpd_tl
+ {
+ \int_step_inline:nnnn {1}{1} {\seq_count:N \l_@@_tmpa_seq}
+ {
+ \seq_gput_right:Nn \g_@@_tmpa_seq {##1}
+ }
+ }
+ {
+ \foreach \l_@@_tmpa_tl in \l_@@_tmpd_tl
+ {
+ \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl
+ }
+ \seq_gsort:Nn \g_@@_tmpa_seq
+ {
+ \int_compare:nNnTF {##1} < {##2}
+ { \sort_return_same: }
+ { \sort_return_swapped: }
+ }
+ }
+
+ \seq_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpa_tl
+ \seq_gpop_left:NN \g_@@_tmpa_seq \l_@@_tmpb_tl
+
+ \tl_set_eq:Nc \l_@@_tmpc_tl
+ {
+ \tl_use:N \l_@@_prefix_tl
+ \tl_use:N \l_@@_tmpc_tl
+ \tl_use:N \l_@@_suffix_tl
+ }
+ \spath_transform:NVnnnnnn \l_@@_tmpd_tl \l_@@_tmpc_tl {1}{0}{0}{-1}{0pt}{0pt}
+
+ \seq_map_indexed_inline:Nn \l_@@_tmpa_seq
+ {
+ \int_compare:nTF
+ {
+ ##1 == \l_@@_tmpb_tl
+ }
+ {
+ \seq_gpop_left:NNF \g_@@_tmpa_seq \l_@@_tmpb_tl
+ {
+ \tl_set:Nn \l_@@_tmpb_tl {-1}
+ }
+ \spath_finalpoint:NV \l_@@_tmpe_tl \l_@@_tmpa_tl
+ \spath_initialpoint:Nn \l_@@_tmpf_tl {##2}
+
+ \dim_compare:nTF
+ {
+ \tl_item:Nn \l_@@_tmpe_tl {1}
+ >
+ \tl_item:Nn \l_@@_tmpf_tl {1}
+ }
+ {
+ \spath_splice_between:NVn
+ \l_@@_tmpa_tl
+ \l_@@_tmpd_tl
+ {##2}
+ }
+ {
+ \spath_splice_between:NVn
+ \l_@@_tmpa_tl
+ \l_@@_tmpc_tl
+ {##2}
+ }
+ }
+ {
+ \tl_put_right:Nn \l_@@_tmpa_tl {##2}
+ }
+ }
+ \tl_gset_eq:cN
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \l_@@_tmpa_tl
+ }
+ {
+ \msg_warning:nnx
+ { spath3 }
+ { missing soft path }
+ { \tl_use:N \l_@@_tmpc_tl }
}
}
{
@@ -5790,22 +6358,6 @@ manipulating PGF soft paths}
},
% \end{macrocode}
%
-% Exports the path as an SVG file.
-%
-% \begin{macrocode}
- export~ to~ svg/.code={
- \tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- {
- \spath_export_to_svg:nv {#1}
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- }
- {
- \msg_warning:nnn { spath3 } { missing soft path } { #1 }
- }
- },
-% \end{macrocode}
-%
% Transforms the named path using TikZ transformation specifications.
%
% \begin{macrocode}
@@ -5858,40 +6410,58 @@ manipulating PGF soft paths}
% \begin{macrocode}
split~ at~ intersections~ with/.code~ n~ args={2}{
\tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ tikz@library@intersections@loaded
+ }
{
\tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
- \spath_split_path_at_intersections:cv
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
{\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_split_path_at_intersections:cv
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ }
}
{
- \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
}
}
{
- \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ \msg_warning:nn { spath3 } { load intersections }
}
},
split~ globally~ at~ intersections~ with/.code~ n~ args={2}{
\tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
- \tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ tikz@library@intersections@loaded
+ }
+ {
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
- \spath_gsplit_path_at_intersections:cv
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
{\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_gsplit_path_at_intersections:cv
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ }
}
{
- \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
}
}
{
- \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ \msg_warning:nn { spath3 } { load intersections }
}
},
% \end{macrocode}
@@ -5901,40 +6471,58 @@ manipulating PGF soft paths}
% \begin{macrocode}
split~ at~ intersections/.code~ n~ args={2}{
\tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ tikz@library@intersections@loaded
+ }
{
\tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
- \spath_split_at_intersections:cc
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
{\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_split_at_intersections:cc
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ }
}
{
- \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
}
}
{
- \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ \msg_warning:nn { spath3 } { load intersections }
}
},
split~ globally~ at~ intersections/.code~ n~ args={2}{
\tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ tikz@library@intersections@loaded
+ }
{
\tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
- \spath_gsplit_at_intersections:cc
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
{\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_gsplit_at_intersections:cc
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ }
}
{
- \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
}
}
{
- \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ \msg_warning:nn { spath3 } { load intersections }
}
},
% \end{macrocode}
@@ -5944,24 +6532,42 @@ manipulating PGF soft paths}
% \begin{macrocode}
split~ at~ self~ intersections/.code={
\tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
- \spath_split_at_self_intersections:c
+ tikz@library@intersections@loaded
+ }
+ {
+ \tl_if_exist:cTF
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_split_at_self_intersections:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
}
{
- \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ \msg_warning:nn { spath3 } { load intersections }
}
},
split~ globally~ at~ self~ intersections/.code={
\tl_if_exist:cTF
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
- \spath_gsplit_at_self_intersections:c
+ tikz@library@intersections@loaded
+ }
+ {
+ \tl_if_exist:cTF
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_gsplit_at_self_intersections:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
}
{
- \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ \msg_warning:nn { spath3 } { load intersections }
}
},
% \end{macrocode}
@@ -6069,40 +6675,64 @@ manipulating PGF soft paths}
% The list of components is passed through a \Verb+\foreach+ loop so can use the shortcut syntax from those loops.
%
% \begin{macrocode}
- insert~ gaps~ after~ components/.code~ n~ args={3}{
+ insert~ gaps~ after~ components/.code~ 2~ args={
\tl_if_exist:cTF
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\group_begin:
+ \tl_if_head_is_group:nTF {#2}
+ {
+ \tl_set:Nx \l_@@_tmpc_tl { \tl_item:nn {#2} {1} }
+ \tl_set:Nx \l_@@_tmpd_tl { \tl_item:nn {#2} {2} }
+ }
+ {
+ \tl_set:Nn \l_@@_tmpc_tl {#2}
+ \tl_clear:N \l_@@_tmpd_tl
+ }
\seq_gclear:N \g_@@_tmpa_seq
\seq_gclear:N \g_@@_tmpb_seq
\spath_numberofcomponents:Nv \l_@@_tmpa_int
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- \foreach \l_@@_tmpa_tl in {#3}
+
+ \spath_components_to_seq:Nv
+ \l_@@_tmpa_seq
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+
+ \tl_if_empty:NTF \l_@@_tmpd_tl
{
- \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl
- \seq_gput_right:Nx
- \g_@@_tmpb_seq
- {\int_eval:n
- {
- \int_mod:nn { \l_@@_tmpa_tl }{ \l_@@_tmpa_int } + 1
+ \int_step_inline:nnnn {1}{1} { \l_@@_tmpa_int - 1 }
+ {
+ \seq_gput_right:Nn \g_@@_tmpa_seq {##1}
+ \seq_gput_right:Nx
+ \g_@@_tmpb_seq
+ {\int_eval:n {##1 + 1}}
+ }
+ }
+ {
+ \foreach \l_@@_tmpa_tl in \l_@@_tmpd_tl
+ {
+ \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl
+ \seq_gput_right:Nx
+ \g_@@_tmpb_seq
+ {\int_eval:n
+ {
+ \int_mod:nn { \l_@@_tmpa_tl }{ \l_@@_tmpa_int } + 1
+ }
}
}
}
- \spath_components_to_seq:Nv
- \l_@@_tmpa_seq
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+
\seq_clear:N \l_@@_tmpb_seq
\seq_map_indexed_inline:Nn \l_@@_tmpa_seq
{
\tl_set:Nn \l_@@_tmpa_tl {##2}
\seq_if_in:NnT \g_@@_tmpa_seq {##1}
{
- \spath_shorten_at_end:Nn \l_@@_tmpa_tl {#2/2}
+ \spath_shorten_at_end:Nn \l_@@_tmpa_tl {\l_@@_tmpc_tl/2}
}
\seq_if_in:NnT \g_@@_tmpb_seq {##1}
{
- \spath_shorten_at_start:Nn \l_@@_tmpa_tl {#2/2}
+ \spath_shorten_at_start:Nn \l_@@_tmpa_tl {\l_@@_tmpc_tl/2}
}
\seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpa_tl
}
@@ -6117,41 +6747,64 @@ manipulating PGF soft paths}
\msg_warning:nnn { spath3 } { missing soft path } { #1 }
}
},
- insert~ gaps~ globally~ after~ components/.code~ n~ args={3}{
+ insert~ gaps~ globally~ after~ components/.code~ 2~ args={
\tl_if_exist:cTF
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\group_begin:
+ \tl_if_head_is_group:nTF {#2}
+ {
+ \tl_set:Nx \l_@@_tmpc_tl { \tl_item:nn {#2} {1} }
+ \tl_set:Nx \l_@@_tmpd_tl { \tl_item:nn {#2} {2} }
+ }
+ {
+ \tl_set:Nn \l_@@_tmpc_tl {#2}
+ \tl_clear:N \l_@@_tmpd_tl
+ }
\seq_gclear:N \g_@@_tmpa_seq
\seq_gclear:N \g_@@_tmpb_seq
\spath_numberofcomponents:Nv \l_@@_tmpa_int
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- \foreach \l_@@_tmpa_tl in {#3}
+
+ \spath_components_to_seq:Nv
+ \l_@@_tmpa_seq
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+
+ \tl_if_empty:NTF \l_@@_tmpd_tl
{
- \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl
- \seq_gput_right:Nx
- \g_@@_tmpb_seq
+ \int_step_inline:nnnn {1}{1} { \l_@@_tmpa_int - 1 }
{
- \int_eval:n
- {
- \int_mod:nn { \l_@@_tmpa_tl }{ \l_@@_tmpa_int } + 1
+ \seq_gput_right:Nn \g_@@_tmpa_seq {##1}
+ \seq_gput_right:Nx
+ \g_@@_tmpb_seq
+ {\int_eval:n {##1 + 1}}
+ }
+ }
+ {
+ \foreach \l_@@_tmpa_tl in \l_@@_tmpd_tl
+ {
+ \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl
+ \seq_gput_right:Nx
+ \g_@@_tmpb_seq
+ {\int_eval:n
+ {
+ \int_mod:nn { \l_@@_tmpa_tl }{ \l_@@_tmpa_int } + 1
+ }
}
}
}
- \spath_components_to_seq:Nv
- \l_@@_tmpa_seq
- {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+
\seq_clear:N \l_@@_tmpb_seq
\seq_map_indexed_inline:Nn \l_@@_tmpa_seq
{
\tl_set:Nn \l_@@_tmpa_tl {##2}
\seq_if_in:NnT \g_@@_tmpa_seq {##1}
{
- \spath_shorten_at_end:Nn \l_@@_tmpa_tl {#2/2}
+ \spath_shorten_at_end:Nn \l_@@_tmpa_tl {\l_@@_tmpc_tl/2}
}
\seq_if_in:NnT \g_@@_tmpb_seq {##1}
{
- \spath_shorten_at_start:Nn \l_@@_tmpa_tl {#2/2}
+ \spath_shorten_at_start:Nn \l_@@_tmpa_tl {\l_@@_tmpc_tl/2}
}
\seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpa_tl
}
@@ -6250,6 +6903,33 @@ manipulating PGF soft paths}
},
% \end{macrocode}
%
+% Replace all line segments by B\'ezier curves.
+%
+% \begin{macrocode}
+ replace~ lines/.code={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_replace_lines:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ replace~ lines~ globally/.code={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_greplace_lines:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+% \end{macrocode}
+%
%
% Join the specified components together, joining each to its previous one.
%
@@ -6547,7 +7227,10 @@ manipulating PGF soft paths}
}
}
{
- \msg_warning:nnx { spath3 } { missing soft path } { \tl_use:N \l_@@_tmpa_tl }
+ \msg_warning:nnx
+ { spath3 }
+ { missing soft path }
+ { \tl_use:N \l_@@_tmpa_tl }
\tl_gset_eq:NN \g_@@_smuggle_tl \pgfpointorigin
}
\group_end:
diff --git a/graphics/pgf/contrib/spath3/spath3_code.pdf b/graphics/pgf/contrib/spath3/spath3_code.pdf
index 0fe9fd3e43..e61a569ddf 100644
--- a/graphics/pgf/contrib/spath3/spath3_code.pdf
+++ b/graphics/pgf/contrib/spath3/spath3_code.pdf
Binary files differ
diff --git a/graphics/pgf/contrib/tikzmark/tikzmark.dtx b/graphics/pgf/contrib/tikzmark/tikzmark.dtx
index 4dfaeb6e78..88aec1a4ed 100644
--- a/graphics/pgf/contrib/tikzmark/tikzmark.dtx
+++ b/graphics/pgf/contrib/tikzmark/tikzmark.dtx
@@ -36,7 +36,7 @@ See http://www.latex-project.org/lppl.txt
\endpreamble
\postamble
-Copyright (C) 2011-2018 by Andrew Stacey <loopspace@mathforge.org>
+Copyright (C) 2011-2021 by Andrew Stacey <loopspace@mathforge.org>
This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License (LPPL), either
@@ -206,7 +206,7 @@ and the derived files tikzmark.ins,
%</driver>
% \fi
%
-% \CheckSum{1138}
+% \CheckSum{1178}
%
% \CharacterTable
% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
@@ -234,18 +234,19 @@ and the derived files tikzmark.ins,
% \changes{1.6}{2018/10/18}{Added the ability to save node information between runs and between TeX documents}
% \changes{1.7}{2019/05/07}{Added conditions to test if a tikzmark is on a particular page}
% \changes{1.8}{2019/10/04}{Fixed some bugs with subnode and tikzmarknode inside maths}
+% \changes{1.10}{2021/02/16}{Tikzmarknode is now prefix and suffix aware, and added a test to see if a picture id has been saved to the aux file for times when pictures are thrown away, eg in AMS's text command}
%
% \DoNotIndex{\newcommand,\newenvironment}
%
+% \GetFileInfo{tikzlibrarytikzmark.code.tex}
% \providecommand*{\url}{\texttt}
% \title{The \textsf{tikzmark} package}
% \author{Andrew Stacey \\ \url{loopspace@mathforge.org}}
-% \date{v1.8~from 2019/10/04}
+% \date{\fileversion~from \filedate}
%
%
% \maketitle
%
-%
% \section{Introduction}
%
% The \Verb+\tikzmark+ macro burst onto the scene in a blaze of glory on \href{http://tex.stackexchange.com}{TeX-SX}.
@@ -452,6 +453,23 @@ and the derived files tikzmark.ins,
% This is the TikZ key that is used by \Verb+\tikzmark+ to actually save the connection between the name and the picture coordinate.
% It can be used on an arbitrary picture to save its origin as a tikzmark.
%
+% \item \Verb+/tikz/check picture id+
+%
+% There are circumstances where, behind the scenes, a tikzpicture is actually placed in a box and processed several times (often this involves \Verb+\mathchoice+).
+% In such a situation, when defining nodes then the last one ``wins'' in that each node remembers the id of the last processed picture.
+% However, only the one that is actually used has its location remembered on the page (since the others don't have a position).
+% This can lead to the situation whereby a node becomes disassociated from its picture and so using it for later reference fails.
+% This key tries to get around that situation by checking the \Verb+aux+ file to see if the current picture was actually typeset last time (by checking for the presence of the remembered location) and if it find that it wasn't, it quietly appends the string \Verb+discard-+ to each node name.
+% The idea being that the version of the picture that is actually typeset will not have this happen and so its nodes ``survive''.
+%
+% \item \Verb+/tikz/maybe define node=#1+
+%
+% The previous key can lead to undefined nodes on the first time that the picture is processed.
+% Using this key will ensure that the specified node is aliased to its \Verb+discard-+ version providing it doesn't already exist.
+% This is purely to get rid of pointless error messages, and also should only be used in conjunction with \Verb+check picture id+.
+%
+% Note that due to the order in which code gets executed, \Verb+check picture id+ should be before any \Verb+maybe define node+ keys.
+%
% \item \Verb+/tikz/if picture id=#1#2#3+
%
% This is a key equivalent of the \Verb+\iftikzmark+ command.
@@ -791,6 +809,10 @@ and the derived files tikzmark.ins,
%
% The \Verb+save nodes+ code uses \LaTeX3.
% \begin{macrocode}
+\ProvidesFile{tikzlibrarytikzmark.code.tex}[%
+ 2021/02/16
+ v1.10
+ TikZ library for marking positions in a document]
\RequirePackage{expl3, l3keys2e, xparse}
% \end{macrocode}
%
@@ -819,6 +841,44 @@ and the derived files tikzmark.ins,
},
},
% \end{macrocode}
+% There are times when some code is executed and then discarded, such as in \Verb+\mathchoice+.
+% This can seriously mess with how TikZ pictures are remembered as the last \Verb+pgfpictureid+ to be \emph{processed} is the one that is used, but it is the one that is \emph{used} that is recorded in the \Verb+aux+ file.
+% This isn't particularly a tikzmark issue, but does come up from time to time with tikzmark as it's all about remembering locations.
+%
+% In actual fact, it only occurs with \Verb+\tikzmarknode+ since the issue is about how nodes are associated with pictures.
+%
+% The solution is to check to see if the \Verb+pgfpictureid+ has been recorded in the \Verb+aux+ file and if it hasn't, quietly prefix the node names with a discard term.
+% This needs to be used \emph{after} \Verb+remember picture+ has been invoked.
+% It probably messes with some other stuff so should only be used under controlled conditions, such as \Verb+\tikzmarknode+.
+% \begin{macrocode}
+ check picture id/.code={
+ \ifpgfrememberpicturepositiononpage
+ \@ifundefined{pgf@sys@pdf@mark@pos@\pgfpictureid}{%
+ \tikzset{%
+ name prefix/.get=\tzmk@name@prefix,
+ name prefix/.prefix=discard-,
+ execute at end picture={%
+ \tikzset{name prefix/.expand once=\tzmk@name@prefix}%
+ },
+ }%
+ }{}%
+ \fi
+ },
+% \end{macrocode}
+% We also want a failsafe that quietly handles the case where the document hasn't been compiled enough times (once) to get the information into the \Verb+aux+ file.
+% There will already be messages about needing reruns so we don't need to add to that.
+% We simply ensure that the node exists.
+% \begin{macrocode}
+ maybe define node/.style={%
+ execute at end picture={%
+ \ifpgfrememberpicturepositiononpage
+ \@ifundefined{pgf@sh@pi@\tikz@pp@name{#1}}{%
+ \pgfnodealias{\tikz@pp@name{#1}}{discard-\tikz@pp@name{#1}}%
+ }{}%
+ \fi
+ }%
+ },
+% \end{macrocode}
% The positions are already recorded in the \Verb+aux+ file, all we really need to do is provide them with better names.
% \begin{macrocode}
save picture id/.code={%
@@ -860,10 +920,14 @@ and the derived files tikzmark.ins,
\@ifundefined{save@pt@\tikzmark@pp@name{#1}}{%
\pgfkeysalso{#3}%
}{%
- \@ifundefined{save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname}{%
+ \@ifundefined{%
+ save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname
+ }{%
\pgfkeysalso{#3}%
}{%
- \ifnum\csname save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname\endcsname=\the\value{page}\relax%
+ \ifnum\csname save@pg@%
+ \csname save@pt@\tikzmark@pp@name{#1}\endcsname%
+ \endcsname=\the\value{page}\relax%
\pgfkeysalso{#2}%
\else
\pgfkeysalso{#3}%
@@ -875,10 +939,14 @@ and the derived files tikzmark.ins,
\@ifundefined{save@pt@\tikzmark@pp@name{#1}}{%
\pgfkeysalso{#4}%
}{%
- \@ifundefined{save@pg@\csname save@pt@\tikzmark@pp@name{#1}@label\endcsname}{%
+ \@ifundefined{%
+ save@pg@\csname save@pt@\tikzmark@pp@name{#1}@label\endcsname%
+ }{%
\pgfkeysalso{#4}%
}{%
- \ifnum\csname save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname\endcsname=#2\relax%
+ \ifnum\csname save@pg@%
+ \csname save@pt@\tikzmark@pp@name{#1}\endcsname%
+ \endcsname=#2\relax%
\pgfkeysalso{#3}%
\else
\pgfkeysalso{#4}%
@@ -969,7 +1037,12 @@ and the derived files tikzmark.ins,
\@ifundefined{save@pg@\csname save@pt@\tmk@label\endcsname}{}{%
\@ifundefined{save@pg@\pgfpictureid}{}{%
\pgfkeysvalueof{/tikz/next page vector}%
- \edef\tmk@pg{\the\numexpr \csname save@pg@\csname save@pt@\tmk@label\endcsname\endcsname - \csname save@pg@\pgfpictureid\endcsname\relax}%
+ \edef\tmk@pg{%
+ \the\numexpr \csname save@pg@%
+ \csname save@pt@\tmk@label\endcsname\endcsname%
+ -
+ \csname save@pg@\pgfpictureid\endcsname\relax%
+ }%
\ifnum \tmk@pg > 0 \relax
\advance \pgf@xa by \pgf@x\relax
\advance \pgf@ya by \pgf@y\relax
@@ -995,6 +1068,7 @@ and the derived files tikzmark.ins,
% This version is for when we're outside a tikzpicture environment
% \begin{macrocode}
\newcommand\tikzmark@outside[2][]{%
+\tikzset{external/export next/.try=false}%
\tikz[remember picture with id=#2]{#1}%
}
% \end{macrocode}
@@ -1004,7 +1078,8 @@ and the derived files tikzmark.ins,
\tikzset{remember picture}%
\tikz@scan@one@point\pgfutil@firstofone#2\relax
\protected@write\pgfutil@auxout{}{%
- \string\savepointas{\tikzmark@pp@name{#1}}{\pgfpictureid}{\the\pgf@x}{\the\pgf@y}}%
+ \string\savepointas%
+ {\tikzmark@pp@name{#1}}{\pgfpictureid}{\the\pgf@x}{\the\pgf@y}}%
}
% \end{macrocode}
% And finally, the ultimate invoker:
@@ -1111,7 +1186,9 @@ and the derived files tikzmark.ins,
\@ifundefined{save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname}{%
\tikzmark@false
}{%
- \ifnum\csname save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname\endcsname=#2\relax%
+ \ifnum\csname save@pg@%
+ \csname save@pt@\tikzmark@pp@name{#1}\endcsname%
+ \endcsname=#2\relax%
\tikzmark@true
\else
\tikzmark@false
@@ -1132,7 +1209,9 @@ and the derived files tikzmark.ins,
\@ifundefined{save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname}{%
\tikzmark@false
}{%
- \ifnum\csname save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname\endcsname=\the\value{page}\relax%
+ \ifnum\csname save@pg@%
+ \csname save@pt@\tikzmark@pp@name{#1}\endcsname%
+ \endcsname=\the\value{page}\relax%
\tikzmark@true
\else
\tikzmark@false
@@ -1252,10 +1331,13 @@ and the derived files tikzmark.ins,
% It does its best to work inside a math environment by a sneaky trick involving \Verb+\mathchoice+: the \Verb+remember picture+ key means that only the picture id of the typeset box is saved to the aux file. So comparing the possible picture ids of the four options with the one read from the aux file, we can figure out which box was actually used.
% \begin{macrocode}
\def\tikzmarknode@#1#2#3{%
+\tikzset{external/export next/.try=false}%
\tikz[%
remember picture,
- baseline=(#2.base),
save picture id={#2},
+ check picture id,
+ maybe define node={#2},
+ baseline=(#2.base),
every tikzmarknode picture/.try
] {
\node[
@@ -1290,25 +1372,25 @@ and the derived files tikzmark.ins,
\expandafter\ifx\csname\tzmk@pic\endcsname\relax
\edef\tzmk@pic{\tzmk@prfx\the\numexpr\the\pgf@picture@serial@count-3\relax}%
\expandafter\ifx\csname\tzmk@pic\endcsname\relax
- \pgfutil@ifundefined{pgf@sh@ns@#2}{%
- \pgfnodealias{#2}{#2-t}%
- \tikzmarkalias{#2}{#2-t}%
+ \pgfutil@ifundefined{pgf@sh@ns@\tikz@pp@name{#2}}{%
+ \pgfnodealias{\tikz@pp@name{#2}}{\tikz@pp@name{#2-t}}%
+ \tikzmarkalias{\tikzmark@pp@name{#2}}{\tikzmark@pp@name{#2-t}}%
}{}%
\else
- \pgfnodealias{#2}{#2-d}%
- \tikzmarkalias{#2}{#2-d}%
+ \pgfnodealias{\tikz@pp@name{#2}}{\tikz@pp@name{#2-d}}%
+ \tikzmarkalias{\tikzmark@pp@name{#2}}{\tikzmark@pp@name{#2-d}}%
\fi
\else
- \pgfnodealias{#2}{#2-t}%
- \tikzmarkalias{#2}{#2-t}%
+ \pgfnodealias{\tikz@pp@name{#2}}{\tikz@pp@name{#2-t}}%
+ \tikzmarkalias{\tikzmark@pp@name{#2}}{\tikzmark@pp@name{#2-t}}%
\fi
\else
- \pgfnodealias{#2}{#2-s}%
- \tikzmarkalias{#2}{#2-s}%
+ \pgfnodealias{\tikz@pp@name{#2}}{\tikz@pp@name{#2-s}}%
+ \tikzmarkalias{\tikzmark@pp@name{#2}}{\tikzmark@pp@name{#2-s}}%
\fi
\else
- \pgfnodealias{#2}{#2-ss}%
- \tikzmarkalias{#2}{#2-ss}%
+ \pgfnodealias{\tikz@pp@name{#2}}{\tikz@pp@name{#2-ss}}%
+ \tikzmarkalias{\tikzmark@pp@name{#2}}{\tikzmark@pp@name{#2-ss}}%
\fi
\else
\tikzmarknode@{#1}{#2}{#3}%
@@ -1886,8 +1968,10 @@ and the derived files tikzmark.ins,
%
% \begin{macro}{\iflst@linemark}
% A conditional to help with placing the mark at the first non-whitespace character.
+% Should be set to true so that we notice the first line of the code.
% \begin{macrocode}
- \newif\iflst@linemark
+ \newif\iflst@linemark
+ \lst@linemarktrue
% \end{macrocode}
% \end{macro}
%
diff --git a/graphics/pgf/contrib/tikzmark/tikzmark.pdf b/graphics/pgf/contrib/tikzmark/tikzmark.pdf
index 0b8d460f3e..62c1de9cca 100644
--- a/graphics/pgf/contrib/tikzmark/tikzmark.pdf
+++ b/graphics/pgf/contrib/tikzmark/tikzmark.pdf
Binary files differ