├── .gitignore ├── README.md ├── tests ├── PW-tikzmark-beamer.tex ├── babel_test.tex ├── circuittikziteration.tex ├── piclocation.tex ├── scopelocation.tex ├── tikzmark-beamer.tex ├── tikzmark_test.tex ├── tikzmathchoice.tex └── tikzrefextnodes.tex ├── tikzmark.dtx └── tikzmarkExample.pdf /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.png 3 | *.gls 4 | *.ilg 5 | *.aux 6 | *.log 7 | *.out 8 | *.hd 9 | *.idx 10 | *.nav 11 | *.snm 12 | *.pdf 13 | *.ins 14 | *.toc 15 | *.glo 16 | README.txt 17 | *.code.tex 18 | CTAN 19 | tests 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The tikzmark Package 2 | 3 | This is the official home of the development repository for the 4 | `tikzmark` library for LaTeX. 5 | This package is for marking a position on a page or within a 6 | `tikzpicture` which can be referred to in another TikZ drawing. 7 | 8 | The current published version can be 9 | found [on CTAN](https://ctan.org/pkg/tikzmark?lang=en) and the 10 | documentation is there as a PDF. 11 | 12 | To use the most recent version, download the file `tikzmark.dtx`. To 13 | generate the library files, run `tex tikzmark.dtx`. To generate the 14 | documentation, run `pdflatex tikzmark.dtx`. 15 | 16 | ## TL;DR 17 | 18 | The `tikzmark` package provides a variety of commands which have 19 | evolved over the years since I first defined it in 2009. Much of this 20 | has taken place on the [TeX-SX Q&A](https://tex.stackexchange.com) 21 | ([questions tagged 22 | `tikzmark`](https://tex.stackexchange.com/questions/tagged/tikzmark) 23 | and just [all posts mentioning `tikzmark`](https://tex.stackexchange.com/search?q=tikzmark)) 24 | site so there are many versions in answers on that site, and there 25 | have been a few spin-offs by others. There is much on that site that 26 | is useful, but due to this evolution sometimes the command used by 27 | older answers is not the right one when used with this library. 28 | 29 | The main question to ask is: does the command make a node or just a 30 | mark? 31 | In brief, the _original_ `\tikzmark` made a node, but then I 32 | simplified it to just make a mark. 33 | 34 | ### Marks 35 | 36 | * `\tikzmark` - remembers a location on a page, can be used both 37 | inside and outside a `tikzpicture`, the position is available 38 | throughout the _entire_ document, including before it is defined. 39 | * `\pgfmark` - a more basic location remembering command. 40 | * `(pic cs:)` - this is how to refer to a remembered mark in a 41 | `tikzpicture`. 42 | 43 | ### Nodes 44 | 45 | * `\tikzmarknode` - creates a node around its contents, and remembers 46 | its location; uses some TeX trickery to detect math modes. 47 | * `\subnode` - when used inside a TikZ node it creates a pseudo-node 48 | around its contents that can be used as if it were a node within the 49 | surrounding `tikzpicture`. 50 | 51 | ## Other Features 52 | 53 | * Node saving: the marks created by `\tikzmark` and `\pgfmark` are 54 | available prior to their definition in the document; there is also 55 | facility for saving node information to make it available where it 56 | wouldn't normally - either earlier in the document or in a different 57 | document. 58 | * Pic and scope positioning: nodes can be _anchored_ at certain 59 | locations, this extends that concept to pics and scopes. 60 | 61 | ### Additional Libraries 62 | 63 | The concept of marking locations for TikZ has inspired a variety of 64 | useful routines for particular situations, so are not loaded 65 | automatically but can be accessed via `\usetikzmarklibrary`. These 66 | are: 67 | 68 | * **listings**: for highlighting code listings when using the 69 | `listings` package. 70 | * **ams**: puts a node around the boxes used by AMS math when it 71 | typesets equations. 72 | * **higlighting**: simulates highlighting text delimited by a couple 73 | of tikzmarks. 74 | -------------------------------------------------------------------------------- /tests/PW-tikzmark-beamer.tex: -------------------------------------------------------------------------------- 1 | % Reported by Patrick Wambacq via email 2017-02-05 2 | \documentclass[12pt]{beamer} 3 | \usepackage{tikz} 4 | \usetikzlibrary{tikzmark} 5 | 6 | \begin{document} 7 | \begin{frame} 8 | \begin{tikzpicture}[remember picture, overlay] 9 | \draw[->,line width=1mm,cyan] (pic cs:a) to [bend left] (pic cs:b); 10 | \end{tikzpicture} 11 | 12 | By placing the \tikzmark{a} code before the marks, the arrow goes 13 | under the subsequent text and picture. 14 | 15 | \begin{tikzpicture} 16 | \filldraw[fill=gray] (0,0) circle[radius=1cm]; 17 | \tikzmark{b}{(-1,-1)} 18 | \end{tikzpicture} 19 | \end{frame} 20 | \end{document} 21 | -------------------------------------------------------------------------------- /tests/babel_test.tex: -------------------------------------------------------------------------------- 1 | \immediate\write18{tex tikzmark.dtx} 2 | \documentclass{article} 3 | \usepackage[frenchb]{babel} 4 | \usepackage{tikz} 5 | \usetikzlibrary{calc,babel,tikzmark} 6 | \begin{document} 7 | test\tikzmark{a} 8 | 9 | \tikz[remember picture with id=b]{} 10 | 11 | Go to test\tikz[overlay, remember picture] \draw[->] (0,0) to (pic cs:a);. 12 | 13 | \tikz[overlay, remember picture] \draw[->] (pic cs:b) to (pic cs:a); 14 | \end{document} 15 | -------------------------------------------------------------------------------- /tests/circuittikziteration.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage{circuitikzgit} 3 | \usetikzlibrary{tikzmark,fpu} 4 | 5 | \tikzset{ov/.pic = { 6 | % reference anchor is -center 7 | \draw coordinate(-center) 8 | (-center) +(-1.2,-1) rectangle +(1.2,1) 9 | (-center) ++(-1.2,0.8) coordinate (-in 1) 10 | (-center) ++(-1.2,-0.8) coordinate (-in 2) 11 | (-center) ++(1.2,0.8) coordinate (-out 1) 12 | (-center) ++(1.2,-0.8) coordinate (-out 2) 13 | (-center) ++(0,1) coordinate (-up) 14 | (-in 1) -- ++(0.5,0) coordinate(-tmp) 15 | to[leD*, diodes/scale=0.6, led arrows from cathode, name=-led] 16 | (-tmp|- -in 2) -- (-in 2) 17 | (-out 1) -- ++(-0.5,0) coordinate(-tmp) 18 | to[pD*, diodes/scale=0.4, mirror, name=-pd1] ++(0,-0.5) 19 | edge[densely dashed] ++(0,-0.533) ++(0,-0.566) 20 | to[pD*, diodes/scale=0.4,mirror, name=-pd2] (-tmp|- -out 2) -- (-out 2) 21 | % leave the position of the path at the center 22 | (-center); 23 | } 24 | } 25 | \begin{document} 26 | 27 | Circuitikz: \pgfcircversion{} (\pgfcircversiondate)\par 28 | Ti\emph{k}Z: \pgfversion{} (\pgfversiondate)\par\bigskip 29 | 30 | 31 | \begin{tikzpicture} 32 | \draw (0,0) pic(one) {ov}; 33 | \node [above] at (one-up) {O1}; 34 | \draw[color=blue] (one-out 1) -- ++(1,0) 35 | % pic[pic anchor=(-in 1)](two) {ov}; 36 | pic[tikzmark round=2, rotate=45, transform shape, pic anchor=(-in 1)](two) {ov}; 37 | \node [above] at (two-up) {O2}; 38 | \end{tikzpicture} 39 | \end{document} 40 | -------------------------------------------------------------------------------- /tests/piclocation.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | 3 | \usepackage{tikz} 4 | \usetikzlibrary{ 5 | tikzmark, 6 | positioning 7 | } 8 | 9 | \tikzset{ 10 | location/.pic={ 11 | \draw (0,0) -- (2,3); 12 | \node (-A) at (2,1) {A}; 13 | \pic at (2,0) {sub location}; 14 | }, 15 | sub location/.pic={ 16 | \node (-B) at (0,0) {B}; 17 | \node (-C) at (0,1) {C}; 18 | } 19 | } 20 | 21 | \begin{document} 22 | 23 | \begin{tikzpicture} 24 | \draw 25 | (0,0) circle[radius=6pt] 26 | (2,1) circle[radius=6pt] 27 | ; 28 | \pic[name=test,pic anchor={(-A)}] at (2,1) {location}; 29 | \draw[red] (pic cs:test-origin) -- (pic cs:test-anchor); 30 | \begin{scope}[shift={(2,3)},rotate=30,scale=2] 31 | \fill 32 | (1,0) circle[radius=3pt] 33 | ; 34 | \draw (pic cs:where is it) -- ++(0,1); 35 | \tikzmark{where is it}{(1,0)} 36 | \end{scope} 37 | \draw (pic cs:where is it) -- ++(0,-1); 38 | \end{tikzpicture} 39 | 40 | \begin{tikzpicture} 41 | \node[draw,circle] (a) {B}; 42 | \pic[below=20pt of a,pic anchor] {location}; 43 | \end{tikzpicture} 44 | 45 | \begin{tikzpicture} 46 | \pic[name=abc,surround pic] {location}; 47 | \fill[red] (abc) circle[radius=5pt]; 48 | \draw[green] (abc.north west) rectangle (abc.south east); 49 | \end{tikzpicture} 50 | 51 | \end{document} 52 | -------------------------------------------------------------------------------- /tests/scopelocation.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | %\url{https://tex.stackexchange.com/q/567245/86} 3 | \usepackage{tikz} 4 | \usetikzlibrary{tikzmark} 5 | 6 | \newenvironment{anEnvironment}{ 7 | \begin{tikzpicture} 8 | \begin{scope} 9 | \fill (0,0) circle[radius=5pt]; 10 | \end{scope} 11 | \begin{scope}[ 12 | anchor=center, 13 | scope anchor location, 14 | adjust scope position, 15 | ] 16 | }{ 17 | \end{scope} 18 | \end{tikzpicture} 19 | } 20 | 21 | \begin{document} 22 | 23 | \begin{anEnvironment} 24 | \fill[red] (2,0) circle[radius=4pt]; 25 | \fill[red] (2,1) circle[radius=4pt]; 26 | \fill[red] (3,0) circle[radius=4pt]; 27 | \fill[red] (3,1) circle[radius=4pt]; 28 | \end{anEnvironment} 29 | 30 | \end{document} 31 | -------------------------------------------------------------------------------- /tests/tikzmark-beamer.tex: -------------------------------------------------------------------------------- 1 | \documentclass{beamer} 2 | %\url{http://tex.stackexchange.com/q/302517/86} 3 | 4 | 5 | 6 | \usepackage{amsmath} 7 | \usepackage{tikz} 8 | \usetikzlibrary{arrows, shapes, calc, decorations.pathmorphing, tikzmark, decorations.pathreplacing, scopes, fit} 9 | 10 | \newcommand{\Bmat}{\mathbf{B}} 11 | \newcommand{\zvec}{\mathbf{z}} 12 | \newcommand{\trace}[1]{\text{Tr}\left[#1\right]} 13 | 14 | \makeatletter 15 | \newcounter{jumping} 16 | \resetcounteronoverlays{jumping} 17 | 18 | \def\jump@setbb#1#2#3{% 19 | \@ifundefined{jump@#1@maxbb}{% 20 | \expandafter\gdef\csname jump@#1@maxbb\endcsname{#3}% 21 | }{% 22 | \csname jump@#1@maxbb\endcsname 23 | \pgf@xa=\pgf@x 24 | \pgf@ya=\pgf@y 25 | #3 26 | \pgfmathsetlength\pgf@x{max(\pgf@x,\pgf@xa)}% 27 | \pgfmathsetlength\pgf@y{max(\pgf@y,\pgf@ya)}% 28 | \expandafter\xdef\csname jump@#1@maxbb\endcsname{\noexpand\pgfpoint{\the\pgf@x}{\the\pgf@y}}% 29 | } 30 | \@ifundefined{jump@#1@minbb}{% 31 | \expandafter\gdef\csname jump@#1@minbb\endcsname{#2}% 32 | }{% 33 | \csname jump@#1@minbb\endcsname 34 | \pgf@xa=\pgf@x 35 | \pgf@ya=\pgf@y 36 | #2 37 | \pgfmathsetlength\pgf@x{min(\pgf@x,\pgf@xa)}% 38 | \pgfmathsetlength\pgf@y{min(\pgf@y,\pgf@ya)}% 39 | \expandafter\xdef\csname jump@#1@minbb\endcsname{\noexpand\pgfpoint{\the\pgf@x}{\the\pgf@y}}% 40 | } 41 | } 42 | 43 | \tikzset{ 44 | stop jumping/.style={ 45 | execute at end picture={% 46 | \stepcounter{jumping}% 47 | \immediate\write\pgfutil@auxout{% 48 | \noexpand\jump@setbb{\the\value{jumping}}{\noexpand\pgfpoint{\the\pgf@picminx}{\the\pgf@picminy}}{\noexpand\pgfpoint{\the\pgf@picmaxx}{\the\pgf@picmaxy}} 49 | }, 50 | \csname jump@\the\value{jumping}@maxbb\endcsname 51 | \path (\the\pgf@x,\the\pgf@y); 52 | \csname jump@\the\value{jumping}@minbb\endcsname 53 | \path (\the\pgf@x,\the\pgf@y); 54 | }, 55 | } 56 | } 57 | 58 | \makeatother 59 | 60 | \begin{document} 61 | 62 | \begin{frame}{The Wahba Problem can be solved through an \textbf{eigenvalue--eigenvector} problem.} 63 | The attitude quaternion is the eigenvector corresponding to the largest eigenvalue in the system 64 | \begin{center} 65 | % \only<1->{ 66 | \begin{tikzpicture}[remember picture] 67 | \node<1-> (dport) {$\subnode[inner sep=0pt]{dmat}{$\textbf{K}$} \bar{\textbf{q}} = \lambda \subnode[inner sep=0pt]{qbar}{$\bar{\textbf{q}}$}$}; 68 | {[draw=blue, ultra thick, <-] 69 | \draw<2-> (dmat.south)--+(-10pt,-10pt) node[inner sep=0pt, anchor=north east, align=center] (dav) {$\textbf{K} = \left[\begin{array}{c c} 70 | \subnode[inner sep=0pt]{smat}{$\textbf{S}$} - \mu \textbf{I}_{3 \times 3} & \textbf{z} \\ 71 | \subnode[inner sep=0pt]{zvec}{$\textbf{z}^T$} & \subnode[inner sep=0pt]{mu}{$\mu$} 72 | \end{array}\right]$}; 73 | 74 | \draw<2-> (qbar.south)--+(10pt,-10pt) node[inner sep=0pt, anchor=north west, align=center] (quat) {\small attitude quaternion}; 75 | 76 | \draw<3-> (smat.north)--+(-10pt,10pt) node[inner sep=0pt, anchor=south east, align=center] (sexp) {\small $\mathbf{S}=\Bmat+\Bmat^T$}; 77 | \draw<3-> (zvec.south)--+(-10pt,-10pt) node[inner sep=0pt, anchor=north east, align=center] (zexp) {\small $\zvec=\sum_{i=1}^m\frac{1}{\sigma_i^2}\left(\widetilde{\mathbf{b}_i}\times\mathbf{a}_i\right)$}; 78 | \draw<3-> (mu.south)--+(10pt,-10pt) node[inner sep=0pt, anchor=north west, align=center] (muexp) {\small $\mu=\trace{\subnode[inner sep=0pt]{bmat}{$\Bmat$}}$}; 79 | \draw<4> (bmat.south)--+(10pt,-10pt) node[inner sep=0pt, anchor=north west, align=center] (bexp) {\small $\Bmat=\sum_{i=1}^m\frac{1}{\sigma_i^2}\widetilde{\mathbf{b}_i}\mathbf{a}_i^T$}; 80 | 81 | } 82 | 83 | 84 | \end{tikzpicture} 85 | % } 86 | \end{center} 87 | 88 | \end{frame} 89 | \end{document} 90 | -------------------------------------------------------------------------------- /tests/tikzmark_test.tex: -------------------------------------------------------------------------------- 1 | %\immediate\write18{tex ../tikzmark.dtx} 2 | \documentclass[a4paper]{article} 3 | \usepackage{amsmath} 4 | \usepackage{tikz} 5 | \usepackage{lipsum} 6 | \usepackage{listings} 7 | \usetikzlibrary{ 8 | arrows.meta, 9 | tikzmark, 10 | fit, 11 | shadows 12 | } 13 | \usetikzmarklibrary{% 14 | highlighting, 15 | ams, 16 | listings 17 | } 18 | 19 | \tikzset{>=Latex} 20 | 21 | \title{TikZmark Tests} 22 | \author{Andrew Stacey} 23 | \date{\today} 24 | 25 | \begin{document} 26 | 27 | \maketitle 28 | 29 | \section{Basic Tests} 30 | 31 | There is a tikzmark here\tikzmark{a} and a tikzmark here\tikzmark{b}. 32 | Let's join them together. 33 | \tikz[remember picture, overlay] {\draw[<->] (pic cs:a) to[out=90,in=90] (pic cs:b);} 34 | 35 | There is a tikzmark node \tikzmarknode{c}{here} and a tikzmark node \tikzmarknode{d}{here}. 36 | Let's join them together. 37 | \tikz[remember picture, overlay] {\draw[<->,red] (pic cs:c) to[out=-90,in=-90] (pic cs:d); \draw[<->,blue] (c) to[out=90,in=90] (d);} 38 | 39 | Here is a tikzmark inside a tikz picture \tikz[remember picture] { \draw (0,0) rectangle (1,1); \tikzmark{f}{(.5,.5)}}. 40 | Now let's draw using it.\tikz[remember picture, overlay] {\draw[green,<-] (pic cs:f) -- +(0,1);} 41 | 42 | \section{Subnodes in Maths} 43 | 44 | \begin{itemize} 45 | \item Display style 46 | \begin{tikzpicture}[remember picture,baseline=-1] 47 | \node {\(\displaystyle S_n = \sum_{k=0}^n r^k = \frac{r^{n+1} - 1}{r-1} \)}; 48 | \node at (0,-1.5) {\(\displaystyle S_n = \subnode{da}{\sum_{k=0}^n r^k} = \frac{r^{n+1} - 1}{r-1} \)}; 49 | \draw[->] (da.south east) to[bend left] (da.south west); 50 | \node[fit=(da),draw,inner sep=0pt,node contents={}]; 51 | \end{tikzpicture} 52 | 53 | \item Text style 54 | \begin{tikzpicture}[remember picture,baseline=-1] 55 | \node {\(S_n = \sum_{k=0}^n r^k = \frac{r^{n+1} - 1}{r-1} \)}; 56 | \node at (0,-1.5) {\(S_n = \subnode{ta}{\sum_{k=0}^n r^k} = \frac{r^{n+1} - 1}{r-1} \)}; 57 | \draw[->] (ta.south east) to[bend left] (ta.south west); 58 | \node[fit=(ta),draw,inner sep=0pt,node contents={}]; 59 | \end{tikzpicture} 60 | 61 | \item Script style 62 | \begin{tikzpicture}[remember picture,baseline=-1] 63 | \node {\(S_n = \sum_{k=0}^n r^k = \frac{r^{n+1} - 1}{r-1} \)}; 64 | \node at (0,-1.5) {\(S_n = \sum_{k=0}^{\subnode{sa}{n}} r^k = \frac{r^{n+1} - 1}{r-1} \)}; 65 | \draw[->] (sa.south east) to[bend left] (sa.south west); 66 | \node[fit=(sa),draw,inner sep=0pt,node contents={}]; 67 | \end{tikzpicture} 68 | 69 | \item Script script style 70 | \begin{tikzpicture}[remember picture,baseline=-1] 71 | \node {\(\scriptstyle S_n = \sum_{k=0}^n r^k = \frac{r^{n+1} - 1}{r-1} \)}; 72 | \node at (0,-1.5) {\(\scriptstyle S_n = \sum_{k=0}^{\subnode{ssa}{n}} r^k = \frac{r^{n+1} - 1}{r-1} \)}; 73 | \draw[->] (ssa.south east) to[bend left] (ssa.south west); 74 | \node[fit=(ssa),draw,inner sep=0pt,node contents={}]; 75 | \end{tikzpicture} 76 | 77 | \end{itemize} 78 | 79 | 80 | \section{Testing transformations} 81 | 82 | There's a tikzmark\tikzmark{l} here 83 | 84 | \begin{tikzpicture}[remember picture, overlay] 85 | \draw (0,0) -- (1,-1); 86 | \draw[->] (0,0) to[bend left] (pic cs:l); 87 | \end{tikzpicture} 88 | 89 | \begin{tikzpicture}[remember picture, overlay, shift={(1cm,-1cm)}, scale=2] 90 | \draw (0,0) -- (1,-1); 91 | \draw[->] (0,0) to[bend left] (pic cs:l); 92 | \end{tikzpicture} 93 | 94 | \section{Testing inside tikzpicture} 95 | 96 | \begin{tikzpicture} 97 | \tikzmark{inside a}{(1,2)} 98 | \draw[->] (0,0) -- (pic cs:inside a); 99 | \fill[blue] (1,2) circle[radius=3pt]; 100 | \fill[green] (0,0) circle[radius=3pt]; 101 | \begin{scope}[shift={(2,1)},rotate=30,scale=.8] 102 | \tikzmark{inside b}{(1,2)} 103 | \fill[red] (1,2) circle[radius=3pt]; 104 | \fill[orange] (0,0) circle[radius=3pt]; 105 | \draw[->] (0,0) -- (pic cs:inside a); 106 | \end{scope} 107 | \draw[->] (0,0) -- (pic cs:inside b); 108 | \end{tikzpicture} 109 | 110 | \section{Testing Prefix/Suffix} 111 | 112 | \begin{itemize} 113 | \item Without suffix: 114 | \tikzmark{bar} 115 | \iftikzmark{bar}{ 116 | TIKZMARK BAR IS AVAILABLE 117 | }{ 118 | TIKZMARK BAR IS NOT AVAILABLE 119 | } 120 | 121 | 122 | \item With suffix: 123 | \tikzset{tikzmark suffix=-foo}% 124 | \tikzmark{baz} 125 | \iftikzmark{baz}{ 126 | TIKZMARK BAZ IS AVAILABLE 127 | }{ 128 | TIKZMARK BAZ IS NOT AVAILABLE 129 | } 130 | \end{itemize} 131 | 132 | \section{Inside a Box} 133 | 134 | \newbox\mybox 135 | 136 | We're about to create a box containing a pgfmark: 137 | \savebox\mybox{\pgfmark{h}hello world}% 138 | it has now been created. 139 | 140 | \wd\mybox=0pt\relax 141 | \ht\mybox=0pt\relax 142 | \dp\mybox=0pt\relax 143 | 144 | Now we used it: \unhbox\mybox\ 145 | it has been used 146 | 147 | \vspace{2cm} 148 | 149 | Let's point to the pgfmark in the box. 150 | \tikz[remember picture,overlay] \draw[->] (0,0) to[bend right] (pic cs:h); 151 | 152 | \section{Subnode tests} 153 | 154 | Tests using subnode. 155 | 156 | \begin{tikzpicture}[remember picture] 157 | \node {Say \subnode{i}{hello} everyone}; 158 | \node[fit=(i),draw,inner sep=0pt] {}; 159 | \draw[->] (3,0) to[bend right] (i.north east); 160 | \end{tikzpicture} 161 | 162 | 163 | \begin{tikzpicture}[remember picture] 164 | \node[text width=3cm] {A lot of text with some of it in a subnode. 165 | Let's write some more before we get to the subnode. 166 | Here's a sentence with more padding. 167 | We'll put a pgfmark here\pgfmark{j} 168 | \subnode{k}{This is the subnode} 169 | Now let's write some more text after the subnode. 170 | }; 171 | \fill (5,0) circle[radius=3pt] coordinate (src); 172 | \draw[->] (src) to[bend left] (k.east); 173 | \node[fit=(k),draw,inner sep=0pt] {}; 174 | \draw[->] (src) -- (pic cs:j); 175 | \end{tikzpicture} 176 | 177 | 178 | 179 | Testing box sizes: 180 | 181 | \begin{tikzpicture}[remember picture] 182 | \node {Some \subnode[inner sep=10pt]{m}{text pqg\rule[-10pt]{5pt}{20pt}} in a subnode}; 183 | \draw[->] (0,2) to[bend left] (m.north); 184 | \node[fit=(m),draw,inner sep=0pt] {}; 185 | \end{tikzpicture} 186 | 187 | \newpage 188 | \section{Listings Tests} 189 | 190 | \tikzset{ 191 | next page=below, 192 | % every highlighter/.style={rounded corners}, 193 | line/.style={ 194 | draw, 195 | rounded corners=3pt, 196 | -latex 197 | }, 198 | balloon/.style={ 199 | draw, 200 | fill=blue!20, 201 | opacity=0.4, 202 | inner sep=4pt, 203 | rounded corners=2pt 204 | }, 205 | comment/.style={ 206 | draw, 207 | fill=blue!70, 208 | text=white, 209 | % text width=3cm, 210 | % minimum height=1cm, 211 | rounded corners, 212 | drop shadow, 213 | align=left, 214 | % font=\scriptsize 215 | }, 216 | } 217 | 218 | \newcommand\balloon[4]{% 219 | \pgfmathtruncatemacro\firstline{% 220 | #3-1 221 | }% 222 | \iftikzmark{line-#2-\firstline-start}{% 223 | \iftikzmark{line-#2-#3-first}{% 224 | \xdef\blines{({pic cs:line-#2-\firstline-start} -| {pic cs:line-#2-#3-first})}% 225 | }{% 226 | \iftikzmark{line-#2-#3-start}{% 227 | \xdef\blines{({pic cs:line-#2-\firstline-start} -| {pic cs:line-#2-#3-start})}% 228 | }{% 229 | \xdef\blines{(pic cs:line-#2-\firstline-start)}% 230 | }% 231 | }% 232 | }{% 233 | \xdef\blines{}% 234 | }% 235 | \foreach \k in {#3,...,#4} {% 236 | \iftikzmark{line-#2-\k-first}{% 237 | \xdef\blines{\blines (pic cs:line-#2-\k-first) } 238 | }{} 239 | \iftikzmark{line-#2-\k-end}{% 240 | \xdef\blines{\blines (pic cs:line-#2-\k-end) } 241 | }{} 242 | }% 243 | \ifx\blines\empty 244 | \else 245 | \edef\temp{\noexpand\tikz[remember picture,overlay]\noexpand\node[fit={\blines},balloon] (#1) {};}% 246 | \temp 247 | \fi 248 | } 249 | 250 | 251 | \begin{lstlisting}[language=TeX,name=texcode,numbers=left,breakatwhitespace=true,breaklines=true] 252 | \newcommand\balloon[4]{% 253 | \pgfmathtruncatemacro\firstline{% 254 | #3-1 255 | }% 256 | \iftikzmark{line-#2-\firstline-start}{% 257 | \iftikzmark{line-#2-#3-first}{% 258 | \xdef\blines{({pic cs:line-#2-\firstline-start} -| {pic cs:line-#2-#3-first})}% 259 | }{% 260 | \iftikzmark{line-#2-#3-start}{% 261 | \xdef\blines{({pic cs:line-#2-\firstline-start} -| {pic cs:line-#2-#3-start})}% 262 | }{% 263 | \xdef\blines{(pic cs:line-#2-\firstline-start)}% 264 | }% 265 | }% 266 | }{% 267 | \xdef\blines{}% 268 | }% 269 | \foreach \k in {#3,...,#4} {% 270 | \iftikzmark{line-#2-\k-first}{% 271 | \xdef\blines{\blines (pic cs:line-#2-\k-first) } 272 | }{} 273 | \iftikzmark{line-#2-\k-end}{% 274 | \xdef\blines{\blines (pic cs:line-#2-\k-end) } 275 | }{} 276 | }% 277 | \ifx\blines\empty 278 | \else 279 | \edef\temp{\noexpand\tikz[remember picture,overlay] \noexpand\node[fit={\blines},balloon] (#1) {};}% 280 | \temp 281 | \fi 282 | } 283 | \end{lstlisting} 284 | 285 | \begin{tikzpicture}[remember picture,overlay,>=Latex] 286 | \draw[<-,ultra thick] (pic cs:line-texcode-1-end) +(1em,.7ex) -| +(2.5,1) node[above,comment,thin] {Command name}; 287 | \draw[<-,ultra thick] (pic cs:line-texcode-3-end) ++(1em,.7ex) -| +(5.8,1) node[above right,comment,thin] {Find previous line}; 288 | \draw[<-,ultra thick] (pic cs:line-texcode-5-end) ++(1em,.7ex) -| +(2.2,.5) node[above,comment,thin] {If previous line exists, add to the list}; 289 | \draw[<-,ultra thick] (pic cs:line-texcode-18-end) ++(1em,.7ex) -| +(2.2,.5) node[above,comment,thin] {Loop through rest of lines}; 290 | \draw[<-,ultra thick] (pic cs:line-texcode-28-end) ++(1em,.7ex) -| +(1,1.5) node[above,comment,thin] {Add a node covering all the lines}; 291 | \end{tikzpicture} 292 | 293 | \newpage 294 | 295 | \section{Tikzmarks on other pages} 296 | 297 | \tikz[overlay,remember picture,ultra thick,red] \draw (pic cs:n) -- (pic cs:o);% 298 | A\tikzmark{n} tikzmark 299 | 300 | \lipsum[1-4] 301 | \lipsum[4] 302 | \lipsum*[4] 303 | \tikzmark{o}% 304 | 305 | \lipsum[1] 306 | \tikz[overlay,remember picture,ultra thick,red] \draw (pic cs:n) -- (pic cs:o); 307 | 308 | \newpage 309 | 310 | \tikzset{ 311 | next page=below, 312 | } 313 | 314 | \tikz[overlay,remember picture,ultra thick,red] \draw (pic cs:p) -- (pic cs:q); 315 | \tikz[overlay,remember picture,ultra thick,red] \draw (0,0) -- (pic cs:r); 316 | 317 | A\tikzmark{p} tikzmark \tikzmark{q}. 318 | 319 | \lipsum[1-4] 320 | \lipsum[4] 321 | \tikzmark{r}% 322 | \lipsum*[4] 323 | \tikzmark{s}% 324 | 325 | \lipsum[1] 326 | \tikz[overlay,remember picture,ultra thick,red] \draw (0,0) -- (pic cs:s); 327 | 328 | \section{Highlighting} 329 | 330 | \lipsum*[3] 331 | \hlstart[fill,rounded corners]{lipsum}\lipsum*[2]\hlend{lipsum} 332 | \lipsum*[3] 333 | 334 | Here is a sentence \hlstart{short}with some highlighting\hlend{short}. 335 | A bit more to make a gap which should then break onto the next line. 336 | And then the highlighting ends. 337 | 338 | Here is a sentence with some highlighting. 339 | A bit more to make a gap \hlstart{break}which should then break onto the next line\hlend{break}. 340 | And then the highlighting ends. 341 | 342 | \newpage 343 | 344 | \section{AMS Equations} 345 | 346 | \begin{tikzmarkmath}[pythagoras] 347 | 348 | \begin{gather} 349 | a^2 = b^2 + c^2 350 | \end{gather} 351 | 352 | \begin{gather} 353 | a = \sqrt[2]{b^2 + c^2} 354 | \end{gather} 355 | \end{tikzmarkmath} 356 | 357 | \begin{tikzpicture}[remember picture, overlay] 358 | \foreach \k in {1,2,3,7,8} { 359 | \draw[red] (pic cs:pythagoras-\k) -- ++(135:1) node[draw,red,circle,font=\tiny,above left] {\k}; 360 | \node[draw,blue,fit=(pythagoras-\k),inner sep=0pt] {}; 361 | } 362 | \end{tikzpicture} 363 | 364 | 365 | \end{document} 366 | 367 | % Local Variables: 368 | % tex-output-type: "pdf18" 369 | % End: 370 | -------------------------------------------------------------------------------- /tests/tikzmathchoice.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | 3 | \usepackage{tikz} 4 | \usetikzlibrary{tikzmark} 5 | 6 | \begin{document} 7 | 8 | \tikzmarknode{test}{hello} 9 | 10 | \[ 11 | x^{2^1} + y^{2^1} = z^{2^1} 12 | \] 13 | 14 | \begin{center} 15 | \( x^{2^1} + y^{2^1} = z^{2^1}\) 16 | \end{center} 17 | 18 | \[ 19 | \tikzmarknode{base}{x}^{\tikzmarknode{exponent}{2}^{\tikzmarknode{highexp}{1}}} + y^{2^1} = z^{2^1} 20 | \] 21 | 22 | \begin{enumerate} 23 | \item \tikzmarknode{Base}{Base} 24 | \item \tikzmarknode{Exponent}{Exponent} 25 | \item \tikzmarknode{HighExponent}{HighExponent} 26 | \end{enumerate} 27 | 28 | \begin{tikzpicture}[remember picture, overlay] 29 | \draw [->] (Base) to[bend left] (base); 30 | \draw [->] (Exponent) to (exponent); 31 | \draw [->] (HighExponent) to[bend right] (highexp); 32 | \end{tikzpicture} 33 | 34 | \end{document} 35 | -------------------------------------------------------------------------------- /tests/tikzrefextnodes.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | %\url{https://tex.stackexchange.com/q/415831/86} 3 | \usepackage{shellesc} 4 | \usepackage{tikz} 5 | \usetikzlibrary{tikzmark} 6 | \usepackage{filecontents} 7 | 8 | %% file1.tex 9 | \begin{filecontents}{\jobname-1.tex} 10 | \RequirePackage{luatex85} 11 | \documentclass[tikz,border=10pt]{standalone} 12 | \usetikzlibrary{tikzmark,shapes.geometric} 13 | \begin{document} 14 | \begin{tikzpicture}[save nodes to file] 15 | \node[draw,rotate=-30,save node](1) at (-2,0) {1}; 16 | \draw[->] (0,0) -- (1); 17 | \node[draw,ellipse,save node] (c) at (current bounding box.center) {}; 18 | \end{tikzpicture} 19 | \end{document} 20 | \end{filecontents} 21 | 22 | %% file2.tex 23 | \begin{filecontents}{\jobname-2.tex} 24 | \RequirePackage{luatex85} 25 | \documentclass[tikz,border=10pt]{standalone} 26 | \usetikzlibrary{tikzmark,shapes.geometric} 27 | \begin{document} 28 | \begin{tikzpicture}[save nodes to file] 29 | \node[draw,rotate=-70,save node] (2) at (2,0) {2}; 30 | \draw[->] (0,0) -- (2); 31 | \node[draw,ellipse,save node] (c) at (current bounding box.center) {}; 32 | \end{tikzpicture} 33 | \end{document} 34 | \end{filecontents} 35 | 36 | %% file3.tex 37 | 38 | \immediate\write18{lualatex \jobname-1.tex} 39 | \immediate\write18{lualatex \jobname-2.tex} 40 | 41 | \begin{document} 42 | \begin{tikzpicture} 43 | 44 | \node[draw, 45 | rotate=30, 46 | restore nodes from file={[transform saved nodes,name prefix=pic-1-]{\jobname-1}} 47 | ] (a-1) at (-2,-3) {\includegraphics{\jobname-1.pdf}}; 48 | 49 | \node[draw, 50 | rotate=70, 51 | restore nodes from file={[transform saved nodes,name prefix=pic-2-]{\jobname-2}} 52 | ] (a-2) at (+2,+2) {\includegraphics{\jobname-2.pdf}}; 53 | 54 | \draw[red] (pic-1-1.north west) -- (pic-1-1.north east) -- (pic-1-1.south east) -- (pic-1-1.south west) -- cycle; 55 | \draw[red] (pic-2-2.north west) -- (pic-2-2.north east) -- (pic-2-2.south east) -- (pic-2-2.south west) -- cycle; 56 | 57 | \node[red] at (pic-1-1) {1}; 58 | \node[red] at (pic-2-2) {2}; 59 | 60 | \draw (a-1) circle[radius=5pt]; 61 | \draw (a-2) circle[radius=5pt]; 62 | 63 | \draw (pic-1-1) -- (pic-2-2); 64 | \end{tikzpicture} 65 | \end{document} 66 | -------------------------------------------------------------------------------- /tikzmark.dtx: -------------------------------------------------------------------------------- 1 | % \iffalse meta-comment 2 | %<*internal> 3 | \iffalse 4 | % 5 | %<*readme> 6 | ---------------------------------------------------------------- 7 | tikzmark --- remembering absolute positioning with TikZ 8 | E-mail: loopspace@mathforge.org 9 | Released under the LaTeX Project Public License v1.3c or later 10 | See http://www.latex-project.org/lppl.txt 11 | ---------------------------------------------------------------- 12 | 13 | The tikzmark package defines a command to "remember" a position 14 | on a page for later (or earlier) use, primarily (but not 15 | exclusively) with TikZ. 16 | % 17 | %<*internal> 18 | \fi 19 | \def\nameofplainTeX{plain} 20 | \ifx\fmtname\nameofplainTeX\else 21 | \expandafter\begingroup 22 | \fi 23 | % 24 | %<*install> 25 | \input docstrip.tex 26 | \keepsilent 27 | \askforoverwritefalse 28 | \preamble 29 | ---------------------------------------------------------------- 30 | tikzmark --- remembering absolute positioning with TikZ. 31 | E-mail: loopspace@mathforge.org 32 | Released under the LaTeX Project Public License v1.3c or later 33 | See http://www.latex-project.org/lppl.txt 34 | ---------------------------------------------------------------- 35 | 36 | \endpreamble 37 | \postamble 38 | 39 | Copyright (C) 2011-2021 by Andrew Stacey 40 | 41 | This work may be distributed and/or modified under the 42 | conditions of the LaTeX Project Public License (LPPL), either 43 | version 1.3c of this license or (at your option) any later 44 | version. The latest version of this license is in the file: 45 | 46 | http://www.latex-project.org/lppl.txt 47 | 48 | This work is "maintained" (as per LPPL maintenance status) by 49 | Andrew Stacey. 50 | 51 | This work consists of the file tikzmark.dtx 52 | and the derived files tikzmark.ins, 53 | tikzmark.pdf, 54 | tikzlibrarytikzmark.code.tex, and 55 | tikzmarklibrarylistings.code.tex 56 | tikzmarklibraryhighlighting.code.tex 57 | tikzmarklibraryams.code.tex 58 | 59 | \endpostamble 60 | \usedir{tex/latex/tikzmark} 61 | \generate{ 62 | \file{tikzlibrarytikzmark.code.tex}{\from{\jobname.dtx}{tikzlibrary}} 63 | } 64 | \generate{ 65 | \file{tikzmarklibrarylistings.code.tex}{\from{\jobname.dtx}{listings}} 66 | } 67 | \generate{ 68 | \file{tikzmarklibraryhighlighting.code.tex}{\from{\jobname.dtx}{highlighting}} 69 | } 70 | \generate{ 71 | \file{tikzmarklibraryams.code.tex}{\from{\jobname.dtx}{ams}} 72 | } 73 | % 74 | %\endbatchfile 75 | %<*internal> 76 | \usedir{source/latex/tikzmark} 77 | \generate{ 78 | \file{\jobname.ins}{\from{\jobname.dtx}{install}} 79 | } 80 | \nopreamble\nopostamble 81 | \usedir{doc/latex/demopkg} 82 | \generate{ 83 | \file{README.txt}{\from{\jobname.dtx}{readme}} 84 | } 85 | \ifx\fmtname\nameofplainTeX 86 | \expandafter\endbatchfile 87 | \else 88 | \expandafter\endgroup 89 | \fi 90 | % 91 | %<*driver> 92 | \documentclass{ltxdoc} 93 | \usepackage[T1]{fontenc} 94 | \usepackage{lmodern} 95 | \usepackage{amsmath} 96 | %\usepackage{morefloats} 97 | \usepackage{listings} 98 | \usepackage{tikz} 99 | \usetikzlibrary{fit,arrows.meta,tikzmark,shadows,decorations.pathreplacing,calc} 100 | \usetikzmarklibrary{ams,listings,highlighting} 101 | 102 | %\usepackage[numbered]{hypdoc} 103 | \definecolor{lstbgcolor}{rgb}{0.9,0.9,0.9} 104 | 105 | \usepackage{listings} 106 | \lstloadlanguages{[LaTeX]TeX} 107 | \lstset{ 108 | gobble=2, 109 | breakatwhitespace=true, 110 | breaklines=true, 111 | language=[LaTeX]TeX, 112 | basicstyle=\small\ttfamily, 113 | keepspaces=true, 114 | columns=fullflexible 115 | } 116 | \usepackage{fancyvrb} 117 | 118 | \usepackage[hyperindex=false]{hyperref} 119 | 120 | \newenvironment{example} 121 | {\VerbatimEnvironment 122 | \begin{VerbatimOut}[gobble=2]{example.out}} 123 | {\end{VerbatimOut} 124 | \begin{center} 125 | % \setlength{\parindent}{0pt} 126 | \fbox{\begin{minipage}{.9\linewidth} 127 | \lstinputlisting{example.out} 128 | \end{minipage}} 129 | 130 | \fbox{\begin{minipage}{.9\linewidth} 131 | \input{example.out} 132 | \end{minipage}} 133 | \end{center} 134 | } 135 | 136 | \newenvironment{justexample} 137 | {\VerbatimEnvironment 138 | \begin{VerbatimOut}[gobble=2]{example.out}} 139 | {\end{VerbatimOut} 140 | \begin{center} 141 | % \setlength{\parindent}{0pt} 142 | \fbox{\begin{minipage}{.9\linewidth} 143 | \lstinputlisting{example.out} 144 | \end{minipage}} 145 | \end{center} 146 | } 147 | 148 | \newcommand\balloon[4]{% 149 | \pgfmathtruncatemacro\firstline{% 150 | #3-1 151 | }% 152 | \iftikzmark{line-#2-\firstline-start}{% 153 | \iftikzmark{line-#2-#3-first}{% 154 | \xdef\blines{({pic cs:line-#2-\firstline-start} -| {pic cs:line-#2-#3-first})}% 155 | }{% 156 | \iftikzmark{line-#2-#3-start}{% 157 | \xdef\blines{({pic cs:line-#2-\firstline-start} -| {pic cs:line-#2-#3-start})}% 158 | }{% 159 | \xdef\blines{(pic cs:line-#2-\firstline-start)}% 160 | }% 161 | }% 162 | }{% 163 | \xdef\blines{}% 164 | }% 165 | \foreach \k in {#3,...,#4} {% 166 | \iftikzmark{line-#2-\k-first}{% 167 | \xdef\blines{\blines (pic cs:line-#2-\k-first) } 168 | }{} 169 | \iftikzmark{line-#2-\k-end}{% 170 | \xdef\blines{\blines (pic cs:line-#2-\k-end) } 171 | }{} 172 | }% 173 | \ifx\blines\empty 174 | \else 175 | \edef\temp{\noexpand\tikz[remember picture,overlay]{\noexpand\node[fit={\blines},balloon] (#1) {};}}% 176 | \temp 177 | \fi 178 | } 179 | \tikzset{ 180 | line/.style={ 181 | draw, 182 | rounded corners=3pt, 183 | -latex 184 | }, 185 | balloon/.style={ 186 | draw, 187 | fill=blue!20, 188 | opacity=0.4, 189 | inner sep=4pt, 190 | rounded corners=2pt 191 | }, 192 | comment/.style={ 193 | draw, 194 | fill=blue!70, 195 | text=white, 196 | text width=3cm, 197 | minimum height=1cm, 198 | rounded corners, 199 | drop shadow, 200 | align=left, 201 | font=\scriptsize 202 | }, 203 | } 204 | 205 | \DisableCrossrefs 206 | % \CodelineIndex 207 | \RecordChanges 208 | \begin{document} 209 | \DocInput{\jobname.dtx} 210 | \end{document} 211 | % 212 | % \fi 213 | % 214 | % \CheckSum{1902} 215 | % 216 | % \CharacterTable 217 | % {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 218 | % Lower-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 219 | % Digits \0\1\2\3\4\5\6\7\8\9 220 | % Exclamation \! Double quote \" Hash (number) \# 221 | % Dollar \$ Percent \% Ampersand \& 222 | % Acute accent \' Left paren \( Right paren \) 223 | % Asterisk \* Plus \+ Comma \, 224 | % Minus \- Point \. Solidus \/ 225 | % Colon \: Semicolon \; Less than \< 226 | % Equals \= Greater than \> Question mark \? 227 | % Commercial at \@ Left bracket \[ Backslash \\ 228 | % Right bracket \] Circumflex \^ Underscore \_ 229 | % Grave accent \` Left brace \{ Vertical bar \| 230 | % Right brace \} Tilde \~} 231 | % 232 | % 233 | % \changes{1.0}{2012/11/08}{Converted to DTX file} 234 | % \changes{1.1}{2013/04/22}{Fix bug relating to active semi-colon} 235 | % \changes{1.2}{2016/04/07}{Tikzmark works inside tikzpicture, added easy suffix and prefix for tikzmarks} 236 | % \changes{1.3}{2017/06/01}{Tikzmark no longer uses semi-colon (too many issues with catcodes) and fix for beamer-awareness} 237 | % \changes{1.4}{2017/10/29}{Bug fixes: spurious characters in aux file, tikzmark prefix/suffix ignored in iftikzmark test} 238 | % \changes{1.5}{2018/09/09}{Reintroduced the original command (now as tikzmarknode) with a mathchoice hack for different math modes} 239 | % \changes{1.6}{2018/10/18}{Added the ability to save node information between runs and between TeX documents} 240 | % \changes{1.7}{2019/05/07}{Added conditions to test if a tikzmark is on a particular page} 241 | % \changes{1.8}{2019/10/04}{Fixed some bugs with subnode and tikzmarknode inside maths} 242 | % \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} 243 | % \changes{1.11}{2021/08/16}{Tikzmark inside a tikzpicture was not applying any surrounding transformation before saving the coordinates. Code for adjusting a pic's location based on an internal coordinate.} 244 | % \changes{1.12}{2021/08/24}{Experimental library for creating pseudo-nodes around AMSMath equation alignment boxes.} 245 | % \changes{1.14}{2022/01/28}{Reimplementing the highlighting code using LaTeX3 hooks.} 246 | % \changes{1.15}{2022/08/24}{Improvements to highlighting code} 247 | % 248 | % \DoNotIndex{\newcommand,\newenvironment} 249 | % \pdfstringdefDisableCommands{% 250 | % \def\\{}% 251 | % \def\url#1{<#1>}% 252 | % } 253 | % 254 | % \GetFileInfo{tikzlibrarytikzmark.code.tex} 255 | % \providecommand*{\url}{\texttt} 256 | % \title{The \textsf{tikzmark} package} 257 | % \author{Andrew Stacey \\ \url{loopspace@mathforge.org}} 258 | % \date{\fileversion~from \filedate} 259 | % 260 | % 261 | % \maketitle 262 | % 263 | % \section{Introduction} 264 | % 265 | % The \Verb+\tikzmark+ macro burst onto the scene in a blaze of glory on \href{http://tex.stackexchange.com}{TeX-SX}. 266 | % Since then, it has proved embarrassingly (to its original author) popular. 267 | % The idea behind it is extremely simple: that the machinery underneath TikZ provides a way to ``mark'' a point on a page for further use. 268 | % This functionality is already provided by several other packages. 269 | % The point of this one is that as TikZ can provide this feature, if already loading TikZ then it makes sense to use the TikZ version than another version. 270 | % Moreover, if the goal is to use these marks with some TikZ code then this version is already set up for that purpose (not that it would be exactly difficult to add this to any of the other implementations). 271 | % 272 | % \section{Use} 273 | % 274 | % Using the \Verb+\tikzmark+ is extremely simple. 275 | % You need to load the \Verb+tikz+ package and then load \Verb+tikzmark+ as a \Verb+tikzlibrary+. 276 | % Thus in your preamble you should have something like: 277 | % 278 | % \begin{lstlisting} 279 | % \usepackage{tikz} 280 | % \usetikzlibrary{tikzmark} 281 | % \end{lstlisting} 282 | % 283 | % In your document, you can now type \Verb+\tikzmark{}+ at a point that you want to remember. 284 | % This will save a mark with name \Verb++ for use later (or earlier). 285 | % To use it in a \Verb+\tikz+ or \Verb+tikzpicture+, simply use the \Verb+pic+ coordinate system: 286 | % 287 | % \begin{lstlisting} 288 | % \tikz[remember picture] \draw[overlay] (0,0) -- (pic cs:); 289 | % \end{lstlisting} 290 | % 291 | % There are two important points to note: 292 | % 293 | % \begin{enumerate} 294 | % \item The enveloping \Verb+\tikz+ or \Verb+tikzpicture+ must have the key \Verb+remember picture+ set. 295 | % 296 | % This is because of how TikZ coordinates work. 297 | % The coordinates inside a TikZ picture are relative to its origin, so that origin can move around on the page and not affect the internals of the picture. 298 | % To use a point outside the picture, therefore, the current picture not only has to know where that point is on the page it also has to know where it itself is on the page. 299 | % Hence the \Verb+remember picture+ key must be set. 300 | % \item The drawing command must have the \Verb+overlay+ key set (or be in a scope or picture where it is set). 301 | % 302 | % This is to keep the bounding box of the current picture under control. 303 | % Otherwise, it would grow to encompass the remembered point as well as the current picture. 304 | % (This isn't necessary if the remembered point is inside the current picture.) 305 | % \end{enumerate} 306 | % 307 | % 308 | % 309 | % \section{History} 310 | % 311 | % I wrote the original \Verb+\tikzmark+ macro in 2009 for use in lecture slides prepared with the \Verb+beamer+ package. 312 | % Its original definition was: 313 | % 314 | % \begin{lstlisting} 315 | % \newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};} 316 | % \end{lstlisting} 317 | % 318 | % Its first use was in the (inelegant) code: 319 | % 320 | % \begin{lstlisting} 321 | % \begin{frame} 322 | % \frametitle{Structure of Continuous Functions} 323 | % 324 | % \begin{tikzpicture}[overlay, remember picture] 325 | % \useasboundingbox (0,0); 326 | % \draw<2-|trans: 0|handout: 0>[red,->] (bsp) .. controls +(-1,-1) and ($(cnvs.north)+(1,1)$) .. ($(cnvs.north)+(0,1)$) .. controls ($(cnvs.north)+(-1,1)$) and +(-1,0) .. (cnvs.north); 327 | % \draw<3-|trans: 0|handout: 0>[green!50!black,->] (cplt) .. controls +(-1,-1) and +(-1,0) .. (mcplt.north); 328 | % \draw<4-|trans: 0|handout: 0>[blue,->] (norm) .. controls +(-1,-.5) and ($(nvs.north)+(0,1.5)$) .. ($(nvs.north)+(0,1.5)$) .. controls ($(nvs.north)+(-1.5,1.5)$) and +(-1.5,0) .. (nvs.north); 329 | % \draw<5-|trans: 0|handout: 0>[purple,->] (vector) .. controls +(-1,-1) and ($(vsp.north)+(2,2)$) .. ($(vsp.north)+(0,2)$) .. controls ($(vsp.north)+(-2,2)$) and +(-2,0) .. (vsp.north); 330 | % \end{tikzpicture} 331 | % 332 | % \begin{theorem} 333 | % \centering 334 | % \(\big(C([0,1],\R),d_\infty\big)\) \\ 335 | % is a \\ 336 | % \alert{Banach\tikzmark{bsp} space} 337 | % \end{theorem} 338 | % 339 | % \pause 340 | % \bigskip 341 | % 342 | % \begin{itemize} 343 | % \item[\tikzmark{cnvs}] {\color<.(2)->{green!50!black}Comp\tikzmark{cplt}lete} {\color<.(3)->{blue}nor\tikzmark{norm}med} {\color<.(4)->{purple}vector\tikzmark{vector} space}. 344 | % 345 | % \bigskip 346 | % \bigskip 347 | % \pause 348 | % 349 | % \begin{itemize}[<+->] 350 | % \item[\tikzmark{mcplt}] {\color{green!50!black}Cauchy sequences converge.} 351 | % \medskip 352 | % \item[\tikzmark{nvs}] {\color{blue}Metric from a norm.} 353 | % \medskip 354 | % \item[\tikzmark{vsp}] {\color{purple}Functions behave like vectors.} 355 | % \end{itemize} 356 | % \end{itemize} 357 | % 358 | % \end{frame} 359 | % \end{lstlisting} 360 | % 361 | % This produced, on the final slide, Figure~\ref{fig:tikzmarkex}. 362 | % 363 | % \begin{figure} 364 | % \centering 365 | % \IfFileExists{tikzmarkExample.pdf}{\includegraphics{tikzmarkExample}}{} 366 | % \caption{First use of tikzmark} 367 | % \label{fig:tikzmarkex} 368 | % \end{figure} 369 | % 370 | % Its first appearance on \href{http://tex.stackexchange.com}{TeX-SX} was in an \href{http://tex.stackexchange.com/a/316/86}{answer} to a question about how to put overlapping braces on a mathematical text. 371 | % This was in July 2010. 372 | % The opening statement of the answer was not overly encouraging: ``This may not be the best solution\dots''. 373 | % And for a macro that would go on to become quite ubiquitous, its initial appearance only garnered it 2 votes. 374 | % 375 | % However, it started out in life as a useful macro for me and as such I found more uses for it in my own code and thus more opportunity for using it to answer questions on TeX-SX. 376 | % The one that seems to have been where it got noticed came in \href{http://tex.stackexchange.com/a/1570/86}{August 2010}, again about putting braces in text but in a more complicated fashion. 377 | % From this answer, it got picked up, picked over, and picked apart. 378 | % A common use was in highlighting or adding marks to text. 379 | % 380 | % Gradually, as it got used, it developed. 381 | % A major revision dates from an answer given in \href{http://tex.stackexchange.com/a/50054/86}{March 2012} where the question was actually about \Verb+\tikzmark+. 382 | % This version added two important features: a TikZ coordinate system for referencing saved marks directly and the ability to refer to marks earlier in the document than they are defined (the mechanism for remembering points uses the \Verb+aux+ file anyway so this was more about exposing the information earlier than anything complicated). 383 | % Then in October 2012 there was a \href{http://tex.stackexchange.com/q/79121/86}{question} where it would have been useful to remember which page the mark was on and a \href{http://tex.stackexchange.com/q/79762/86}{question} where for some reason using the \Verb+\tikz+ macro didn't work so the \Verb+\pgfmark+ macro was introduced. 384 | % 385 | % By this point, the \Verb+\tikzmark+ command had morphed considerably from its original definition. 386 | % Experience has shown that on the TeX-SX site it has continued to be used in its original form as well as its current form. 387 | % I've therefore taken the decision to reintroduce a form of the original command, now called \Verb+\tikzmarknode+. 388 | % It goes beyond the original version in that it uses some \Verb+\mathchoice+ trickery (inspired by \href{https://tex.stackexchange.com/a/122419/86}{this answer} from Heiko Oberdiek) to hopefully correctly choose the correct math style. 389 | % 390 | % The original reason for not using nodes inside \Verb+\tikzmark+ was to be able to use the information from a \Verb+\tikzmark+ before the point where it was defined (via information saved into the \Verb+aux+ file). 391 | % Thanks to a \href{https://tex.stackexchange.com/a/415862/86}{question on TeX-SX} about saving node information, I've developed code that solves that issue with nodes. 392 | % As it fits in the general concept of this package, I've added that code to the \Verb+\tikzmark+ package. 393 | % 394 | % \section{Usage} 395 | % 396 | % This package defines the following commands and usable stuff. 397 | % 398 | % \subsection{Core Commands} 399 | % 400 | % \begin{enumerate} 401 | % \item \Verb+\tikzmark+\oarg{drawing command}\marg{name} 402 | % 403 | % The mandatory argument is the name of the mark to be used to refer back to this point later. 404 | % 405 | % The \Verb+\tikzmark+ command can take an optional parameter which is some drawing command that can be put in a \Verb+\tikz ... ;+ command. 406 | % This drawing command can be used to place a node or something similar at the marked point, or to set some \Verb+\tikzset+ keys. 407 | % Sometimes this can be useful. 408 | % Note, though, that if this is used to define an offset coordinate then this will only be available in the document \emph{after} the \Verb+\tikzmark+ command, even on later runs. 409 | % 410 | % If the \Verb+beamer+ class is loaded then this command is made overlay-aware. 411 | % 412 | % \item \Verb+\tikzmark+\marg{name}\marg{coordinate} 413 | % 414 | % v1.2 of the \Verb+tikzmark+ package introduced a new variant of \Verb+\tikzmark+ which works inside a \Verb+tikzpicture+. 415 | % One feature of \Verb+\tikzmark+ which isn't part of TikZ's normal coordinate remembering system is the ability to use a \Verb+\tikzmark+ coordinate before it is defined (due to the use of the \Verb+aux+ file). 416 | % This is potentially useful to have inside a \Verb+tikzpicture+ and so it is now possible to use \Verb+\tikzmark+ inside a \Verb+tikzpicture+. 417 | % The syntax is slightly different as we need to specify the coordinates of a point to remember. 418 | % 419 | % This was inspired by the question \href{http://tex.stackexchange.com/q/295903/86}{Refer to a node in tikz that will be defined ``in the future'' (two passes)?} on TeX-SX. 420 | % 421 | % \item \Verb+\pgfmark+\marg{name} 422 | % 423 | % This is a more basic form of the \Verb+\tikzmark+ which doesn't use any of the \Verb+\tikz+ overhead. 424 | % One advantage of this command is that it doesn't create an \Verb+hbox+. 425 | % It does, however, insert a \Verb+whatsit+ into the stream so it will, for example, stop two vertical spaces either side of it being merged. 426 | % This can't be avoided. 427 | % 428 | % If the \Verb+beamer+ class is loaded then this command is made overlay-aware. 429 | % 430 | % \item \Verb+\iftikzmark+\marg{name}\marg{true code}\marg{false code} 431 | % 432 | % This is a conditional to test if a particular mark is available. 433 | % It executes \Verb+true code+ if it is and \Verb+false code+ if not. 434 | % 435 | % \item \Verb+\iftikzmarkexists+\marg{name} 436 | % 437 | % This is a conditional to test if a particular mark is available which works with the lower level \TeX\ \Verb+\else+ and \Verb+\fi+. 438 | % 439 | % \item \Verb+\iftikzmarkoncurrentpage+\marg{name} 440 | % 441 | % This is a conditional to test if a particular mark is on the current page; it works with the lower level \TeX\ \Verb+\else+ and \Verb+\fi+. 442 | % 443 | % \item \Verb+\iftikzmarkonpage+\marg{name}\marg{page} 444 | % 445 | % This is a conditional to test if a particular mark is on a given page; it works with the lower level \TeX\ \Verb+\else+ and \Verb+\fi+. 446 | % 447 | % \item \Verb+\tikzmarknode+\oarg{options}\marg{name}\marg{contents} 448 | % 449 | % This is a reincarnation of the original \Verb+\tikzmark+ command which places its contents inside a \Verb+\tikz+ node. It also defines a \Verb+tikzmark+ with the same name. Using a sneaky trick with \Verb+\mathchoice+, it works inside a math environment. The spacing either side might not be quite right as although it detects the math style it doesn't got beyond that. The \Verb+options+ are passed to the node. 450 | % 451 | % Two styles are attempted, one on the surrounding picture and one on the node, which are: 452 | % 453 | % \begin{itemize} 454 | % \item \Verb+every tikzmarknode picture+ 455 | % \item \Verb+every tikzmarknode+ 456 | % \end{itemize} 457 | % 458 | % To refer to the \emph{node}, use usual TikZ coordinates. 459 | % To refer to the underlying \emph{tikzmark}, use the special tikzmark coordinates (see below). 460 | % 461 | % \item \Verb+(pic cs:)+ or \Verb+(pic cs:,)+ 462 | % 463 | % This is the method for referring to a position remembered by \Verb+\tikzmark+ (or \Verb+\pgfmark+) as a coordinate in a \Verb+tikzpicture+ environment (or \Verb+\tikz+ command). 464 | % If the extra \Verb+coordinate+ is specified then this is used in case the mark \Verb+name+ has not yet been defined (this can be useful for defining code that does something sensible on the first run). 465 | % 466 | % \item \Verb+/tikz/save picture id=+ 467 | % 468 | % This is the TikZ key that is used by \Verb+\tikzmark+ to actually save the connection between the name and the picture coordinate. 469 | % It can be used on an arbitrary picture to save its origin as a tikzmark. 470 | % 471 | % \item \Verb+/tikz/check picture id+ 472 | % 473 | % There are circumstances where, behind the scenes, a tikzpicture is actually placed in a box and processed several times (often this involves \Verb+\mathchoice+). 474 | % In such a situation, when defining nodes then the last one ``wins'' in that each node remembers the id of the last processed picture. 475 | % However, only the one that is actually used has its location remembered on the page (since the others don't have a position). 476 | % This can lead to the situation whereby a node becomes disassociated from its picture and so using it for later reference fails. 477 | % 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 finds that it wasn't, it quietly appends the string \Verb+discard-+ to each node name. 478 | % The idea being that the version of the picture that is actually typeset will not have this happen and so its nodes ``survive''. 479 | % 480 | % \item \Verb+/tikz/maybe define node=#1+ 481 | % 482 | % The previous key can lead to undefined nodes on the first time that the picture is processed. 483 | % Using this key will ensure that the specified node is aliased to its \Verb+discard-+ version providing it doesn't already exist. 484 | % This is purely to get rid of pointless error messages, and also should only be used in conjunction with \Verb+check picture id+. 485 | % 486 | % Note that due to the order in which code gets executed, \Verb+check picture id+ should be before any \Verb+maybe define node+ keys. 487 | % 488 | % \item \Verb+/tikz/if picture id=#1#2#3+ 489 | % 490 | % This is a key equivalent of the \Verb+\iftikzmark+ command. 491 | % 492 | % \item \Verb+/tikz/if tikzmark on current page=#1#2#3+ 493 | % 494 | % This is a key equivalent of the \Verb+\iftikzmarkoncurrentpage+ command. 495 | % If true, the keys in \Verb+#2+ are executed, otherwise the keys in \Verb+#3+. 496 | % 497 | % \item \Verb+/tikz/if tikzmark on page=#1#2#3#4+ 498 | % 499 | % This is a key equivalent of the \Verb+\iftikzmarkonpage+ command. 500 | % 501 | % \item \Verb+/tikz/next page+, \Verb+/tikz/next page vector+ 502 | % 503 | % It is possible to refer to a mark on a different page to the current page. 504 | % When this is done, the mark is offset by a vector stored in the key \Verb+/tikz/next page vector+. 505 | % The key \Verb+/tikz/next page+ can be used to set this to certain standard vectors by specifying where the ``next page'' is considered as lying corresponding to the current page. 506 | % Possible values are (by default) \Verb+above+, \Verb+below+, \Verb+left+, \Verb+right+, and \Verb+ignore+. 507 | % (The last one sets the vector to the zero vector.) 508 | % 509 | % Previous versions of \Verb+tikzmark+ tried to make this work correctly with the mark being on, say, \(5\) pages further on but this got too fiddly so this version just pretends that the mark is on the next or previous page and points to it as appropriate. 510 | % 511 | % \item \Verb+/tikz/tikzmark prefix=+ and \Verb+/tikz/tikzmark suffix=+ 512 | % 513 | % These keys allow for the automatic addition of a prefix and/or suffix to each \Verb+\tikzmark+ name. 514 | % The prefix and suffix are added both at time of definition and of use, so providing one is in the same scope there is no difference in at the user level when using prefixes and suffixes. 515 | % What it can be useful for is to make the \Verb+\tikzmark+ names unique. 516 | % In particular, if the \Verb+beamer+ class is loaded then an automatic suffix is added corresponding to the overlay. 517 | % This means that if a slide consists of several overlays with \Verb+\tikzmark+s on them, and the positions of the \Verb+\tikzmark+s move then the resulting pictures should look right. 518 | % Without the automatic suffix, only the final positions of the marks would be used throughout. 519 | % 520 | % This was inspired by the question \href{http://tex.stackexchange.com/q/302517/86}{using tikzmark subnode with overlays beamer} on TeX-SX. 521 | % 522 | % \end{enumerate} 523 | % 524 | % \subsection{Pic and Scope Positioning} 525 | % 526 | % \Verb+scope anchor+, \Verb+pic anchor+, and \Verb+surround pic+. 527 | % 528 | % These keys can be used to enable advanced positioning of \Verb+scope+s and \Verb+pic+s. 529 | % The standard positioning of a \Verb+pic+ places its internal origin at the location specified on the \Verb!\pic! command. 530 | % This is more limited than what is available to a \Verb+node+ whereby any of the defined anchors can be placed at the given position. 531 | % The key \Verb+pic anchor+ allows a little more flexibility to \Verb+pic+ positioning by allowing a \Verb+pic anchor+ to be defined and used as the point to place at the given position. 532 | % 533 | % When invoking the \Verb!pic! the key \Verb!pic anchor={coordinate}! can be used to specify a point inside the \Verb!pic! to use as the anchor. 534 | % This point is evaluated inside the \Verb!pic! so if using a node then the node name should be specified as if inside the \Verb!pic!. 535 | % 536 | % The node positioning syntax, things like \Verb!below! and \Verb!below=5pt of!, sets the anchor of the following node. 537 | % Using \Verb!pic anchor! without a coordinate uses this anchor on the bounding box of the pic when positioning the pic. 538 | % 539 | % Internally, this works by adjusting the location of the \Verb!pic!'s surrounding scope. 540 | % So the code can equally be used on \Verb!scope!s. 541 | % For a \Verb!scope!, use the \Verb!scope anchor! version on the scope directly. 542 | % The keys \Verb!name! and \Verb!anchor! can be used on the scope as if on a \Verb!node! with the same effect on the positioning. 543 | % 544 | % The key \Verb!surround pic! saves the bounding box of the pic as if it were the boundary of a rectangular node, using the name of the pic as the name of the node. 545 | % 546 | % This was inspired by the questions \href{https://tex.stackexchange.com/q/185279/86}{Anchoring TiKZ pics} and \href{https://tex.stackexchange.com/q/567245/86}{Reposition Tikz Scope After Size Known}. 547 | % 548 | % \subsection{Subnodes} 549 | % 550 | % \Verb+\subnode[options]{name}{content}+ 551 | % 552 | % This produces a pseudo-node named \Verb+name+ around the \Verb+content+. 553 | % The design purpose of this is to create a ``subnode'' inside a TikZ node. 554 | % As far as TikZ is concerned, the contents of a node is just a box. 555 | % It therefore does not know anything about it beyond its external size and so cannot easily determine the coordinates of pieces inside. 556 | % The \Verb+\subnode+ command boxes its contents and saves the position of that box and its dimensions. 557 | % This information is stored in the same way that PGF stores the necessary information about a node. 558 | % It is therefore possible to use ordinary node syntax (within a \Verb+tikzpicture+) to access this information. 559 | % Thus after \Verb+\node {a \subnode{a}{sub} node};+ it is possible to use \Verb+a+ as a node. 560 | % The \Verb+options+ are passed to the node construction mechanism, but note that the only sensible options are those that affect the size and shape of the node: drawing options are ignored (except in so far as they affect the size -- as an example, \Verb+line width+ affects the node size). 561 | % 562 | % There are two important points to make about this. 563 | % The first is that, as with all the \Verb+tikzmark+ macros, the information is always one compilation old. 564 | % The second is that the pseudo-node is purely about coordinates: the path information is not used and the contents are not moved. 565 | % This is partly for reasons of implementation: the pseudo-node is constructed when TikZ is not in ``picture mode''. 566 | % But also interleaving the background path of the pseudo-node and any containing node would be problematic and so is best left to the user. 567 | % 568 | % The simplest way to turn a pseudo-node into a more normal node is to use the \Verb+fit+ library. 569 | % Using the above example, \Verb+\node[fit=(a),draw,inner sep=0pt] {};+ would draw a rectangle around the word \Verb+sub+ of exactly the same size as would appear had a normal node been created. 570 | % 571 | % Using a sneaky trick with \Verb+\mathchoice+, \Verb+subnode+ works inside a math environment. 572 | % The spacing either side might not be quite right as although it detects the math style it doesn't got beyond that. 573 | % 574 | % Note that because of the way that this works, the outer \Verb!tikzpicture! must have the \Verb!remember picture! option set. 575 | % 576 | % \subsection{Node saving} 577 | % 578 | % The node saving system takes the information stored about a node and saves it for later use. 579 | % That later use can be in the same document, in which case it should be saved just to the memory of the current TeX process, or it can be used earlier in the same document or another document altogether (in particular, if the nodes are defined in a \Verb+tikzpicture+ that has been externalised, this can be used to import the node information into the main file) in which cases the node data is saved to a file. 580 | % 581 | % When working with files, nodes are saved and restored in bulk. 582 | % When working in memory, nodes are saved and restored in named lists. 583 | % Nodes are not actually saved until the end of the tikzpicture in which they are defined, meaning that if saving to memory then all the nodes in a tikzpicture will belong to the same list. 584 | % 585 | % The keys for working with saving and restoring nodes are as follows. 586 | % 587 | % \begin{itemize} 588 | % \item \Verb+save node+, \Verb+save node=+ 589 | % 590 | % This is the key that indicates a node to be saved. 591 | % The version with no argument is to be used directly in the keys for a node and it saves that node. 592 | % With an argument then it saves a node that has been declared somewhere in the current tikz picture (it may not always be convenient to issue the \Verb+save node+ key directly on the node itself). 593 | % Since the list is saved up to the end of the picture, this can be invoked before the node is defined. 594 | % 595 | % \item \Verb+\SaveNode[group name]{name}+ 596 | % 597 | % This command is for outside a tikzpicture and saves the named node directly. 598 | % The optional argument is a group name for saving to a group. 599 | % If this is not specified then the node is saved to a file. 600 | % 601 | % \item \Verb+set node group=+ 602 | % 603 | % Nodes are grouped together into a list that can be saved either to a file or for use later on in the document. 604 | % This sets the name for the current group. 605 | % 606 | % \item \Verb+restore nodes from list=+ 607 | % 608 | % This restores the node information from the named list to the current \Verb+tikzpicture+. 609 | % This is required both for when the node information comes from a file or from earlier in the same document. 610 | % 611 | % \item \Verb+save nodes to file+ 612 | % 613 | % This is a \Verb+true/false+ key which determines whether to save the node information to a file. 614 | % 615 | % \item \Verb+set saved nodes file name=+ 616 | % 617 | % This sets the file name for the saved nodes (the extension will be \Verb+.nodes+. 618 | % The default is to use the current \TeX\ filename. 619 | % This is set globally, and once the file is opened then changing the name will have no effect. 620 | % (The file is not opened until it is actually needed to avoid creating empty files unnecessarily.) 621 | % 622 | % \item \Verb+restore nodes from file=+ 623 | % 624 | % This loads the node information from the file into the current document. 625 | % 626 | % The \Verb++ can have the syntax \Verb+[options]{name}+, where \Verb+options+ can be used to influence how the nodes are restored. 627 | % The key \Verb+transform saved nodes+ (see below) can be given here. 628 | % Another useful key is the \Verb+name prefix+ key which is applied to all restored nodes. 629 | % 630 | % \item \Verb+transform saved nodes+ 631 | % 632 | % A particular use-case for restoring saved nodes is to safely include one \Verb+tikzpicture+ inside another by creating an image out of the inner picture and including it back in as a picture inside a node. 633 | % In that situation, restoring the nodes from the inner picture can make it possible to refer to coordinates from the inner picture to the outer one. 634 | % If there is a transformation in place on the containing node, this key applies that transformation to all the nodes in the inner picture. 635 | % 636 | % \end{itemize} 637 | % 638 | % \section{Examples} 639 | % 640 | % The \Verb+\tikzmark+ command has been used in numerous answers on \href{http://tex.stackexchange.com}{TeX-SX}. 641 | % 642 | % \subsection{Basic Examples} 643 | % 644 | % A simple example of the \Verb+\tikzmark+ macro is the following. 645 | % 646 | % \begin{example} 647 | % \tikzset{tikzmark prefix=ex1-} 648 | % \[ 649 | % \tikzmark{a} e^{i \pi/2} = i 650 | % \] 651 | % 652 | % This\tikz[remember picture,overlay,baseline=0pt] \draw[->] (0,1em) to[bend left] ([shift={(-1ex,1ex)}]pic cs:a); is an important equation. 653 | % \end{example} 654 | % 655 | % \begin{example} 656 | % \tikzset{tikzmark prefix=ex2-} 657 | % \begin{itemize} 658 | % \item A first item,\tikzmark{b} 659 | % \item A second item,\tikzmark{c} 660 | % \item A third item.\tikzmark{d} 661 | % \end{itemize} 662 | % \begin{tikzpicture}[remember picture,overlay] 663 | % \draw[decorate,decoration={brace}] ({pic cs:c} |- {pic cs:b}) +(0,1em) -- node[right,inner sep=1em] {some items} ({pic cs:c} |- {pic cs:d}); 664 | % \end{tikzpicture} 665 | % \end{example} 666 | % 667 | % \begin{example} 668 | % \tikzset{tikzmark prefix=ex3-} 669 | % \begin{tikzpicture}[remember picture] 670 | % \node (a) at (0,0) {This has a \subnode{sub}{subnode} in it}; 671 | % \draw[->] (0,-1) to[bend right] (sub); 672 | % \end{tikzpicture} 673 | % \end{example} 674 | % 675 | % An example using \Verb+\tikzmark+ inside a \Verb+tikzpicture+ 676 | % 677 | % \begin{example} 678 | % \tikzset{tikzmark prefix=ex4-} 679 | % \begin{tikzpicture}[remember picture,overlay] 680 | % \draw[->,line width=1mm,cyan] (pic cs:a) to[bend left] (pic cs:b); 681 | % \end{tikzpicture} 682 | % 683 | % By placing the \tikzmark{a}code before the marks, the arrow goes under the subsequent text and picture. 684 | % 685 | % \begin{tikzpicture} 686 | % \filldraw[fill=gray] (0,0) circle[radius=1cm]; 687 | % \tikzmark{b}{(-1,-1)} 688 | % \end{tikzpicture} 689 | % \end{example} 690 | % 691 | % The \Verb+\tikmarknode+ puts a node around some text, which can be referred to later, and adds a \Verb+\tikzmark+ at its origin. 692 | % 693 | % \begin{example} 694 | % \tikzset{tikzmark prefix=ex5-} 695 | % Putting a node around \tikzmarknode{txt}{some text} means we can connect text together, including in maths: 696 | % \[ 697 | % \tikzmarknode{a}{\sum_{k=1}^n} k^{\tikzmarknode{b}{2}} 698 | % \] 699 | % 700 | % \begin{tikzpicture}[remember picture,overlay] 701 | % \draw[->] (txt) -- (a); 702 | % \draw[->] (a.south) to[out=-90,in=-45] (b.south east); 703 | % \end{tikzpicture} 704 | % \end{example} 705 | % 706 | % \subsection{More Intricate Examples} 707 | % 708 | % The syntax for saving node data is illustrated by the following example. 709 | % 710 | % File \Verb+firstpicture.tex+: 711 | % 712 | % \begin{justexample} 713 | % \documentclass[tikz,border=10pt]{standalone} 714 | % \usetikzlibrary{tikzmark,shapes.geometric} 715 | % \begin{document} 716 | % \begin{tikzpicture}[save nodes to file] 717 | % \node[draw,rotate=-30,save node](1) at (-2,0) {1}; 718 | % \draw[->] (0,0) -- (1); 719 | % \node[draw,ellipse,save node] (c) at (current bounding box.center) {}; 720 | % \end{tikzpicture} 721 | % \end{document} 722 | % \end{justexample} 723 | % 724 | % File \Verb+secondpicture.tex+: 725 | % 726 | % \begin{justexample} 727 | % \documentclass[tikz,border=10pt]{standalone} 728 | % \usetikzlibrary{tikzmark,shapes.geometric} 729 | % \begin{document} 730 | % \begin{tikzpicture}[save nodes to file] 731 | % \node[draw,rotate=-70,save node] (2) at (2,0) {2}; 732 | % \draw[->] (0,0) -- (2); 733 | % \node[draw,ellipse,save node] (c) at (current bounding box.center) {}; 734 | % \end{tikzpicture} 735 | % \end{document} 736 | % \end{justexample} 737 | % 738 | % Main file: 739 | % 740 | % \begin{justexample} 741 | % \documentclass{article} 742 | % \usepackage{tikz} 743 | % \usetikzlibrary{tikzmark} 744 | % 745 | % \begin{document} 746 | % \begin{tikzpicture} 747 | % 748 | % \node[draw, 749 | % rotate=30, 750 | % restore nodes from file={[transform saved nodes,name prefix=pic-1-]{firstpicture}} 751 | % ] (a-1) at (-2,-3) {\includegraphics{firstpicture.pdf}}; 752 | % 753 | % \node[draw, 754 | % rotate=70, 755 | % restore nodes from file={[transform saved nodes,name prefix=pic-2-]{secondpicture}} 756 | % ] (a-2) at (+2,+2) {\includegraphics{secondpicture.pdf}}; 757 | % 758 | % \draw[red] (pic-1-1.north west) -- (pic-1-1.north east) -- (pic-1-1.south east) -- (pic-1-1.south west) -- cycle; 759 | % \draw[red] (pic-2-2.north west) -- (pic-2-2.north east) -- (pic-2-2.south east) -- (pic-2-2.south west) -- cycle; 760 | % 761 | % \node[red] at (pic-1-1) {1}; 762 | % \node[red] at (pic-2-2) {2}; 763 | % 764 | % \draw (a-1) circle[radius=5pt]; 765 | % \draw (a-2) circle[radius=5pt]; 766 | % 767 | % \draw (pic-1-1) -- (pic-2-2); 768 | % \end{tikzpicture} 769 | % \end{document} 770 | % \end{justexample} 771 | % 772 | % This produces: 773 | % 774 | % \begin{center} 775 | % \fbox{\IfFileExists{tikzrefextnodes.pdf}{\includegraphics{tikzrefextnodes}}{}} 776 | % \end{center} 777 | % 778 | % One issue with placing things via \Verb+\tikzmark+ is that the necessity of using the \Verb+overlay+ key means that the various elements don't take up any space. 779 | % While this is needed to ensure that pictures don't explode in size, it can be important to leave space for the additional elements. 780 | % This isn't simple. 781 | % The difficulty is that \Verb+\tikzmark+ positions depend on the previous compilation, so if we're trying to leave space for items that depend on a previous compilation which might then affect the positions of the \Verb+\tikzmark+s then we can get into a loop that never settles down. 782 | % The solution is to ensure that the dependency loop doesn't arise, and that the way each measurement or position depends on others is a tree. 783 | % 784 | % There are two key parts to this. 785 | % The first is the \Verb+\tikz+ command that adds a vertical strut to reserve the right vertical space. 786 | % The second is the \Verb+tikzpicture+ that defines the annotations. 787 | % This defines \Verb+\tikzmark+s at its top and bottom extents and its baseline, but to ensure that the dependencies don't form a loop then all are defined inside that environment even though one of them is actually at the same location as a \Verb+\tikzmark+ defined elsewhere. 788 | % This can, therefore, take more compilations than usual to settle (the following example usually takes three). 789 | % 790 | % This example is based on my answer to \href{https://tex.stackexchange.com/q/361375/86}{How to add arrow in equations and matrix?}. 791 | % 792 | % \begin{example} 793 | % \tikzset{tikzmark prefix=ex7-} 794 | % \begin{align*} 795 | % A(\vec{u} + \vec{v}) &= 796 | % \begin{bmatrix} \vec{a}_1 & \vec{a}_2 & \vec{a}_3 \end{bmatrix} 797 | % \begin{bmatrix} u_1 + v_1 \\ u_2 + v_2 \\ u_3 + v_3 \end{bmatrix} \\ 798 | % &= \tikzmarknode{uv1}{(u_1 + v_1)} \tikzmarknode{a1}{\vec{a}_1} + 799 | % \tikzmarknode{uv2}{(u_2 + v_2)} \tikzmarknode{a2}{\vec{a}_2} + 800 | % \tikzmarknode{uv3}{(u_3 + v_2)} \tikzmarknode{a3}{\vec{a}_3} 801 | % \tikz[remember picture,baseline={(0,0)}] {\path let \p1=(pic cs:upper), \p2=(pic cs:lower), \p3=(pic cs:middle) in (0,\y1-\y3) (0,\y2-\y3);} 802 | % \\ 803 | % &= (u_1 \vec{a}_1 + u_2 \vec{a}_2 + u_3 \vec{a}_3) + 804 | % (v_1 \vec{a}_1 + v_2 \vec{a}_2 + v_3 \vec{a}_3) \\ 805 | % &= A \vec{u} + A \vec{v} 806 | % \end{align*} 807 | % 808 | % \begin{tikzpicture}[remember picture, overlay,>=Latex, cyan] 809 | % 810 | % \node[above right] (entries) at ($(a3.north east)+(1,.5)$) {Entries in \(\vec{u} + \vec{v}\)}; 811 | % \node[below right] (columns) at ($(a3.south east)+(1,-.5)$) {Columns of \(A\)}; 812 | % 813 | % \draw[<-,rounded corners] (uv1.north) |- (entries); 814 | % \draw[<-,rounded corners] (uv2.north) |- (entries); 815 | % \draw[<-,rounded corners] (uv3.north) |- (entries); 816 | % \draw[<-,rounded corners] (a1.south) |- (columns); 817 | % \draw[<-,rounded corners] (a2.south) |- (columns); 818 | % \draw[<-,rounded corners] (a3.south) |- (columns); 819 | % 820 | % \tikzmark{upper}{(entries.north)} 821 | % \tikzmark{lower}{(columns.south)} 822 | % \tikzmark{middle}{(a3.base)} 823 | % \end{tikzpicture} 824 | % 825 | % \end{example} 826 | % 827 | % 828 | % \section{Additional Libraries} 829 | % 830 | % Some of the more ambitious uses of \Verb!\tikzmark! involve a fair bit of extra code and so are worth gathering in to extra libraries of their own. 831 | % These can be loaded via \Verb+\usetikzmarklibrary+. 832 | % 833 | % At present, there are three libraries: one for code listings which works with the \Verb+listings+ package, one for AMSMath equations, and one for highlighting. 834 | % 835 | % \subsection{Code Listings} 836 | % 837 | % If the \Verb+listings+ package has been loaded then issuing 838 | % 839 | % \Verb+\usetikzmarklibrary{listings}+ 840 | % 841 | % \noindent will load in some code to add marks to \Verb+lstlisting+ environments. 842 | % This code places a mark at three places on a line of code in a \Verb+listings+ environment. 843 | % The marks are placed at the start of the line, the first non-whitespace character, and the end of the line (if the line is blank the latter two are not placed). 844 | % (This has not been extensively tested, it works by adding code to various ``hooks'' that are made available by the \Verb+listings+ package; it is quite possible that the hooks chosen are both wrong and insufficient to cover all desired cases.) 845 | % 846 | % 847 | % These are inspired by questions such as \href{http://tex.stackexchange.com/q/79762/86}{Marking lines in listings} and \href{http://tex.stackexchange.com/q/86309/86}{Macros for code annotations}. 848 | % 849 | % In more detail, the \Verb+listings+ library places lots of marks around the code. 850 | % The marks are: 851 | % 852 | % \begin{itemize} 853 | % \item \Verb+line---start+ at the start of each line. 854 | % \item \Verb+line---end+ at the end of each line. 855 | % \item \Verb+line---first+ at the first non-space character of the line (assuming it exists). 856 | % \end{itemize} 857 | % 858 | % The line numbers \emph{should} match up with the line numbers in the code in that any initial offset is also applied. 859 | % 860 | % Not every mark is available on every line. 861 | % If a line is blank, in particular, it will only have a \Verb+start+ mark. 862 | % The following example shows this, where the red dots are the \Verb+start+, the blue are \Verb+end+, and the green are \Verb+first+. 863 | % 864 | % \begin{example} 865 | % \tikzset{tikzmark prefix=ex6-} 866 | % \begin{tikzpicture}[remember picture] 867 | % \foreach \k in {0,...,7} { 868 | % \iftikzmark{line-code-\k-start}{\fill[red,overlay] (pic cs:line-code-\k-start) circle[radius=4pt];}{\message{No start for \k}} 869 | % \iftikzmark{line-code-\k-end}{\fill[blue,overlay] (pic cs:line-code-\k-end) circle[radius=2pt];}{\message{No end for \k}} 870 | % \iftikzmark{line-code-\k-first}{\fill[green,overlay] (pic cs:line-code-\k-first) circle[radius=2pt];}{\message{No first for \k}} 871 | % } 872 | % \draw[->,overlay] (0,0) -- (pic cs:line-code-5-first); 873 | % \draw[->,overlay] (0,0) -- (pic cs:line-code-5-start); 874 | % \draw[->,overlay] (0,0) -- (pic cs:line-code-5-end); 875 | % \node[above] at (0,0) {Line 5}; 876 | % \end{tikzpicture} 877 | % 878 | % \begin{lstlisting}[language=c,name=code,numbers=left] 879 | % #include 880 | % 881 | % int main(void) 882 | % { 883 | % printf("hello, world\n"); 884 | % return 0; 885 | % } 886 | % \end{lstlisting} 887 | % \end{example} 888 | % 889 | % This example puts a fancy node behind certain lines of the code, computing the necessary extents. 890 | % 891 | % \begin{example} 892 | % \balloon{comment}{more code}{3}{3} 893 | % \balloon{comment}{more code}{7}{8} 894 | % \begin{lstlisting}[language=c,name=more code,numbers=left,firstnumber=3] 895 | % #include 896 | % 897 | % int main(void) 898 | % { 899 | % printf("hello, world\n"); 900 | % return 0; 901 | % } 902 | % \end{lstlisting} 903 | % \end{example} 904 | % 905 | % The \Verb+\balloon+ command was introduced in \href{https://tex.stackexchange.com/a/79787/86}{this question} on TeX-SX. 906 | % Its definition in this document is as follows: 907 | % 908 | % \begin{justexample} 909 | % \newcommand\balloon[4]{% 910 | % \pgfmathtruncatemacro\firstline{% 911 | % #3-1 912 | % }% 913 | % \iftikzmark{line-#2-\firstline-start}{% 914 | % \iftikzmark{line-#2-#3-first}{% 915 | % \xdef\blines{({pic cs:line-#2-\firstline-start} -| {pic cs:line-#2-#3-first})}% 916 | % }{% 917 | % \iftikzmark{line-#2-#3-start}{% 918 | % \xdef\blines{({pic cs:line-#2-\firstline-start} -| {pic cs:line-#2-#3-start})}% 919 | % }{% 920 | % \xdef\blines{(pic cs:line-#2-\firstline-start)}% 921 | % }% 922 | % }% 923 | % }{% 924 | % \xdef\blines{}% 925 | % }% 926 | % \foreach \k in {#3,...,#4} {% 927 | % \iftikzmark{line-#2-\k-first}{% 928 | % \xdef\blines{\blines (pic cs:line-#2-\k-first) } 929 | % }{} 930 | % \iftikzmark{line-#2-\k-end}{% 931 | % \xdef\blines{\blines (pic cs:line-#2-\k-end) } 932 | % }{} 933 | % }% 934 | % \ifx\blines\empty 935 | % \else 936 | % \edef\temp{\noexpand\tikz[remember picture,overlay]{\noexpand\node[fit={\blines},balloon] (#1) {}}}% 937 | % \temp 938 | % \fi 939 | % } 940 | % \tikzset{ 941 | % line/.style={ 942 | % draw, 943 | % rounded corners=3pt, 944 | % -latex 945 | % }, 946 | % balloon/.style={ 947 | % draw, 948 | % fill=blue!20, 949 | % opacity=0.4, 950 | % inner sep=4pt, 951 | % rounded corners=2pt 952 | % }, 953 | % comment/.style={ 954 | % draw, 955 | % fill=blue!70, 956 | % text=white, 957 | % text width=3cm, 958 | % minimum height=1cm, 959 | % rounded corners, 960 | % drop shadow, 961 | % align=left, 962 | % font=\scriptsize 963 | % }, 964 | % } 965 | % \end{justexample} 966 | % 967 | % 968 | % \subsection{AMS Equation Environments} 969 | % 970 | % \textbf{This is an experimental library.} 971 | % 972 | % If the \Verb+amsmath+ package has been loaded then issuing 973 | % 974 | % \Verb+\usetikzmarklibrary{ams}+ 975 | % 976 | % \noindent loads some code that places pseudo-nodes around the boxes that are used in AMSMath's various equation alignment environments, such as \Verb!align! and \Verb!gather!. 977 | % These environments work by constructing boxes with each of the pieces of the equations that are then put together into the grid. 978 | % This library hooks in to the unboxing code, before the box is typeset then it measures it and stores that information in various macros as if it were a TikZ node. 979 | % The aim is that this doesn't disturb the placement, but as far as TikZ is concerned then there is a node there that can be referred to later. 980 | % 981 | % As it is experimental, even if this library is loaded then it isn't automatically switched on. 982 | % To do that, use either the \Verb!tikzmarkmath! environment or the \Verb!\tikzmarkmath! command. 983 | % Each has an optional argument which is a prefix for the node names (the default is \Verb!equation!). 984 | % The node names are then of the form \Verb!-!. 985 | % The numbering is held in a counter called \Verb!tikzmarkequation! and is reset when the command is invoked or the environment is started. 986 | % As usual, redefining \Verb!\thetikzmarkequation! changes the styling of the \Verb!!. 987 | % 988 | % To disable the marking, either end the environment or use \Verb!\endtikzmarkmath!. 989 | % The ending command explicitly removes the hook rather than rely on \TeX\ groupings. 990 | % It also prints out the number of nodes created to the log file and terminal. 991 | % This can be useful with figuring out which nodes to use, since the box that this library hooks into is used many times. 992 | % For example, equation numbers are included with this. 993 | % 994 | % The box is also used when assembling a \Verb!\sqrt[3]{4}! command, and as that uses \Verb!\mathchoice! then there are more boxes created than used. 995 | % So the count of number of nodes created can be more than are actually there. 996 | % 997 | % \begin{example} 998 | % \begin{tikzmarkmath}[pythagoras] 999 | % 1000 | % \begin{gather} 1001 | % a^2 = b^2 + c^2 1002 | % \end{gather} 1003 | % 1004 | % \begin{gather} 1005 | % a = \sqrt[2]{b^2 + c^2} 1006 | % \end{gather} 1007 | % \end{tikzmarkmath} 1008 | % 1009 | % \begin{tikzpicture}[remember picture, overlay] 1010 | % \foreach \k in {1,2,3,7,8} { 1011 | % \draw[red] (pic cs:pythagoras-\k) -- ++(135:1) node[draw,red,circle,font=\tiny,above left] {\k}; 1012 | % \node[draw,blue,fit=(pythagoras-\k),inner sep=0pt] {}; 1013 | % } 1014 | % \end{tikzpicture} 1015 | % % \end{example} 1016 | % 1017 | % 1018 | % \subsection{Highlighting} 1019 | % 1020 | % I've returned to the highlighting library. 1021 | % The \LaTeX3 hook mechanism makes a couple of things possible that were tricky before. 1022 | % 1023 | % The idea of the highlighting mechanism is to use two \Verb!\tikzmark!s to mark a start and end of a region to be highlighted. 1024 | % The region is considered to be formed by lines of text, with the first mark at the baseline of the start and the second at the baseline of the end. 1025 | % 1026 | % The highlighting itself is done by inserting code in the shipout routine before the page itself is laid out. 1027 | % So the highlighting is on a separate layer to the text itself, which can be either behind or in front of the text layer. 1028 | % The hook mechanism also makes it relatively simple to support page breaks between the start and end of highlighting. 1029 | % 1030 | % Since the highlighting is separate to the flow of the text, it doesn't make sense to use an environment to mark the start and end of the highlighting so instead there are two commands: \Verb!\StartHighlighting[options]! and \Verb!\StopHighlighting!, or a single command \Verb!\Highlight[options]{text}! that just highlights the \Verb!text!. 1031 | % At the moment, nesting highlighting is not supported but the plan is to implement it via an option to specify a name for a highlighting block. 1032 | % 1033 | % The optional argument to \Verb!\StartHighlighting! (or \Verb!\Highlight!) consists of key-value pairs that control the behaviour of the highlighted region. 1034 | % There are particular keys in the \Verb!/tikz/highlighter! family which control the size of the highlighted region. 1035 | % Note that both \Verb!\StartHighlighting! (or \Verb!\Highlight!) change the key directory to \Verb!/tikz/highlighter! so the following keys can be used as-is, and any unknown keys are passed back to the \Verb!/tikz/! directory so ordinary \Verb!tikz! keys can be used also as-is. 1036 | % 1037 | % The \Verb+highlighter+ keys are as follows: 1038 | % 1039 | % \begin{itemize} 1040 | % \item \texttt{direction} 1041 | % \item \texttt{layer} 1042 | % \item \texttt{initial height} 1043 | % \item \texttt{initial depth} 1044 | % \item \texttt{initial offset} 1045 | % \item \texttt{final height} 1046 | % \item \texttt{final depth} 1047 | % \item \texttt{final offset} 1048 | % \item \texttt{left margin} 1049 | % \item \texttt{right margin} 1050 | % \item \texttt{height} 1051 | % \item \texttt{depth} 1052 | % \item \texttt{offset} 1053 | % \item \texttt{margin} 1054 | % \end{itemize} 1055 | % 1056 | % The highlighting code draws a region which can be styled with standard TikZ keys, more of which in a moment. 1057 | % Although it is a single region, the \emph{intention} is to simulate using an actual highlighter. 1058 | % The first key, \Verb!direction!, is used to draw the region as if the highlighter were used in a particular direction. 1059 | % The options are \Verb!horizontal!, \Verb!vertical!, or \Verb!box!. 1060 | % The default is \Verb!horizontal!. 1061 | % 1062 | % The second key, \Verb!layer!, determines whether the highlighter is rendered on the \Verb!background! or \Verb!foreground! layer. 1063 | % Using the \Verb!background! layer puts the highlighting underneath the text, which will make the text easier to read. 1064 | % The \Verb!foreground! option puts the highlighting over the text, which can be used to fade the text. 1065 | % The default is \Verb!background!. 1066 | % 1067 | % The shape of the region depends on a few things, such as whether the highlighting starts and ends on the same line. 1068 | % 1069 | % \begin{tikzpicture}[>=Latex] 1070 | % \fill (0,0) circle[radius=2pt]; 1071 | % \fill (4,0) circle[radius=2pt]; 1072 | % \draw (-1,-1) rectangle (5,1); 1073 | % \draw[dashed] (0,0) -- (4,0); 1074 | % \draw[<->] (0,0) -- +(-1,0); 1075 | % \draw[<->] (0,0) -- +(0,1); 1076 | % \draw[<->] (4,0) -- +(0,-1); 1077 | % \draw[<->] (4,0) -- +(1,0); 1078 | % \draw[<-] (-.5,0) to[out=90,in=-90] +(-1,1.5) node[above] {initial offset}; 1079 | % \draw[<-] (4.5,0) to[out=90,in=-90] +(1,1.5) node[above] {final offset}; 1080 | % \draw[<-] (0,.5) to[out=0,in=180] +(1,1.5) node[right] {initial height}; 1081 | % \draw[<-] (4,-.5) to[out=0,in=180] +(1,-1.5) node[right] {final depth}; 1082 | % \node[anchor=base] at (2,0) {Single line}; 1083 | % \end{tikzpicture} 1084 | % 1085 | % \begin{tikzpicture}[>=Latex] 1086 | % \fill (0,0) circle[radius=2pt]; 1087 | % \draw (-1,-1) rectangle (4,1); 1088 | % \draw[dashed] (0,0) -- (4,0); 1089 | % \draw[<->] (0,0) -- +(-1,0); 1090 | % \draw[<->] (0,0) -- +(0,1); 1091 | % \draw[<->] (0,0) -- +(0,-1); 1092 | % \draw[<-] (-.5,0) to[out=90,in=-90] +(-1,1.5) node[above] {initial offset}; 1093 | % \draw[<-] (0,.5) to[out=0,in=180] +(1,1.5) node[right] {initial height}; 1094 | % \draw[<-] (0,-.5) to[out=0,in=180] +(1,-1.5) node[right] {initial depth}; 1095 | % \node[anchor=base] at (2,0) {Split line}; 1096 | % \begin{scope}[yshift=-3cm,xshift=-5cm] 1097 | % \fill (4,0) circle[radius=2pt]; 1098 | % \draw (0,-1) rectangle (5,1); 1099 | % \draw[dashed] (0,0) -- (4,0); 1100 | % \draw[<->] (4,0) -- +(1,0); 1101 | % \draw[<->] (4,0) -- +(0,1); 1102 | % \draw[<->] (4,0) -- +(0,-1); 1103 | % \draw[<-] (4.5,0) to[out=90,in=180] +(2.5,0) node[right] {final offset}; 1104 | % \draw[<-] (4,.5) to[out=180,in=0] +(-1,1.5) node[left] {final height}; 1105 | % \draw[<-] (4,-.5) to[out=0,in=180] +(1.5,-1) node[right] {final depth}; 1106 | % \node[anchor=base] at (2,0) {Split line}; 1107 | % \end{scope} 1108 | % \end{tikzpicture} 1109 | % 1110 | % \begin{tikzpicture}[>=Latex] 1111 | % \fill (0,0) circle[radius=2pt]; 1112 | % \fill (4,0) circle[radius=2pt]; 1113 | % \fill (-4,-1) circle[radius=2pt]; 1114 | % \fill (4,-1) circle[radius=2pt]; 1115 | % \fill (-4,-2) circle[radius=2pt]; 1116 | % \fill (0,-2) circle[radius=2pt]; 1117 | % \draw (-1,0) -- (-1,1) -- (5,1) -- (5,-2) -- (1,-2) -- (1,-3) -- (-5,-3) -- (-5,0) -- cycle; 1118 | % \draw[dashed] (0,0) -- (4,0); 1119 | % \draw[dashed] (-4,-1) -- (4,-1); 1120 | % \draw[dashed] (-4,-2) -- (0,-2); 1121 | % \draw[<->] (0,0) -- +(-1,0); 1122 | % \draw[<->] (0,0) -- +(0,1); 1123 | % \draw[<->] (4,0) -- +(1,0); 1124 | % \draw[<->] (0,-2) -- +(1,0); 1125 | % \draw[<->] (0,-2) -- +(0,-1); 1126 | % \draw[<->] (-4,-2) -- +(-1,0); 1127 | % \draw[<-] (-.5,0) to[out=90,in=0] +(-1,.5) node[left] {initial offset}; 1128 | % \draw[<-] (0,.5) to[out=0,in=180] +(1,0) node[right] {initial height}; 1129 | % \draw[<-] (4.5,0) to[out=90,in=-90] +(1,1.5) node[above] {right margin}; 1130 | % \draw[<-] (.5,-2) to[out=-90,in=180] +(1,-.5) node[right] {final offset}; 1131 | % \draw[<-] (0,-2.5) to[out=180,in=0] +(-1,0) node[left] {final depth}; 1132 | % \draw[<-] (-4.5,-2) to[out=90,in=-90] +(-1,1.5) node[above] {left margin}; 1133 | % \node[anchor=base] at (0,-1) {Multiple lines}; 1134 | % \end{tikzpicture} 1135 | % 1136 | % The \texttt{vertical} regions and the \texttt{box} are defined similarly. 1137 | % With the vertical regions then the meaning of the \Verb!height!, \Verb!depth!, and \Verb!offset! are rotated \(90^\circ\), and the vertical regions don't stretch to the page boundaries. 1138 | % The \texttt{box} region is always a rectangle. 1139 | % 1140 | % Once the region is defined, it can be styled using options directly on the \Verb!StartHighlighting! or \Verb!\Highlight! command and by using the following styles: 1141 | % 1142 | % \begin{itemize} 1143 | % \item \texttt{every highlight picture} 1144 | % \item \texttt{every highlight picture} 1145 | % \item \texttt{every highlight picture} 1146 | % \item \texttt{every highlight path} 1147 | % \item \texttt{every highlight path} 1148 | % \item \texttt{every highlight path} 1149 | % \item \texttt{highlight path} 1150 | % \item \texttt{ highlight path} 1151 | % \item \texttt{ highlight path} 1152 | % \end{itemize} 1153 | % 1154 | % The \Verb!picture! keys are for the surrounding \Verb!tikzpicture!, while the \Verb!path! keys are for the path itself. 1155 | % 1156 | % Lastly, a word about scoping the options. 1157 | % Since the code that actually renders the highlighting is processed when the page is shipped out, it may well be that the settings in force when the highlighting was defined have changed. 1158 | % The keys that adjust the size of the region (in the \Verb!highlighter! family) are processed and saved at the moment of invocation but keys such as the colour or whether to fill or draw the path are passed without being processed. 1159 | % Where this can cause issues is if those styles are themselves gathered into a single style. 1160 | % This grouping style must be defined in a scope accessible to the code when the highlighting is rendered (so almost certainly it should be in a global scope), and if it is changed between when the highlighter is declared and is rendered then the latest version will be what is used. 1161 | % Therefore, it is wise to use styles that persist to set the rendering styles and to avoid trying to be too cunning with changing styles. 1162 | % 1163 | % An attempt has been made to ensure that setting the various options obeys \TeX's grouping, there might yet be a few bugs in this. 1164 | % 1165 | % \begin{example} 1166 | % The sun was shining on the sea, shining with all its might. 1167 | % \StartHighlighting[fill=cyan!50] 1168 | % And this was very odd because it was the middle of the night. 1169 | % \StopHighlighting 1170 | % The moon was up there sulkily because she thought the sun had no 1171 | % business to be there after the day was done. 1172 | % \StartHighlighting[fill=magenta!50] 1173 | % ``It's very rude of him,'' she said, ``to come and spoil the fun.'' 1174 | % \StopHighlighting 1175 | 1176 | % \noindent The sun was shining on the sea, shining with all its might. 1177 | % And this was very odd because it was the middle of the night. 1178 | % \StartHighlighting[fill=yellow!50] 1179 | % The moon was up there sulkily because she thought the sun had no business to be there after the day was done\StopHighlighting. 1180 | % ``It's very rude of him,'' she said, ``to come and spoil the fun.'' 1181 | % \end{example} 1182 | % 1183 | % \section{Acknowledgements} 1184 | % 1185 | % The \Verb+\tikzmark+ macro has been used and abused by many users of \href{http://tex.stackexchange.com}{TeX-SX}. 1186 | % Of particular note (but in no particular order) are \href{https://tex.stackexchange.com/users/4301/peter-grill}{Peter Grill}, \href{https://tex.stackexchange.com/users/3954/gonzalo-medina}{Gonzalo Medina}, \href{https://tex.stackexchange.com/users/13304/claudio-fiandrino}{Claudio Fiandrino}, \href{https://tex.stackexchange.com/users/3235/percusse}{percusse}, and \href{https://tex.stackexchange.com/users/121799/marmot}{marmot}. 1187 | % I would also like to mention \href{https://tex.stackexchange.com/users/1090/david-carlisle}{David Carlisle} whose knowledge of TikZ continues to astound us all. 1188 | % 1189 | % 1190 | % \StopEventually{} 1191 | % 1192 | % \section{Implementation} 1193 | % 1194 | % \iffalse 1195 | %<*tikzlibrary> 1196 | % \fi 1197 | % \subsection{Main Code} 1198 | % 1199 | % 1200 | % The \Verb+save nodes+ code uses \LaTeX3. 1201 | % \begin{macrocode} 1202 | \ProvidesFile{tikzlibrarytikzmark.code.tex}[% 1203 | 2022/08/24 1204 | v1.15 1205 | TikZ library for marking positions in a document] 1206 | \RequirePackage{expl3, l3keys2e, xparse} 1207 | % \end{macrocode} 1208 | % 1209 | % \begin{macrocode} 1210 | \tikzset{% 1211 | remember picture with id/.style={% 1212 | remember picture, 1213 | overlay, 1214 | save picture id=#1, 1215 | }, 1216 | % \end{macrocode} 1217 | % Not totally happy with using \Verb+every picture+ here as it's too easily overwritten by the user. 1218 | % Maybe it would be better to patch \Verb+endtikzpicture+ directly. 1219 | % \begin{macrocode} 1220 | every picture/.append style={% 1221 | execute at end picture={% 1222 | \ifpgfrememberpicturepositiononpage% 1223 | \edef\pgf@temp{% 1224 | \noexpand\write\noexpand\pgfutil@auxout{% 1225 | \string\savepicturepage% 1226 | {\pgfpictureid}{\noexpand\arabic{page}}% 1227 | }% 1228 | }% 1229 | \pgf@temp 1230 | \fi% 1231 | }, 1232 | }, 1233 | % \end{macrocode} 1234 | % There are times when some code is executed and then discarded, such as in \Verb+\mathchoice+. 1235 | % 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. 1236 | % This isn't particularly a tikzmark issue, but does come up from time to time with tikzmark as it's all about remembering locations. 1237 | % 1238 | % In actual fact, it only occurs with \Verb+\tikzmarknode+ since the issue is about how nodes are associated with pictures. 1239 | % 1240 | % 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. 1241 | % This needs to be used \emph{after} \Verb+remember picture+ has been invoked. 1242 | % It probably messes with some other stuff so should only be used under controlled conditions, such as \Verb+\tikzmarknode+. 1243 | % \begin{macrocode} 1244 | check picture id/.code={ 1245 | \ifpgfrememberpicturepositiononpage 1246 | \@ifundefined{pgf@sys@pdf@mark@pos@\pgfpictureid}{% 1247 | \tikzset{% 1248 | name prefix/.get=\tzmk@name@prefix, 1249 | name prefix/.prefix=discard-, 1250 | execute at end picture={% 1251 | \tikzset{name prefix/.expand once=\tzmk@name@prefix}% 1252 | }, 1253 | }% 1254 | }{}% 1255 | \fi 1256 | }, 1257 | % \end{macrocode} 1258 | % 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. 1259 | % There will already be messages about needing reruns so we don't need to add to that. 1260 | % We simply ensure that the node exists. 1261 | % \begin{macrocode} 1262 | maybe define node/.style={% 1263 | execute at end picture={% 1264 | \ifpgfrememberpicturepositiononpage 1265 | \@ifundefined{pgf@sh@pi@\tikz@pp@name{#1}}{% 1266 | \pgfnodealias{\tikz@pp@name{#1}}{discard-\tikz@pp@name{#1}}% 1267 | }{}% 1268 | \fi 1269 | }% 1270 | }, 1271 | % \end{macrocode} 1272 | % The positions are already recorded in the \Verb+aux+ file, all we really need to do is provide them with better names. 1273 | % \begin{macrocode} 1274 | save picture id/.code={% 1275 | \protected@write\pgfutil@auxout{}{% 1276 | \string\savepointas% 1277 | {\tikzmark@pp@name{#1}}{\pgfpictureid}{0pt}{0pt}}% 1278 | }, 1279 | % \end{macrocode} 1280 | % Provides a way to test if a picture has already been saved (in particular, can avoid errors on first runs) 1281 | % \begin{macrocode} 1282 | if picture id/.code args={#1#2#3}{% 1283 | \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{% 1284 | \pgfkeysalso{#3}% 1285 | }{ 1286 | \pgfkeysalso{#2}% 1287 | } 1288 | }, 1289 | % \end{macrocode} 1290 | % 1291 | % With complicated \Verb+tikzmark+ stuff, because we are always using the results from a previous run then we can end up in a situation where precision errors mean that the stuff written out to the \Verb+aux+ file changes ever so slightly each time, meaning that the document never officially stabilises, but the difference is too small to notice. 1292 | % One way to avoid this is to round the coordinates read in by the \Verb+pic cs+ syntax. 1293 | % \begin{macrocode} 1294 | tikzmark round/.code={ 1295 | \def\tkmk@round{#1}% 1296 | \ifx\tkmk@round\tkmk@off 1297 | \tkmk@round@false 1298 | \else 1299 | \ifx\tkmk@round\tkmk@none 1300 | \tkmk@round@false 1301 | \else 1302 | \tkmk@round@true 1303 | \fi 1304 | \fi 1305 | }, 1306 | % \end{macrocode} 1307 | % 1308 | % Page handling 1309 | % \begin{macrocode} 1310 | next page/.is choice, 1311 | next page vector/.initial={\pgfqpoint{0pt}{0pt}}, 1312 | next page/below/.style={% 1313 | next page vector={\pgfqpoint{0pt}{-\the\paperheight}}% 1314 | }, 1315 | next page/above/.style={% 1316 | next page vector={\pgfqpoint{0pt}{\the\paperheight}}% 1317 | }, 1318 | next page/left/.style={% 1319 | next page vector={\pgfqpoint{-\the\paperwidth}{0pt}}% 1320 | }, 1321 | next page/right/.style={% 1322 | next page vector={\pgfqpoint{\the\paperwidth}{0pt}}% 1323 | }, 1324 | next page/ignore/.style={% 1325 | next page vector={\pgfqpoint{0pt}{0pt}}% 1326 | }, 1327 | if tikzmark on current page/.code n args={3}{% 1328 | \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{% 1329 | \pgfkeysalso{#3}% 1330 | }{% 1331 | \@ifundefined{% 1332 | save@pg@\csname save@pt@\tikzmark@pp@name{#1}\endcsname 1333 | }{% 1334 | \pgfkeysalso{#3}% 1335 | }{% 1336 | \ifnum\csname save@pg@% 1337 | \csname save@pt@\tikzmark@pp@name{#1}\endcsname% 1338 | \endcsname=\the\value{page}\relax% 1339 | \pgfkeysalso{#2}% 1340 | \else 1341 | \pgfkeysalso{#3}% 1342 | \fi 1343 | }% 1344 | }% 1345 | }, 1346 | if tikzmark on page/.code n args={4}{% 1347 | \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{% 1348 | \pgfkeysalso{#4}% 1349 | }{% 1350 | \@ifundefined{% 1351 | save@pg@\csname save@pt@\tikzmark@pp@name{#1}@label\endcsname% 1352 | }{% 1353 | \pgfkeysalso{#4}% 1354 | }{% 1355 | \ifnum\csname save@pg@% 1356 | \csname save@pt@\tikzmark@pp@name{#1}\endcsname% 1357 | \endcsname=#2\relax% 1358 | \pgfkeysalso{#3}% 1359 | \else 1360 | \pgfkeysalso{#4}% 1361 | \fi 1362 | }% 1363 | }% 1364 | }, 1365 | % \end{macrocode} 1366 | % Prefix and suffix for tikzmark names, shamelessly borrowed from the main tikz code 1367 | % \begin{macrocode} 1368 | tikzmark prefix/.initial=,% 1369 | tikzmark suffix/.initial=,% 1370 | tikzmark clear ixes/.style={ 1371 | tikzmark prefix={}, 1372 | tikzmark suffix={} 1373 | }, 1374 | % \end{macrocode} 1375 | % Tikzmarks can be used to adjust the position of a scope or pic so that an internally defined coordinate is used to locate the scope or pic. 1376 | % 1377 | % The key used to adjust the location is \Verb!scope anchor={coordinate}! for \Verb!scope!s and \Verb!pic anchor={coordinate}! for \Verb!pic!s, where \Verb!coordinate! is evaluated internally to the \Verb!scope! or \Verb!pic!, so can use node names. 1378 | % \begin{macrocode} 1379 | scope anchor location/.initial={(0,0)}, 1380 | scope anchor location/.default=@auto, 1381 | pic anchor/.style={ 1382 | scope anchor location={#1}, 1383 | next pic/.append style={ 1384 | adjust scope position, 1385 | } 1386 | }, 1387 | scope anchor/.style={ 1388 | scope anchor location={#1}, 1389 | adjust scope position, 1390 | }, 1391 | % \end{macrocode} 1392 | % The code that does the adjustment is added to the \Verb!pic! on its enclosing scope using the \Verb!every pic! key. 1393 | % \begin{macrocode} 1394 | adjust scope position/.code={% 1395 | \pgfutil@ifundefined{tikz@fig@name}% 1396 | {\let\tikz@fig@name=\pgfutil@empty}{}% 1397 | \tikz@resetexpandcount% 1398 | \tikz@fig@mustbenamed 1399 | \pgfkeysgetvalue{/tikz/scope anchor location}\tkzmk@anchor 1400 | \ifx\tkzmk@anchor\tikz@auto@text 1401 | \tikzset{local bounding box/.expanded=\tikz@fig@name}% 1402 | \def\tkzmk@anchor{(\tikz@fig@name.\tikz@anchor)}% 1403 | \fi 1404 | \tikz@scan@one@point 1405 | \pgfutil@firstofone(pic cs:\tikz@fig@name-origin)\relax 1406 | \pgf@xa=\pgf@x 1407 | \pgf@ya=\pgf@y 1408 | \tikz@scan@one@point 1409 | \pgfutil@firstofone(pic cs:\tikz@fig@name-anchor)\relax 1410 | \advance\pgf@xa by -\pgf@x 1411 | \advance\pgf@ya by -\pgf@y 1412 | \tikzset{ 1413 | shift={(\the\pgf@xa,\the\pgf@ya)}, 1414 | execute at end scope={% 1415 | \tikzmark{\tikz@fig@name-origin}{(0,0)}% 1416 | \tikzmark{\tikz@fig@name-anchor}{\tkzmk@anchor}% 1417 | } 1418 | } 1419 | }, 1420 | % \end{macrocode} 1421 | % 1422 | % To install this code on a pic, we hook in to the pic's enclosing scope using the \Verb+every pic+ key. 1423 | % To avoid this bubbling down to pics within pics, we clear it once it has been executed. 1424 | % So any code that triggers this adjustment adds \Verb!adjust pic position! to the !next pic! style. 1425 | % \begin{macrocode} 1426 | every pic/.append style={ 1427 | next pic/.try, 1428 | next pic/.style={} 1429 | }, 1430 | % \end{macrocode} 1431 | % 1432 | % This code remembers the bounding box of a pic, saving it as if it were a node. 1433 | % The \Verb+local bounding box+ keeps track of the size of the local scope, which since we're in a pic effectively means the size of the pic, saving it to a node as it goes along (so the current size of that node is the current size of the scope). 1434 | % Since we're inside a pic, the name of the pic is automatically added as the prefix of node names so to make this externally have the same name as the pic then internally it has no name. 1435 | % We wrap this in the \Verb+next pic+ style so that it only applies to the pic that is actually being used and not to any subpics that might exist within that outermost pic. 1436 | % \begin{macrocode} 1437 | save pic bounding box/.code={% 1438 | \tikz@fig@mustbenamed% 1439 | \tikzset{local bounding box}% 1440 | }, 1441 | surround pic/.style={ 1442 | next pic/.append style={ 1443 | save pic bounding box 1444 | } 1445 | }, 1446 | } 1447 | % \end{macrocode} 1448 | % 1449 | % \begin{macro}{\tikzmark@pp@name} 1450 | % \begin{macrocode} 1451 | \def\tikzmark@pp@name#1{% 1452 | \csname pgfk@/tikz/tikzmark prefix\endcsname% 1453 | #1% 1454 | \csname pgfk@/tikz/tikzmark suffix\endcsname% 1455 | }% 1456 | % \end{macrocode} 1457 | % \end{macro} 1458 | % 1459 | % \begin{macro}{\savepointas} 1460 | % This is what gets written to the \Verb+aux+ file. 1461 | % \begin{macrocode} 1462 | \def\savepointas#1#2#3#4{% 1463 | \expandafter\gdef\csname save@pt@#1\endcsname{#2}% 1464 | \expandafter\gdef\csname save@pt@#1@offset\endcsname% 1465 | {\pgfqpoint{#3}{#4}}% 1466 | } 1467 | \def\savepicturepage#1#2{% 1468 | \expandafter\gdef\csname save@pg@#1\endcsname{#2}% 1469 | } 1470 | % \end{macrocode} 1471 | % \end{macro} 1472 | % 1473 | % \begin{macro}{\tikzmarkalias} 1474 | % Alias a tikzmark to another name (used in tikzmarknode). 1475 | % The alias is saved to the aux-file so that it is available prior to the definition. 1476 | % The private one doesn't use the prefix-suffix for greater internal flexibility. 1477 | % The public one does. 1478 | % \begin{macrocode} 1479 | \def\@tikzmarkalias#1#2{% 1480 | \@ifundefined{save@pt@#2}{}{% 1481 | \pgf@node@gnamelet{save@pt@#1}{save@pt@#2}% 1482 | \pgf@node@gnamelet{save@pt@#1@offset}{save@pt@#2@offset}% 1483 | \protected@write\pgfutil@auxout{}{% 1484 | \string\savepointas% 1485 | {#1}{\csname save@pt@#2\endcsname}% 1486 | \expandafter\expandafter\expandafter 1487 | \@gobble\csname save@pt@#2@offset\endcsname 1488 | }% 1489 | }% 1490 | } 1491 | \def\tikzmarkalias#1#2{% 1492 | \@tikzmarkalias{\tikzmark@pp@name{#1}}{\tikzmark@pp@name{#2}}% 1493 | } 1494 | % \end{macrocode} 1495 | % \end{macro} 1496 | % 1497 | % \begin{macro}{\tmk@labeldef} 1498 | % Auxiliary command for the coordinate system. 1499 | % \begin{macrocode} 1500 | \def\tmk@labeldef#1,#2\@nil{% 1501 | \edef\tmk@label{\tikzmark@pp@name{#1}}% 1502 | \def\tmk@def{#2}% 1503 | } 1504 | % \end{macrocode} 1505 | % \end{macro} 1506 | % 1507 | % \begin{macro}{pic} 1508 | % This defines the new coordinate system. 1509 | % \begin{macrocode} 1510 | \newif\iftkmk@round@ 1511 | \tkmk@round@false 1512 | \def\tkmk@none{none} 1513 | \def\tkmk@off{off} 1514 | \tikzdeclarecoordinatesystem{pic}{% 1515 | \pgfutil@in@,{#1}% 1516 | \ifpgfutil@in@% 1517 | \tmk@labeldef#1\@nil 1518 | \else 1519 | \tmk@labeldef#1,(0pt,0pt)\@nil 1520 | \fi 1521 | \@ifundefined{save@pt@\tmk@label}{% 1522 | \expandafter\tikz@scan@one@point 1523 | \expandafter\pgfutil@firstofone\tmk@def\relax 1524 | }{% 1525 | \pgfsys@getposition{\csname save@pt@\tmk@label\endcsname}% 1526 | \save@orig@pic% 1527 | \pgfsys@getposition{\pgfpictureid}\save@this@pic% 1528 | \pgf@process{\pgfpointorigin\save@this@pic}% 1529 | \pgf@xa=\pgf@x 1530 | \pgf@ya=\pgf@y 1531 | \pgf@process{\pgfpointorigin\save@orig@pic}% 1532 | \advance\pgf@x by -\pgf@xa 1533 | \advance\pgf@y by -\pgf@ya 1534 | \pgf@xa=\pgf@x 1535 | \pgf@ya=\pgf@y 1536 | \pgf@process% 1537 | {\pgfpointorigin\csname save@pt@\tmk@label @offset\endcsname}% 1538 | \advance\pgf@xa by \pgf@x 1539 | \advance\pgf@ya by \pgf@y 1540 | \iftkmk@round@ 1541 | \pgfmathsetlength\pgf@xa{round(\pgf@xa * 10^\tkmk@round)/(10^\tkmk@round)}% 1542 | \pgfmathsetlength\pgf@ya{round(\pgf@ya * 10^\tkmk@round)/(10^\tkmk@round)}% 1543 | \fi 1544 | \@ifundefined{save@pg@\csname save@pt@\tmk@label\endcsname}{}{% 1545 | \@ifundefined{save@pg@\pgfpictureid}{}{% 1546 | \pgfkeysvalueof{/tikz/next page vector}% 1547 | \edef\tmk@pg{% 1548 | \the\numexpr \csname save@pg@% 1549 | \csname save@pt@\tmk@label\endcsname\endcsname% 1550 | - 1551 | \csname save@pg@\pgfpictureid\endcsname\relax% 1552 | }% 1553 | \ifnum \tmk@pg > 0 \relax 1554 | \advance \pgf@xa by \pgf@x\relax 1555 | \advance \pgf@ya by \pgf@y\relax 1556 | \fi 1557 | \ifnum \tmk@pg < 0 \relax 1558 | \advance \pgf@xa by -\pgf@x\relax 1559 | \advance \pgf@ya by -\pgf@y\relax 1560 | \fi 1561 | }% 1562 | }% 1563 | \pgf@x=\pgf@xa 1564 | \pgf@y=\pgf@ya 1565 | \pgftransforminvert 1566 | \pgf@pos@transform{\pgf@x}{\pgf@y}% 1567 | }% 1568 | } 1569 | % \end{macrocode} 1570 | % \end{macro} 1571 | % 1572 | % \begin{macro}{\tikzmark} 1573 | % The active/non-active semi-colon is proving somewhat hazardous to \Verb+\tikzmark+ (see \href{http://tex.stackexchange.com/q/110014/86}{ Tikzmark and french seem to conflict} and \href{http://tex.stackexchange.com/q/335485/86}{Clash between tikzmark, babel package (french) and babel tikzlibrary}) so \Verb+\tikzmark+ now uses the brace-delimited version of the \Verb+\tikz+ command. 1574 | % 1575 | % This version is for when we're outside a tikzpicture environment 1576 | % \begin{macrocode} 1577 | \newcommand\tikzmark@outside[2][]{% 1578 | \tikzset{external/export next/.try=false}% 1579 | \tikz[remember picture with id=#2]{#1}% 1580 | } 1581 | % \end{macrocode} 1582 | % This is for when we're inside a tikzpicture environment 1583 | % \begin{macrocode} 1584 | \def\tikzmark@inside#1#2{% 1585 | \tikzset{remember picture}% 1586 | \tikz@resetexpandcount% 1587 | \tikz@scan@one@point\pgfutil@firstofone#2\relax 1588 | \pgf@pos@transform{\pgf@x}{\pgf@y}% 1589 | \protected@write\pgfutil@auxout{}{% 1590 | \string\savepointas% 1591 | {\tikzmark@pp@name{#1}}{\pgfpictureid}{\the\pgf@x}{\the\pgf@y}}% 1592 | } 1593 | % \end{macrocode} 1594 | % And finally, the ultimate invoker: 1595 | % \begin{macrocode} 1596 | \def\tikzmark{% 1597 | \ifx\pgfpictureid\@undefined 1598 | \let\tikzmark@next=\tikzmark@outside 1599 | \else 1600 | \relax 1601 | \ifx\scope\tikz@origscope\relax 1602 | \let\tikzmark@next=\tikzmark@outside 1603 | \else 1604 | \let\tikzmark@next=\tikzmark@inside 1605 | \fi 1606 | \fi 1607 | \tikzmark@next% 1608 | } 1609 | % \end{macrocode} 1610 | % \end{macro} 1611 | % 1612 | % \begin{macro}{\pgfmark} 1613 | % \begin{macrocode} 1614 | \newcommand\pgfmark[1]{% 1615 | \bgroup 1616 | \global\advance\pgf@picture@serial@count by1\relax% 1617 | \edef\pgfpictureid{pgfid\the\pgf@picture@serial@count}% 1618 | \pgfsys@markposition{\pgfpictureid}% 1619 | \edef\pgf@temp{% 1620 | \noexpand\write\noexpand\pgfutil@auxout{% 1621 | \string\savepicturepage 1622 | {\pgfpictureid}{\noexpand\arabic{page}}% 1623 | }% 1624 | }% 1625 | \pgf@temp 1626 | \protected@write\pgfutil@auxout{}{% 1627 | \string\savepointas 1628 | {\tikzmark@pp@name{#1}}{\pgfpictureid}{0pt}{0pt}}% 1629 | \egroup 1630 | } 1631 | % \end{macrocode} 1632 | % \end{macro} 1633 | % 1634 | % 1635 | % If the beamer class is used, make the commands overlay aware. 1636 | % \begin{macro}{\tikzmark<>} 1637 | % \begin{macrocode} 1638 | \@ifclassloaded{beamer}{ 1639 | \renewcommand<>{\tikzmark@outside}[2][]{% 1640 | \only#3{\beameroriginal{\tikzmark@outside}[{#1}]{#2}}% 1641 | } 1642 | \renewcommand<>{\tikzmark@inside}[2]{% 1643 | \only#3{\beameroriginal{\tikzmark@inside}{#1}{#2}}% 1644 | } 1645 | }{} 1646 | % \end{macrocode} 1647 | % \end{macro} 1648 | % 1649 | % \begin{macro}{\pgfmark<>} 1650 | % \begin{macrocode} 1651 | \@ifclassloaded{beamer}{ 1652 | \renewcommand<>{\pgfmark}[1]{\only#2{\beameroriginal{\pgfmark}{#1}}} 1653 | }{} 1654 | % \end{macrocode} 1655 | % \end{macro} 1656 | % 1657 | % If beamer is loaded, add a suffix based on the frame number 1658 | % \begin{macrocode} 1659 | \@ifclassloaded{beamer}{ 1660 | \tikzset{ 1661 | tikzmark suffix=-\the\beamer@slideinframe 1662 | } 1663 | }{} 1664 | % \end{macrocode} 1665 | % 1666 | % 1667 | % \begin{macro}{\iftikzmark} 1668 | % \begin{macrocode} 1669 | \newif\iftikzmark@ 1670 | \newcommand\iftikzmark[3]{% 1671 | \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{% 1672 | #3% 1673 | }{% 1674 | #2% 1675 | }% 1676 | }% 1677 | % \end{macrocode} 1678 | % 1679 | % A version suitable for \Verb+\if ... \else ... \fi+. 1680 | % \begin{macrocode} 1681 | \newcommand\iftikzmarkexists[1]{% 1682 | \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{% 1683 | \tikzmark@false% 1684 | }{% 1685 | \tikzmark@true% 1686 | }% 1687 | \iftikzmark@ 1688 | }% 1689 | % \end{macrocode} 1690 | % \end{macro} 1691 | % 1692 | % 1693 | % \begin{macro}{\iftikzmarkonpage} 1694 | % \begin{macrocode} 1695 | \newcommand\iftikzmarkonpage[2]{% 1696 | \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{% 1697 | \tikzmark@false 1698 | }{% 1699 | \@ifundefined{save@pg@% 1700 | \csname save@pt@\tikzmark@pp@name{#1}\endcsname% 1701 | }{% 1702 | \tikzmark@false 1703 | }{% 1704 | \ifnum\csname save@pg@% 1705 | \csname save@pt@\tikzmark@pp@name{#1}\endcsname% 1706 | \endcsname=#2\relax% 1707 | \tikzmark@true 1708 | \else 1709 | \tikzmark@false 1710 | \fi 1711 | }% 1712 | }% 1713 | \iftikzmark@ 1714 | } 1715 | % \end{macrocode} 1716 | % \end{macro} 1717 | % 1718 | % \begin{macro}{\iftikzmarkoncurrentpage} 1719 | % \begin{macrocode} 1720 | \newcommand\iftikzmarkoncurrentpage[1]{% 1721 | \@ifundefined{save@pt@\tikzmark@pp@name{#1}}{% 1722 | \tikzmark@false 1723 | }{% 1724 | \@ifundefined{save@pg@% 1725 | \csname save@pt@\tikzmark@pp@name{#1}\endcsname% 1726 | }{% 1727 | \tikzmark@false 1728 | }{% 1729 | \ifnum\csname save@pg@% 1730 | \csname save@pt@\tikzmark@pp@name{#1}\endcsname% 1731 | \endcsname=\the\value{page}\relax% 1732 | \tikzmark@true 1733 | \else 1734 | \tikzmark@false 1735 | \fi 1736 | }% 1737 | }% 1738 | \iftikzmark@ 1739 | } 1740 | % \end{macrocode} 1741 | % \end{macro} 1742 | % 1743 | % \begin{macro}{\subnode} 1744 | % Note: much of this code was inevitably adapted from the node defining code in the TikZ/PGF sources. 1745 | % 1746 | % The \Verb!\pgfmark! applies the current tikzmark prefix/suffix. 1747 | % The current node prefix/suffix is applied by using the \Verb!name=! key. 1748 | % \begin{macrocode} 1749 | \def\subnode@#1#2#3{% 1750 | \begingroup 1751 | \pgfmark{#2}% 1752 | \setbox\pgfnodeparttextbox=\hbox\bgroup #3\egroup 1753 | \tikzset{every subnode/.try,#1,name=#2}% 1754 | \pgfpointorigin 1755 | \tikz@scan@one@point\pgfutil@firstofone(pic cs:#2)\relax 1756 | \advance\pgf@x by .5\wd\pgfnodeparttextbox 1757 | \advance\pgf@y by .5\ht\pgfnodeparttextbox 1758 | \advance\pgf@y by -.5\dp\pgfnodeparttextbox 1759 | \pgftransformshift{}% 1760 | \setbox\@tempboxa=\hbox\bgroup 1761 | {% 1762 | \let\pgf@sh@savedmacros=\pgfutil@empty% MW 1763 | \let\pgf@sh@savedpoints=\pgfutil@empty% 1764 | \def\pgf@sm@shape@name{rectangle}% CJ % TT added prefix! 1765 | \pgf@sh@s@rectangle% 1766 | \pgf@sh@savedpoints% 1767 | \pgf@sh@savedmacros% MW 1768 | \pgftransformshift{% 1769 | \pgf@sh@reanchor{rectangle}{center}% 1770 | \pgf@x=-\pgf@x% 1771 | \pgf@y=-\pgf@y% 1772 | }% 1773 | \expandafter\pgfsavepgf@process 1774 | \csname pgf@sh@sa@\tikz@fig@name\endcsname{% 1775 | \pgf@sh@reanchor{rectangle}{center}% FIXME : this is double work! 1776 | }% 1777 | % Save the saved points and the transformation matrix 1778 | \edef\pgf@node@name{\tikz@fig@name}% 1779 | \ifx\pgf@node@name\pgfutil@empty% 1780 | \else% 1781 | \expandafter\xdef 1782 | \csname pgf@sh@ns@\pgf@node@name\endcsname{rectangle}% 1783 | \edef\pgf@sh@@temp{% 1784 | \noexpand\gdef\expandafter 1785 | \noexpand\csname pgf@sh@np@\pgf@node@name\endcsname}% 1786 | \expandafter\pgf@sh@@temp\expandafter{% 1787 | \pgf@sh@savedpoints}% 1788 | \edef\pgf@sh@@temp{% 1789 | \noexpand\gdef\expandafter 1790 | \noexpand\csname pgf@sh@ma@\pgf@node@name\endcsname}% MW 1791 | \expandafter\pgf@sh@@temp\expandafter{\pgf@sh@savedmacros}% MW 1792 | \pgfgettransform\pgf@temp 1793 | \expandafter\xdef 1794 | \csname pgf@sh@nt@\pgf@node@name\endcsname{\pgf@temp}% 1795 | \expandafter\xdef 1796 | \csname pgf@sh@pi@\pgf@node@name\endcsname{\pgfpictureid}% 1797 | \fi% 1798 | }% 1799 | \egroup 1800 | \box\pgfnodeparttextbox 1801 | \endgroup 1802 | } 1803 | 1804 | \newcommand\subnode[3][]{% 1805 | \ifmmode 1806 | \mathchoice{% 1807 | \subnode@{#1}{#2-d}{\(\displaystyle #3\)}% 1808 | }{% 1809 | \subnode@{#1}{#2-t}{\(\textstyle #3\)}% 1810 | }{% 1811 | \subnode@{#1}{#2-s}{\(\scriptstyle #3\)}% 1812 | }{% 1813 | \subnode@{#1}{#2-ss}{\(\scriptscriptstyle #3\)}% 1814 | }% 1815 | \let\pgf@nodecallback\pgfutil@gobble 1816 | \def\tzmk@prfx{pgf@sys@pdf@mark@pos@pgfid}% 1817 | \edef\tzmk@pic{\tzmk@prfx\the\pgf@picture@serial@count} 1818 | \expandafter\ifx\csname\tzmk@pic\endcsname\relax 1819 | \edef\tzmk@pic% 1820 | {\tzmk@prfx\the\numexpr\the\pgf@picture@serial@count-1\relax}% 1821 | \expandafter\ifx\csname\tzmk@pic\endcsname\relax 1822 | \edef\tzmk@pic% 1823 | {\tzmk@prfx\the\numexpr\the\pgf@picture@serial@count-2\relax}% 1824 | \expandafter\ifx\csname\tzmk@pic\endcsname\relax 1825 | \edef\tzmk@pic% 1826 | {\tzmk@prfx\the\numexpr\the\pgf@picture@serial@count-3\relax}% 1827 | \expandafter\ifx\csname\tzmk@pic\endcsname\relax 1828 | \pgfutil@ifundefined{pgf@sh@ns@\tikz@pp@name{#2}}{% 1829 | \pgfnodealias{\tikz@pp@name{#2}}{\tikz@pp@name{#2-t}}% 1830 | \@tikzmarkalias{\tikzmark@pp@name{#2}}{\tikzmark@pp@name{#2-t}}% 1831 | }{}% 1832 | \else 1833 | \pgfnodealias{\tikz@pp@name{#2}}{\tikz@pp@name{#2-d}}% 1834 | \@tikzmarkalias{\tikzmark@pp@name{#2}}{\tikzmark@pp@name{#2-d}}% 1835 | \fi 1836 | \else 1837 | \pgfnodealias{\tikz@pp@name{#2}}{\tikz@pp@name{#2-t}}% 1838 | \@tikzmarkalias{\tikzmark@pp@name{#2}}{\tikzmark@pp@name{#2-t}}% 1839 | \fi 1840 | \else 1841 | \pgfnodealias{\tikz@pp@name{#2}}{\tikz@pp@name{#2-s}}% 1842 | \@tikzmarkalias{\tikzmark@pp@name{#2}}{\tikzmark@pp@name{#2-s}}% 1843 | \fi 1844 | \else 1845 | \pgfnodealias{\tikz@pp@name{#2}}{\tikz@pp@name{#2-ss}}% 1846 | \@tikzmarkalias{\tikzmark@pp@name{#2}}{\tikzmark@pp@name{#2-ss}}% 1847 | \fi 1848 | \else 1849 | \subnode@{#1}{#2}{#3}% 1850 | \fi 1851 | } 1852 | 1853 | % \end{macrocode} 1854 | % \end{macro} 1855 | % 1856 | % \begin{macro}{\tikzmarknode} 1857 | % The \Verb+\tikzmark+ macro has changed considerably since its first inception, but there does still seem to be a use for the original version which put stuff inside a node. This command reintroduces that command. 1858 | % 1859 | % 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. 1860 | % \begin{macrocode} 1861 | \def\tikzmarknode@#1#2#3{% 1862 | \tikzset{external/export next/.try=false}% 1863 | \tikz[% 1864 | remember picture, 1865 | save picture id={#2}, 1866 | check picture id, 1867 | maybe define node={#2}, 1868 | baseline=(#2.base), 1869 | every tikzmarknode picture/.try 1870 | ] { 1871 | \node[ 1872 | anchor=base, 1873 | inner sep=0pt, 1874 | minimum width=0pt, 1875 | name={#2}, 1876 | node contents={#3}, 1877 | every tikzmarknode/.try, 1878 | #1 1879 | ];}% 1880 | } 1881 | 1882 | \newcommand\tikzmarknode[3][]{% 1883 | \ifmmode 1884 | \mathchoice{% 1885 | \tikzmarknode@{#1}{#2-d}{\(\displaystyle #3\)}% 1886 | }{% 1887 | \tikzmarknode@{#1}{#2-t}{\(\textstyle #3\)}% 1888 | }{% 1889 | \tikzmarknode@{#1}{#2-s}{\(\scriptstyle #3\)}% 1890 | }{% 1891 | \tikzmarknode@{#1}{#2-ss}{\(\scriptscriptstyle #3\)}% 1892 | }% 1893 | \let\pgf@nodecallback\pgfutil@gobble 1894 | \def\tzmk@prfx{pgf@sys@pdf@mark@pos@pgfid}% 1895 | \edef\tzmk@pic{\tzmk@prfx\the\pgf@picture@serial@count}% 1896 | \expandafter\ifx\csname\tzmk@pic\endcsname\relax 1897 | \edef\tzmk@pic% 1898 | {\tzmk@prfx\the\numexpr\the\pgf@picture@serial@count-1\relax}% 1899 | \expandafter\ifx\csname\tzmk@pic\endcsname\relax 1900 | \edef\tzmk@pic% 1901 | {\tzmk@prfx\the\numexpr\the\pgf@picture@serial@count-2\relax}% 1902 | \expandafter\ifx\csname\tzmk@pic\endcsname\relax 1903 | \edef\tzmk@pic% 1904 | {\tzmk@prfx\the\numexpr\the\pgf@picture@serial@count-3\relax}% 1905 | \expandafter\ifx\csname\tzmk@pic\endcsname\relax 1906 | \pgfutil@ifundefined{pgf@sh@ns@\tikz@pp@name{#2}}{% 1907 | \pgfnodealias{\tikz@pp@name{#2}}{\tikz@pp@name{#2-t}}% 1908 | \@tikzmarkalias{\tikzmark@pp@name{#2}}{\tikzmark@pp@name{#2-t}}% 1909 | }{}% 1910 | \else 1911 | \pgfnodealias{\tikz@pp@name{#2}}{\tikz@pp@name{#2-d}}% 1912 | \@tikzmarkalias{\tikzmark@pp@name{#2}}{\tikzmark@pp@name{#2-d}}% 1913 | \fi 1914 | \else 1915 | \pgfnodealias{\tikz@pp@name{#2}}{\tikz@pp@name{#2-t}}% 1916 | \@tikzmarkalias{\tikzmark@pp@name{#2}}{\tikzmark@pp@name{#2-t}}% 1917 | \fi 1918 | \else 1919 | \pgfnodealias{\tikz@pp@name{#2}}{\tikz@pp@name{#2-s}}% 1920 | \@tikzmarkalias{\tikzmark@pp@name{#2}}{\tikzmark@pp@name{#2-s}}% 1921 | \fi 1922 | \else 1923 | \pgfnodealias{\tikz@pp@name{#2}}{\tikz@pp@name{#2-ss}}% 1924 | \@tikzmarkalias{\tikzmark@pp@name{#2}}{\tikzmark@pp@name{#2-ss}}% 1925 | \fi 1926 | \else 1927 | \tikzmarknode@{#1}{#2}{#3}% 1928 | \fi 1929 | } 1930 | % \end{macrocode} 1931 | % \end{macro} 1932 | % 1933 | % \begin{macro}{\tikzmark@box} 1934 | % This macro takes a name and a box. 1935 | % It pretends that there is a tight-fitting rectangular PGF node around that box with the given name, and saves the required information so that that node can be used later on in a tikzpicture drawing. 1936 | % 1937 | % It does not actually build a node, and it doesn't create a TikZ drawing. 1938 | % Rather, it measures the box and uses that information to define the various macros that store the information about the node. 1939 | % 1940 | % Apart from assigning a load of macros, it does also place a \Verb+\pgfmark+ just before the box. 1941 | % This is needed to be able to locate the node on the page. 1942 | % 1943 | % The command is defined with an \Verb!@! because it is more likely to be used in other packages than by a user. 1944 | % \begin{macrocode} 1945 | \def\tikzmark@box#1#2{% 1946 | \begingroup 1947 | \pgfmark{#1}% 1948 | \let\pgfnodeparttextbox=#2% 1949 | \edef\pgfpictureid{pgfid\the\pgf@picture@serial@count}% 1950 | \def\tikz@fig@name{#1}% 1951 | \pgfpointorigin 1952 | \advance\pgf@x by .5\wd\pgfnodeparttextbox 1953 | \advance\pgf@y by .5\ht\pgfnodeparttextbox 1954 | \advance\pgf@y by -.5\dp\pgfnodeparttextbox 1955 | \pgftransformshift{}% 1956 | \setbox\@tempboxa=\hbox\bgroup 1957 | {% 1958 | \tikzset{ 1959 | inner sep=0pt, 1960 | minimum size=0pt, 1961 | outer sep=0pt, 1962 | anchor=base 1963 | }% 1964 | \let\pgf@sh@savedmacros=\pgfutil@empty% MW 1965 | \let\pgf@sh@savedpoints=\pgfutil@empty 1966 | \def\pgf@sm@shape@name{rectangle}% CJ % TT added prefix! 1967 | \pgf@sh@s@rectangle 1968 | \pgf@sh@savedpoints 1969 | \pgf@sh@savedmacros% MW 1970 | \pgftransformshift{% 1971 | \pgf@sh@reanchor{rectangle}{center}% 1972 | \pgf@x=-\pgf@x 1973 | \pgf@y=-\pgf@y 1974 | }% 1975 | \expandafter\pgfsavepgf@process 1976 | \csname pgf@sh@sa@\tikz@fig@name\endcsname{% 1977 | \pgf@sh@reanchor{rectangle}{center}% FIXME : this is double work! 1978 | }% 1979 | % Save the saved points and the transformation matrix 1980 | \edef\pgf@node@name{\tikz@fig@name}% 1981 | \ifx\pgf@node@name\pgfutil@empty 1982 | \else 1983 | \expandafter\xdef 1984 | \csname pgf@sh@ns@\pgf@node@name\endcsname{rectangle}% 1985 | \edef\pgf@sh@@temp{% 1986 | \noexpand\gdef\expandafter 1987 | \noexpand\csname pgf@sh@np@\pgf@node@name\endcsname}% 1988 | \expandafter\pgf@sh@@temp\expandafter{% 1989 | \pgf@sh@savedpoints}% 1990 | \edef\pgf@sh@@temp{% 1991 | \noexpand\gdef\expandafter 1992 | \noexpand\csname pgf@sh@ma@\pgf@node@name\endcsname}% MW 1993 | \expandafter\pgf@sh@@temp\expandafter{\pgf@sh@savedmacros}% MW 1994 | \pgfgettransform\pgf@temp 1995 | \expandafter\xdef 1996 | \csname pgf@sh@nt@\pgf@node@name\endcsname{\pgf@temp}% 1997 | \expandafter\xdef 1998 | \csname pgf@sh@pi@\pgf@node@name\endcsname{\pgfpictureid}% 1999 | \fi 2000 | }% 2001 | \egroup 2002 | \endgroup 2003 | \box#2% 2004 | } 2005 | % \end{macrocode} 2006 | % \end{macro} 2007 | % 2008 | % \begin{macro}{\usetikzmarklibrary} 2009 | % \begin{macrocode} 2010 | \def\usetikzmarklibrary{% 2011 | \pgfutil@ifnextchar[{\use@tikzmarklibrary}{\use@@tikzmarklibrary}% 2012 | }%} 2013 | \def\use@tikzmarklibrary[#1]{\use@@tikzmarklibrary{#1}} 2014 | \def\use@@tikzmarklibrary#1{% 2015 | \edef\pgf@list{#1}% 2016 | \pgfutil@for\pgf@temp:=\pgf@list\do{% 2017 | \expandafter\pgfkeys@spdef 2018 | \expandafter\pgf@temp\expandafter{\pgf@temp}% 2019 | \ifx\pgf@temp\pgfutil@empty 2020 | \else 2021 | \expandafter\ifx 2022 | \csname tikzmark@library@\pgf@temp @loaded\endcsname\relax% 2023 | \expandafter\global\expandafter\let% 2024 | \csname tikzmark@library@\pgf@temp @loaded\endcsname 2025 | =\pgfutil@empty% 2026 | \expandafter\edef 2027 | \csname tikzmark@library@#1@atcode\endcsname{\the\catcode`\@} 2028 | \expandafter\edef 2029 | \csname tikzmark@library@#1@barcode\endcsname{\the\catcode`\|} 2030 | \catcode`\@=11 2031 | \catcode`\|=12 2032 | \pgfutil@InputIfFileExists{tikzmarklibrary\pgf@temp.code.tex}{}{ 2033 | \PackageError{tikzmark}{ 2034 | I did not find the tikzmark extras library '\pgf@temp'.}{} 2035 | }% 2036 | \catcode`\@=\csname tikzmark@library@#1@atcode\endcsname 2037 | \catcode`\|=\csname tikzmark@library@#1@barcode\endcsname 2038 | \fi% 2039 | \fi 2040 | }% 2041 | } 2042 | % \end{macrocode} 2043 | % \end{macro} 2044 | % 2045 | % The \Verb+save node+ code is written in \LaTeX3. 2046 | % 2047 | % \begin{macrocode} 2048 | \ExplSyntaxOn 2049 | \cs_new_protected:Nn \tikzmark_tl_put_right_braced:Nn 2050 | { 2051 | \tl_put_right:Nn #1 { { #2 } } 2052 | } 2053 | \cs_generate_variant:Nn \tikzmark_tl_put_right_braced:Nn { NV, cV, cv, Nx, cx } 2054 | % \end{macrocode} 2055 | % 2056 | % This is how we handle return values from functions 2057 | % \begin{macrocode} 2058 | \tl_new:N \g__sn_output_tl 2059 | % \end{macrocode} 2060 | % We save our information in a ``property list'', which is L3's 2061 | % version of an associative array or dictionary. They keys will give 2062 | % the ability to store several groups of nodes and restore them at 2063 | % will. 2064 | % \begin{macrocode} 2065 | \prop_new:N \g__sn_prop 2066 | % \end{macrocode} 2067 | % We'll need a couple of spare token lists 2068 | % \begin{macrocode} 2069 | \tl_new:N \l__sn_tmpa_tl 2070 | \tl_new:N \l__sn_tmpb_tl 2071 | % \end{macrocode} 2072 | % 2073 | % Another useful token list 2074 | % \begin{macrocode} 2075 | \tl_new:N \l__open_bracket_tl 2076 | \tl_set:Nn \l__open_bracket_tl {[} %] 2077 | % \end{macrocode} 2078 | % 2079 | % This token list is used for our current node group name 2080 | % \begin{macrocode} 2081 | \tl_new:N \l__sn_group_tl 2082 | % \end{macrocode} 2083 | % 2084 | % We store up the nodes in a list and save them at the end of a given tikzpicture. 2085 | % Has to be global as we're often in a group. 2086 | % \begin{macrocode} 2087 | \clist_new:N \g__sn_nodes_clist 2088 | % \end{macrocode} 2089 | % 2090 | % This boolean is for whether we save to a file or not. 2091 | % \begin{macrocode} 2092 | \bool_new:N \l__sn_file_bool 2093 | % \end{macrocode} 2094 | % 2095 | % This boolean is for whether we are in the preamble or not. 2096 | % \begin{macrocode} 2097 | \bool_new:N \g__sn_preamble_bool 2098 | \bool_gset_true:N \g__sn_preamble_bool 2099 | % \end{macrocode} 2100 | % 2101 | % Key interface for setting some of the options 2102 | % \begin{macrocode} 2103 | \keys_define:nn {tikzmark / save nodes} 2104 | { 2105 | file .bool_set:N = \l__sn_file_bool, 2106 | group .tl_set:N = \l__sn_group_tl, 2107 | } 2108 | % \end{macrocode} 2109 | % 2110 | % 2111 | % \begin{macrocode} 2112 | \msg_new:nnn {tikzmark} {no file} {File~ "#1"~ doesn't~ exist.} 2113 | \msg_new:nnn {tikzmark} {loading nodes} {Loading~ nodes~ from~ "#1".} 2114 | % \end{macrocode} 2115 | % 2116 | % Dimensions and token lists for shifting 2117 | % \begin{macrocode} 2118 | \dim_new:N \l__sn_x_dim 2119 | \dim_new:N \l__sn_y_dim 2120 | \dim_new:N \l__sn_xa_dim 2121 | \dim_new:N \l__sn_ya_dim 2122 | \tl_new:N \l__sn_centre_tl 2123 | 2124 | \tl_new:N \l__sn_transformation_tl 2125 | \tl_set:Nn \l__sn_transformation_tl {{1}{0}{0}{1}{0pt}{0pt}} 2126 | % \end{macrocode} 2127 | % 2128 | % Set up a stream for saving the nodes data to a file 2129 | % \begin{macrocode} 2130 | \iow_new:N \g__sn_stream 2131 | \bool_new:N \g__sn_stream_bool 2132 | \tl_new:N \g__sn_filename_tl 2133 | \tl_gset:Nx \g__sn_filename_tl {\c_sys_jobname_str} 2134 | 2135 | \cs_new_nopar:Npn \sn_open_stream: 2136 | { 2137 | \bool_if:NF \g__sn_stream_bool 2138 | { 2139 | \iow_open:Nn \g__sn_stream {\tl_use:N \g__sn_filename_tl .nodes} 2140 | \bool_gset_true:N \g__sn_stream_bool 2141 | } 2142 | } 2143 | 2144 | \AtEndDocument 2145 | { 2146 | \ExplSyntaxOn 2147 | \bool_if:NT \g__sn_stream_bool 2148 | { 2149 | \iow_close:N \g__sn_stream 2150 | } 2151 | \ExplSyntaxOff 2152 | } 2153 | % \end{macrocode} 2154 | % 2155 | % LaTeX3 wrappers around some PGF functions (to avoid @-catcode issues) 2156 | % \begin{macrocode} 2157 | \makeatletter 2158 | \cs_set_eq:NN \tikz_set_node_name:n \tikz@pp@name 2159 | \cs_set_eq:NN \tikz_fig_must_be_named: \tikz@fig@mustbenamed 2160 | 2161 | \cs_if_exist:NF \tikz_scan_point:n 2162 | { 2163 | \cs_new_nopar:Npn \tikz_scan_point:n #1 2164 | { 2165 | \tikz@scan@one@point\pgfutil@firstofone#1\relax 2166 | } 2167 | } 2168 | 2169 | \cs_if_exist:NF \tikz_scan_point:NNn 2170 | { 2171 | \cs_new_nopar:Npn \tikz_scan_point:NNn #1#2#3 2172 | { 2173 | \tikz@scan@one@point\pgfutil@firstofone#3\relax 2174 | \dim_set_eq:NN #1 \pgf@x 2175 | \dim_set_eq:NN #2 \pgf@y 2176 | } 2177 | } 2178 | 2179 | \makeatother 2180 | \cs_generate_variant:Nn \tikz_scan_point:n {V} 2181 | \cs_generate_variant:Nn \tikz_scan_point:NNn {NNV} 2182 | % \end{macrocode} 2183 | % 2184 | % \begingroup 2185 | % \catcode`_=12 2186 | % \begin{macro}{\process_node:Nn} 2187 | % This is the command that actually does the work. It constructs a 2188 | % token list which contains the code that will restore the node data 2189 | % when invoked. The two arguments are the token list to store this in 2190 | % and the node name to be saved. 2191 | % \begin{macrocode} 2192 | \cs_new_nopar:Npn \__sn_process_node:n #1 2193 | { 2194 | \group_begin: 2195 | % \end{macrocode} 2196 | % Clear our token list 2197 | % \begin{macrocode} 2198 | \tl_clear:N \l__sn_tmpa_tl 2199 | % \end{macrocode} 2200 | % Set the centre of the picture 2201 | % \begin{macrocode} 2202 | \tl_if_exist:NTF \pgfpictureid 2203 | { 2204 | \tikz_scan_point:NNn \l__sn_x_dim \l__sn_y_dim 2205 | {(current~ bounding~ box.center)} 2206 | \dim_set:Nn \l__sn_x_dim {-\l__sn_x_dim} 2207 | \dim_set:Nn \l__sn_y_dim {-\l__sn_y_dim} 2208 | } 2209 | { 2210 | \dim_zero:N \l__sn_x_dim 2211 | \dim_zero:N \l__sn_y_dim 2212 | } 2213 | \tl_set:Nx \l__sn_centre_tl { 2214 | {1}{0}{0}{1}{\dim_use:N \l__sn_x_dim}{\dim_use:N \l__sn_y_dim} 2215 | } 2216 | % \end{macrocode} 2217 | % Test to see if the node has been defined 2218 | % \begin{macrocode} 2219 | \tl_if_exist:cT {pgf@sh@ns@#1} 2220 | { 2221 | % \end{macrocode} 2222 | % The node information is stored in a series of macros of the form 2223 | % \Verb+\pgf@sh@XX@nodename+ where XX is one of the following. 2224 | % \begin{macrocode} 2225 | \clist_map_inline:nn {ns,np,ma,pi} 2226 | { 2227 | % \end{macrocode} 2228 | % Our token list will look like: 2229 | % 2230 | % \Verb+\tl_set:cn {pgf@sh@XX@nodename}+ {} 2231 | % 2232 | % This will restore \Verb+\pgf@sh@XX@nodename+ to its current value 2233 | % when this list is invoked. 2234 | % 2235 | % This part puts the \Verb+\tl_set:cn {pgf@sh@XX@nodename}+ in place 2236 | % \begin{macrocode} 2237 | \tl_put_right:Nn \l__sn_tmpa_tl 2238 | { 2239 | \tl_gset:cn {pgf@sh@##1@ \tikz_set_node_name:n{#1} } 2240 | } 2241 | % \end{macrocode} 2242 | % Now we put the current contents in place. We're doing this in 2243 | % an expansive context to get at the contents. The \Verb+\exp_not:v+ 2244 | % part takes the current value of \Verb+\pgf@sh@XX@nodename+ and puts 2245 | % it in place, preventing further expansion. 2246 | % \begin{macrocode} 2247 | \tl_if_exist:cTF {pgf@sh@##1@#1} 2248 | { 2249 | \tl_put_right:Nx \l__sn_tmpa_tl { 2250 | {\exp_not:v {pgf@sh@##1@ \tikz_set_node_name:n {#1}}} 2251 | } 2252 | } 2253 | { 2254 | \tl_put_right:Nx \l__sn_tmpa_tl {{}} 2255 | } 2256 | } 2257 | \tl_put_right:Nn \l__sn_tmpa_tl 2258 | { 2259 | \tl_gset:cn {pgf@sh@nt@ \tikz_set_node_name:n{#1} } 2260 | } 2261 | \compose_transformations:NVv 2262 | \l__sn_tmpb_tl \l__sn_centre_tl {pgf@sh@nt@#1} 2263 | \tl_put_right:Nx \l__sn_tmpa_tl {{\exp_not:V \l__sn_tmpb_tl}} 2264 | \tl_put_right:Nn \l__sn_tmpa_tl { 2265 | \transform_node:Nn \l__sn_transformation_tl { 2266 | \tikz_set_node_name:n{#1} 2267 | } 2268 | } 2269 | } 2270 | % \end{macrocode} 2271 | % Once we've assembled our token list, we store it in the given 2272 | % token list 2273 | % \begin{macrocode} 2274 | \tl_gset_eq:NN \g__sn_output_tl \l__sn_tmpa_tl 2275 | \group_end: 2276 | } 2277 | \cs_new_protected_nopar:Npn \process_node:Nn #1#2 2278 | { 2279 | \__sn_process_node:n {#2} 2280 | \tl_set_eq:NN #1 \g__sn_output_tl 2281 | \tl_gclear:N \g__sn_output_tl 2282 | } 2283 | \cs_new_protected_nopar:Npn \process_gnode:Nn #1#2 2284 | { 2285 | \__sn_process_node:n {#2} 2286 | \tl_gset_eq:NN #1 \g__sn_output_tl 2287 | \tl_gclear:N \g__sn_output_tl 2288 | } 2289 | % \end{macrocode} 2290 | % \end{macro} 2291 | % 2292 | % \begin{macro}{\save_nodes_to_list:nn} 2293 | % Save the nodes to a list, given a key 2294 | % \begin{macrocode} 2295 | \cs_new_nopar:Npn \save_nodes_to_list:nn #1#2 2296 | { 2297 | \tl_clear:N \l__sn_tmpa_tl 2298 | \clist_map_inline:nn {#2} 2299 | { 2300 | \process_node:Nn \l__sn_tmpb_tl {##1} 2301 | \tl_put_right:NV \l__sn_tmpa_tl \l__sn_tmpb_tl 2302 | } 2303 | \prop_gput:NnV \g__sn_prop {#1} \l__sn_tmpa_tl 2304 | } 2305 | % \end{macrocode} 2306 | % \end{macro} 2307 | % 2308 | % \begin{macro}{\save_nodes_to_file:n} 2309 | % Save the nodes to a file 2310 | % \begin{macrocode} 2311 | \cs_generate_variant:Nn \iow_now:Nn {NV} 2312 | \cs_new_nopar:Npn \save_nodes_to_file:n #1 2313 | { 2314 | \sn_open_stream: 2315 | \clist_map_inline:nn {#1} 2316 | { 2317 | \process_node:Nn \l__sn_tmpa_tl {##1} 2318 | % \end{macrocode} 2319 | % Save the token list to the nodes file so that on reading it back in, we restore the node definitions 2320 | % \begin{macrocode} 2321 | \iow_now:Nx \g__sn_stream 2322 | { 2323 | \iow_newline: 2324 | \exp_not:V \l__sn_tmpa_tl 2325 | } 2326 | } 2327 | } 2328 | % \end{macrocode} 2329 | % \end{macro} 2330 | % \begin{macrocode} 2331 | \cs_generate_variant:Nn \save_nodes_to_list:nn {VV, Vn} 2332 | \cs_generate_variant:Nn \save_nodes_to_file:n {V} 2333 | % \end{macrocode} 2334 | % 2335 | % \begin{macro}{\restore_nodes_from_list:n} 2336 | % \begin{macrocode} 2337 | \cs_new_nopar:Npn \restore_nodes_from_list:n #1 2338 | { 2339 | % \end{macrocode} 2340 | % Restoring nodes is simple: look in the property list for the key 2341 | % and if it exists, invoke the macro stored there. 2342 | % \begin{macrocode} 2343 | \prop_get:NnNT \g__sn_prop {#1} \l__sn_tmpa_tl 2344 | { 2345 | \tl_use:N \l__sn_tmpa_tl 2346 | } 2347 | } 2348 | % \end{macrocode} 2349 | % \end{macro} 2350 | % 2351 | % \begin{macro}{\restore_nodes_from_file:n} 2352 | % \begin{macrocode} 2353 | \cs_new_nopar:Npn \restore_nodes_from_file:n #1 2354 | { 2355 | \file_if_exist:nTF {#1.nodes} 2356 | { 2357 | \msg_log:nnn {tikzmark} {loading nodes} {#1} 2358 | \ExplSyntaxOn 2359 | \file_input:n {#1.nodes} 2360 | \ExplSyntaxOff 2361 | } 2362 | { 2363 | \msg_warning:nnn {tikzmark} {no file} {#1} 2364 | } 2365 | } 2366 | \cs_generate_variant:Nn \restore_nodes_from_file:n {x} 2367 | \AtBeginDocument{\bool_gset_false:N \g__sn_preamble_bool} 2368 | % \end{macrocode} 2369 | % \end{macro} 2370 | % 2371 | % \begin{macro}{\compose_transformations:Nnn} 2372 | % Compose PGF transformations \Verb+#2 * #3+, storing the result in \Verb+#1+ 2373 | 2374 | % I think the PGF Manual might be incorrect. It implies that the 2375 | % matrix is stored row-major, but experimentation implies column-major. 2376 | % 2377 | % That is, \Verb+{a}{b}{c}{d}{s}{t}+ is: 2378 | % 2379 | % \[ 2380 | % \begin{bmatrix} a & c \\ b & d \end{bmatrix} 2381 | % \] 2382 | % 2383 | % \begin{macrocode} 2384 | \cs_new_nopar:Npn \compose_transformations:Nnn #1#2#3 2385 | { 2386 | \tl_gset:Nx #1 2387 | { 2388 | {\fp_eval:n { 2389 | \tl_item:nn {#2} {1} 2390 | * \tl_item:nn {#3} {1} 2391 | + 2392 | \tl_item:nn {#2} {3} 2393 | * \tl_item:nn {#3} {2} 2394 | } 2395 | } 2396 | {\fp_eval:n { 2397 | \tl_item:nn {#2} {2} 2398 | * \tl_item:nn {#3} {1} 2399 | + 2400 | \tl_item:nn {#2} {4} 2401 | * \tl_item:nn {#3} {2} 2402 | } 2403 | } 2404 | {\fp_eval:n { 2405 | \tl_item:nn {#2} {1} 2406 | * \tl_item:nn {#3} {3} 2407 | + 2408 | \tl_item:nn {#2} {3} 2409 | * \tl_item:nn {#3} {4} 2410 | } 2411 | } 2412 | {\fp_eval:n { 2413 | \tl_item:nn {#2} {2} 2414 | * \tl_item:nn {#3} {3} 2415 | + 2416 | \tl_item:nn {#2} {4} 2417 | * \tl_item:nn {#3} {4} 2418 | } 2419 | } 2420 | {\fp_to_dim:n { 2421 | \tl_item:nn {#2} {1} 2422 | * \tl_item:nn {#3} {5} 2423 | + 2424 | \tl_item:nn {#2} {3} 2425 | * \tl_item:nn {#3} {6} 2426 | + 2427 | \tl_item:nn {#2} {5} 2428 | } 2429 | } 2430 | {\fp_to_dim:n { 2431 | \tl_item:nn {#2} {2} 2432 | * \tl_item:nn {#3} {5} 2433 | + 2434 | \tl_item:nn {#2} {4} 2435 | * \tl_item:nn {#3} {6} 2436 | + 2437 | \tl_item:nn {#2} {6} 2438 | } 2439 | } 2440 | } 2441 | } 2442 | % \end{macrocode} 2443 | % \end{macro} 2444 | % 2445 | % \begin{macrocode} 2446 | \cs_generate_variant:Nn \compose_transformations:Nnn 2447 | {cVv,NVv,NVn,NvV,NnV} 2448 | % \end{macrocode} 2449 | % 2450 | % \begin{macro}{\transform_node:Nn} 2451 | % \begin{macrocode} 2452 | \cs_new_nopar:Npn \transform_node:Nn #1#2 2453 | { 2454 | \compose_transformations:cVv {pgf@sh@nt@#2} #1 {pgf@sh@nt@#2} 2455 | } 2456 | % \end{macrocode} 2457 | % \end{macro} 2458 | % 2459 | % \begin{macro}{\set_transform_from_node:n} 2460 | % \begin{macrocode} 2461 | \cs_new_nopar:Npn \set_transform_from_node:n #1 2462 | { 2463 | \tl_set_eq:Nc \l__sn_transformation_tl {pgf@sh@nt@#1} 2464 | \tikz_scan_point:NNn \l__sn_x_dim \l__sn_y_dim {(#1.center)} 2465 | 2466 | \dim_set:Nn \l__sn_x_dim { 2467 | \l__sn_x_dim - \tl_item:cn {pgf@sh@nt@#1}{5} 2468 | } 2469 | \dim_set:Nn \l__sn_y_dim { 2470 | \l__sn_y_dim - \tl_item:cn {pgf@sh@nt@#1}{6} 2471 | } 2472 | 2473 | \compose_transformations:NnV \l__sn_transformation_tl { 2474 | {1}{0}{0}{1}{\dim_use:N \l__sn_x_dim}{\dim_use:N \l__sn_y_dim} 2475 | } \l__sn_transformation_tl 2476 | } 2477 | % \end{macrocode} 2478 | % \end{macro} 2479 | % 2480 | % \begin{macrocode} 2481 | \cs_generate_variant:Nn \set_transform_from_node:n {v} 2482 | % \end{macrocode} 2483 | % 2484 | % Set the TikZ keys for access to the above commands. 2485 | % \begin{macrocode} 2486 | \tikzset{ 2487 | set~ saved~ nodes~ file~ name/.code={ 2488 | \tl_gset:Nx \g__sn_filename_tl {#1} 2489 | }, 2490 | transform~ saved~ nodes/.code={ 2491 | \set_transform_from_node:v {tikz@last@fig@name} 2492 | }, 2493 | set~ node~ group/.code={ 2494 | \tl_set:Nn \l__sn_group_tl {#1} 2495 | \pgfkeysalso{ 2496 | execute~ at~ end~ scope={ 2497 | \maybe_save_nodes: 2498 | } 2499 | } 2500 | }, 2501 | % \end{macrocode} 2502 | % Are we saving to a file? 2503 | % \begin{macrocode} 2504 | save~ nodes~ to~ file/.code={ 2505 | \tl_if_eq:nnTF {#1}{false} 2506 | { 2507 | \bool_set_false:N \l__sn_file_bool 2508 | } 2509 | { 2510 | \bool_set_true:N \l__sn_file_bool 2511 | } 2512 | \pgfkeysalso{ 2513 | execute~ at~ end~ scope={ 2514 | \maybe_save_nodes: 2515 | } 2516 | } 2517 | }, 2518 | % \end{macrocode} 2519 | % Append current node or named node to the list of nodes to be saved 2520 | % \begin{macrocode} 2521 | save~ node/.code={ 2522 | \tl_if_eq:nnTF {#1} {\pgfkeysnovalue} 2523 | { 2524 | \tikz_fig_must_be_named: 2525 | \pgfkeysalso{ 2526 | append~ after~ command={ 2527 | \pgfextra{ 2528 | \clist_gput_right:Nv \g__sn_nodes_clist {tikz@last@fig@name} 2529 | } 2530 | } 2531 | } 2532 | } 2533 | { 2534 | \clist_gput_right:Nn \g__sn_nodes_clist {#1} 2535 | } 2536 | }, 2537 | % \end{macrocode} 2538 | % If wanting to save a tikzmarknode then one needs a single key that does both parts (adding the node name to the list and installs the saving code). 2539 | % \begin{macrocode} 2540 | save~ tikzmarknode/.code={ 2541 | \tikz_fig_must_be_named: 2542 | \pgfkeysalso{ 2543 | append~ after~ command={ 2544 | \pgfextra{ 2545 | \clist_gput_right:Nv \g__sn_nodes_clist {tikz@last@fig@name} 2546 | \maybe_save_nodes: 2547 | } 2548 | } 2549 | } 2550 | }, 2551 | % \end{macrocode} 2552 | % Restore nodes from file 2553 | % \begin{macrocode} 2554 | restore~ nodes~ from~ file/.code={ 2555 | \bool_if:NTF \g__sn_preamble_bool 2556 | { 2557 | \restore_nodes_from_file:x {#1} 2558 | } 2559 | { 2560 | \tikz_fig_must_be_named: 2561 | \pgfkeysalso{append~ after~ command={ 2562 | \pgfextra{ 2563 | \scope 2564 | \split_argument:NNn \tikzset \restore_nodes_from_file:x {#1} 2565 | \endscope 2566 | } 2567 | } 2568 | } 2569 | } 2570 | }, 2571 | restore~ nodes~ from~ file/.default = \g__sn_filename_tl, 2572 | % \end{macrocode} 2573 | % Restore nodes from list 2574 | % \begin{macrocode} 2575 | restore~ nodes~ from~ list/.code={ 2576 | \tikz_fig_must_be_named: 2577 | \pgfkeysalso{append~ after~ command={ 2578 | \pgfextra{ 2579 | \scope 2580 | \split_argument:NNn \tikzset \restore_nodes_from_list:n {#1} 2581 | \endscope 2582 | } 2583 | } 2584 | } 2585 | } 2586 | } 2587 | \cs_generate_variant:Nn \clist_gput_right:Nn {Nv} 2588 | % \end{macrocode} 2589 | % 2590 | % \begin{macro}{\split_argument:NNn} 2591 | % \begin{macrocode} 2592 | \cs_new_nopar:Npn \split_argument:NNn #1#2#3 2593 | { 2594 | \tl_set:Nx \l__sn_tmpa_tl {\tl_head:n {#3}} 2595 | \tl_if_eq:NNTF \l__sn_tmpa_tl \l__open_bracket_tl 2596 | { 2597 | \split_argument_aux:NNp #1#2#3 2598 | } 2599 | { 2600 | #2 {#3} 2601 | } 2602 | } 2603 | % \end{macrocode} 2604 | % \end{macro} 2605 | % 2606 | % \begin{macro}{\split_argument_aux:NNp} 2607 | % \begin{macrocode} 2608 | \cs_new_nopar:Npn \split_argument_aux:NNp #1#2[#3]#4 2609 | { 2610 | #1 {#3} 2611 | #2 {#4} 2612 | } 2613 | % \end{macrocode} 2614 | % \end{macro} 2615 | % 2616 | % \begin{macro}{\maybe_save_nodes:} 2617 | % \begin{macrocode} 2618 | \cs_new_nopar:Npn \maybe_save_nodes: 2619 | { 2620 | \clist_if_empty:NF \g__sn_nodes_clist 2621 | { 2622 | \bool_if:NTF \l__sn_file_bool 2623 | { 2624 | \save_nodes_to_file:V \g__sn_nodes_clist 2625 | } 2626 | { 2627 | \tl_if_empty:NF \l__sn_group_tl 2628 | { 2629 | \save_nodes_to_list:VV \l__sn_group_tl \g__sn_nodes_clist 2630 | } 2631 | } 2632 | \clist_gclear:N \g__sn_nodes_clist 2633 | } 2634 | } 2635 | % \end{macrocode} 2636 | % \end{macro} 2637 | % 2638 | % \begin{macro}{\SaveNode} 2639 | % Command for saving a node outside a TikZ picture. 2640 | % \begin{macrocode} 2641 | \DeclareDocumentCommand \SaveNode { o m } 2642 | { 2643 | \group_begin: 2644 | \IfNoValueF {#1} 2645 | { 2646 | \keys_set:nn {tikzmark / save nodes} 2647 | { 2648 | file=false, 2649 | group=#1 2650 | } 2651 | } 2652 | \bool_if:NTF \l__sn_file_bool 2653 | { 2654 | \save_nodes_to_file:n {#2} 2655 | } 2656 | { 2657 | \tl_if_empty:NF \l__sn_group_tl 2658 | { 2659 | \save_nodes_to_list:Vn \l__sn_group_tl {#2} 2660 | } 2661 | } 2662 | \group_end: 2663 | } 2664 | % \end{macrocode} 2665 | % \end{macro} 2666 | % \endgroup 2667 | % \begin{macrocode} 2668 | \ExplSyntaxOff 2669 | % \end{macrocode} 2670 | % \iffalse 2671 | % 2672 | % \fi 2673 | % 2674 | % \subsection{Listings} 2675 | % 2676 | % \iffalse 2677 | %<*listings> 2678 | % \fi 2679 | % 2680 | % From \url{http://tex.stackexchange.com/q/79762/86} 2681 | % 2682 | % \begin{macrocode} 2683 | \@ifpackageloaded{listings}{% 2684 | % \end{macrocode} 2685 | % 2686 | % \begin{macro}{\iflst@linemark} 2687 | % A conditional to help with placing the mark at the first non-whitespace character. 2688 | % Should be set to true so that we notice the first line of the code. 2689 | % \begin{macrocode} 2690 | \newif\iflst@linemark 2691 | \lst@linemarktrue 2692 | % \end{macrocode} 2693 | % \end{macro} 2694 | % 2695 | % \begin{macro}{EveryLine} 2696 | % This hook places the mark at the start of the line. 2697 | % \begin{macrocode} 2698 | \lst@AddToHook{EveryLine}{% 2699 | \begingroup 2700 | \advance\c@lstnumber by 1\relax 2701 | \pgfmark{line-\lst@name-\the\c@lstnumber-start}% 2702 | \endgroup 2703 | } 2704 | % \end{macrocode} 2705 | % \end{macro} 2706 | % 2707 | % \begin{macro}{EOL} 2708 | % This hook places the mark at the end of the line and resets the conditional for placing the first mark. 2709 | % \begin{macrocode} 2710 | \lst@AddToHook{EOL}{\pgfmark{line-\lst@name-\the\c@lstnumber-end}% 2711 | \global\lst@linemarktrue 2712 | } 2713 | % \end{macrocode} 2714 | % \end{macro} 2715 | % 2716 | % \begin{macro}{OutputBox} 2717 | % Experimenting shows that this is the right place to set the mark at the first non-whitespace character. 2718 | % But we only want to do this once per line. 2719 | % \begin{macrocode} 2720 | \lst@AddToHook{OutputBox}{% 2721 | \iflst@linemark 2722 | \pgfmark{line-\lst@name-\the\c@lstnumber-first}% 2723 | \global\lst@linemarkfalse 2724 | \fi 2725 | } 2726 | % \end{macrocode} 2727 | % \end{macro} 2728 | % 2729 | % \begin{macro}{\tikzmk@lst@fnum} 2730 | % An auxiliary macro to figure out if the \Verb+firstnumber+ key was set. 2731 | % If so, it has the form \Verb+\relax+. 2732 | % If not, it expands to a single token. 2733 | % \begin{macrocode} 2734 | \def\tkzmk@lst@fnum#1\relax#2\@STOP{% 2735 | \def\@test{#2}% 2736 | \ifx\@test\@empty 2737 | \def\tkzmk@lst@start{0}% 2738 | \else 2739 | \@tempcnta=#1\relax 2740 | \advance\@tempcnta by -1\relax 2741 | \def\tkzmk@lst@start{\the\@tempcnta}% 2742 | \fi 2743 | } 2744 | % \end{macrocode} 2745 | % \end{macro} 2746 | % 2747 | % \begin{macro}{Init} 2748 | % Adds a mark at the start of the listings environment. 2749 | % \begin{macrocode} 2750 | \lst@AddToHook{Init}{% 2751 | \expandafter\tkzmk@lst@fnum\lst@firstnumber\relax\@STOP 2752 | \pgfmark{line-\lst@name-\tkzmk@lst@start-start}% 2753 | } 2754 | % \end{macrocode} 2755 | % \end{macro} 2756 | % 2757 | % \begin{macrocode} 2758 | }{% 2759 | \PackageError{tikzmark listings}% 2760 | {The listings package has not been loaded.}{} 2761 | } 2762 | % \end{macrocode} 2763 | % \iffalse 2764 | % 2765 | % \fi 2766 | % 2767 | % \subsection{AMS Math} 2768 | % 2769 | % This tikzmark library defines a routine that puts a pseudo-node (using \Verb+\tikzmark@box+) around all the pieces used in constructing the various math environments that the AMS Math package provides, such as \Verb+gather+ and \Verb+align+. 2770 | % All of these (and their labels) work by putting various pieces into a box and then typesetting that box in the cells of an \Verb+halign+. 2771 | % By using \Verb+\tikzmark@box+, this can be infiltrated to put nodes around each of those boxes as it is placed. 2772 | % 2773 | % \iffalse 2774 | %<*ams> 2775 | % \fi 2776 | % \begin{macrocode} 2777 | \@ifpackageloaded{amsmath}{% 2778 | % \end{macrocode} 2779 | % 2780 | % \begin{macro}{tikzmarkmath} 2781 | % 2782 | % Defines an environment in which any AMS mathematical aligned environments get nodes around each piece of their contents. 2783 | % 2784 | % Start by saving the original \Verb+\boxz@+ command. 2785 | % \begin{macrocode} 2786 | \let\tikzmark@ams@boxz@=\boxz@ 2787 | % \end{macrocode} 2788 | % 2789 | % We'll need a counter to keep track of the nodes. 2790 | % \begin{macrocode} 2791 | \newcounter{tikzmarkequation} 2792 | % \end{macrocode} 2793 | % 2794 | % The nodes will be labelled \Verb!-!. 2795 | % By default the name is \Verb!equation! but this can be customised. 2796 | % \begin{macrocode} 2797 | \def\tikzmark@ams@name{equation} 2798 | % \end{macrocode} 2799 | % 2800 | % This is the substitute command. 2801 | % I don't know if the \Verb=\ifmeasuring@= actually does anything, but it's here just in case at the moment. 2802 | % \begin{macrocode} 2803 | \def\tikzmark@boxz@{% 2804 | \ifmeasuring@ 2805 | \tikzmark@ams@boxz@ 2806 | \else 2807 | \stepcounter{tikzmarkequation}% 2808 | \tikzmark@box{\tikzmark@ams@name-\thetikzmarkequation}{\z@}% 2809 | \fi 2810 | } 2811 | % \end{macrocode} 2812 | % 2813 | % This is the environment that sets the node name and swaps out the box code. 2814 | % At the end of the environment we swap back the code so that the commands can be used as standalone \Verb+\tikzmarkmath+ and \Verb+\endtikzmarkmath+ in occasions when it isn't appropriate to use an environment (for example, if it crosses sections, or if it is wanted to turn on this feature for an entire document). 2815 | % At the end of the environment, the number of nodes is written out to the terminal and log file to make it easier to keep track. 2816 | % \begin{macrocode} 2817 | \newenvironment{tikzmarkmath}[1][equation]{% 2818 | \def\tikzmark@ams@name{#1}% 2819 | \setcounter{tikzmarkequation}{0}% 2820 | \let\boxz@=\tikzmark@boxz@ 2821 | }{% 2822 | \let\boxz@=\tikzmark@ams@boxz@ 2823 | \message{% 2824 | Tikzmark math environment 2825 | \tikzmark@ams@name\space had 2826 | \the\value{tikzmarkequation} nodes in it 2827 | }% 2828 | } 2829 | % \end{macrocode} 2830 | % \end{macro} 2831 | % \begin{macrocode} 2832 | }{% 2833 | \PackageError{tikzmark AMS}% 2834 | {The amsmath package has not been loaded.}% 2835 | {} 2836 | } 2837 | % \end{macrocode} 2838 | % \iffalse 2839 | % 2840 | % \fi 2841 | % 2842 | % \iffalse 2843 | %<*highlighting> 2844 | % \fi 2845 | % 2846 | % \subsection{Highlighting} 2847 | % 2848 | % An early use of \Verb!\tikzmark! was to add highlighting to text by drawing over or under the text between two tikzmarks, for example the question \href{http://tex.stackexchange.com/q/46434/86}{How to "highlight" text/formulas with tikz?}. 2849 | % 2850 | % I was never totally happy with the overall mechanism, so didn't include it in the main tikzmark package. 2851 | % Recently, I had occasion to revisit it and by using the new \LaTeX3 hook facility I got something that I was sufficiently happy with to add to the main package. 2852 | % 2853 | % The key idea is to hook into the \texttt{shipout/background} routine to insert the highlighting behind the text. 2854 | % This allows us to draw the highlighting before the page is laid out and so is under the text. 2855 | % 2856 | % \LaTeX3 makes life just that little bit easier. 2857 | % \begin{macrocode} 2858 | \ExplSyntaxOn 2859 | % \end{macrocode} 2860 | % 2861 | % Since the code that draws the highlighting will probably be very separate from the code that defines it, when storing the highlighting code then we want to expand the tikzmark full name. 2862 | % \begin{macrocode} 2863 | \cs_new_protected_nopar:Npn \tikzmark_fix_name:Nn #1#2 2864 | { 2865 | \tl_set:Nx #1 {\tikzmark@pp@name{#2}} 2866 | } 2867 | % \end{macrocode} 2868 | % 2869 | % \begin{macro}{\StartHighlighting,\EndHighlighting,\Highlight} 2870 | % These are the user interfaces for highlighting a section. 2871 | % The first command inserts the drawing code into the relevant hook and places a tikzmark at the current location. 2872 | % The second command indicates when the highlighting should stop. 2873 | % The third is a short cut for highlighting its argument. 2874 | % 2875 | % These are commands rather than an environment to allow it to span, for example, different parts of an aligned equation. 2876 | % \begin{macrocode} 2877 | \tl_new:N \g__tikzmark_highlighter_tl 2878 | \tl_set:Nn \g__tikzmark_highlighter_tl {tikzmark~ highlighter~} 2879 | \int_new:N \g__tikzmark_highlighter_int 2880 | \tl_new:N \l__tikzmark_start_tl 2881 | \tl_new:N \l__tikzmark_end_tl 2882 | \tl_new:N \l__tikzmark_highlighter_name_tl 2883 | \tl_new:N \l__tikzmark_tmpa_tl 2884 | \tl_new:N \l__tikzmark_tmpb_tl 2885 | \tl_new:N \l__tikzmark_tmpc_tl 2886 | 2887 | \cs_new_protected_nopar:Npn \tikzmark_bake_highlighter:N #1 2888 | { 2889 | \tl_clear:N #1 2890 | \clist_map_inline:nn {direction,layer} 2891 | { 2892 | \tl_put_right:Nx #1 { 2893 | /tikz/highlighter/##1=\pgfkeysvalueof{/tikz/highlighter/##1}, 2894 | } 2895 | } 2896 | \clist_map_inline:nn { 2897 | initial~ height, 2898 | initial~ depth, 2899 | initial~ offset, 2900 | final~ height, 2901 | final~ depth, 2902 | final~ offset, 2903 | left~ margin, 2904 | right~ margin, 2905 | top~ margin, 2906 | bottom~ margin, 2907 | } 2908 | { 2909 | \tl_put_right:Nx #1 { 2910 | /tikz/highlighter/##1=\dim_eval:n {\pgfkeysvalueof{/tikz/highlighter/##1}}, 2911 | } 2912 | } 2913 | } 2914 | 2915 | \cs_new_protected_nopar:Npn \tikzmark_start_highlighting:n #1 2916 | { 2917 | \int_gincr:N \g__tikzmark_highlighter_int 2918 | \tl_set:Nx \l__tikzmark_highlighter_name_tl 2919 | { 2920 | \tl_use:N \g__tikzmark_highlighter_tl 2921 | \int_use:N \g__tikzmark_highlighter_int 2922 | } 2923 | \tl_set:Nn \l__tikzmark_tmpb_tl 2924 | { 2925 | every~ highlighter/.try, 2926 | } 2927 | \tikzmark_bake_highlighter:N \l__tikzmark_tmpc_tl 2928 | \tl_put_right:NV \l__tikzmark_tmpb_tl \l__tikzmark_tmpc_tl 2929 | \tl_put_right:Nn \l__tikzmark_tmpb_tl {/tikz/highlighter/.cd,#1} 2930 | \tikzmark_process_highlighting:VV 2931 | \l__tikzmark_tmpb_tl 2932 | \l__tikzmark_highlighter_name_tl 2933 | \tikzmark{highlight-start-\tl_use:N \l__tikzmark_highlighter_name_tl} 2934 | } 2935 | \cs_new_protected_nopar:Npn \tikzmark_end_highlighting: 2936 | { 2937 | \tl_set:Nx \l__tikzmark_highlighter_name_tl 2938 | { 2939 | \tl_use:N \g__tikzmark_highlighter_tl 2940 | \int_use:N \g__tikzmark_highlighter_int 2941 | } 2942 | \tikzmark{highlight-end-\tl_use:N \l__tikzmark_highlighter_name_tl} 2943 | } 2944 | 2945 | \NewDocumentCommand \StartHighlighting {O{}} 2946 | {% 2947 | \tikzmark_start_highlighting:n {#1} 2948 | } 2949 | \NewDocumentCommand \StopHighlighting {} 2950 | {% 2951 | \tikzmark_end_highlighting: 2952 | } 2953 | \NewDocumentCommand \Highlight {O{} m} 2954 | {% 2955 | \tikzmark_start_highlighting:n {#1} 2956 | #2 2957 | \tikzmark_end_highlighting: 2958 | } 2959 | % \end{macrocode} 2960 | % \end{macro} 2961 | % 2962 | % The following code inserts the drawing command into the shipout hook. 2963 | % \begin{macrocode} 2964 | % \end{macrocode} 2965 | % We need an ordinary colon, rather than a \LaTeX3 one 2966 | % \begin{macrocode} 2967 | \tl_const:Nx \c__tikzmark_colon_tl 2968 | { 2969 | \char_generate:nn {`:} {12} 2970 | } 2971 | 2972 | \cs_generate_variant:Nn \hook_gput_next_code:nn {nV} 2973 | % \end{macrocode} 2974 | % 2975 | % \begin{macrocode} 2976 | \cs_new_protected_nopar:Npn \tikzmark_highlight_or_shunt:nnnn #1#2#3#4 2977 | { 2978 | % \end{macrocode} 2979 | % First, test to check if the tikzmarks are actually defined yet, 2980 | % if not then bail out. 2981 | % The names have already been frozen, so we don't wrap them in \Verb~\tikzmark@pp@name~ here. 2982 | % \begin{macrocode} 2983 | \bool_lazy_all:nT 2984 | { 2985 | {\tl_if_exist_p:c {save@pt@#2}} 2986 | {\tl_if_exist_p:c {save@pg@\tl_use:c{save@pt@#2}}} 2987 | {\tl_if_exist_p:c {save@pt@#3}} 2988 | {\tl_if_exist_p:c {save@pg@\tl_use:c{save@pt@#3}}} 2989 | } 2990 | { 2991 | % \end{macrocode} 2992 | % Okay, so all the tikzmarks are defined. Now see if we're on the 2993 | % right page. Is our start tikzmark in the future? 2994 | % \begin{macrocode} 2995 | \int_compare:nTF 2996 | { 2997 | \tl_use:c {save@pg@\tl_use:c{save@pt@#2}} 2998 | > 2999 | \the\value{page} 3000 | } 3001 | { 3002 | % \end{macrocode} 3003 | % It is, so we just punt our highlighting down the line 3004 | % \begin{macrocode} 3005 | \hook_gput_next_code:nn {#1} { 3006 | \tikzmark_highlight_or_shunt:nnnn {#1}{#2}{#3}{#4} 3007 | } 3008 | } 3009 | { 3010 | % \end{macrocode} 3011 | % It isn't, so we have some highlighting to do. 3012 | % We need to build our highlighting code. 3013 | % \begin{macrocode} 3014 | \tl_set:Nn \l__tikzmark_tmpa_tl {#4} 3015 | % \end{macrocode} 3016 | % Is our starting tikzmark on \emph{this} page? 3017 | % \begin{macrocode} 3018 | \int_compare:nTF 3019 | { 3020 | \tl_use:c {save@pg@\tl_use:c{save@pt@#2}} 3021 | = 3022 | \the\value{page} 3023 | } 3024 | { 3025 | % \end{macrocode} 3026 | % It is, so we use the starting tikzmark as our first coordinate. 3027 | % \begin{macrocode} 3028 | \tl_put_right:Nx \l__tikzmark_tmpa_tl 3029 | { 3030 | { 3031 | pic~ cs 3032 | \tl_use:N \c__tikzmark_colon_tl 3033 | #2 3034 | } 3035 | } 3036 | } 3037 | { 3038 | % \end{macrocode} 3039 | % It isn't, so we use the north west corner of the page 3040 | % \begin{macrocode} 3041 | \tl_put_right:Nn \l__tikzmark_tmpa_tl 3042 | { 3043 | { 3044 | page.north~ west 3045 | } 3046 | } 3047 | } 3048 | % \end{macrocode} 3049 | % Is our ending tikzmark on \emph{this} page? 3050 | % \begin{macrocode} 3051 | \int_compare:nTF 3052 | { 3053 | \tl_use:c {save@pg@\tl_use:c{save@pt@#3}} 3054 | = 3055 | \the\value{page} 3056 | } 3057 | { 3058 | % \end{macrocode} 3059 | % It is, so we use the ending tikzmark as our second coordinate. 3060 | % \begin{macrocode} 3061 | \tl_put_right:Nx \l__tikzmark_tmpa_tl 3062 | { 3063 | { 3064 | pic~ cs 3065 | \tl_use:N \c__tikzmark_colon_tl 3066 | #3 3067 | } 3068 | } 3069 | } 3070 | { 3071 | % \end{macrocode} 3072 | % It isn't, so we use the south east corner of the page, and 3073 | % we have to shunt the code to the next page. 3074 | % \begin{macrocode} 3075 | \tl_put_right:Nn \l__tikzmark_tmpa_tl 3076 | { 3077 | { 3078 | page.south~ east 3079 | } 3080 | } 3081 | \hook_gput_next_code:nn {#1} { 3082 | \tikzmark_highlight_or_shunt:nnnn {#1}{#2}{#3}{#4} 3083 | } 3084 | } 3085 | % \end{macrocode} 3086 | % We've built our highlighting code, now's time to execute it. 3087 | % \begin{macrocode} 3088 | \tl_use:N \l__tikzmark_tmpa_tl 3089 | } 3090 | } 3091 | } 3092 | % \end{macrocode} 3093 | % 3094 | % \begin{macrocode} 3095 | \cs_new_protected_nopar:Npn \tikzmark_process_highlighting:nn #1#2 3096 | { 3097 | \group_begin: 3098 | \pgfkeys{/tikz/highlighter/configuration/.activate~ family} 3099 | \pgfkeysfiltered{/tikz/highlighter/.cd,direction,layer,#1} 3100 | 3101 | \tikzmark_fix_name:Nn \l__tikzmark_start_tl {highlight-start-#2} 3102 | \tikzmark_fix_name:Nn \l__tikzmark_end_tl {highlight-end-#2} 3103 | \tl_set:Nx \l__tikzmark_tmpa_tl {\pgfkeysvalueof{/tikz/highlighter/direction}} 3104 | \tl_clear:N \l__tikzmark_tmpb_tl 3105 | \tl_clear:N \l__tikzmark_tmpc_tl 3106 | \tl_if_eq:NnTF \l__tikzmark_tmpa_tl {vertical} 3107 | { 3108 | \tl_put_right:Nn \l__tikzmark_tmpb_tl 3109 | { 3110 | \vl@draw 3111 | } 3112 | } 3113 | { 3114 | \tl_if_eq:NnTF \l__tikzmark_tmpa_tl {box} 3115 | { 3116 | \tl_put_right:Nn \l__tikzmark_tmpb_tl 3117 | { 3118 | \box@draw 3119 | } 3120 | } 3121 | { 3122 | \tl_put_right:Nn \l__tikzmark_tmpb_tl 3123 | { 3124 | \hl@draw 3125 | } 3126 | } 3127 | } 3128 | 3129 | \tl_put_right:Nn \l__tikzmark_tmpb_tl 3130 | { 3131 | {tikzmark~ clear~ ixes,#1} 3132 | } 3133 | 3134 | \tl_set:Nx \l__tikzmark_tmpa_tl {\pgfkeysvalueof{/tikz/highlighter/layer}} 3135 | \tl_set:Nn \l__tikzmark_tmpc_tl 3136 | { 3137 | \tikzmark_highlight_or_shunt:nnnn 3138 | } 3139 | \tl_if_eq:NnTF \l__tikzmark_tmpa_tl {foreground} 3140 | { 3141 | \tl_put_right:Nn \l__tikzmark_tmpc_tl {{shipout/foreground}} 3142 | } 3143 | { 3144 | \tl_put_right:Nn \l__tikzmark_tmpc_tl {{shipout/background}} 3145 | } 3146 | 3147 | \tikzmark_tl_put_right_braced:NV \l__tikzmark_tmpc_tl \l__tikzmark_start_tl 3148 | \tikzmark_tl_put_right_braced:NV \l__tikzmark_tmpc_tl \l__tikzmark_end_tl 3149 | \tikzmark_tl_put_right_braced:NV \l__tikzmark_tmpc_tl \l__tikzmark_tmpb_tl 3150 | 3151 | \tl_if_eq:NnTF \l__tikzmark_tmpa_tl {foreground} 3152 | { 3153 | \hook_gput_next_code:nV {shipout/foreground} \l__tikzmark_tmpc_tl 3154 | } 3155 | { 3156 | \hook_gput_next_code:nV {shipout/background} \l__tikzmark_tmpc_tl 3157 | } 3158 | \group_end: 3159 | } 3160 | \cs_generate_variant:Nn \tikzmark_process_highlighting:nn {nV,VV} 3161 | \ExplSyntaxOff 3162 | % \end{macrocode} 3163 | % 3164 | % The command that draws the horizontal highlighter or fader. 3165 | % This fills a shape determined by two coordinates assumed to be (in effect) on the baseline of the start and end of the region to be highlighted. 3166 | % \begin{macrocode} 3167 | \def\hl@draw#1#2#3{% 3168 | \pgfkeys{/tikz/highlighter/configuration/.activate family} 3169 | \pgfkeysfiltered{/tikz/highlighter/.cd,direction,layer,#1} 3170 | \begin{tikzpicture}[ 3171 | remember picture, 3172 | overlay, 3173 | highlight picture action, 3174 | highlighter/.cd, 3175 | #1, 3176 | ]% 3177 | % 3178 | \page@node 3179 | % 3180 | \tikz@scan@one@point\pgfutil@firstofone(#2)\relax 3181 | \pgf@ya=\pgf@y 3182 | \tikz@scan@one@point\pgfutil@firstofone(#3)\relax 3183 | \pgf@yb=\pgf@y 3184 | % 3185 | \ifdim\pgf@ya=\pgf@yb 3186 | % 3187 | \path (#2) 3188 | ++(-1*\pgfkeysvalueof{/tikz/highlighter/initial offset}, 3189 | \pgfkeysvalueof{/tikz/highlighter/initial height}) 3190 | coordinate (start); 3191 | % 3192 | \path (#3) 3193 | ++(\pgfkeysvalueof{/tikz/highlighter/final offset}, 3194 | -1*\pgfkeysvalueof{/tikz/highlighter/final depth}) 3195 | coordinate (end); 3196 | % 3197 | \path[ 3198 | highlight action, 3199 | #1 3200 | ] (start) rectangle (end); 3201 | % 3202 | \else 3203 | % 3204 | \path (page.east) 3205 | ++(\pgfkeysvalueof{/tikz/highlighter/right margin},0pt) 3206 | coordinate (east); 3207 | % 3208 | \path (page.west) 3209 | ++(-1*\pgfkeysvalueof{/tikz/highlighter/left margin},0pt) 3210 | coordinate (west); 3211 | % 3212 | \pgfmathsetlength\pgf@x{% 3213 | \pgfkeysvalueof{/tikz/highlighter/initial height}% 3214 | }% 3215 | % 3216 | \advance\pgf@yb by \pgf@x\relax 3217 | % 3218 | \pgfmathsetlength\pgf@x{% 3219 | -1*\pgfkeysvalueof{/tikz/highlighter/final depth}% 3220 | }% 3221 | % 3222 | \advance\pgf@ya by \pgf@x\relax 3223 | % 3224 | \ifdim\pgf@yb>\pgf@ya 3225 | % 3226 | \path (#2) 3227 | ++(-1*\pgfkeysvalueof{/tikz/highlighter/initial offset}, 3228 | \pgfkeysvalueof{/tikz/highlighter/initial height}) 3229 | coordinate (start); 3230 | % 3231 | \path (#2) 3232 | ++(0pt,-1*\pgfkeysvalueof{/tikz/highlighter/final depth}) 3233 | coordinate (end); 3234 | % 3235 | \path[ 3236 | highlight action, 3237 | #1 3238 | ] (start) rectangle (end -| east); 3239 | % 3240 | \path (#3) 3241 | ++(0pt,\pgfkeysvalueof{/tikz/highlighter/initial height}) 3242 | coordinate (start); 3243 | % 3244 | \path (#3) 3245 | ++(\pgfkeysvalueof{/tikz/highlighter/final offset}, 3246 | -1*\pgfkeysvalueof{/tikz/highlighter/final depth}) 3247 | coordinate (end); 3248 | % 3249 | \path[ 3250 | highlight action, 3251 | #1 3252 | ] (start -| west) rectangle (end); 3253 | % 3254 | \else 3255 | % 3256 | \path (#2) 3257 | ++(-1*\pgfkeysvalueof{/tikz/highlighter/initial offset}, 3258 | \pgfkeysvalueof{/tikz/highlighter/initial height}) 3259 | coordinate (tl); 3260 | % 3261 | \path (#2) 3262 | ++(-1*\pgfkeysvalueof{/tikz/highlighter/initial offset}, 3263 | -1*\pgfkeysvalueof{/tikz/highlighter/initial depth}) 3264 | coordinate (start); 3265 | % 3266 | \path (#3) 3267 | ++(\pgfkeysvalueof{/tikz/highlighter/final offset}, 3268 | -1*\pgfkeysvalueof{/tikz/highlighter/final depth}) 3269 | coordinate (end); 3270 | % 3271 | \path (#3) 3272 | ++(\pgfkeysvalueof{/tikz/highlighter/final offset}, 3273 | \pgfkeysvalueof{/tikz/highlighter/final height}) 3274 | coordinate (mr); 3275 | % 3276 | \path[ 3277 | highlight action, 3278 | #1 3279 | ] (start) -- (tl) -- (tl -| east) -- (mr -| east) -- (mr) -- 3280 | (end) -- (end -| west) -- (start -| west) -- cycle; 3281 | % 3282 | \fi 3283 | \fi 3284 | \end{tikzpicture}% 3285 | } 3286 | % \end{macrocode} 3287 | % 3288 | % This one draws a box. 3289 | % \begin{macrocode} 3290 | \def\box@draw#1#2#3{% 3291 | \pgfkeys{/tikz/highlighter/configuration/.activate family} 3292 | \pgfkeysfiltered{/tikz/highlighter/.cd,direction,layer,#1} 3293 | \begin{tikzpicture}[ 3294 | remember picture, 3295 | overlay, 3296 | highlight picture action, 3297 | highlighter/.cd, 3298 | #1, 3299 | ]% 3300 | % 3301 | \tikz@scan@one@point\pgfutil@firstofone(#2)\relax 3302 | \pgf@xa=\pgf@x 3303 | \tikz@scan@one@point\pgfutil@firstofone(#3)\relax 3304 | \pgf@xb=\pgf@x 3305 | % 3306 | \def\tkmk@high@bscale{1}% 3307 | \ifdim\pgf@xa>\pgf@xb 3308 | \def\tkmk@high@bscale{-1}% 3309 | \fi 3310 | % 3311 | \path (#2) 3312 | ++({\tkmk@high@bscale*(-1)*\pgfkeysvalueof{/tikz/highlighter/initial offset}}, 3313 | \pgfkeysvalueof{/tikz/highlighter/initial height}) 3314 | coordinate (start); 3315 | % 3316 | \path (#3) 3317 | ++(\tkmk@high@bscale*\pgfkeysvalueof{/tikz/highlighter/final offset}, 3318 | -1*\pgfkeysvalueof{/tikz/highlighter/final depth}) 3319 | coordinate (end); 3320 | % 3321 | \path[ 3322 | highlight action, 3323 | #1 3324 | ] (start) rectangle (end); 3325 | \end{tikzpicture}% 3326 | } 3327 | % \end{macrocode} 3328 | % 3329 | % In this one the region is defined vertically. 3330 | % \begin{macrocode} 3331 | \def\vl@draw#1#2#3{% 3332 | \pgfkeys{/tikz/highlighter/configuration/.activate family} 3333 | \pgfkeysfiltered{/tikz/highlighter/.cd,direction,layer,#1} 3334 | \begin{tikzpicture}[ 3335 | remember picture, 3336 | overlay, 3337 | highlight picture action, 3338 | highlighter/.cd, 3339 | #1, 3340 | ]% 3341 | % 3342 | \tikz@scan@one@point\pgfutil@firstofone(#2)\relax 3343 | \pgf@ya=\pgf@y 3344 | \pgf@xa=\pgf@x 3345 | \tikz@scan@one@point\pgfutil@firstofone(#3)\relax 3346 | \pgf@yb=\pgf@y 3347 | \pgf@xb=\pgf@x 3348 | % 3349 | \pgfmathsetlength\pgf@y{% 3350 | \pgfkeysvalueof{/tikz/highlighter/initial offset}% 3351 | }% 3352 | \advance\pgf@yb by \pgf@y 3353 | \pgfmathsetlength\pgf@y{% 3354 | -1*\pgfkeysvalueof{/tikz/highlighter/final offset}% 3355 | }% 3356 | \advance\pgf@ya by \pgf@y 3357 | % 3358 | \ifdim\pgf@yb>\pgf@ya 3359 | % 3360 | \ifdim\pgf@xa>\pgf@xb 3361 | % 3362 | \path (#2) 3363 | ++(\pgfkeysvalueof{/tikz/highlighter/initial height}, 3364 | \pgfkeysvalueof{/tikz/highlighter/initial offset}) 3365 | coordinate (start); 3366 | % 3367 | \path (#3) 3368 | ++(-1*\pgfkeysvalueof{/tikz/highlighter/final depth}, 3369 | -1*\pgfkeysvalueof{/tikz/highlighter/final offset}) 3370 | coordinate (end); 3371 | % 3372 | \else 3373 | % 3374 | \path (#2) 3375 | ++(-1*\pgfkeysvalueof{/tikz/highlighter/initial depth}, 3376 | \pgfkeysvalueof{/tikz/highlighter/initial offset}) 3377 | coordinate (start); 3378 | % 3379 | \path (#3) 3380 | ++(\pgfkeysvalueof{/tikz/highlighter/final height}, 3381 | -1*\pgfkeysvalueof{/tikz/highlighter/final offset}) 3382 | coordinate (end); 3383 | % 3384 | \fi 3385 | % 3386 | \path[ 3387 | highlight action, 3388 | #1 3389 | ] (start) rectangle (end); 3390 | % 3391 | \else 3392 | % 3393 | \path (#2) 3394 | ++(\pgfkeysvalueof{/tikz/highlighter/initial height},0) 3395 | coordinate (tr); 3396 | % 3397 | \path (#2) 3398 | ++(0,\pgfkeysvalueof{/tikz/highlighter/initial offset}) 3399 | coordinate (start); 3400 | % 3401 | \path (#2) 3402 | ++(-1*\pgfkeysvalueof{/tikz/highlighter/initial depth},0) 3403 | coordinate (tl); 3404 | % 3405 | \path (#3) 3406 | ++(\pgfkeysvalueof{/tikz/highlighter/final height},0) 3407 | coordinate (br); 3408 | % 3409 | \path (#3) 3410 | ++(0,-1*\pgfkeysvalueof{/tikz/highlighter/final offset}) 3411 | coordinate (end); 3412 | % 3413 | \path (#3) 3414 | ++(-1*\pgfkeysvalueof{/tikz/highlighter/final depth},0) 3415 | coordinate (bl); 3416 | % 3417 | \tikz@scan@one@point\pgfutil@firstofone(#2)\relax 3418 | \pgf@xa=\pgf@x 3419 | \tikz@scan@one@point\pgfutil@firstofone(#3)\relax 3420 | \pgf@xb=\pgf@x 3421 | % 3422 | \ifdim\pgf@xa<\pgf@xb 3423 | % 3424 | \path[ 3425 | highlight action, 3426 | #1 3427 | ] (tl) |- (start) -| (tr) -| (br) |- (end) -| (bl) -| cycle; 3428 | % 3429 | \else 3430 | % 3431 | \path[ 3432 | highlight action, 3433 | #1 3434 | ] (tl) |- (start) -| (tr) |- (br) |- (end) -| (bl) |- cycle; 3435 | % 3436 | \fi 3437 | % 3438 | \fi 3439 | \end{tikzpicture} 3440 | } 3441 | % \end{macrocode} 3442 | % 3443 | % These set various options. 3444 | % \begin{macrocode} 3445 | \tikzset{% 3446 | /tikz/highlighter/.is family, 3447 | /tikz/highlighter/.search also={/tikz,/pgf}, 3448 | /tikz/highlighter/highlighter/.is family, 3449 | /tikz/highlighter/highlighter/.search also={/tikz/highlighter,/tikz,/pgf}, 3450 | every highlight path/.style={ 3451 | fill=yellow!50, 3452 | rounded corners, 3453 | }, 3454 | every foreground highlight path/.style={ 3455 | fill opacity=.5, 3456 | }, 3457 | highlight picture action/.style={ 3458 | every highlight picture/.try, 3459 | every \pgfkeysvalueof{/tikz/highlighter/direction} highlight picture/.try, 3460 | every \pgfkeysvalueof{/tikz/highlighter/layer} highlight picture/.try, 3461 | }, 3462 | highlight action/.style={ 3463 | every highlight path/.try, 3464 | every \pgfkeysvalueof{/tikz/highlighter/direction} highlight path/.try, 3465 | every \pgfkeysvalueof{/tikz/highlighter/layer} highlight path/.try, 3466 | highlight path/.try, 3467 | \pgfkeysvalueof{/tikz/highlighter/direction} highlight path/.try, 3468 | \pgfkeysvalueof{/tikz/highlighter/layer} highlight path/.try, 3469 | }, 3470 | /tikz/highlighter/.cd, 3471 | direction/.initial=horizontal, 3472 | layer/.initial=background, 3473 | direction/.default=horizontal, 3474 | layer/.default=background, 3475 | initial height/.initial=\baselineskip, 3476 | initial depth/.initial=.5ex, 3477 | initial offset/.initial=.5\baselineskip, 3478 | final height/.initial=\baselineskip, 3479 | final depth/.initial=.5ex, 3480 | final offset/.initial=.5\baselineskip, 3481 | left margin/.initial=.5\baselineskip, 3482 | right margin/.initial=.5\baselineskip, 3483 | top margin/.initial=.5\baselineskip, 3484 | bottom margin/.initial=-.5\baselineskip, 3485 | height/.style={ 3486 | initial height=#1, 3487 | final height=#1 3488 | }, 3489 | depth/.style={ 3490 | initial depth=#1, 3491 | final depth=#1 3492 | }, 3493 | offset/.style={ 3494 | initial offset=#1, 3495 | final offset=#1 3496 | }, 3497 | margin/.style={ 3498 | left margin=#1, 3499 | right margin=#1, 3500 | top margin=#1, 3501 | bottom margin=#1, 3502 | }, 3503 | /tikz/highlighter/configuration/.is family, 3504 | /tikz/highlighter/direction/.belongs to family=/tikz/highlighter/configuration, 3505 | /tikz/highlighter/layer/.belongs to family=/tikz/highlighter/configuration, 3506 | } 3507 | % \end{macrocode} 3508 | % 3509 | % 3510 | % \begin{macrocode} 3511 | \def\page@node{ 3512 | \path (current page.north west) 3513 | ++(\hoffset + 1in + \oddsidemargin + \leftskip, 3514 | -\voffset - 1in - \topmargin - \headheight - \headsep) 3515 | node[ 3516 | minimum width=\textwidth - \leftskip - \rightskip, 3517 | minimum height=\textheight, 3518 | anchor=north west, 3519 | line width=0mm, 3520 | inner sep=0pt, 3521 | outer sep=0pt, 3522 | ] (page) {}; 3523 | } 3524 | % \end{macrocode} 3525 | % 3526 | % 3527 | % 3528 | % \iffalse 3529 | % 3530 | % \fi 3531 | % 3532 | % \Finale 3533 | \endinput 3534 | -------------------------------------------------------------------------------- /tikzmarkExample.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/loopspace/tikzmark/21140c455d4c915017bef09b165193cccb0ff6de/tikzmarkExample.pdf --------------------------------------------------------------------------------