├── .github └── FUNDING.yml ├── doc ├── robust-externalize.sty ├── common_inputs.tex ├── mylib.py ├── robust-externalize.pdf ├── gnuplot-lua-tikz.tex ├── figures │ └── demo.tikz ├── gnuplot-lua-tikz.sty ├── zx-calculus.sty ├── 04-example-forest.tex ├── 01-quickstart-too-pure.tex ├── 00-quickstart-impure.tex ├── tikzit.sty ├── gnuplot_data.dat ├── 02-quickstart-pure.tex ├── new_zxstyle.tikzstyles ├── styles │ └── new_zxstyle.tikzstyles ├── ltxdoc.cls ├── gnuplot-lua-tikz-common.tex └── tikzlibraryzx-calculus.code.tex ├── .gitignore ├── README.md └── Makefile /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: tobiasBora 2 | -------------------------------------------------------------------------------- /doc/robust-externalize.sty: -------------------------------------------------------------------------------- 1 | ../robust-externalize.sty -------------------------------------------------------------------------------- /doc/common_inputs.tex: -------------------------------------------------------------------------------- 1 | \def\myValueDefinedInCommonInputs{42} -------------------------------------------------------------------------------- /doc/mylib.py: -------------------------------------------------------------------------------- 1 | def mylib(): 2 | # Some comments 3 | a = b % 2 4 | return "Hello world" 5 | -------------------------------------------------------------------------------- /doc/robust-externalize.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leo-colisson/robust-externalize/HEAD/doc/robust-externalize.pdf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | tests/ 2 | old/ 3 | *.log 4 | robExt* 5 | *.ind 6 | *.out 7 | *.toc 8 | *.synctex.gz 9 | *.ilg 10 | *tmp-file-you-can-remove.tmp 11 | *compile-missing-figures.sh 12 | *all-figures.txt 13 | *.aux 14 | *.idx 15 | *debug* 16 | *backup* 17 | *.fdb_latexmk 18 | *.fls 19 | *.zip 20 | build_ctan/ -------------------------------------------------------------------------------- /doc/gnuplot-lua-tikz.tex: -------------------------------------------------------------------------------- 1 | %% 2 | %% plain TeX wrapper for gnuplot-tikz style file 3 | %% 4 | \input tikz.tex 5 | \usetikzlibrary{arrows,patterns,plotmarks,backgrounds,fit} 6 | 7 | \edef\tikzatcode{\the\catcode`\@} 8 | \catcode`\@=11 9 | 10 | \input gnuplot-lua-tikz-common.tex 11 | 12 | \catcode`\@=\tikzatcode 13 | 14 | \endinput 15 | -------------------------------------------------------------------------------- /doc/figures/demo.tikz: -------------------------------------------------------------------------------- 1 | \begin{tikzpicture} 2 | \begin{pgfonlayer}{nodelayer} 3 | \node [style=Z dot] (0) at (0, 0) {}; 4 | \node [style=X dot] (1) at (1, 0) {}; 5 | \end{pgfonlayer} 6 | \begin{pgfonlayer}{edgelayer} 7 | \draw [bend left=60] (0) to (1); 8 | \draw [bend right=60] (0) to (1); 9 | \draw (0) to (1); 10 | \end{pgfonlayer} 11 | \end{tikzpicture} 12 | -------------------------------------------------------------------------------- /doc/gnuplot-lua-tikz.sty: -------------------------------------------------------------------------------- 1 | %% 2 | %% LaTeX wrapper for gnuplot-tikz style file 3 | %% 4 | \NeedsTeXFormat{LaTeX2e} 5 | \ProvidesPackage{gnuplot-lua-tikz}% 6 | [2021/10/08 22:39:00 (rev. 115) GNUPLOT Lua terminal style] 7 | 8 | \RequirePackage{tikz} 9 | 10 | \usetikzlibrary{arrows,patterns,plotmarks,backgrounds,fit} 11 | \input gnuplot-lua-tikz-common.tex 12 | 13 | \endinput 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # `robust-externalize` 2 | 3 | LaTeX library to cache anything (TikZ, python…), in a robust, efficient and pure way. For more information, see the documentation in [`doc/robust-exteralize.pdf`][1]. 4 | 5 | The project, created by Léo Colisson, is hosted at https://github.com/leo-colisson/robust-externalize . Feel free to report any bug there. It is licensed under MIT. 6 | 7 | [1]: https://raw.githubusercontent.com/leo-colisson/robust-externalize/master/doc/robust-externalize.pdf 8 | -------------------------------------------------------------------------------- /doc/zx-calculus.sty: -------------------------------------------------------------------------------- 1 | % This is a zx library to typeset ZX calculus directly in LaTeX. 2 | % Written by Léo Colisson. Report bugs on https://github.com/leo-colisson/zx-calculus/issues 3 | % Published under the MIT license. 4 | \NeedsTeXFormat{LaTeX2e} 5 | \ProvidesPackage{zx-calculus}[2022/02/09 A package to typeset ZX calculus in directly in LaTeX, based on tikz/tikzcd.] 6 | 7 | \RequirePackage{tikz} 8 | \RequirePackage{tikz-cd} 9 | 10 | \usetikzlibrary{zx-calculus} % See library in "tikzlibraryzx.code.tex". 11 | -------------------------------------------------------------------------------- /doc/04-example-forest.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | 3 | \usepackage{robust-externalize} 4 | % Updates \graphicspath in compiled files to look for images in the root folder: 5 | \robExtConfigure{latex support pictures} 6 | 7 | % Automatically cache all tikz figures 8 | % WARNING: read the "Bonus: how to cache all tikz pictures automatically" or you'll get into troubles 9 | \cacheTikz 10 | \cacheEnvironment{forest}{latex, add to preamble={\usepackage{forest}}} 11 | 12 | \begin{document} 13 | 14 | \begin{tikzpicture} 15 | \node[rounded corners]{See, this picture is automatically cached!}; 16 | \end{tikzpicture} 17 | 18 | and this forest image is also automatically cached: 19 | \begin{forest} 20 | [VP 21 | [DP] 22 | [V’ 23 | [V] 24 | [DP] 25 | ] 26 | ] 27 | \end{forest} 28 | \end{document} 29 | -------------------------------------------------------------------------------- /doc/01-quickstart-too-pure.tex: -------------------------------------------------------------------------------- 1 | % Simple but not recommended: impure (= manual recompilations), requires v4.0 or above 2 | \documentclass{article} 3 | 4 | \usepackage{tikz} 5 | \usepackage{robust-externalize} 6 | % Updates \graphicspath in compiled files to look for images in the root folder, 7 | % requires v4.0 or above: 8 | \robExtConfigure{latex support pictures} 9 | 10 | % Put your preamble here (loaded in this file + cached files) 11 | % (warning: recompile all pictures when changed) 12 | \begin{CacheMeCode}{latex too pure workflow} 13 | \def\myname{Alice} 14 | \end{CacheMeCode} 15 | 16 | \begin{document} 17 | 18 | You can use the macro ``\myname{}'' in the main document or in cached pictures. Since you are 19 | in the too pure workflow, you don't need to force recompilation, but it will recompile all 20 | pictures every time you update the preamble. See ``pure workflows'' and ``defAutoForward'' 21 | for more fine-grained recompilation. 22 | 23 | % Note the C -----+ to mean that we should cache this picture. 24 | % | See \cacheTikz + \cacheCommand to automatically cache all tikz pictures 25 | % V 26 | \begin{tikzpictureC} 27 | \node[draw,rounded corners,fill=yellow,align=left,text width=7cm]{\myname{}}; 28 | \end{tikzpictureC} 29 | 30 | \end{document} 31 | -------------------------------------------------------------------------------- /doc/00-quickstart-impure.tex: -------------------------------------------------------------------------------- 1 | % Simple but not recommended: impure (= manual recompilations), requires v4.0 or above 2 | \documentclass{article} 3 | 4 | \usepackage{tikz} 5 | \usepackage{robust-externalize} 6 | % Updates \graphicspath in compiled files to look for images in the root folder: 7 | \robExtConfigure{latex support pictures} 8 | 9 | % Put your preamble here (loaded in this file + cached files) 10 | \begin{CacheMeCode}{latex impure workflow} 11 | \def\myname{Alice} 12 | \end{CacheMeCode} 13 | 14 | \begin{document} 15 | 16 | You can use the macro ``\myname{}'' in the main document or in cached pictures, but since you are 17 | in the impure workflow, you need to recompile the picture if you update the preamble (or see 18 | ``too pure'' or ``pure'' workflows and ``defAutoForward'' for more fine-grained recompilation). 19 | 20 | % Note the C -----+ to mean that we should cache this picture. 21 | % | See \cacheTikz + \cacheCommand to automatically cache all tikz pictures 22 | % | +--- This forces recompilation (add it temporarily when preamble changes) 23 | % V V 24 | \begin{tikzpictureC} 25 | \node[draw,rounded corners,fill=yellow,align=left,text width=7cm]{\myname{}}; 26 | \end{tikzpictureC} 27 | 28 | \end{document} 29 | -------------------------------------------------------------------------------- /doc/tikzit.sty: -------------------------------------------------------------------------------- 1 | \usepackage{tikz} 2 | \usetikzlibrary{backgrounds} 3 | \usetikzlibrary{arrows} 4 | \usetikzlibrary{shapes,shapes.geometric,shapes.misc} 5 | 6 | % this style is applied by default to any tikzpicture included via \tikzfig 7 | \tikzstyle{tikzfig}=[baseline=-0.25em,scale=0.5] 8 | 9 | % these are dummy properties used by TikZiT, but ignored by LaTex 10 | \pgfkeys{/tikz/tikzit fill/.initial=0} 11 | \pgfkeys{/tikz/tikzit draw/.initial=0} 12 | \pgfkeys{/tikz/tikzit shape/.initial=0} 13 | \pgfkeys{/tikz/tikzit category/.initial=0} 14 | 15 | % standard layers used in .tikz files 16 | \pgfdeclarelayer{edgelayer} 17 | \pgfdeclarelayer{nodelayer} 18 | \pgfsetlayers{background,edgelayer,nodelayer,main} 19 | 20 | % style for blank nodes 21 | \tikzstyle{none}=[inner sep=0mm] 22 | 23 | % include a .tikz file 24 | \newcommand{\tikzfig}[1]{% 25 | {\tikzstyle{every picture}=[tikzfig] 26 | \IfFileExists{#1.tikz} 27 | {\input{#1.tikz}} 28 | {% 29 | \IfFileExists{./figures/#1.tikz} 30 | {\input{./figures/#1.tikz}} 31 | {\tikz[baseline=-0.5em]{\node[draw=red,font=\color{red},fill=red!10!white] {\textit{#1}};}}% 32 | }}% 33 | } 34 | 35 | % the same as \tikzfig, but in a {center} environment 36 | \newcommand{\ctikzfig}[1]{% 37 | \begin{center}\rm 38 | \tikzfig{#1} 39 | \end{center}} 40 | 41 | % fix strange self-loops, which are PGF/TikZ default 42 | \tikzstyle{every loop}=[] 43 | -------------------------------------------------------------------------------- /doc/gnuplot_data.dat: -------------------------------------------------------------------------------- 1 | # X Y 2 | 0.0 0.0 3 | 0.1 0.010000000000000002 4 | 0.2 0.04000000000000001 5 | 0.3 0.09 6 | 0.4 0.16000000000000003 7 | 0.5 0.25 8 | 0.6 0.36 9 | 0.7 0.48999999999999994 10 | 0.8 0.6400000000000001 11 | 0.9 0.81 12 | 1.0 1.0 13 | 1.1 1.2100000000000002 14 | 1.2 1.44 15 | 1.3 1.6900000000000002 16 | 1.4 1.9599999999999997 17 | 1.5 2.25 18 | 1.6 2.5600000000000005 19 | 1.7 2.8899999999999997 20 | 1.8 3.24 21 | 1.9 3.61 22 | 2.0 4.0 23 | 2.1 4.41 24 | 2.2 4.840000000000001 25 | 2.3 5.289999999999999 26 | 2.4 5.76 27 | 2.5 6.25 28 | 2.6 6.760000000000001 29 | 2.7 7.290000000000001 30 | 2.8 7.839999999999999 31 | 2.9 8.41 32 | 3.0 9.0 33 | 3.1 9.610000000000001 34 | 3.2 10.240000000000002 35 | 3.3 10.889999999999999 36 | 3.4 11.559999999999999 37 | 3.5 12.25 38 | 3.6 12.96 39 | 3.7 13.690000000000001 40 | 3.8 14.44 41 | 3.9 15.209999999999999 42 | 4.0 16.0 43 | 4.1 15.209999999999999 44 | 4.2 14.44 45 | 4.3 13.690000000000001 46 | 4.4 12.96 47 | 4.5 12.25 48 | 4.6 11.559999999999999 49 | 4.7 10.889999999999999 50 | 4.8 10.240000000000002 51 | 4.9 9.610000000000001 52 | 5.0 9.0 53 | 5.1 8.41 54 | 5.2 7.839999999999999 55 | 5.3 7.290000000000001 56 | 5.4 6.760000000000001 57 | 5.5 6.25 58 | 5.6 5.76 59 | 5.7 5.289999999999999 60 | 5.8 4.840000000000001 61 | 5.9 4.41 62 | 6.0 4.0 63 | 6.1 3.61 64 | 6.2 3.24 65 | 6.3 2.8899999999999997 66 | 6.4 2.5600000000000005 67 | 6.5 2.25 68 | 6.6 1.9599999999999997 69 | 6.7 1.6900000000000002 70 | 6.8 1.44 71 | 6.9 1.2100000000000002 72 | 7.0 1.0 73 | 7.1 0.81 74 | 7.2 0.6400000000000001 75 | 7.3 0.48999999999999994 76 | 7.4 0.36 77 | 7.5 0.25 78 | 7.6 0.16000000000000003 79 | 7.7 0.09 80 | 7.8 0.04000000000000001 81 | 7.9 0.010000000000000002 82 | -------------------------------------------------------------------------------- /doc/02-quickstart-pure.tex: -------------------------------------------------------------------------------- 1 | % Recommended (pure but recompiles only needed blocks), but slightly more complex 2 | % (requires v4.0 or above) 3 | \documentclass{article} 4 | 5 | \usepackage{tikz} 6 | \usepackage{robust-externalize} 7 | % Updates \graphicspath in compiled files to look for images in the root folder 8 | % (require v4.0 or above): 9 | \robExtConfigure{latex support pictures} 10 | 11 | % You can combine this with the too pure/impure workflows to include code in all images 12 | % or use the following code to execute code only in cached content but not in current document: 13 | % \robExtConfigure{add to preset={latex}{add to preamble={code to load only in cached pictures}}}. 14 | 15 | % Add "AutoForward" to all self-contained macro definitions that may be used in cached content 16 | % The definition will automatically be copied when compiling the picture, and when this macro 17 | % changes only pictures using them will be recompiled 18 | % (can be further customized to automatically load packages etc, see the documentation) 19 | \NewDocumentCommandAutoForward{\mySelfcontainedMacro}{m}{``#1''} 20 | 21 | % When macros are not self-contained, it is simpler to include all the block that defines them: 22 | % This is the list of macros that will trigger inclusion of this code --V 23 | \begin{CacheMeCode}{latex pure workflow={\myname,\myfullname,\myfirstname}{myenv}} 24 | \def\myfirstname{Alice} 25 | \def\mysecondname{Bob} 26 | \def\myname{\myfirstname{} \mysecondname{}} 27 | \NewDocumentEnvironment{myenv}{}{My env involving \myname{}}{} 28 | \end{CacheMeCode} 29 | 30 | \begin{document} 31 | 32 | You can use the macro \mySelfcontainedMacro{\myname{}} in the main document or in cached pictures, 33 | and only pictures containing them will be recompiled when you change their definition: 34 | 35 | % Note the C -----+ to mean that we should cache this picture. 36 | % | See \cacheTikz + \cacheCommand to automatically cache all tikz pictures 37 | % V 38 | \begin{tikzpictureC} 39 | \node[draw,rounded corners,fill=yellow,align=left,text width=7cm]{\mySelfcontainedMacro{\myname{}}}; 40 | \end{tikzpictureC} 41 | 42 | \end{document} 43 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ctan_package: doc/robust-externalize.pdf doc/robust-externalize.tex robust-externalize.sty README.md 2 | rm -rf build_ctan 3 | mkdir -p build_ctan/robust-externalize 4 | cp $^ build_ctan/robust-externalize/ 5 | # On CTAN the file won't be in doc: 6 | sed -i 's#`doc/#`#g' build_ctan/robust-externalize/README.md 7 | sed -i 's#\\input{../robust-externalize.sty}#\\usepackage{robust-externalize}#g' build_ctan/robust-externalize/robust-externalize.tex 8 | cd build_ctan && zip robust-externalize.zip -r robust-externalize && mv robust-externalize.zip .. 9 | 10 | doc/robust-externalize.pdf: doc/robust-externalize.tex 11 | cd doc && latexmk robust-externalize 12 | 13 | arxiv: doc/robust-externalize.tex doc/gnuplot-lua-tikz-common.tex robust-externalize.sty doc/gnuplot-lua-tikz.sty doc/gnuplot-lua-tikz.tex doc/zx-calculus.sty doc/tikzlibraryzx-calculus.code.tex doc/common_inputs.tex doc/gnuplot_data.dat doc/robust-externalize-robExt-all-figures.txt doc/mylib.py doc/ltxdoc.cls doc/robExt-prepare-for-arxiv.py 14 | rm -rf build_ctan 15 | mkdir -p build_ctan/robust-externalize/create-latest-cache 16 | cp -r $^ doc/robustExternalize/ build_ctan/robust-externalize/create-latest-cache 17 | # On arXiv the file won't be in doc: 18 | sed -i 's#%\pdfoutput=1#\pdfoutput=1#g' build_ctan/robust-externalize/create-latest-cache/robust-externalize.tex 19 | sed -i 's#\\input{../robust-externalize.sty}#\\usepackage{robust-externalize}#g' build_ctan/robust-externalize/create-latest-cache/robust-externalize.tex 20 | # the "recompile" option needs shell-escape, so we disable it on arxiv by printing only the source code and not the 21 | # result 22 | sed -i 's#%TURN_INTO_CODE_ONLY_ARXIV#code only#g' build_ctan/robust-externalize/create-latest-cache/robust-externalize.tex 23 | # cd build_ctan/robust-externalize/create-latest-cache && (yes | python robExt-remove-old-figures.py) 24 | # As a consequence, the page number might change, and some cached picture might be invalid now, so we compile this version locally once. But before we backup this folder: 25 | cp -r build_ctan/robust-externalize/create-latest-cache build_ctan/robust-externalize/final-version 26 | cd build_ctan/robust-externalize/create-latest-cache && latexmk -shell-escape robust-externalize.tex 27 | # cp build_ctan/robust-externalize/create-latest-cache/robust-externalize-robExt-all-figures.txt build_ctan/robust-externalize/final-version/robust-externalize-robExt-all-figures.txt 28 | cp build_ctan/robust-externalize/create-latest-cache/robustExternalize/* build_ctan/robust-externalize/final-version/robustExternalize/ 29 | cd build_ctan/robust-externalize/final-version/ && python robExt-prepare-for-arxiv.py 30 | # cp build_ctan/robust-externalize/create-latest-cache/robExt-remove-old-figures.py build_ctan/robust-externalize/final-version/robExt-remove-old-figures.py 31 | # ArXiv will remove the .pdf if there is a .tex file. So we need to remove it manually or using backup source for arxiv. 32 | # cd build_ctan/robust-externalize/final-version && xargs -I "{}" mv "robustExternalize/{}" "robustExternalize/{}-backup" < robust-externalize-robExt-all-figures.txt 33 | cd build_ctan/robust-externalize/final-version && zip robust-externalize-arxiv.zip -r * && mv robust-externalize-arxiv.zip ../../.. 34 | 35 | -------------------------------------------------------------------------------- /doc/new_zxstyle.tikzstyles: -------------------------------------------------------------------------------- 1 | % TiKZ style file generated by TikZiT. You may edit this file manually, 2 | % but some things (e.g. comments) may be overwritten. To be readable in 3 | % TikZiT, the only non-comment lines must be of the form: 4 | % \tikzstyle{NAME}=[PROPERTY LIST] 5 | 6 | % Node styles 7 | \tikzstyle{small_text}=[font={\footnotesize\boldmath}, draw=none, fill=none, minimum size=.3cm, inner sep=0, tikzit fill={rgb,255: red,141; green,136; blue,137}] 8 | \tikzstyle{Z dot}=[minimum size=3mm, font={\footnotesize\boldmath}, shape=rectangle, rounded corners=1.3mm, inner sep=1mm, outer sep=-1.8mm, scale=0.8, tikzit shape=circle, draw=black, fill={rgb,255: red,204; green,255; blue,204}] 9 | \tikzstyle{X dot}=[minimum size=3mm, font={\footnotesize\boldmath}, shape=rectangle, rounded corners=1.3mm, inner sep=1mm, outer sep=-1.8mm, scale=0.8, tikzit shape=circle, draw=black, fill={rgb,255: red,255; green,136; blue,136}] 10 | \tikzstyle{wn}=[minimum size=3mm, font={\footnotesize\boldmath}, shape=rectangle, rounded corners=1.3mm, inner sep=1mm, outer sep=-1.8mm, scale=0.8, tikzit shape=circle, draw=black, fill=white, tikzit draw=black] 11 | \tikzstyle{black}=[fill=black, draw=black, shape=circle, tikzit fill=black, tikzit draw=black, tikzit shape=circle, tikzit category=IH, inner sep=2pt] 12 | \tikzstyle{white}=[fill=white, draw=black, shape=circle, inner sep=2pt, tikzit category=IH] 13 | \tikzstyle{mbox}=[fill=white, draw=black, rounded rectangle, rounded rectangle west arc=none, tikzit category=scal, tikzit shape=rectangle, minimum size=3mm, font={\footnotesize\boldmath}] 14 | \tikzstyle{boxm}=[fill=white, draw=black, rounded rectangle, tikzit category=scal, tikzit shape=rectangle, rounded rectangle east arc=none] 15 | \tikzstyle{box}=[fill=white, draw=black, shape=rectangle] 16 | \tikzstyle{hadamard}=[fill=yellow, draw=black, shape=rectangle, tikzit category=ZX, tikzit fill=yellow, tikzit draw=black, inner sep=2pt, font={\footnotesize\boldmath}] 17 | \tikzstyle{rmat}=[draw, signal, fill={zx_grey}, signal to=east, signal from=west, inner sep=1pt, minimum height=6pt, font={\footnotesize\boldmath}] 18 | \tikzstyle{lmat}=[draw, signal, fill={zx_grey}, signal to=west, signal from=east, inner sep=1pt, minimum height=6pt, font={\footnotesize\boldmath}] 19 | \tikzstyle{umat}=[draw, signal, fill={zx_grey}, signal to=north, signal from=south, inner sep=1pt, minimum width=6pt, font={\footnotesize\boldmath}] 20 | \tikzstyle{dmat}=[draw, signal, fill={zx_grey}, signal to=south, signal from=north, inner sep=1pt, minimum width=6pt, font={\footnotesize\boldmath}] 21 | \tikzstyle{box fixed}=[shape=rectangle, text height=1.5ex, text depth=0.25ex, yshift=0.5mm, fill=white, draw=black, minimum height=5mm, yshift=-0.5mm, minimum width=5mm, font={\small}] 22 | \tikzstyle{smallbox}=[fill=white, draw=black, shape=rectangle] 23 | \tikzstyle{smallbox black}=[fill=black, draw=black, shape=rectangle] 24 | \tikzstyle{medium box}=[fill=white, draw=black, shape=rectangle, minimum height=.75cm, minimum width=1cm] 25 | 26 | % Edge styles 27 | \tikzstyle{arrow}=[->] 28 | \tikzstyle{very thick}=[-, line width=1pt, tikzit draw=red] 29 | \tikzstyle{black_dashed}=[dashed, -] 30 | \tikzstyle{red}=[-, draw=red] 31 | \tikzstyle{blue}=[-, draw=blue] 32 | \tikzstyle{green}=[-, draw=green] 33 | \tikzstyle{arrow}=[->] 34 | \tikzstyle{strike}=[-, tikzit draw={rgb,255: red,191; green,0; blue,64}, strike through] 35 | \tikzstyle{strike'}=[-, tikzit draw=cyan, strike bend] 36 | \tikzstyle{grey_dashed}=[-, draw={rgb,255: red,124; green,124; blue,124}, dashed] 37 | -------------------------------------------------------------------------------- /doc/styles/new_zxstyle.tikzstyles: -------------------------------------------------------------------------------- 1 | % TiKZ style file generated by TikZiT. You may edit this file manually, 2 | % but some things (e.g. comments) may be overwritten. To be readable in 3 | % TikZiT, the only non-comment lines must be of the form: 4 | % \tikzstyle{NAME}=[PROPERTY LIST] 5 | 6 | % Node styles 7 | \tikzstyle{small_text}=[font={\footnotesize\boldmath}, draw=none, fill=none, minimum size=.3cm, inner sep=0, tikzit fill={rgb,255: red,141; green,136; blue,137}] 8 | \tikzstyle{Z dot}=[minimum size=3mm, font={\footnotesize\boldmath}, shape=rectangle, rounded corners=1.3mm, inner sep=1mm, outer sep=-1.8mm, scale=0.8, tikzit shape=circle, draw=black, fill={rgb,255: red,204; green,255; blue,204}] 9 | \tikzstyle{X dot}=[minimum size=3mm, font={\footnotesize\boldmath}, shape=rectangle, rounded corners=1.3mm, inner sep=1mm, outer sep=-1.8mm, scale=0.8, tikzit shape=circle, draw=black, fill={rgb,255: red,255; green,136; blue,136}] 10 | \tikzstyle{wn}=[minimum size=3mm, font={\footnotesize\boldmath}, shape=rectangle, rounded corners=1.3mm, inner sep=1mm, outer sep=-1.8mm, scale=0.8, tikzit shape=circle, draw=black, fill=white, tikzit draw=black] 11 | \tikzstyle{black}=[fill=black, draw=black, shape=circle, tikzit fill=black, tikzit draw=black, tikzit shape=circle, tikzit category=IH, inner sep=2pt] 12 | \tikzstyle{white}=[fill=white, draw=black, shape=circle, inner sep=2pt, tikzit category=IH] 13 | \tikzstyle{mbox}=[fill=white, draw=black, rounded rectangle, rounded rectangle west arc=none, tikzit category=scal, tikzit shape=rectangle, minimum size=3mm, font={\footnotesize\boldmath}] 14 | \tikzstyle{boxm}=[fill=white, draw=black, rounded rectangle, tikzit category=scal, tikzit shape=rectangle, rounded rectangle east arc=none] 15 | \tikzstyle{box}=[fill=white, draw=black, shape=rectangle] 16 | \tikzstyle{hadamard}=[fill=yellow, draw=black, shape=rectangle, tikzit category=ZX, tikzit fill=yellow, tikzit draw=black, inner sep=2pt, font={\footnotesize\boldmath}] 17 | \tikzstyle{rmat}=[draw, signal, fill={zx_grey}, signal to=east, signal from=west, inner sep=1pt, minimum height=6pt, font={\footnotesize\boldmath}] 18 | \tikzstyle{lmat}=[draw, signal, fill={zx_grey}, signal to=west, signal from=east, inner sep=1pt, minimum height=6pt, font={\footnotesize\boldmath}] 19 | \tikzstyle{umat}=[draw, signal, fill={zx_grey}, signal to=north, signal from=south, inner sep=1pt, minimum width=6pt, font={\footnotesize\boldmath}] 20 | \tikzstyle{dmat}=[draw, signal, fill={zx_grey}, signal to=south, signal from=north, inner sep=1pt, minimum width=6pt, font={\footnotesize\boldmath}] 21 | \tikzstyle{box fixed}=[shape=rectangle, text height=1.5ex, text depth=0.25ex, yshift=0.5mm, fill=white, draw=black, minimum height=5mm, yshift=-0.5mm, minimum width=5mm, font={\small}] 22 | \tikzstyle{smallbox}=[fill=white, draw=black, shape=rectangle] 23 | \tikzstyle{smallbox black}=[fill=black, draw=black, shape=rectangle] 24 | \tikzstyle{medium box}=[fill=white, draw=black, shape=rectangle, minimum height=.75cm, minimum width=1cm] 25 | 26 | % Edge styles 27 | \tikzstyle{arrow}=[->] 28 | \tikzstyle{very thick}=[-, line width=1pt, tikzit draw=red] 29 | \tikzstyle{black_dashed}=[dashed, -] 30 | \tikzstyle{red}=[-, draw=red] 31 | \tikzstyle{blue}=[-, draw=blue] 32 | \tikzstyle{green}=[-, draw=green] 33 | \tikzstyle{arrow}=[->] 34 | \tikzstyle{strike}=[-, tikzit draw={rgb,255: red,191; green,0; blue,64}, strike through] 35 | \tikzstyle{strike'}=[-, tikzit draw=cyan, strike bend] 36 | \tikzstyle{grey_dashed}=[-, draw={rgb,255: red,124; green,124; blue,124}, dashed] 37 | -------------------------------------------------------------------------------- /doc/ltxdoc.cls: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `ltxdoc.cls', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% ltxdoc.dtx (with options: `class') 8 | %% 9 | %% This is a generated file. 10 | %% 11 | %% The source is maintained by the LaTeX Project team and bug 12 | %% reports for it can be opened at https://latex-project.org/bugs.html 13 | %% (but please observe conditions on bug reports sent to that address!) 14 | %% 15 | %% 16 | %% Copyright (C) 1993-2022 17 | %% The LaTeX Project and any individual authors listed elsewhere 18 | %% in this file. 19 | %% 20 | %% This file was generated from file(s) of the LaTeX base system. 21 | %% -------------------------------------------------------------- 22 | %% 23 | %% It may be distributed and/or modified under the 24 | %% conditions of the LaTeX Project Public License, either version 1.3c 25 | %% of this license or (at your option) any later version. 26 | %% The latest version of this license is in 27 | %% https://www.latex-project.org/lppl.txt 28 | %% and version 1.3c or later is part of all distributions of LaTeX 29 | %% version 2008 or later. 30 | %% 31 | %% This file has the LPPL maintenance status "maintained". 32 | %% 33 | %% This file may only be distributed together with a copy of the LaTeX 34 | %% base system. You may however distribute the LaTeX base system without 35 | %% such generated files. 36 | %% 37 | %% The list of all files belonging to the LaTeX base distribution is 38 | %% given in the file `manifest.txt'. See also `legal.txt' for additional 39 | %% information. 40 | %% 41 | %% The list of derived (unpacked) files belonging to the distribution 42 | %% and covered by LPPL is defined by the unpacking scripts (with 43 | %% extension .ins) which are part of the distribution. 44 | \NeedsTeXFormat{LaTeX2e} 45 | \ProvidesClass{ltxdoc} 46 | [2022/06/22 v2.1i Standard LaTeX documentation class] 47 | \DeclareOption{a5paper}{\@latexerr{Option not supported}% 48 | {}} 49 | \newif\ifltxdoc@load@cfg@ \ltxdoc@load@cfg@true 50 | \DeclareOption{nocfg}{\ltxdoc@load@cfg@false} 51 | \let\ltxdoc@doc@version\@empty % use current version by default 52 | \DeclareOption{doc2}{\def\ltxdoc@doc@version{=v2}} 53 | \DeclareOption*{% 54 | \PassOptionsToClass {\CurrentOption}{article}} 55 | \ProcessOptions 56 | \ifltxdoc@load@cfg@ 57 | \InputIfFileExists{ltxdoc.cfg} 58 | {\typeout{*************************************^^J% 59 | * Local config file ltxdoc.cfg used^^J% 60 | *************************************}} 61 | {} 62 | \else 63 | \typeout{*************************************^^J% 64 | * Local config file ignored^^J% 65 | *************************************} 66 | \fi 67 | \LoadClass{article} 68 | \RequirePackage{doc}[\ltxdoc@doc@version] 69 | \AtBeginDocument{\MakeShortVerb{\|}} 70 | \DeclareFontShape{OT1}{cmtt}{bx}{n}{<-> ssub * cmtt/m/n}{} 71 | \DeclareFontFamily{OMS}{cmtt}{\skewchar\font 48} % '60 72 | \DeclareFontShape{OMS}{cmtt}{m}{n}{<-> ssub * cmsy/m/n}{} 73 | \DeclareFontShape{OMS}{cmtt}{bx}{n}{<-> ssub * cmsy/b/n}{} 74 | \DeclareFontShape{OT1}{cmss}{m}{it}{<->ssub*cmss/m/sl}{} 75 | \CodelineNumbered 76 | \DisableCrossrefs 77 | \setlength{\textwidth}{355pt} 78 | \addtolength\marginparwidth{30pt} 79 | \addtolength\oddsidemargin{20pt} 80 | \addtolength\evensidemargin{20pt} 81 | \setcounter{StandardModuleDepth}{1} 82 | \def\cmd#1{\texttt{\char`\\\expandafter\cmd@to@cs\string#1}} 83 | \def\cmd@to@cs#1#2{\char\number`#2\relax} 84 | \providecommand\marg[1]{% 85 | {\ttfamily\char`\{}\meta{#1}{\ttfamily\char`\}}} 86 | \providecommand\oarg[1]{% 87 | {\ttfamily[}\meta{#1}{\ttfamily]}} 88 | \providecommand\parg[1]{% 89 | {\ttfamily(}\meta{#1}{\ttfamily)}} 90 | \def\oc@scan#1{% 91 | \ifx\oc@bslash#1% 92 | \egroup\let\next\oc@bslash\else 93 | \ifcat a\noexpand#1% 94 | #1\let\next\oc@scan\else 95 | \ifx\oc@percent#1% 96 | \def\next{\char`\%\egroup}% 97 | \else 98 | #1\let\next\egroup 99 | \fi\fi\fi\next} 100 | \def\oc@bslash{\bgroup\oc@ttf\char`\\\oc@scan}% 101 | \def\oc@verb#1{% 102 | \catcode`#1\active 103 | \uccode`\~`#1% 104 | \uppercase{\def~{{\oc@ttf\char`#1}}}} 105 | \begingroup 106 | \obeyspaces% 107 | \catcode`\/=\catcode`\\ 108 | /catcode`/\/active 109 | /catcode`<=/catcode`{% 110 | /catcode`>=/catcode`}% 111 | /catcode`/{/active% 112 | /catcode`/}/active% 113 | /gdef/oldc< \end{oldcomments}>% 114 | /gdef/begmac< \begin{macrocode}>% 115 | /gdef/obs>>% 116 | /endgroup% 117 | \begingroup 118 | \catcode`\/=\catcode`\\ 119 | \catcode`\\=13 120 | /catcode`/|=/catcode`/% 121 | /catcode`/%=13 122 | /gdef/oldcomments{| 123 | /makeatletter 124 | /let/do/oc@verb/dospecials 125 | /frenchspacing/@vobeyspaces/obs 126 | /raggedright 127 | /oc@verb/>| 128 | /oc@verb/<| 129 | /let\/oc@bslash 130 | /let%/oc@percent 131 | /obeylines 132 | /parindent/z@ 133 | /ttfamily/expandafter/let/expandafter/oc@ttf/the/font 134 | /rmfamily 135 | /textit{Historical /LaTeX/,2.09 comments (not necessarily accurate any more):} 136 | /hfuzz/maxdimen 137 | } 138 | /endgroup 139 | \begingroup 140 | \sloppy% 141 | \obeylines% 142 | \gdef\oc@percent#1^^M{% 143 | \ifvmode% 144 | \def\commentline{#1}% 145 | \ifx\commentline\oldc% 146 | \textit{End of historical \LaTeX\,2.09 comments.} 147 | \end{oldcomments}% 148 | \else% 149 | \ifx\commentline\begmac% 150 | \begin{macrocode}% 151 | \else% 152 | \leavevmode% 153 | #1^^M% 154 | \fi\fi% 155 | \else% 156 | {\oc@ttf\char`\%}#1^^M% 157 | \fi}% 158 | \endgroup% 159 | \@addtoreset{CodelineNo}{part} 160 | \def\partname{File} 161 | \newcommand*{\DocInclude}[1]{% 162 | \relax 163 | \clearpage 164 | \docincludeaux 165 | \IfFileExists{#1.fdd}% 166 | {\def\currentfile{#1.fdd}}% 167 | {\def\currentfile{#1.dtx}}% 168 | \ifnum\@auxout=\@partaux 169 | \@latexerr{\string\include\space cannot be nested}\@eha 170 | \else 171 | \set@curr@file{#1}% 172 | \edef\@curr@file{\@strip@tex@ext\@curr@file}% 173 | \expandafter\@docinclude\expandafter{\@curr@file} 174 | \fi} 175 | \def\@docinclude#1 {\clearpage 176 | \if@filesw \immediate\write\@mainaux{\string\@input{#1.aux}}\fi 177 | \@tempswatrue\if@partsw \@tempswafalse\edef\@tempb{#1}\@for 178 | \@tempa:=\@partlist\do{\ifx\@tempa\@tempb\@tempswatrue\fi}\fi 179 | \if@tempswa \let\@auxout\@partaux \if@filesw 180 | \immediate\openout\@partaux "#1.aux" 181 | \immediate\write\@partaux{\relax}\fi 182 | \@filehook@set@CurrentFile 183 | \let\@ltxdoc@PrintIndex\PrintIndex 184 | \let\PrintIndex\relax 185 | \let\@ltxdoc@PrintChanges\PrintChanges 186 | \let\PrintChanges\relax 187 | \let\@ltxdoc@theglossary\theglossary 188 | \let\@ltxdoc@endtheglossary\endtheglossary 189 | \part{\currentfile}% 190 | {\let\ttfamily\relax 191 | \xdef\filekey{\filekey, \thepart={\ttfamily\currentfile}}}% 192 | \DocInput{\currentfile}% 193 | \let\PrintIndex\@ltxdoc@PrintIndex 194 | \let\PrintChanges\@ltxdoc@PrintChanges 195 | \let\theglossary\@ltxdoc@theglossary 196 | \let\endtheglossary\@ltxdoc@endtheglossary 197 | \clearpage 198 | \@writeckpt{#1}\if@filesw \immediate\closeout\@partaux \fi 199 | \else\@nameuse{cp@#1}\fi\let\@auxout\@mainaux} 200 | \gdef\codeline@wrindex#1{\if@filesw 201 | \begingroup 202 | \let\protect\noexpand 203 | \immediate\write\@indexfile 204 | {\string\indexentry{#1}% 205 | {\filesep\number\c@CodelineNo}}% 206 | \endgroup\fi} 207 | \let\filesep\@empty 208 | \def\aalph#1{\@aalph{\csname c@#1\endcsname}} 209 | \def\@aalph#1{% 210 | \ifcase#1\or a\or b\or c\or d\or e\or f\or g\or h\or i\or 211 | j\or k\or l\or m\or n\or o\or p\or q\or r\or s\or 212 | t\or u\or v\or w\or x\or y\or z\or A\or B\or C\or 213 | D\or E\or F\or G\or H\or I\or J\or K\or L\or M\or 214 | N\or O\or P\or Q\or R\or S\or T\or U\or V\or W\or 215 | X\or Y\or Z\else\@ctrerr\fi} 216 | \def\docincludeaux{% 217 | \def\thepart{\aalph{part}}\def\filesep{\thepart-}% 218 | \let\filekey\@gobble 219 | \g@addto@macro\index@prologue{% 220 | \gdef\@oddfoot{\parbox[t]{\textwidth}{\strut\footnotesize 221 | \raggedright{\bfseries File Key:} \filekey}}% 222 | \let\@evenfoot\@oddfoot}% 223 | \global\let\docincludeaux\relax 224 | \gdef\@oddfoot{% 225 | \expandafter\ifx\csname ver@\currentfile\endcsname\relax 226 | File \thepart: {\ttfamily\currentfile} % 227 | \else 228 | \GetFileInfo{\currentfile}% 229 | File \thepart: {\ttfamily\filename} % 230 | Date: \filedate\ % 231 | Version \fileversion 232 | \fi 233 | \hfill\thepage}% 234 | \let\@evenfoot\@oddfoot}% 235 | \def\MaintainedBy#1{\gdef\@maintainedby{#1}} 236 | \let\@maintainedby\@empty 237 | \def\MaintainedByLaTeXTeam#1{% 238 | {\gdef\@maintainedby{% 239 | This file is maintained by the \LaTeX{} Project team.\\% 240 | Bug reports can be opened (category \texttt{#1}) at\\% 241 | \url{https://latex-project.org/bugs.html}.}}} 242 | \def\@maketitle{% 243 | \newpage 244 | \null 245 | \vskip 2em% 246 | \begin{center}% 247 | \let \footnote \thanks 248 | {\LARGE \@title \par}% 249 | \vskip 1.5em% 250 | {\large 251 | \lineskip .5em% 252 | \begin{tabular}[t]{c}% 253 | \@author 254 | \end{tabular}\par}% 255 | \vskip 1em% 256 | {\large \@date}% 257 | \ifx\@maintainedby\@empty 258 | \else 259 | \vskip 1em% 260 | \fbox{\fbox{\begin{tabular}{@{}l@{}}\@maintainedby\end{tabular}}}% 261 | \fi 262 | \end{center}% 263 | \par 264 | \vskip 1.5em} 265 | \def\task#1#2{} 266 | \AtBeginDocument{% 267 | \providecommand\LuaTeX{Lua\TeX} 268 | \providecommand\cls{\textsf} 269 | \providecommand\pkg{\textsf} 270 | \providecommand\enquote[1]{``#1''} 271 | \providecommand\url{\texttt} 272 | } 273 | \endinput 274 | %% 275 | %% End of file `ltxdoc.cls'. 276 | -------------------------------------------------------------------------------- /doc/gnuplot-lua-tikz-common.tex: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | %% 3 | %% Common style file for TeX, LaTeX and ConTeXt 4 | %% 5 | %% It is associated with the 'gnuplot.lua' script, and usually generated 6 | %% automatically. So take care whenever you make any changes! 7 | %% 8 | 9 | % check for the correct TikZ version 10 | \def\gpchecktikzversion#1.#2\relax{% 11 | \ifnum#1<2% 12 | \errmessage{PGF/TikZ version >= 2.0 is required!}% 13 | \fi} 14 | \expandafter\gpchecktikzversion\pgfversion\relax 15 | 16 | \def\gnuplot@output@ps{ps} % required for comparison in \gprawimage 17 | 18 | \expandafter\def\csname gnuplot@select@driver@pgfsys-dvi.def\endcsname {ps} 19 | \expandafter\def\csname gnuplot@select@driver@pgfsys-dvipdfm.def\endcsname {pdf} 20 | \expandafter\def\csname gnuplot@select@driver@pgfsys-dvipdfmx.def\endcsname{pdf} 21 | \expandafter\def\csname gnuplot@select@driver@pgfsys-dvips.def\endcsname {ps} 22 | \expandafter\def\csname gnuplot@select@driver@pgfsys-pdftex.def\endcsname {pdf} 23 | \expandafter\def\csname gnuplot@select@driver@pgfsys-luatex.def\endcsname {pdf} 24 | \expandafter\def\csname gnuplot@select@driver@pgfsys-tex4ht.def\endcsname {html} 25 | \expandafter\def\csname gnuplot@select@driver@pgfsys-textures.def\endcsname{ps} 26 | \expandafter\def\csname gnuplot@select@driver@pgfsys-vtex.def\endcsname {ps} 27 | \expandafter\def\csname gnuplot@select@driver@pgfsys-xetex.def\endcsname {pdf} 28 | 29 | \ifcsname gnuplot@select@driver@\pgfsysdriver\endcsname 30 | \edef\gnuplot@output@mode{\csname gnuplot@select@driver@\pgfsysdriver\endcsname} 31 | \else 32 | \errmessage{The driver \pgfsysdriver\space is not supported by gnuplot-lua-tikz}% 33 | \fi 34 | 35 | \ifcsname PackageWarning\endcsname 36 | \let\gnuplot@packagewarning\PackageWarning 37 | \else 38 | \def\gnuplot@packagewarning#1#2{\immediate\write-1{Package #1 Warning: #2}} 39 | \fi 40 | 41 | % uncomment the following lines to make font values "appendable" 42 | % and if you are really sure about that ;-) 43 | % \pgfkeyslet{/tikz/font/.@cmd}{\undefined} 44 | % \tikzset{font/.initial={}} 45 | % \def\tikz@textfont{\pgfkeysvalueof{/tikz/font}} 46 | 47 | % 48 | % image related stuff 49 | % 50 | \def\gp@rawimage@pdf#1#2#3#4#5#6{% 51 | \def\gp@tempa{cmyk}% 52 | \def\gp@tempb{#1}% 53 | \ifx\gp@tempa\gp@tempb% 54 | \def\gp@temp{/CMYK}% 55 | \else% 56 | \def\gp@temp{/RGB}% 57 | \fi% 58 | \pgf@sys@bp{#4}\pgfsysprotocol@literalbuffered{0 0}\pgf@sys@bp{#5}% 59 | \pgfsysprotocol@literalbuffered{0 0 cm}% 60 | \pgfsysprotocol@literalbuffered{BI /W #2 /H #3 /CS \gp@temp}% 61 | \pgfsysprotocol@literalbuffered{/BPC 8 /F /AHx ID}% 62 | \pgfsysprotocol@literal{#6 > EI}% 63 | } 64 | \def\gp@rawimage@ps#1#2#3#4#5#6{% 65 | \def\gp@tempa{cmyk}% 66 | \def\gp@tempb{#1}% 67 | \ifx\gp@tempa\gp@tempb% 68 | \def\gp@temp{4}% 69 | \else% 70 | \def\gp@temp{3}% 71 | \fi% 72 | \pgfsysprotocol@literalbuffered{0 0 translate}% 73 | \pgf@sys@bp{#4}\pgf@sys@bp{#5}\pgfsysprotocol@literalbuffered{scale}% 74 | \pgfsysprotocol@literalbuffered{#2 #3 8 [#2 0 0 -#3 0 #3]}% 75 | \pgfsysprotocol@literalbuffered{currentfile /ASCIIHexDecode filter}% 76 | \pgfsysprotocol@literalbuffered{false \gp@temp\space colorimage}% 77 | \pgfsysprotocol@literal{#6 >}% 78 | } 79 | \def\gp@rawimage@html#1#2#3#4#5#6{% 80 | \gnuplot@packagewarning{gnuplot-lua-tikz}{% 81 | \noexpand\gp@rawimage is not implemented for \gnuplot@output@mode\space output.% 82 | }% 83 | } 84 | 85 | % Select \gp@rawimage depending on the output mode 86 | \expandafter\let\expandafter\gp@rawimage\csname gp@rawimage@\gnuplot@output@mode\endcsname 87 | 88 | \def\gploadimage#1#2#3#4#5{% 89 | \pgftext[left,bottom,x=#1cm,y=#2cm] {\pgfimage[interpolate=false,width=#3cm,height=#4cm]{#5}};% 90 | } 91 | 92 | \def\gp@set@size#1{% 93 | \def\gp@image@size{#1}% 94 | } 95 | 96 | \def\gp@rawimage@#1#2#3#4#5#6#7#8{% 97 | \tikz@scan@one@point\gp@set@size(#6,#7)\relax% 98 | \tikz@scan@one@point\pgftransformshift(#2,#3)\relax% 99 | \pgftext{% 100 | \pgfsys@beginpurepicture% 101 | \gp@image@size% fill \pgf@x and \pgf@y 102 | \gp@rawimage{#1}{#4}{#5}{\pgf@x}{\pgf@y}{#8}% 103 | \pgfsys@endpurepicture% 104 | }% 105 | } 106 | 107 | %% \gprawimage{color model}{xcoord}{ycoord}{# of xpixel}{# of ypixel}{xsize}{ysize}{rgb/cmyk hex data RRGGBB/CCMMYYKK ...}{file name} 108 | %% color model is 'cmyk' or 'rgb' (default) 109 | \def\gprawimage#1#2#3#4#5#6#7#8#9{% 110 | \ifx &% 111 | \gp@rawimage@{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}% 112 | \else 113 | \ifx\gnuplot@output@mode\gnuplot@output@ps 114 | \gp@rawimage@{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}% 115 | \else 116 | \gploadimage{#2}{#3}{#6}{#7}{#9}% 117 | \fi 118 | \fi 119 | } 120 | 121 | % 122 | % gnuplottex compatibility 123 | % (see http://www.ctan.org/tex-archive/help/Catalogue/entries/gnuplottex.html) 124 | % 125 | 126 | \def\gnuplottexextension@lua{\string tex} 127 | \def\gnuplottexextension@tikz{\string tex} 128 | 129 | % 130 | % gnuplot variables getter and setter 131 | % 132 | 133 | \def\gpsetvar#1#2{% 134 | \expandafter\xdef\csname gp@var@#1\endcsname{#2} 135 | } 136 | 137 | \def\gpgetvar#1{% 138 | \csname gp@var@#1\endcsname % 139 | } 140 | 141 | % 142 | % some wrapper code 143 | % 144 | 145 | % short for a filled path 146 | \def\gpfill#1{\path[line width=0.1\gpbaselw,draw,fill,#1]} 147 | 148 | % short for changing the line width 149 | \def\gpsetlinewidth#1{\pgfsetlinewidth{#1\gpbaselw}} 150 | 151 | % short for changing the line type 152 | \def\gpsetlinetype#1{\tikzset{gp path/.style={#1,#1 add}}} 153 | 154 | % short for changing the dash pattern 155 | \def\gpsetdashtype#1{\tikzset{gp path/.append style={#1}}} 156 | 157 | % short for changing the point size 158 | \def\gpsetpointsize#1{\tikzset{gp point/.style={mark size=#1\gpbasems}}} 159 | 160 | % wrapper for color settings 161 | \def\gpcolor#1{\tikzset{global #1}} 162 | \tikzset{rgb color/.code={\pgfutil@definecolor{.}{rgb}{#1}\tikzset{color=.}}} 163 | \tikzset{global rgb color/.code={\pgfutil@definecolor{.}{rgb}{#1}\pgfutil@color{.}}} 164 | \tikzset{global color/.code={\pgfutil@color{#1}}} 165 | 166 | % prevent plot mark distortions due to changes in the PGF transformation matrix 167 | % use `\gpscalepointstrue' and `\gpscalepointsfalse' for enabling and disabling 168 | % point scaling 169 | % 3-parameter variant gp3point passes style options as well as point type and coordinates 170 | % 171 | \newif\ifgpscalepoints 172 | \tikzset{gp shift only/.style={% 173 | \ifgpscalepoints\else shift only\fi% 174 | }} 175 | \def\gppoint#1#2{% 176 | \path[solid] plot[only marks,gp point,mark options={gp shift only},#1] coordinates {#2};% 177 | } 178 | \def\gp3point#1#2#3{% 179 | \path[solid#2] plot[only marks,gp point,mark options={gp shift only},#1] coordinates {#3};% 180 | } 181 | 182 | 183 | % 184 | % char size calculation, that might be used with gnuplottex 185 | % 186 | % Example code (needs gnuplottex.sty): 187 | % 188 | % % calculate the char size when the "gnuplot" style is used 189 | % \tikzset{gnuplot/.append style={execute at begin picture=\gpcalccharsize}} 190 | % 191 | % \tikzset{gnuplot/.append style={font=\ttfamily\footnotesize}} 192 | % 193 | % \begin{tikzpicture}[gnuplot] 194 | % \begin{gnuplot}[terminal=lua,% 195 | % terminaloptions={tikz solid nopic charsize \the\gphcharsize,\the\gpvcharsize}] 196 | % test 197 | % \end{gnuplot} 198 | % \end{tikzpicture} 199 | % 200 | %%% 201 | % The `\gpcalccharsize' command fills the lengths \gpvcharsize and \gphcharsize with 202 | % the values of the current default font used within nodes and is meant to be called 203 | % within a tikzpicture environment. 204 | % 205 | \newdimen\gpvcharsize 206 | \newdimen\gphcharsize 207 | \def\gpcalccharsize{% 208 | \pgfinterruptboundingbox% 209 | \pgfsys@begininvisible% 210 | \node at (0,0) {% 211 | \global\gphcharsize=1.05\fontcharwd\font`0% 212 | \global\gpvcharsize=1.05\fontcharht\font`0% 213 | \global\advance\gpvcharsize by 1.05\fontchardp\font`g% 214 | };% 215 | \pgfsys@endinvisible% 216 | \endpgfinterruptboundingbox% 217 | } 218 | 219 | % 220 | % define a rectangular node in tikz e.g. for the plot area 221 | % 222 | % #1 node name 223 | % #2 coordinate of "south west" 224 | % #3 coordinate of "north east" 225 | % 226 | \def\gpdefrectangularnode#1#2#3{% 227 | \expandafter\gdef\csname pgf@sh@ns@#1\endcsname{rectangle}% 228 | \expandafter\gdef\csname pgf@sh@np@#1\endcsname{% 229 | \def\southwest{#2}% 230 | \def\northeast{#3}% 231 | }% 232 | \pgfgettransform\pgf@temp% 233 | % once it is defined, no more transformations will be applied, I hope 234 | \expandafter\xdef\csname pgf@sh@nt@#1\endcsname{\pgf@temp}% 235 | \expandafter\xdef\csname pgf@sh@pi@#1\endcsname{\pgfpictureid}% 236 | } 237 | 238 | 239 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 240 | %% 241 | %% You may want to adapt the following to fit your needs (in your 242 | %% individual style file and/or within your document). 243 | %% 244 | 245 | % 246 | % style for every plot 247 | % 248 | \tikzset{gnuplot/.style={% 249 | >=stealth',% 250 | line cap=round,% 251 | line join=round,% 252 | }} 253 | 254 | \tikzset{gp node left/.style={anchor=mid west,yshift=-.12ex,line width=0pt}} 255 | \tikzset{gp node center/.style={anchor=mid,yshift=-.12ex,line width=0pt}} 256 | \tikzset{gp node right/.style={anchor=mid east,yshift=-.12ex,line width=0pt}} 257 | 258 | % basic plot mark size (points) 259 | \newdimen\gpbasems 260 | \gpbasems=.4pt 261 | 262 | % basic linewidth 263 | \newdimen\gpbaselw 264 | \gpbaselw=.4pt 265 | 266 | % this is the default color for pattern backgrounds 267 | \colorlet{gpbgfillcolor}{white} 268 | 269 | % set background color and fill color 270 | \def\gpsetbgcolor#1{% 271 | \pgfutil@definecolor{gpbgfillcolor}{rgb}{#1}% 272 | \tikzset{tight background,background rectangle/.style={fill=gpbgfillcolor},show background rectangle}% 273 | } 274 | 275 | % this should reverse the normal text node presets, for the 276 | % later referencing as described below 277 | \tikzset{gp refnode/.style={coordinate,yshift=.12ex}} 278 | 279 | % to add an empty label with the referenceable name "my node" 280 | % to the plot, just add the following line to your gnuplot 281 | % file: 282 | % 283 | % set label "" at 1,1 font ",gp refnode,name=my node" 284 | % 285 | 286 | % enlargement of the bounding box in standalone mode (only used by LaTeX/ConTeXt) 287 | \def\gpbboxborder{0mm} 288 | 289 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 290 | %% 291 | %% The following TikZ-styles are derived from the 'pgf.styles.*' tables 292 | %% in the Lua script. 293 | %% To change the number of used styles you should change them there and 294 | %% regenerate this style file. 295 | %% 296 | 297 | % arrow styles settings 298 | \tikzset{gp arrow 1/.style={>=latex}} 299 | \tikzset{gp arrow 2/.style={>=angle 90}} 300 | \tikzset{gp arrow 3/.style={>=angle 60}} 301 | \tikzset{gp arrow 4/.style={>=angle 45}} 302 | \tikzset{gp arrow 5/.style={>=o}} 303 | \tikzset{gp arrow 6/.style={>=*}} 304 | \tikzset{gp arrow 7/.style={>=diamond}} 305 | \tikzset{gp arrow 8/.style={>=open diamond}} 306 | \tikzset{gp arrow 9/.style={>={]}}} 307 | \tikzset{gp arrow 10/.style={>={[}}} 308 | \tikzset{gp arrow 11/.style={>=)}} 309 | \tikzset{gp arrow 12/.style={>=(}} 310 | 311 | % plotmark settings 312 | \tikzset{gp mark 0/.style={mark size=.5\pgflinewidth,mark=*}} 313 | \tikzset{gp mark 1/.style={mark=+}} 314 | \tikzset{gp mark 2/.style={mark=x}} 315 | \tikzset{gp mark 3/.style={mark=star}} 316 | \tikzset{gp mark 4/.style={mark=square}} 317 | \tikzset{gp mark 5/.style={mark=square*}} 318 | \tikzset{gp mark 6/.style={mark=o}} 319 | \tikzset{gp mark 7/.style={mark=*}} 320 | \tikzset{gp mark 8/.style={mark=triangle}} 321 | \tikzset{gp mark 9/.style={mark=triangle*}} 322 | \tikzset{gp mark 10/.style={mark=triangle,every mark/.append style={rotate=180}}} 323 | \tikzset{gp mark 11/.style={mark=triangle*,every mark/.append style={rotate=180}}} 324 | \tikzset{gp mark 12/.style={mark=diamond}} 325 | \tikzset{gp mark 13/.style={mark=diamond*}} 326 | \tikzset{gp mark 14/.style={mark=otimes}} 327 | \tikzset{gp mark 15/.style={mark=oplus}} 328 | 329 | % pattern settings 330 | \tikzset{gp pattern 0/.style={white}} 331 | \tikzset{gp pattern 1/.style={pattern=north east lines}} 332 | \tikzset{gp pattern 2/.style={pattern=north west lines}} 333 | \tikzset{gp pattern 3/.style={pattern=crosshatch}} 334 | \tikzset{gp pattern 4/.style={pattern=grid}} 335 | \tikzset{gp pattern 5/.style={pattern=vertical lines}} 336 | \tikzset{gp pattern 6/.style={pattern=horizontal lines}} 337 | \tikzset{gp pattern 7/.style={pattern=dots}} 338 | \tikzset{gp pattern 8/.style={pattern=crosshatch dots}} 339 | \tikzset{gp pattern 9/.style={pattern=fivepointed stars}} 340 | \tikzset{gp pattern 10/.style={pattern=sixpointed stars}} 341 | \tikzset{gp pattern 11/.style={pattern=bricks}} 342 | 343 | % if the 'tikzplot' option is used the corresponding lines will be smoothed by default 344 | \tikzset{gp plot axes/.style=} 345 | \tikzset{gp plot border/.style=} 346 | \tikzset{gp plot 0/.style=smooth} 347 | \tikzset{gp plot 1/.style=smooth} 348 | \tikzset{gp plot 2/.style=smooth} 349 | \tikzset{gp plot 3/.style=smooth} 350 | \tikzset{gp plot 4/.style=smooth} 351 | \tikzset{gp plot 5/.style=smooth} 352 | \tikzset{gp plot 6/.style=smooth} 353 | \tikzset{gp plot 7/.style=smooth} 354 | 355 | % linestyle settings 356 | \tikzset{gp lt axes/.style=dotted} 357 | \tikzset{gp lt border/.style=solid} 358 | 359 | % linestyle "addon" settings for overwriting a default linestyle within the 360 | % TeX document via eg. \tikzset{gp lt plot 1 add/.style={fill=black,draw=none}} etc. 361 | \tikzset{gp lt axes add/.style={}} 362 | \tikzset{gp lt border add/.style={}} 363 | \tikzset{gp lt plot 0 add/.style={}} 364 | \tikzset{gp lt plot 1 add/.style={}} 365 | \tikzset{gp lt plot 2 add/.style={}} 366 | \tikzset{gp lt plot 3 add/.style={}} 367 | \tikzset{gp lt plot 4 add/.style={}} 368 | \tikzset{gp lt plot 5 add/.style={}} 369 | \tikzset{gp lt plot 6 add/.style={}} 370 | \tikzset{gp lt plot 7 add/.style={}} 371 | \tikzset{gp lt plot 0/.style={}} 372 | \tikzset{gp lt plot 1/.style={}} 373 | \tikzset{gp lt plot 2/.style={}} 374 | \tikzset{gp lt plot 3/.style={}} 375 | \tikzset{gp lt plot 4/.style={}} 376 | \tikzset{gp lt plot 5/.style={}} 377 | \tikzset{gp lt plot 6/.style={}} 378 | \tikzset{gp lt plot 7/.style={}} 379 | 380 | % linestyle color settings 381 | \colorlet{gp lt color axes}{black!30} 382 | \colorlet{gp lt color border}{black} 383 | 384 | % dash type settings 385 | % Define this as a macro so that the dash patterns expand later with the current \pgflinewidth. 386 | \def\gpdashlength{\pgflinewidth} 387 | \tikzset{gp dt 0/.style={solid}} 388 | \tikzset{gp dt 1/.style={solid}} 389 | \tikzset{gp dt 2/.style={dash pattern=on 7.5*\gpdashlength off 7.5*\gpdashlength}} 390 | \tikzset{gp dt 3/.style={dash pattern=on 3.75*\gpdashlength off 5.625*\gpdashlength}} 391 | \tikzset{gp dt 4/.style={dash pattern=on 1*\gpdashlength off 2.8125*\gpdashlength}} 392 | \tikzset{gp dt 5/.style={dash pattern=on 11.25*\gpdashlength off 3.75*\gpdashlength on 1*\gpdashlength off 3.75*\gpdashlength}} 393 | \tikzset{gp dt 6/.style={dash pattern=on 5.625*\gpdashlength off 5.625*\gpdashlength on 1*\gpdashlength off 5.625*\gpdashlength}} 394 | \tikzset{gp dt 7/.style={dash pattern=on 3.75*\gpdashlength off 3.75*\gpdashlength on 3.75*\gpdashlength off 11.25*\gpdashlength}} 395 | \tikzset{gp dt 8/.style={dash pattern=on 1*\gpdashlength off 3.75*\gpdashlength on 11.25*\gpdashlength off 3.75*\gpdashlength on 1*\gpdashlength off 3.75*\gpdashlength}} 396 | \tikzset{gp dt solid/.style={solid}} 397 | \tikzset{gp dt axes/.style={dotted}} 398 | 399 | % command for switching to colored lines 400 | \def\gpcoloredlines{% 401 | \colorlet{gp lt color 0}{red}% 402 | \colorlet{gp lt color 1}{green}% 403 | \colorlet{gp lt color 2}{blue}% 404 | \colorlet{gp lt color 3}{magenta}% 405 | \colorlet{gp lt color 4}{cyan}% 406 | \colorlet{gp lt color 5}{yellow}% 407 | \colorlet{gp lt color 6}{orange}% 408 | \colorlet{gp lt color 7}{purple}% 409 | } 410 | 411 | % command for switching to monochrome (black) lines 412 | \def\gpmonochromelines{% 413 | \colorlet{gp lt color 0}{black}% 414 | \colorlet{gp lt color 1}{black}% 415 | \colorlet{gp lt color 2}{black}% 416 | \colorlet{gp lt color 3}{black}% 417 | \colorlet{gp lt color 4}{black}% 418 | \colorlet{gp lt color 5}{black}% 419 | \colorlet{gp lt color 6}{black}% 420 | \colorlet{gp lt color 7}{black}% 421 | } 422 | 423 | % 424 | % some initialisations 425 | % 426 | % by default all lines will be colored 427 | \gpcoloredlines 428 | \gpsetpointsize{4} 429 | \gpsetlinetype{gp lt solid} 430 | \gpscalepointsfalse 431 | \endinput 432 | -------------------------------------------------------------------------------- /doc/tikzlibraryzx-calculus.code.tex: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | %%% Version: 2023/09/06 3 | %%% License: MIT 4 | %%% Author: Léo Colisson 5 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6 | %%% Understand why if a "fake" alias does not exists but was created before I get no error 7 | 8 | % A tikzlibrary[libraryName].code.tex is loaded automatically by tikz when using 9 | % \usetikzlibrary{libraryName}. Therefore, you should just use 10 | % \usetikzlibrary{zx} to load this library. We also provide a package to 11 | % directly load this library using \usepackage{zx}. 12 | 13 | %%% Some random notes for myself: 14 | %%% - \tikz@pp@name{X} outputs the name prefix + X + the name suffix, where these prefix are local prefix assigned to all node names. While they are often empty, it might not be always the case. 15 | 16 | \RequirePackage{amssymb} % For short minus 17 | \RequirePackage{etoolbox} % \AfterEndPreamble... 18 | \RequirePackage{ifthen} % For conditions 19 | \RequirePackage{xparse} % For NewDocumentComments 20 | \RequirePackage{bm} % For bold math fonts 21 | 22 | \usetikzlibrary{cd,backgrounds,positioning,shapes,calc,intersections,fit} 23 | % Declare layers. 24 | \pgfdeclarelayer{background} % Fox boxes using "fit" to group parts of the graph. 25 | \pgfdeclarelayer{belownodelayer} % For nodes that always want to stay below any arrow... 26 | \pgfdeclarelayer{edgelayer} % For nodes that always want to stay below any arrow... 27 | \pgfdeclarelayer{nodelayer} % For nodes... in theory, this fails for now. 28 | \pgfdeclarelayer{main} 29 | \pgfdeclarelayer{abovenodelayer} % For nodes that want to stay above others. 30 | \pgfdeclarelayer{box} % For boxes using "fit" to fake multi-column boxes 31 | \pgfdeclarelayer{labellayer} % For labels... in theory, this fails for now. https://tex.stackexchange.com/questions/618823/node-on-layer-style-in-tikz-matrix-tikzcd 32 | \pgfdeclarelayer{foreground} % For the user, if they want to put anything really above everything. 33 | 34 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 35 | %%%% User modifiable variables 36 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 37 | 38 | % Define colors, can be redefine by user 39 | \definecolor{colorZxZ}{RGB}{204,255,204} 40 | \definecolor{colorZxX}{RGB}{255,136,136} 41 | \definecolor{colorZxH}{RGB}{255,255,0} 42 | \definecolor{colorZxMatrix}{RGB}{200,200,200} 43 | 44 | %%% Some wires (the one having an intermediate H, X, or S gate) may need some additional space for 45 | %%% specific columns. 46 | %%% Use these spaces like &[\zxHCol] or \\[\zxHRow] in that case 47 | %% Defines the space to add for columns and rows containing a connection with Hadamard 48 | % This is for "curved" wires 49 | \newcommand{\zxHCol}{1mm} 50 | \newcommand{\zxHRow}{1mm} 51 | % This is for "flat" wires (usually takes more space) 52 | \newcommand{\zxHColFlat}{1.5mm} 53 | \newcommand{\zxHRowFlat}{1.5mm} 54 | %% Defines the space to add for columns and rows containing a connection with small X/Z 55 | \newcommand{\zxSCol}{1mm} 56 | \newcommand{\zxSRow}{1mm} 57 | \newcommand{\zxSColFlat}{1.5mm} 58 | \newcommand{\zxSRowFlat}{1.5mm} 59 | %% Defines the space to add for columns having both H and Spiders 60 | \newcommand{\zxHSCol}{1mm} 61 | \newcommand{\zxHSRow}{1mm} 62 | \newcommand{\zxHSColFlat}{1mm} 63 | \newcommand{\zxHSRowFlat}{1mm} 64 | %% Wires only: when adding only wires with empty nodes, the space between columns can be too small. Useful not to shrink swap gates... 65 | \newcommand{\zxWCol}{2mm} 66 | \newcommand{\zxWRow}{2mm} 67 | %% Same as zxWCol, but when a single empty node is connected to a non-empty node. 68 | \newcommand{\zxwCol}{1mm} 69 | \newcommand{\zxwRow}{1mm} 70 | %% When vdots/dots are used in lines 71 | \newcommand{\zxDotsCol}{3mm} 72 | \newcommand{\zxDotsRow}{3mm} 73 | %% Default separation between rows and columns 74 | \newcommand{\zxDefaultColumnSep}{1.5mm} 75 | \newcommand{\zxDefaultRowSep}{1.5mm} 76 | % To cancel the default tow separation 77 | \newcommand{\zxZeroCol}{-\zxDefaultColumnSep} 78 | \newcommand{\zxZeroRow}{-\zxDefaultRowSep} 79 | %% When adding two lines with only empty nodes, it can create quite a large space. Use this to reduce it 80 | %% Yes, we can add multiple arguments, space will add up (see documentation pgfmatrixnextcell) 81 | \newcommand{\zxNCol}{-\zxDefaultColumnSep,.5mm} 82 | \newcommand{\zxNRow}{-\zxDefaultRowSep,.5mm} 83 | 84 | 85 | % Angles by default for s and o related arrows 86 | \def\zxDefaultSoftAngleS{30} 87 | \def\zxDefaultSoftAngleN{60} 88 | \def\zxDefaultSoftAngleO{40} 89 | \def\zxDefaultSoftAngleChevron{60} 90 | 91 | % Angles by default for s and o related arrows 92 | \def\zxDefaultSoftAngleS{30} 93 | \def\zxDefaultSoftAngleN{60} 94 | \def\zxDefaultSoftAngleO{40} 95 | \def\zxDefaultSoftAngleChevron{60} 96 | 97 | % Angles by default for s and o related arrows (in/out version) 98 | \def\zxDefaultSoftAngleN{60} 99 | \def\zxDefaultSoftAngleO{40} 100 | \def\zxDefaultSoftAngleChevron{60} 101 | 102 | \def\zxGroundScale{1.8} 103 | 104 | % Styles for O,N,... (new bezier version) 105 | \tikzset{ 106 | /zx/args/-andL/.cd, 107 | defaultO/.style={-=.2,L=.4}, 108 | defaultN/.style={-=.2,L=.8}, 109 | defaultN-/.style={1-=.4,1L=0}, 110 | defaultNN/.style={}, 111 | defaultNIN/.style={1-=0,1L=.6}, 112 | defaultChevron/.style={}, % < should be stronger than N- also in ui mode. 113 | defaultChevronDown/.style={}, % The ^ v versions (default NN and default NIN will be loaded before). 114 | defaultS/.style={-=.8,L=0}, 115 | defaultS'/.style={-=.8,L=.2}, 116 | default-S/.style={1-=.8,1L=0}, 117 | defaultSIS/.style={1-=0,1L=.8}, 118 | % Loads the default styles for the "use intersection" method. 119 | /zx/args/-andL/ui/.style={ 120 | /zx/args/-andL/defaultO/.style={-=.2,L=.17}, 121 | /zx/args/-andL/defaultN/.style={-=.2,L=.7}, 122 | /zx/args/-andL/defaultN-/.style={1-=.5,1L=.2,2-=.2,2L=.5}, %% Todo: write a different style for < 123 | /zx/args/-andL/defaultNN/.style={}, 124 | /zx/args/-andL/defaultChevron/.style={1-=.2,1L=0,2-=.2,2L=.8}, 125 | /zx/args/-andL/defaultChevronDown/.style={1L=.2,1-=0,2L=.2,2-=.8}, 126 | /zx/args/-andL/defaultNIN/.style={1-=0,1L=.66,2-=.55,2L=.16}, 127 | /zx/args/-andL/defaultS/.style={-=.8,L=0}, 128 | /zx/args/-andL/defaultS'/.style={-=.8,L=.3}, 129 | /zx/args/-andL/default-S/.style={1-=.8,1L=0}, 130 | /zx/args/-andL/defaultSIS/.style={1-=0,1L=.8,2-=.15,2L=.6}, 131 | }, 132 | } 133 | 134 | 135 | % Scale to use when scaling 3 dots 136 | \def\zxScaleDots{.7} 137 | 138 | % 0.4pt is default in tikz. Also used to ensure it has not been modified document wise by other libraries 139 | % (quantikz notably changes this parameter). 140 | \newcommand{\zxDefaultLineWidth}{0.4pt} 141 | 142 | % For phase in content: How to convert sign ("-" for minus, nothing for "+", anything else should be inserted directly), 143 | % above fraction (no parens), below fraction (no parens), above fraction (with parens), below fraction (with parens) 144 | \NewExpandableDocumentCommand{\zxConvertToFracInContent}{mmmmm}{% 145 | \ifthenelse{\equal{#1}{-}}{\zxMinus}{#1}\frac{#2}{#3}% 146 | } 147 | 148 | % For phase in label: How to convert sign ("-" for minus, nothing for "+", anything else should be inserted directly), 149 | % above fraction (no parens), below fraction (no parens), above fraction (with parens), below fraction (with parens) 150 | \NewExpandableDocumentCommand{\zxConvertToFracInLabel}{mmmmm}{% 151 | \ifthenelse{\equal{#1}{-}}{\zxMinus}{#1}#4/#5% 152 | } 153 | 154 | % Minus sign to use in \zxZ-{\alpha} 155 | %\NewExpandableDocumentCommand{\zxMinusInShort}{}{-} 156 | \NewExpandableDocumentCommand{\zxMinusInShort}{}{-} 157 | 158 | % The library tries to find intersection between fake center east/... and the border of the node 159 | % to draw the nodes directly on the border. 160 | % To enable this function (can also be set locally), enable this macro: 161 | % \def\zxEnableIntersectionsNodes{} %% To add the "name shape" on each node 162 | % \def\zxEnableIntersectionsWires{} %% For wires only (can't work without \zxEnableIntersectionsNodes) 163 | \newcommand{\zxEnableIntersections}{% 164 | \def\zxEnableIntersectionsWires{}% 165 | \def\zxEnableIntersectionsNodes{}% 166 | } 167 | % to disable intersections, undefined it: 168 | \let\zxEnableIntersectionsNodes\undefined 169 | \let\zxEnableIntersectionsWires\undefined 170 | \newcommand{\zxDisableIntersections}{% 171 | \let\zxEnableIntersectionsNodes\undefined% 172 | \let\zxEnableIntersectionsWires\undefined% 173 | } 174 | % Now, if it cannot find a good intersection (either because "name path" is disabled, or 175 | % because no intersection is found, or because intersections are disabled anyway) we need to 176 | % have a fallback mechanism. Either we choose instead the "fake center" (or center if fake 177 | % center does not exists), but then the wire will be hidden behind the node (it is a problem 178 | % mostly if you use H nodes a lot, otherwise we recommend this solution): 179 | \def\zxWireInsideIfNoIntersectionName{} 180 | % If you prefer to start the wire on the surface of the node, do that instead... but it will take longer to compute. See also our ui style 181 | % as the default styles are not meant to work in that setting. 182 | % \let\zxWireInsideIfNoIntersectionName\undefined 183 | 184 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 185 | %%%% Adding anchors 186 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 187 | 188 | % We add anchors "fake center {north, south, east, west}" to the nodes. The wires will leave from these anchors (except in IO mode) depending on the direction. If the anchor does not exist, center is picked. 189 | % https://tex.stackexchange.com/questions/14769/add-more-anchors-to-standard-tikz-nodes 190 | \def\zx@pgfaddtoshape#1#2{% 191 | \begingroup 192 | \def\pgf@sm@shape@name{#1}% 193 | \let\anchor\pgf@sh@anchor 194 | #2% 195 | \endgroup 196 | } 197 | \def\zx@useanchor#1#2{\csname pgf@anchor@#1@#2\endcsname} 198 | \zx@pgfaddtoshape{rounded rectangle}{% 199 | \anchor{fake center east}{% 200 | \zx@useanchor{rounded rectangle}{north east}% 201 | \pgf@yc=.5\pgf@y% final y = 0.5*this y + 0.5*other y. 202 | \zx@useanchor{rounded rectangle}{south east}% 203 | \pgf@y=.5\pgf@y% 204 | \advance\pgf@y by \pgf@yc% 205 | }% 206 | \anchor{fake center west}{% 207 | \zx@useanchor{rounded rectangle}{north west}% 208 | \pgf@yc=.5\pgf@y% final y = 0.5*this y + 0.5*other y. 209 | \zx@useanchor{rounded rectangle}{south west}% 210 | \pgf@y=.5\pgf@y% 211 | \advance\pgf@y by \pgf@yc% 212 | }% 213 | \anchor{fake center north}{% 214 | \zx@useanchor{rounded rectangle}{center}% 215 | }% 216 | \anchor{fake center south}{% 217 | \zx@useanchor{rounded rectangle}{center}% 218 | }% 219 | } 220 | 221 | \zx@pgfaddtoshape{coordinate}{% 222 | \anchor{fake center east}{% 223 | \zx@useanchor{coordinate}{center}% 224 | }% 225 | \anchor{fake center west}{% 226 | \zx@useanchor{coordinate}{center}% 227 | }% 228 | \anchor{fake center north}{% 229 | \zx@useanchor{coordinate}{center}% 230 | }% 231 | \anchor{fake center south}{% 232 | \zx@useanchor{coordinate}{center}% 233 | }% 234 | } 235 | 236 | \zx@pgfaddtoshape{circle}{% 237 | \anchor{fake center east}{% 238 | \zx@useanchor{circle}{center}% 239 | }% 240 | \anchor{fake center west}{% 241 | \zx@useanchor{circle}{center}% 242 | }% 243 | \anchor{fake center north}{% 244 | \zx@useanchor{circle}{center}% 245 | }% 246 | \anchor{fake center south}{% 247 | \zx@useanchor{circle}{center}% 248 | }% 249 | } 250 | 251 | \zx@pgfaddtoshape{rectangle}{ 252 | \anchor{fake center east}{% 253 | \zx@useanchor{rectangle}{center}% 254 | }% 255 | \anchor{fake center west}{% 256 | \zx@useanchor{rectangle}{center}% 257 | }% 258 | \anchor{fake center north}{% 259 | \zx@useanchor{rectangle}{center}% 260 | }% 261 | \anchor{fake center south}{% 262 | \zx@useanchor{rectangle}{center}% 263 | }% 264 | } 265 | 266 | 267 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 268 | %%%% Tikz styles 269 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 270 | 271 | %%% For arguments later: 272 | \tikzset{ 273 | /zx/args/-andL/.cd, 274 | % - is "towards the point", or "x value", 275 | % L is "perpendicular to the line going towards the point" (L is for the perpendicular shape), or "y value". 276 | 1-/.initial=.5, % random value, defaultO... will change that. 277 | 2-/.initial=.5, 278 | -/.style={ 279 | 1-=#1, 280 | 2-=#1, 281 | }, 282 | 1L/.initial=.5, 283 | 2L/.initial=.5, 284 | L/.style={ 285 | 1L=#1, 286 | 2L=#1, 287 | }, 288 | symmetry-L/.code={% 1- <-> 1L, 2- <-> 2L 289 | \edef\zx@tmpone{\pgfkeysvalueof{/zx/args/-andL/1-}}% 290 | \edef\zx@tmptwo{\pgfkeysvalueof{/zx/args/-andL/2-}}% 291 | \pgfkeysalso{% 292 | 1-/.evaluated=\pgfkeysvalueof{/zx/args/-andL/1L}, 293 | 2-/.evaluated=\pgfkeysvalueof{/zx/args/-andL/2L}, 294 | 1L/.evaluated=\zx@tmpone, 295 | 2L/.evaluated=\zx@tmptwo, 296 | }% 297 | }, 298 | symmetry/.code={% 1- <-> 2-, 1L <-> 2L 299 | \edef\zx@tmpone{\pgfkeysvalueof{/zx/args/-andL/1-}}% 300 | \edef\zx@tmptwo{\pgfkeysvalueof{/zx/args/-andL/1L}}% 301 | \pgfkeysalso{ 302 | 1-/.evaluated=\pgfkeysvalueof{/zx/args/-andL/2-}, 303 | 1L/.evaluated=\pgfkeysvalueof{/zx/args/-andL/2L}, 304 | 2-/.evaluated=\zx@tmpone, 305 | 2L/.evaluated=\zx@tmptwo, 306 | }% 307 | }, 308 | negate1L/.style={ 309 | /zx/args/-andL/1L/.evaluated=-\pgfkeysvalueof{/zx/args/-andL/1L}, 310 | }, 311 | negate2L/.style={ 312 | /zx/args/-andL/2L/.evaluated=-\pgfkeysvalueof{/zx/args/-andL/2L}, 313 | }, 314 | negateL/.style={ 315 | negate1L, 316 | negate2L, 317 | }, 318 | negate1-/.style={ 319 | /zx/args/-andL/1-/.evaluated=-\pgfkeysvalueof{/zx/args/-andL/1-}, 320 | }, 321 | negate2-/.style={ 322 | /zx/args/-andL/2-/.evaluated=-\pgfkeysvalueof{/zx/args/-andL/2-}, 323 | }, 324 | negate-/.style={ 325 | negate1-, 326 | negate2-, 327 | }, 328 | negateL/.style={ 329 | negate1L, 330 | negate2L, 331 | }, 332 | oneMinus1-/.style={ 333 | /zx/args/-andL/2-/.evaluated=1-\pgfkeysvalueof{/zx/args/-andL/2-}, 334 | }, 335 | oneMinus2-/.style={ 336 | /zx/args/-andL/2-/.evaluated=1-\pgfkeysvalueof{/zx/args/-andL/2-}, 337 | }, 338 | oneMinus1L/.style={ 339 | /zx/args/-andL/1L/.evaluated=1-\pgfkeysvalueof{/zx/args/-andL/1L}, 340 | }, 341 | oneMinus2L/.style={ 342 | /zx/args/-andL/2L/.evaluated=1-\pgfkeysvalueof{/zx/args/-andL/2L}, 343 | }, 344 | % Angle/length: 345 | 1 angle and length/.code 2 args={% 346 | \pgfmathparse{#2*cos(#1)}% 347 | \pgfkeysalso{1-/.expand once=\pgfmathresult}% 348 | \pgfmathparse{#2*sin(#1)}% 349 | \pgfkeysalso{1L/.expand once=\pgfmathresult}% 350 | }, 351 | 2 angle and length/.code 2 args={% 352 | \pgfmathparse{#2*cos(#1)}% 353 | \pgfkeysalso{2-/.expand once=\pgfmathresult}% 354 | \pgfmathparse{#2*sin(#1)}% 355 | \pgfkeysalso{2L/.expand once=\pgfmathresult}% 356 | }, 357 | 1al/.style 2 args={ 358 | 1 angle and length={#1}{#2} 359 | }, 360 | 2al/.style 2 args={ 361 | 2 angle and length={#1}{#2} 362 | }, 363 | al/.style 2 args={ 364 | 1 angle and length={#1}{#2}, 365 | 2 angle and length={#1}{#2}, 366 | }, 367 | 1 angle/.style={ 368 | 1 angle and length={#1}{.6} 369 | }, 370 | 2 angle/.style={ 371 | 2 angle and length={#1}{.6} 372 | }, 373 | 1a/.style={ 374 | 1 angle={#1}, 375 | }, 376 | 2a/.style={ 377 | 2 angle={#1}, 378 | }, 379 | angle/.style={ 380 | 1 angle={#1}, 381 | 2 angle={#1}, 382 | }, 383 | a/.style={ 384 | 1 angle and length={#1}{.6}, 385 | 2 angle and length={#1}{.6}, 386 | }, 387 | } 388 | 389 | %%% Useful debug functions 390 | %% This function will be called when debugging the library. 391 | \def\zx@message#1{} 392 | % The ^^J adds a new line: 393 | \def\zx@verbose@message#1{\message{#1^^J}} % For more important messages. Like to show the code is not looping forever 394 | % To enable debugging: 395 | % WARNING: if you use in code, do not forget the makeatletter! 396 | %\def\zx@message#1{\message{#1^^J}} 397 | % To display stroke of while trying to compute the intersections: 398 | % WARNING: if you use in code, do not forget the makeatletter! 399 | %\def\zx@draw@stroke@inter@debug{} 400 | 401 | 402 | %% This function checks if the node has a "name path", if so it computes the intersection between 403 | %% if not if \zxWireInsideIfNoIntersectionName is defined it defines the \tikzto* to the 404 | %% new@center (argument #2), otherwise it does nothing. 405 | % #1: Node to consider: \tikztostart or \tikztotarget 406 | % #2: name of the new@center node corresponding to #1 407 | % #3: name of the other new@center node 408 | % #4: result will be stored in this macro... if there is something to change. 409 | % #5: 1 if start, 2 if end 410 | % Result will be moved back into #1 411 | \def\zx@find@intersection@fakecenter#1#2#3#4#5{% 412 | % First, we check if the user wants to compute the intersection: 413 | \ifdefined\zxEnableIntersectionsWires% 414 | %% We compute the intersection 415 | \edef\tikz@intersect@path@a{zx@name@path@#1}% 416 | \ifcsname tikz@intersect@path@name@\tikz@intersect@path@a \endcsname% 417 | \zx@verbose@message{[ZX] I will start computing intersections}% 418 | \pgfintersectionofpaths{% 419 | \begin{pgfinterruptboundingbox}% 420 | %%%% /!\ This lines is the one I'm not sure how to write: 421 | \expandafter\pgfsetpath\csname tikz@intersect@path@name@\tikz@intersect@path@a\endcsname% 422 | \pgfgetpath\temppath% 423 | \ifdefined\zx@draw@stroke@inter@debug% 424 | \pgfusepath{stroke} % We draw it, useful to debug, and realize the shape is moved. 425 | \fi% 426 | \pgfsetpath\temppath% 427 | \end{pgfinterruptboundingbox}% 428 | }{% The first path is moved to the center... So we need to shift it also here. 429 | %%% First intersection: we use the line between the two nodes... but it's really ugly (e.g. in o it does not make a lot of sense) 430 | \begin{pgfinterruptboundingbox}% 431 | \ifdefined\zxIntersectionLineBetweenStartEnd% 432 | \pgfpointdiff{\pgfpointanchor{#1}{center}}{\tikz@scan@one@point\pgf@process(#2)}% 433 | \pgfpathmoveto{\pgfpoint{\pgf@x}{\pgf@y}}% 434 | \pgfpointdiff{\pgfpointanchor{#1}{center}}{\tikz@scan@one@point\pgf@process(#3)}% 435 | \pgfpathlineto{\pgfpoint{\pgf@x}{\pgf@y}}% 436 | \else% 437 | %% We use now the method used for bezier curve (at least it's what I see "experimentally") 438 | %% More precisely, we use the direction of the bezier curve to know where to start the wire. 439 | %% Parse once the control points for efficiency reasons: 440 | %% First parse the fake centers. 441 | \tikz@scan@one@point\pgf@process(#2)% 442 | \edef\zx@tmp@current@fake@x{\the\pgf@x}% 443 | \edef\zx@tmp@current@fake@y{\the\pgf@y}% 444 | \zx@message{The input fakes are #2 and #3.}% 445 | \tikz@scan@one@point\pgf@process(#3)% 446 | \edef\zx@tmp@other@fake@x{\the\pgf@x}% 447 | \edef\zx@tmp@other@fake@y{\the\pgf@y}% 448 | \zx@message{The parsed input fakes are (\zx@tmp@current@fake@x , \zx@tmp@current@fake@y) and (\zx@tmp@other@fake@x , \zx@tmp@other@fake@y).}% 449 | %% Reorder the controls to compute. #5 = 1 if "start fake center" is "current fake center". 450 | \ifnum#5=1 % <-- important space!!! 451 | \edef\zx@tmp@start@fake@x{\zx@tmp@current@fake@x}% 452 | \edef\zx@tmp@start@fake@y{\zx@tmp@current@fake@y}% 453 | \edef\zx@tmp@end@fake@x{\zx@tmp@other@fake@x}% 454 | \edef\zx@tmp@end@fake@y{\zx@tmp@other@fake@y}% 455 | \else% 456 | \edef\zx@tmp@end@fake@x{\zx@tmp@current@fake@x}% 457 | \edef\zx@tmp@end@fake@y{\zx@tmp@current@fake@y}% 458 | \edef\zx@tmp@start@fake@x{\zx@tmp@other@fake@x}% 459 | \edef\zx@tmp@start@fake@y{\zx@tmp@other@fake@y}% 460 | \fi% 461 | \zx@message{We computed: start fake (\zx@tmp@start@fake@x , \zx@tmp@start@fake@y) end fake (\zx@tmp@end@fake@x , \zx@tmp@end@fake@y )}% 462 | \pgfkeysalso{/zx/tmp/zx@getControlPoints={\zx@tmp@start@fake@x}{\zx@tmp@start@fake@y}{\zx@tmp@end@fake@x}{\zx@tmp@end@fake@y}}% 463 | % Now results are in controlOne, and controlTwo 464 | \ifnum#5=1 \relax% 465 | \def\zx@control{\controlOne}% 466 | \else% 467 | \def\zx@control{\controlTwo}% 468 | \fi% 469 | %%% Parse new control 470 | \tikz@scan@one@point\pgf@process(\zx@control)% 471 | \edef\zx@tmp@current@ctrl@x{\the\pgf@x}% 472 | \edef\zx@tmp@current@ctrl@y{\the\pgf@y}% 473 | \zx@message{[ZX] Current control is number #5, i.e. \zx@control (both are \controlOne and \controlTwo)}% 474 | % We store the center coordinates since it's used several times 475 | \pgfpointanchor{#1}{center}% 476 | \edef\zx@tmp@real@center@x{\the\pgf@x}% 477 | \edef\zx@tmp@real@center@y{\the\pgf@y}% 478 | %%% Go to current fake center, except that real center is the new origin. 479 | \pgfpointdiff{\pgfpoint{\zx@tmp@real@center@x}{\zx@tmp@real@center@y}}{\pgfpoint{\zx@tmp@current@fake@x}{\zx@tmp@current@fake@y}}% 480 | \pgfpathmoveto{\pgfpoint{\pgf@x}{\pgf@y}}% 481 | %% What, now both axis are inverted??? If someone can explain me this... 482 | %% We scale the point to force it to cross the boundary. 483 | \pgfpathlineto{% 484 | \pgfpointadd{% 485 | \pgf@process{% 486 | \pgfpointscale{10}{% 487 | \pgf@process{% 488 | \pgfpointdiff{% 489 | \pgfpoint{\zx@tmp@current@fake@x}{\zx@tmp@current@fake@y}% 490 | }{% 491 | \pgfpoint{\zx@tmp@current@ctrl@x}{\zx@tmp@current@ctrl@y}% 492 | }% 493 | }% 494 | }% 495 | }% 496 | }{% 497 | \pgfpointdiff{% 498 | \pgfpoint{\zx@tmp@real@center@x}{\zx@tmp@real@center@y}% 499 | }{% 500 | \pgfpoint{\zx@tmp@current@fake@x}{\zx@tmp@current@fake@y}% 501 | }% 502 | }% 503 | }% 504 | \fi% 505 | \pgfgetpath\temppath% 506 | \ifdefined\zx@draw@stroke@inter@debug% 507 | \pgfusepath{stroke}% We draw it, useful to debug, and realize the shape is moved. 508 | \fi% 509 | \pgfsetpath\temppath% 510 | \end{pgfinterruptboundingbox}% 511 | }% 512 | \pgfintersectionsolutions% 513 | \pgfpointintersectionsolution{1}% 514 | \ifnum\pgfintersectionsolutions=1%% The good number of solution has been found! 515 | \zx@message{[ZX] Cool, just found one solution!} 516 | %% Store the intersection (warning: the center of the shape is moved to the center!) 517 | \edef\zx@relinter@x{\the\pgf@x}% 518 | \edef\zx@relinter@y{\the\pgf@y}% 519 | %% Because the shape was moved to center, we shift it back by adding the coord of the shape: 520 | \pgfextractx\pgf@xa{\pgfpointanchor{#1}{center}}% 521 | \pgfextractx\pgf@xb{\pgfpointanchor{#1}{center}}% 522 | % WARNING! pgfmath removes the dimension (converted in pt). Make sure to put them back after 523 | \pgfmathsetmacro{\zx@inter@x}{\pgf@x+\zx@relinter@x}% 524 | \pgfmathsetmacro{\zx@inter@y}{\pgf@y+\zx@relinter@y}% 525 | \edef#4{\zx@inter@x pt,\zx@inter@y pt}% 526 | \else% The bad number of solution has been found 527 | \zx@message{[ZX] WARNING: expecting one solution, found \pgfintersectionsolutions}% 528 | \ifdefined\zxWireInsideIfNoIntersectionName% 529 | % No intersection was found, but still want to use fake center (or center). 530 | % ==> The wire will be inside the shape 531 | % Basically \tikztostart := tikztostart@new@center 532 | \edef#4{#2}% 533 | \fi% Otherwise, do nothing 534 | \fi% 535 | \else% 536 | \zx@message{ZX: no path named \tikz@intersect@path@a was found.}% 537 | \ifdefined\zxWireInsideIfNoIntersectionName% 538 | % No intersection was found, but still want to use fake center (or center). 539 | % ==> The wire will be inside the shape 540 | % Basically \tikztostart := tikztostart@new@center 541 | \edef#4{#2}% 542 | \fi% Otherwise, do nothing 543 | \fi% 544 | \else% 545 | \zx@message{[ZX]: intersection mechanism disabled}% 546 | \ifdefined\zxWireInsideIfNoIntersectionName% 547 | % No intersection was found, but still want to use fake center (or center). 548 | % ==> The wire will be inside the shape 549 | % Basically \tikztostart := tikztostart@new@center 550 | \edef#4{#2}% 551 | \fi% Otherwise, do nothing 552 | \fi% 553 | }% 554 | 555 | % Styles. User should not modify "wires definition", but is free to change: 556 | % - "/zx/default style nodes/" to change completely the node style 557 | % - "/zx/user overlay nodes" to add stuff on current node style 558 | % - "/zx/default style wires" to change the wire style 559 | % - "/zx/user overlay wires/" to add stuff on wire style 560 | % The user is not supposed to use node styles directly (use \zxZ{}, \zxZ{\alpha+\beta}, \zxFrac-{\pi}{4}...) 561 | % but is free (and encouraged) to use the styles in "wires definition" like \ar[r,o']. 562 | \tikzset{ 563 | /zx/wires definition/.style={ 564 | %%% Basic default properties 565 | draw, 566 | -, 567 | line width=\zxDefaultLineWidth, 568 | %%% Useful shortcut (shorter lines means easy "align" of & symbols. Love M-x align in emacs btw.) 569 | ls/.style={looseness=##1}, 570 | looseness wires only/.style={% Looseness used for wires only. 571 | looseness=1.2, 572 | }, 573 | lw/.style={looseness wires only}, 574 | bold/.style={very thick}, 575 | non bold/.style={line width=\zxDefaultLineWidth,}, 576 | B/.style={bold}, 577 | NB/.style={non bold}, 578 | %% Adds a n above to denote the number of wires 579 | Bn/.style={BnArgs={##1}{}}, 580 | Bn/.default={n}, 581 | boldn/.style={BnArgs={##1}{}}, 582 | boldn/.default={n}, 583 | Bn'/.style={Bn'Args={##1}{}}, 584 | Bn'/.default={n}, 585 | boldn'/.style={Bn'Args={##1}{}}, 586 | boldn'/.default={n}, 587 | Bn./.style={Bn.Args={##1}{}}, 588 | Bn./.default={n}, 589 | boldn./.style={Bn.Args={##1}{}}, 590 | boldn./.default={n}, 591 | Bn-/.style={Bn-Args={##1}{}}, 592 | Bn-/.default={n}, 593 | boldn-/.style={Bn-Args={##1}{}}, 594 | boldn-/.default={n}, 595 | %% For wires left to right 596 | Bn'Args/.style 2 args={bold, "/" {anchor=center,##2}, "##1" {above,yshift=3pt,##2}}, 597 | Bn'Args/.default={n}{}, 598 | Bn.Args/.style 2 args={bold, "/" {anchor=center,##2}, "##1" {below,yshift=-3pt,##2}}, 599 | Bn.Args/.default={n}{}, 600 | %% for wires top/down (left,right) 601 | BnArgs/.style 2 args={bold, "/" {rotate=90,anchor=center,##2}, "##1" {left,xshift=-2pt,##2}}, 602 | BnArgs/.default={n}{}, 603 | Bn-Args/.style 2 args={bold, "/" {rotate=90,anchor=center,##2}, "##1" {right,xshift=2pt,##2}}, 604 | Bn-Args/.default={n}{}, 605 | % boldnPos/.style={bold, "/" {anchor=center}, "##1" {yshift=3pt}}, 606 | % boldnPos/.default={n}{pos=50}, 607 | % boldn.Pos/.style={bold, "/" {anchor=center}, "##1" {below,yshift=-3pt}}, 608 | % boldn.Pos/.default={n}{pos=50}, 609 | % Use this when you are drawing lines between none nodes only (like swap gates...) in IO mode 610 | between none/.style={ 611 | looseness wires only, 612 | wire centered 613 | }, 614 | bn/.style={ 615 | between none 616 | }, 617 | % To debug the bezier curve. 618 | edge above/.code={% 619 | \def\zxEdgesAbove{}% 620 | },% 621 | edge not above/.code={% 622 | \let\zxEdgesAbove\undefined% 623 | }, 624 | control points visible/.code={% 625 | \def\zxControlPointsVisible{}% 626 | },% 627 | control points not visible/.code={% 628 | \let\zxControlPointsVisible\undefined% 629 | }, 630 | % See explaination at the beginning where we define \def\zxEnableIntersectionsWires{} 631 | % Rouhgly, tries to start the wires on the border of the shape on the line between the 632 | % fake anchors. 633 | use intersections/.code={% 634 | \def\zxEnableIntersectionsWires{}% 635 | }, 636 | dont use intersections/.code={% 637 | \let\zxEnableIntersectionsWires\undefined% 638 | }, 639 | ui/.style={ 640 | use intersections, 641 | /zx/args/-andL/ui 642 | }, 643 | intersections mode between start end/.code={% 644 | \def\zxIntersectionLineBetweenStartEnd{}% 645 | }, 646 | intersections mode bezier controls/.code={% 647 | \let\zxIntersectionLineBetweenStartEnd\undefined% 648 | }, 649 | wires behind nodes/.code={% 650 | \def\zxWireInsideIfNoIntersectionName{}% 651 | }, 652 | no wires behind nodes/.code={% 653 | \let\zxWireInsideIfNoIntersectionName\undefined% 654 | }, 655 | intersection between start end/.code={ 656 | \def\zxIntersectionLineBetweenStartEnd{}% 657 | }, 658 | intersection bezier control/.code={ 659 | \let\zxIntersectionLineBetweenStartEnd\undefined% 660 | }, 661 | % ------------------------------ 662 | % Practical stuff to draw lines easily: 663 | % Prefer to use these are they can be easily customized for each style and shorter to type. 664 | % Note that the letter is supposed to represent the shape of the link 665 | % dots/dashes are used to specify the position of the arrow. 666 | % Typically ' means top, . bottom, X- is right to X (or should arrive with angle 0), 667 | % -X is left to X (or should leave with angle zero). These shapes are usually designed to 668 | % work when the starting node is left most (or above of both nodes have the same column). 669 | % But they may work both way for some of them. 670 | % ------------------------------ 671 | %%% Cup/Cap 672 | % Like a C shape (with without a perfect half circle). Useful maybe when perfect circles are too big. 673 | % If only tex was a functional language... https://tex.stackexchange.com/questions/618955 674 | C@generic/.style n args={8}{ % min/max, angle1, angle2, anchor, \x or \y, \y or \x, where to move,radius code (for circle should be "radius=\n3") 675 | to path={ 676 | \pgfextra{%% <- we will use def... so need to "exit" a few seconds pgf 677 | % Test if tikztostart is a point or a node, and define StartPoint accordingly. 678 | \ifPgfpointOrNode{\tikztostart}{% 679 | \def\StartPoint{\tikztostart}% 680 | }{% 681 | % For some nodes, "north" might not point to north (notably after a rotation). So we can define some anchors "true north" that actually point 682 | % to the north. 683 | % Test if "true north" etc exists: 684 | \ifAnchorExistsNodeSpecific{\tikztostart}{true ##4}{% 685 | \def\StartPoint{\tikztostart.true ##4}% 686 | }{% 687 | \def\StartPoint{\tikztostart.##4}% 688 | }% 689 | }% 690 | % Test if tikztostart is a point or a node, and define StartPoint accordingly. 691 | \ifPgfpointOrNode{\tikztotarget}{% 692 | \def\TargetPoint{\tikztotarget}% 693 | }{% 694 | % Test if "true north" etc exists: 695 | \ifAnchorExistsNodeSpecific{\tikztotarget}{true ##4}{% 696 | \def\TargetPoint{\tikztotarget.true ##4}% 697 | }{% 698 | \def\TargetPoint{\tikztotarget.##4}% 699 | }% 700 | }% 701 | }% 702 | (\StartPoint) % <- the path starts at StartPoint 703 | %%% Get x coordinate of left-most point 704 | let \p1=(\StartPoint), 705 | \p2=(\TargetPoint), 706 | \n1={##1(##51,##52)}, % coordinate of the most left part (when ##1=min and ##5=\x: ##52 goes to \x2) 707 | \n3={abs(##61-##62)/2} % Radius of circle 708 | in % Warning: no comma after last line before in 709 | %%%% We go on the left if needed (we check that we do move, otherwise we break the arrows tip if 710 | %%%% we stay on place 711 | %%%% First go to the left if needed 712 | \pgfextra{% 713 | %% We check if we are moving or not (required to preserve arrow tip direction) 714 | \pgfmathapproxequalto{##51}{\n1}% 715 | }% 716 | \ifpgfmathcomparison\else -- ##7\fi 717 | %%%% Version 1: 718 | \pgfextra{% 719 | \pgfmathparse{% 720 | ifthenelse(##61<##62, % if end angle < angle, draw clockwis 721 | "arc[start angle=##3,end angle=##2,##8]",% 722 | "arc[start angle=##2,end angle=##3,##8]"% 723 | )% 724 | }% 725 | }% 726 | \pgfmathresult% 727 | \pgfextra{% 728 | %% We check if we are moving or not (required to preserve arrow tip direction) 729 | \pgfmathapproxequalto{##52}{\n1}% 730 | }% 731 | \ifpgfmathcomparison\else -- (\TargetPoint)\fi 732 | \tikztonodes% All to path finishes with that to deal with future nodes I think 733 | } 734 | }, 735 | % At the first version, styles were defined using in=... out=... looseness=... However 736 | % it gives sometimes bad results (like the curve goes forward at some points) when nodes are 737 | % too close or too far appart. However, it may still be useful, so now we define the old 738 | % styles, that you can use them using \ar[r,IO,C]. 739 | % NB: for the newest styles, we add new anchors to the nodes depending on the direction. 740 | C/.style={C@generic={min}{90}{180+90}{west}{\x}{\y}{(\n1,\y1)}{y radius=\n3, x radius=##1*\n3}}, 741 | C/.default=1, 742 | % Like C, but rotated 743 | C-/.style={C@generic={max}{90}{-90}{east}{\x}{\y}{(\n1,\y1)}{y radius=\n3, x radius=##1*\n3}}, 744 | C-/.default=1, 745 | C'/.style={C@generic={max}{0}{180}{north}{\y}{\x}{(\x1,\n1)}{x radius=\n3, y radius=##1*\n3}}, 746 | C'/.default=1, 747 | C./.style={C@generic={min}{0}{-180}{south}{\y}{\x}{(\x1,\n1)}{x radius=\n3, y radius=##1*\n3}}, 748 | C./.default=1, 749 | %%% bezier{px1}{py1}{px2}{py2} creates a bezier curve where px1/py1 are the 750 | %%% coordinates of the first control (in "percentage" 0 1 - (2-) 1070 | oneMinus2-, 1071 | }, 1072 | }, 1073 | o./.style={% 1074 | left to right, 1075 | bezier x={% 1076 | /zx/args/-andL/.cd, 1077 | defaultO, 1078 | ##1, 1079 | %% 2- --> 1 - (2-) 1080 | oneMinus2-, 1081 | negate1L, 1082 | negate2L, 1083 | },% 1084 | }, 1085 | -o/.style={% 1086 | up to down, 1087 | bezier y={% 1088 | /zx/args/-andL/.cd, 1089 | defaultO, 1090 | ##1, 1091 | /zx/args/-andL/2-/.evaluated=1-\pgfkeysvalueof{/zx/args/-andL/2-}, 1092 | symmetry-L, 1093 | } 1094 | }, 1095 | o-/.style={% 1096 | up to down, 1097 | bezier y={% 1098 | /zx/args/-andL/.cd, 1099 | defaultO, 1100 | ##1, 1101 | /zx/args/-andL/2-/.evaluated=1-\pgfkeysvalueof{/zx/args/-andL/2-}, 1102 | /zx/args/-andL/1L/.evaluated=-\pgfkeysvalueof{/zx/args/-andL/1L}, 1103 | /zx/args/-andL/2L/.evaluated=-\pgfkeysvalueof{/zx/args/-andL/2L}, 1104 | symmetry-L, 1105 | }, 1106 | }, 1107 | % Similar to o, but can be used also for diagonal items. Combine it with 1108 | % The dot versions are mode logic in "left to right", and the others for up to down (possible to change) 1109 | % Can combine with "force left to right"... 1110 | (/.style={ 1111 | bend right=##1, 1112 | }, 1113 | (/.default=30, 1114 | )/.style={ 1115 | bend left=##1, 1116 | }, 1117 | )/.default=30, 1118 | ('/.style={ 1119 | bend left=##1 1120 | }, 1121 | ('/.default=30, 1122 | (./.style={ 1123 | bend right=##1 1124 | }, 1125 | (./.default=30, 1126 | %%%% Links with a N-shape, i.e. like s shape, but symetric against the diagonal. Equivalently, it's a soft 's' shape with a much wider angle (>45). 1127 | %% Nbase will be reused later by < > shapes as well. It's useful to make a distinction between N and 1128 | %% Nbase when user will want to overwrite N without overwritting < >. 1129 | Nbase/.style={ 1130 | left to right, 1131 | bezier={ 1132 | /zx/args/-andL/.cd, 1133 | defaultN, 1134 | ##1, 1135 | oneMinus2-, 1136 | oneMinus2L, 1137 | }, 1138 | }, 1139 | N/.style={Nbase={##1}}, 1140 | % With this model, we don't need differences between N' and N. so we can also call it N. 1141 | % But keep other notations to allow easy style change (to use IO again for instance). 1142 | N'/.style={N={##1}}, 1143 | N./.style={N={##1}}, 1144 | -N/.style={N={defaultN-,##1}}, 1145 | -N'/.style={-N={##1}}, 1146 | -N./.style={-N={##1}}, 1147 | N-/.style={-N'={symmetry,##1}}, 1148 | N'-/.style={N-={##1}}, 1149 | N.-/.style={N-={##1}}, 1150 | %% Up to down version 1151 | NN/.style={N'={symmetry-L,defaultNN,##1},up to down}, 1152 | NN./.style={NN={##1}}, 1153 | .NN/.style={NN={##1}}, 1154 | NIN/.style={NN={defaultNIN,##1}}, 1155 | INN/.style={NIN={symmetry,##1}}, 1156 | NNI/.style={INN={##1}}, 1157 | %%% <' is basically like -N' (historically < was first), we just put an anchor on the east/.... 1158 | <'/.style={Nbase={defaultN,defaultN-,defaultChevron,symmetry,##1},end anchor=west}, 1159 | <./.style={<'={##1}}, 1160 | % Don't use <>^ alone char as style name, it could be useful later for other shortcuts 1161 | % (replacement directions) 1162 | '>/.style={Nbase={defaultN,defaultN-,defaultChevron,##1},start anchor=east}, 1163 | .>/.style={'>={##1}}, 1164 | ^./.style={ 1165 | Nbase={defaultN,defaultN-,defaultChevron,symmetry-L,defaultNN,defaultNIN,defaultChevronDown,symmetry,##1}, 1166 | end anchor=north 1167 | }, 1168 | .^/.style={^.={##1}}, 1169 | 'v/.style={ 1170 | Nbase={defaultN,defaultN-,defaultChevron,symmetry-L,defaultNN,defaultNIN,defaultChevronDown,##1}, 1171 | start anchor=south 1172 | }, 1173 | v'/.style={'v={##1}}, 1174 | %%%% Links with a s-like shape. 1175 | s/.style={ 1176 | left to right, 1177 | bezier={% 1178 | /zx/args/-andL/.cd, 1179 | defaultS, 1180 | ##1, 1181 | oneMinus2-, 1182 | oneMinus2L, 1183 | } 1184 | }, 1185 | % like S, but with anchor east and west 1186 | S/.style={ 1187 | s={##1}, start anchor=east, end anchor=west 1188 | }, 1189 | % -s'.- shapes are like s, but with a soften (customizable like o) angle. 1190 | % The '. say if you are going up or down, and - forces a sharp angle (- is flat) on the side of the - 1191 | s'/.style={s={defaultS',##1}}, 1192 | s./.style={s'={##1}}, 1193 | -s/.style={s'={default-S,##1}}, 1194 | -s'/.style={-s={##1}}, % To fit with s' notation 1195 | -s./.style={-s={##1}}, 1196 | s-/.style={-s'={symmetry,##1}}, 1197 | s'-/.style={s-={##1}}, 1198 | s.-/.style={s-={##1}}, 1199 | % Anchor more marked 1200 | S/.style={s={##1}, start anchor=east, end anchor=west,}, 1201 | -S/.style={-s'={##1},start anchor=east}, 1202 | -S'/.style={-S={##1}}, 1203 | -S./.style={-S={##1}}, 1204 | S-/.style={s'-={##1},end anchor=west}, 1205 | S'-/.style={S-={##1}}, 1206 | S.-/.style={S-={##1}}, 1207 | %%%% Doubling = up to down. 1208 | % Links with a s-like shape... but read from top to bottom 1209 | ss/.style={s={symmetry-L,##1},up to down}, 1210 | SS/.style={ss={##1}, start anchor=south, end anchor=north}, 1211 | % -s'.- shapes are like s, but with a soften (customizable like o) angle. 1212 | % The '. say if you are going up or down, and 'I' forces a sharp angle (I is flat) on the side of the I 1213 | ss./.style={s.={symmetry-L,##1},up to down}, 1214 | .ss/.style={ss.={##1}}, 1215 | sIs/.style={ss={defaultSIS,##1}}, 1216 | sIs./.style={ss.={defaultSIS,##1}}, 1217 | .sIs/.style={sIs.={##1}}, 1218 | Iss/.style={sIs={symmetry,##1}}, 1219 | ssI/.style={Iss={##1}}, 1220 | ss.I/.style={sIs.={symmetry,##1}}, 1221 | I.ss/.style={ss.I={##1}}, 1222 | SIS/.style={sIs={##1},start anchor=south}, 1223 | .SIS/.style={.sIs={##1},start anchor=south}, 1224 | ISS/.style={ssI={##1},end anchor=north}, 1225 | SS.I/.style={ss.I={##1},end anchor=north}, 1226 | I.SS/.style={SS.I={##1}}, 1227 | SSI/.style={ISS={##1}}, 1228 | % At the first version, styles were defined using in=... out=... looseness=... However 1229 | % it gives sometimes bad results (like the curve goes forward at some points) when nodes are 1230 | % too close or too far appart. However, it may still be useful, so now we define the old 1231 | % styles, that you can use them using \ar[r,IO,C]. 1232 | IO/.style={ 1233 | C/.style={/tikz/in=180,/tikz/out=180,looseness=2}, 1234 | % Like C, but symetric 1235 | C-/.style={/tikz/in=0,/tikz/out=0,looseness=2}, 1236 | C'/.style={/tikz/in=90,/tikz/out=90,looseness=2}, 1237 | C./.style={/tikz/in=-90,/tikz/out=-90,looseness=2}, 1238 | % Similar to C, but with a softer angle. The '.- marker represents the portion of 1239 | % the circle (hence the o) to keep (top, bottom,left/right). 1240 | % Angle is customizable, for instance o'=50. 1241 | o'/.style={/tikz/out=####1,/tikz/in=180-####1}, 1242 | o'/.default=\zxDefaultSoftAngleO, 1243 | o./.style={/tikz/out=-####1,/tikz/in=180+####1}, 1244 | o./.default=\zxDefaultSoftAngleO, 1245 | -o/.style={/tikz/out=-90-####1,/tikz/in=90+####1}, 1246 | -o/.default=\zxDefaultSoftAngleO, 1247 | o-/.style={/tikz/out=-90+####1,/tikz/in=90-####1}, 1248 | o-/.default=\zxDefaultSoftAngleO, 1249 | % Similar to o, but can be used also for diagonal items. 1250 | % Why ()? Visualize fixing the top part and moving the bottom part. 1251 | (/.style={bend right=####1}, 1252 | (/.default=30, 1253 | )/.style={bend left=####1}, 1254 | )/.default=30, 1255 | ('/.style={bend left=####1}, 1256 | ('/.default=30, 1257 | (./.style={bend right=####1}, 1258 | (./.default=30, 1259 | <'/.style={out=####1,in=180,looseness=0.65}, 1260 | <'/.default=\zxDefaultSoftAngleChevron, 1261 | <./.style={out=-####1,in=180,looseness=0.65}, 1262 | <./.default=\zxDefaultSoftAngleChevron, 1263 | '>/.style={out=0,in=180-####1,looseness=0.65}, 1264 | '>/.default=\zxDefaultSoftAngleChevron, 1265 | .>/.style={out=0,in=180+####1,looseness=0.65}, 1266 | .>/.default=\zxDefaultSoftAngleChevron, 1267 | ^./.style={out=-90+####1,in=90,looseness=0.65}, 1268 | ^./.default=\zxDefaultSoftAngleChevron, 1269 | .^/.style={out=-90-####1,in=90,looseness=0.65}, 1270 | .^/.default=\zxDefaultSoftAngleChevron, 1271 | 'v/.style={out=90+####1,in=-90,looseness=0.65}, 1272 | 'v/.default=\zxDefaultSoftAngleChevron, 1273 | v'/.style={out=90-####1,in=-90,looseness=0.65}, 1274 | v'/.default=\zxDefaultSoftAngleChevron, 1275 | % Links with a s-like shape. 1276 | s/.style={/tikz/out=0,/tikz/in=180,looseness=0.6}, 1277 | % -s'.- shapes are like s, but with a soften (customizable like o) angle. 1278 | % The '. say if you are going up or down, and - forces a sharp angle (- is flat) on the side of the - 1279 | s'/.style={/tikz/out=####1,/tikz/in=180+####1}, 1280 | s'/.default=\zxDefaultSoftAngleS, 1281 | s./.style={/tikz/out=-####1,/tikz/in=180-####1}, 1282 | s./.default=\zxDefaultSoftAngleS, 1283 | -s'/.style={/tikz/out=0,/tikz/in=180+####1}, 1284 | -s'/.default=\zxDefaultSoftAngleS, 1285 | -s./.style={/tikz/out=0,/tikz/in=180-####1}, 1286 | -s./.default=\zxDefaultSoftAngleS, 1287 | s'-/.style={/tikz/out=####1,/tikz/in=180}, 1288 | s'-/.default=\zxDefaultSoftAngleS, 1289 | s.-/.style={/tikz/out=-####1,/tikz/in=180}, 1290 | s.-/.default=\zxDefaultSoftAngleS, 1291 | % Links with a s-like shape... but read from top to bottom 1292 | ss/.style={/tikz/out=0-90,/tikz/in=180-90,looseness=0.6}, 1293 | % -s'.- shapes are like s, but with a soften (customizable like o) angle. 1294 | % The '. say if you are going up or down, and - forces a sharp angle (- is flat) on the side of the - 1295 | ss./.style={/tikz/out=####1-90,/tikz/in=180-90+####1}, 1296 | ss./.default=\zxDefaultSoftAngleS, 1297 | .ss/.style={/tikz/out=-####1-90,/tikz/in=180-90-####1}, 1298 | .ss/.default=\zxDefaultSoftAngleS, 1299 | sIs./.style={/tikz/out=0-90,/tikz/in=180-90+####1}, 1300 | sIs./.default=\zxDefaultSoftAngleS, 1301 | .sIs/.style={/tikz/out=0-90,/tikz/in=180-90-####1}, 1302 | .sIs/.default=\zxDefaultSoftAngleS, 1303 | ss.I/.style={/tikz/out=####1-90,/tikz/in=180-90}, 1304 | ss.I/.default=\zxDefaultSoftAngleS, 1305 | I.ss/.style={/tikz/out=-####1-90,/tikz/in=180-90}, 1306 | I.ss/.default=\zxDefaultSoftAngleS, 1307 | %%%% Links with a N-shape, i.e. like s shape, but symetric against the diagonal. Equivalently, it's a soft 's' shape with a much wider angle (>45). 1308 | N'/.style={/tikz/out=####1,/tikz/in=180+####1}, 1309 | N'/.default=\zxDefaultSoftAngleN, 1310 | N./.style={/tikz/out=-####1,/tikz/in=180-####1}, 1311 | N./.default=\zxDefaultSoftAngleN, 1312 | -N'/.style={/tikz/out=0,/tikz/in=180+####1}, 1313 | -N'/.default=\zxDefaultSoftAngleN, 1314 | -N./.style={/tikz/out=0,/tikz/in=180-####1}, 1315 | -N./.default=\zxDefaultSoftAngleN, 1316 | N'-/.style={/tikz/out=####1,/tikz/in=180}, 1317 | N'-/.default=\zxDefaultSoftAngleN, 1318 | N.-/.style={/tikz/out=-####1,/tikz/in=180}, 1319 | N.-/.default=\zxDefaultSoftAngleN, 1320 | }, 1321 | % No line but vdots/dots in between. 1322 | 3 vdots/.style={draw=none, "\makebox[0pt][r]{\footnotesize\smash{##1\,}}\scalebox{\zxScaleDots}{$\cvdotsCenterMathline$}" {anchor=center,zxNormalFont}}, 1323 | 3 vdots/.default={}, 1324 | 3 vdotsr/.style={draw=none, "\scalebox{\zxScaleDots}{$\cvdotsCenterMathline$}\makebox[0pt][l]{\footnotesize\smash{\,##1}}" {anchor=center,zxNormalFont}}, 1325 | 3 vdotsr/.default={}, 1326 | 3 dots/.style={draw=none, "\makebox[0pt][r]{\footnotesize\smash{##1}}\scalebox{\zxScaleDots}{$\chdots$}" {anchor=center,zxNormalFont}}, 1327 | 3 dots/.default={}, 1328 | % Add a Hadmard/Z/X (no phase) in the middle of the line. Practical to add small nodes without creating 1329 | % a new column/row. However, make sure the corresponding row/column is larger, using &[\zxHCol] 1330 | % for columns and \\[\zxHRow] for rows (for Z/X style, use zxSCol and sxSRow), if you have both spiders 1331 | % and Hadamard, use \zxHSCol and \zxHSRow. 1332 | H/.style={"" {zxHSmall,anchor=center,##1}}, 1333 | H/.default={}, 1334 | Z/.style={"" {zxNoPhaseSmallZ,anchor=center,##1}}, 1335 | Z/.default={}, 1336 | X/.style={"" {zxNoPhaseSmallX,anchor=center,##1}}, 1337 | X/.default={}, 1338 | % Sometimes, it might be handy to specify an anchor only if no anchor was set before, notably when using "post arrow style if end node" (see 1339 | % for instance the Divider). 1340 | end anchor if not set/.code={% 1341 | \ifx\tikzcd@endanchor\pgfutil@empty% If there is no anchor, we can set ours: 1342 | \pgfkeysalso{/tikz/commutative diagrams/end anchor={##1}}% 1343 | \fi% 1344 | }, 1345 | start anchor if not set/.code={% 1346 | \ifx\tikzcd@startanchor\pgfutil@empty% If there is no anchor, we can set ours: 1347 | \pgfkeysalso{/tikz/commutative diagrams/start anchor=##1}% 1348 | \fi% 1349 | }, 1350 | % Arrow will go out from the center of the shape instead of from the border. Useful e.g. 1351 | % when connecting nodes with different shapes, it will give back a symetric connection. 1352 | wire centered/.style={ 1353 | on layer=edgelayer, 1354 | /tikz/commutative diagrams/start anchor=center, 1355 | /tikz/commutative diagrams/end anchor=center, 1356 | }, 1357 | wire centered start/.style={ 1358 | on layer=edgelayer, 1359 | /tikz/commutative diagrams/start anchor=center, 1360 | }, 1361 | wire centered end/.style={ 1362 | on layer=edgelayer, 1363 | /tikz/commutative diagrams/end anchor=center, 1364 | }, 1365 | wc/.style={wire centered}, 1366 | wcs/.style={wire centered start}, 1367 | wce/.style={wire centered end}, 1368 | wire not centered/.style={ 1369 | /tikz/commutative diagrams/start anchor=, 1370 | /tikz/commutative diagrams/end anchor=, 1371 | }, 1372 | }, 1373 | %% Will be loaded in tikzcd options directly. 1374 | /zx/styles/rounded style preload/.style={ 1375 | content fixed baseline/.style={ 1376 | /zx/user overlay nodes/.style={ 1377 | zxShort/.append style={content fixed baseline}, 1378 | % fixed baseline gives poor result in fractions, so we disable it here 1379 | zxSpecificFrac/.append style={content vertically centered}, 1380 | }, 1381 | }, 1382 | content fixed baseline also frac/.style={ 1383 | /zx/user overlay nodes/.style={ 1384 | zxShort/.append style={content fixed baseline}, 1385 | }, 1386 | }, 1387 | content vertically centered/.style={ 1388 | /zx/user overlay nodes/.style={ 1389 | zxShort/.append style={content vertically centered} 1390 | }, 1391 | }, 1392 | /zx/styles/rounded style common nodes and ZX, 1393 | }, 1394 | % These styles make sense both in "ZX" options and in nodes options. 1395 | /zx/styles/rounded style common nodes and ZX/.style={ 1396 | small minus/.code={ 1397 | \def\zxMinus{\zxShortMinus}% 1398 | \def\zxMinusInShort{\zxShortMinus}% 1399 | }, 1400 | big minus/.code={ 1401 | \def\zxMinus{-}% 1402 | \def\zxMinusInShort{-}% 1403 | }, 1404 | }, 1405 | /zx/styles/rounded style/.style={ 1406 | /zx/styles/rounded style common nodes and ZX, 1407 | %% Can be redefined by user 1408 | % Style for empty nodes 1409 | zxSpacingInsideNodes/.style={ 1410 | execute at begin node={\thinmuskip=0mu\medmuskip=0mu\thickmuskip=0mu}, % Reduce space around +/-... 1411 | }, 1412 | %% Normalize fonts to avoid different rendering when document has a different font shape. 1413 | zxNormalFont/.style={ 1414 | font={\fontsize{10}{12}\selectfont}, 1415 | }, 1416 | % Practical styles to either vertically center the content, or fix the position of the baseline. 1417 | content fixed baseline/.style={ 1418 | text height=1.5mm,%5.4pt,%1.5mm,%.45em, 1419 | text depth=0.1mm,%1.8pt,%0.1mm,%.15em, 1420 | }, 1421 | % Style for empty nodes 1422 | content vertically centered/.style={ 1423 | text height=, 1424 | text depth=, 1425 | }, 1426 | bold/.style={very thick}, 1427 | B/.style={bold}, 1428 | non bold/.style={line width=\zxDefaultLineWidth,}, 1429 | NB/.style={non bold}, 1430 | %% To set bold all wires connected to the current wire 1431 | wires bold/.style={ 1432 | post arrow style if end node={B}, 1433 | post arrow style if start node={B}, 1434 | }, 1435 | Bw/.style={wires bold}, 1436 | BBw/.style={bold, wires bold,}, 1437 | zxAllNodes/.style={ 1438 | shape=rectangle, % Otherwise nodes are asymetrical rectangle, which is not practical in our case. Gives notably anchor "center" which is really centered compared to asymatrical rectangles 1439 | anchor=center, % Center cells 1440 | line width=\zxDefaultLineWidth, 1441 | % Normalize the font size (avoids different rendering of dots...) 1442 | zxSpacingInsideNodes, 1443 | zxNormalFont, 1444 | }, 1445 | % Use this to denote an empty diagram 1446 | zxEmptyDiagram/.style={ 1447 | zxAllNodes, 1448 | draw, 1449 | dashed, 1450 | minimum size=4mm, 1451 | }, 1452 | % Style to use when no node is drawn 1453 | zxNone/.style={ 1454 | zxAllNodes, 1455 | shape=coordinate, % A coordinate has just a center. Nothing more. 1456 | }, 1457 | % Style to use when no node is drawn, but a bit of space is required not to make the diagram too small 1458 | zxNone+/.style={ 1459 | zxAllNodes, 1460 | inner sep=1mm, 1461 | outer sep=0mm 1462 | }, 1463 | % Like zxNone+, but without width (wold prefer |, but special car in |[]|... 1464 | zxNoneI/.style={ 1465 | zxNone+, 1466 | inner xsep=0mm, 1467 | }, 1468 | % Like zxNone+, but without height 1469 | zxNone-/.style={ 1470 | zxNone+, 1471 | inner ysep=0mm, 1472 | }, 1473 | % Style to use when no node is drawn, but a large space must be reserved (typically used to fake two 1474 | % nodes on a single line) (for +I- versions) 1475 | zxNoneDouble/.style={ 1476 | shape=coordinate 1477 | }, 1478 | % Style to use when no node is drawn, but a bit of space is required not to make the diagram too small 1479 | zxNoneDouble+/.style={ 1480 | zxAllNodes, 1481 | inner sep=.6em, 1482 | outer sep=0mm 1483 | }, 1484 | % Like zxNoneDouble+, but without width (wold prefer |, but special car in |[]|... 1485 | zxNoneDoubleI/.style={ 1486 | zxNoneDouble+, 1487 | inner xsep=0mm, 1488 | }, 1489 | % Like zxNoneDouble+, but without height 1490 | zxNoneDouble-/.style={ 1491 | zxNoneDouble+, 1492 | inner ysep=0mm, 1493 | }, 1494 | % Used to compute the intersection with the node's boundary 1495 | allow boundary intersection/.code={% 1496 | \ifdefined\zxEnableIntersectionsNodes% 1497 | \edef\zx@name@path{zx@name@path@\tikz@fig@name}% 1498 | \zx@message{[ZX] The name of the path will be \zx@name@path.}% 1499 | \pgfkeysalso{ 1500 | name path=\zx@name@path, % Used by intersection library 1501 | }% 1502 | \fi% 1503 | }, 1504 | % Will be specific to all spiders 1505 | zxSpiders/.style={ 1506 | draw=black, 1507 | allow boundary intersection,% Used later to do math on it. 1508 | }, 1509 | % Will use this style when drawing a X/Z node without phase (not for end user directly) 1510 | zxNoPhase/.style={ 1511 | zxAllNodes, 1512 | zxSpiders, 1513 | inner sep=0mm, 1514 | minimum size=2mm, 1515 | shape=circle, 1516 | }, 1517 | % Used only in decoration of wires, to add small empty X/Z nodes. 1518 | zxNoPhaseSmall/.style={ 1519 | zxNoPhase 1520 | }, 1521 | % Style for nodes that are small enough to fit in a circle, like $\zxMinus \frac{\pi}{4}$ or $- \alpha$ 1522 | zxShort/.style={ 1523 | zxAllNodes, 1524 | zxSpiders, 1525 | minimum size=5mm, 1526 | font={\fontsize{8}{10}\selectfont\boldmath}, 1527 | rounded rectangle, 1528 | inner sep=0.0mm, 1529 | scale=0.8, 1530 | },% negative outer sep would draw lines from inside... 1531 | % Style for nodes that are bigger, like $\alpha+\beta$ or $(a\oplus b)\pi$ 1532 | zxLong/.style={zxShort, inner xsep=1.2mm}, 1533 | %%% Styles of the label when |phase in label| is used 1534 | stylePhaseInLabel/.style={ 1535 | font={\fontsize{8}{10}\selectfont\boldmath}, 1536 | inner sep=2pt, 1537 | outer sep=0pt, 1538 | rounded rectangle, 1539 | % node on layer=labellayer, %% Fails in tikzcd: https://tex.stackexchange.com/questions/618823/node-on-layer-style-in-tikz-matrix-tikzcd 1540 | }, 1541 | stylePhaseInLabelZ/.style={ 1542 | stylePhaseInLabel, 1543 | fill=green!20!white 1544 | }, 1545 | stylePhaseInLabelX/.style={ 1546 | stylePhaseInLabel, 1547 | fill=red!20!white 1548 | }, 1549 | % Some styles should be applied only on frac 1550 | zxSpecificFrac/.style={ 1551 | }, 1552 | %%%%%%%%%%% Style defined depending on above ones. Feel free to redefine. 1553 | zxNoPhaseZ/.style={zxNoPhase,fill=colorZxZ}, 1554 | zxNoPhaseX/.style={zxNoPhase,fill=colorZxX}, 1555 | zxNoPhaseSmallZ/.style={zxNoPhaseSmall,fill=colorZxZ}, 1556 | zxNoPhaseSmallX/.style={zxNoPhaseSmall,fill=colorZxX}, 1557 | zxShortZ/.style={zxShort,fill=colorZxZ}, 1558 | zxShortX/.style={zxShort,fill=colorZxX}, 1559 | zxLongZ/.style={zxLong,fill=colorZxZ}, 1560 | zxLongX/.style={zxLong,fill=colorZxX}, 1561 | %%%%%%%%%%% 1562 | %%% Instead of adding directly the style as the node's content (which would make 1563 | %%% impossible styles that adds the phase in a label outside of the node) 1564 | %%% add@Phase@Spider{,Z,X}={phase of the node} will be in charge of adding it. 1565 | % add@Phase@Spider{emptyStyle}{ShortStyle}{LongStyle}{label style}{node content} 1566 | add@Phase@Spider/.style n args={5}{% 1567 | zx@emptyStyle/.style={##1}, 1568 | zx@shortStyle/.style={##2}, 1569 | zx@notEmptyStyle/.style={##3}, 1570 | zx@labelStyle/.style={##4}, 1571 | /zx/zx@content/.initial={##5}, 1572 | phase in content, 1573 | }, 1574 | add@Phase@Spider@Frac/.style n args={8}{% add@Phase@Spider{emptyStyle}{NotEmptyStyle}{labelstyle}{sign}{above fraction (no parens)}{below fraction (no parens)}{above fraction (parens)}{below fraction (parens)} 1575 | zx@emptyStyle/.style={##1}, 1576 | zx@notEmptyStyle/.style={##2}, 1577 | zx@labelStyle/.style={##3}, 1578 | % Useful to help "phase in content" to know if we are in Frac or not. 1579 | /zx/zx@isInFrac/.initial={true}, 1580 | phase in content, 1581 | }, 1582 | % #1 is the node content. Seems that storing it in /zx/zx@content is not enough because keys 1583 | % seems to be local to nodes and are not transfered to label. 1584 | zx@Execute@Very@End/.style n args={5}{ 1585 | zx@commandToExecuteVeryEnd/.try={##1}{##2}{##3}{##4}{##5}, 1586 | }, 1587 | zx@Execute@Very@End/.default={}{}{}{}, 1588 | %% zx@Execute@Very@End@Frac={emptystyle}{contentstyle}{labelstyle}{sign}{above frac (no parens)}{below frac (no parens)}{above frac (parens)}{below frac (parens)} 1589 | zx@Execute@Very@End@Frac/.style n args={8}{ 1590 | zx@commandToExecuteVeryEndFrac/.try={##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}, 1591 | }, 1592 | zx@Execute@Very@End@Frac/.default={}{}{}{}{}{}{}{}, 1593 | %% /!\ WARNING: the following styles "phase..." must be loaded by or *after* add@Phase@Spider... 1594 | %% To load it on the whole picture, prefer to do: 1595 | %% \zx[/zx/user post preparation labels/.style={phase in label}]{ 1596 | %% \zxZ{\alpha} 1597 | %% } 1598 | phase in content/.code={% 1599 | % Check if we are in a Frac or not 1600 | \ifthenelse{\equal{\pgfkeysvalueof{/zx/zx@isInFrac}}{true}}{% 1601 | %%% ### We are in a fraction node! 1602 | %% Modifies zx@commandToExecuteVeryEnd (which is executed at the very end by zx@Execute@Very@End) 1603 | %% in order to add the good style 1604 | \pgfkeysalso{ 1605 | % zx@commandToExecuteVeryEndFrac{emptystyle}{contentstyle}{labelstyle}{sign}{above frac (no parens)}{below frac (no parens)}{above frac (parens)}{below frac (parens)} 1606 | zx@commandToExecuteVeryEndFrac/.style n args={8}{% 1607 | execute at begin node={\zxConvertToFracInContent{####4}{####5}{####6}{####7}{####8}},% 1608 | },% 1609 | % Adds the style: 1610 | zx@notEmptyStyle, 1611 | }% 1612 | }{ %%% ### We are NOT in a fraction node. 1613 | %% Modifies zx@commandToExecuteVeryEnd (which is executed at the very end by zx@Execute@Very@End) 1614 | %% in order to add the good style 1615 | \pgfkeysalso{ 1616 | zx@commandToExecuteVeryEnd/.style n args={5}{% 1617 | execute at begin node={####5},% ####4 = content 1618 | }% 1619 | }% 1620 | % Checks if the content (stored by add@Phase@Spider in /zx/zx@content) is empty or not 1621 | \ifthenelse{\equal{\pgfkeysvalueof{/zx/zx@content}}{}}{% 1622 | \pgfkeysalso{% 1623 | zx@emptyStyle,% 1624 | }% 1625 | }{% We check if we need to force "short mode" (zxShort instead of zxLong) 1626 | \ifthenelse{\equal{\pgfkeysvalueof{/zx/zx@shortModeForced}}{true}}{% 1627 | \pgfkeysalso{% 1628 | zx@shortStyle,% 1629 | }% 1630 | }{% Otherwise, just use the default style. 1631 | \pgfkeysalso{% 1632 | zx@notEmptyStyle,% 1633 | }% 1634 | }% 1635 | }% 1636 | }% 1637 | }, 1638 | phase in label/.code={ 1639 | % Check if we are in a Frac or not 1640 | \ifthenelse{\equal{\pgfkeysvalueof{/zx/zx@isInFrac}}{true}}{% 1641 | %%% ### We are in a fraction node! 1642 | \pgfkeysalso{% 1643 | % zx@commandToExecuteVeryEndFrac{emptystyle}{contentstyle}{labelstyle}{sign}{above frac (no parens)}{below frac (no parens)}{above frac (parens)}{below frac (parens)} 1644 | zx@commandToExecuteVeryEndFrac/.code n args={8}{% 1645 | \pgfkeysalso{ 1646 | label={[####3,##1] \zxConvertToFracInLabel{####4}{####5}{####6}{####7}{####8}},% 1647 | }% 1648 | },% 1649 | zx@emptyStyle, 1650 | }% 1651 | }{% 1652 | \pgfkeysalso{% 1653 | % ##1 is the argument of "phase in label", i.e. the style of the label 1654 | zx@commandToExecuteVeryEnd/.code n args={5}{% ####4: label style, ####5: content 1655 | % Checks if the content (stored by add@Phase@Spider in /zx/zx@content) is empty or not 1656 | \ifthenelse{\equal{####5}{}}{% Content is empty 1657 | }{% Content is not empty 1658 | \pgfkeysalso{ 1659 | label={[####4,##1] ####5},% 1660 | }% 1661 | }% 1662 | },% 1663 | zx@emptyStyle, 1664 | }% 1665 | }% 1666 | }, 1667 | pil/.style={phase in label={##1}}, 1668 | phase in label below/.style={ 1669 | phase in label={label position=below,##1} 1670 | }, 1671 | pilb/.style={phase in label below={##1}}, 1672 | phase in label above/.style={ 1673 | phase in label={label position=above,##1} 1674 | }, 1675 | pila/.style={phase in label above={##1}}, 1676 | phase in label right/.style={ 1677 | phase in label={label position=right,##1} 1678 | }, 1679 | pilr/.style={phase in label right={##1}}, 1680 | phase in label left/.style={ 1681 | phase in label={label position=left,##1} 1682 | }, 1683 | pill/.style={phase in label left={##1}}, 1684 | %%% Was supposed to automatically find the good style depending on content... Can't find how to do. 1685 | % Styles zxLong{X/Z} zxNoPhase{X/Z} are automatically selected by \zxZ4{...} and \zxX4{...} commands 1686 | % and zxShort is selected for fractions only like in \zxFracZ-{\pi}{4} 1687 | % zxZ/.style={zxChoose={##1},fill=colorZxZ}, 1688 | % zxX/.style={zxChoose={##1},fill=colorZxX}, 1689 | %%% First argument is additional style. 1690 | %%% Second argument is the minus mode: "-" for minus sign, which forces short mode. 1691 | %%% Third argument is "*" for forced short mode. 1692 | %%% 4th argument is content of node. 1693 | zx@spider/.code n args={8}{ 1694 | %% ##1: zxnophase style 1695 | %% ##2: zxshort style 1696 | %% ##3: zxlong style 1697 | %% ##4: label style 1698 | %% user provided: 1699 | %% ##5: additional tikz options 1700 | %% ##6: minus "-" or empty, like "-alpha" 1701 | %% ##7: star "*" or empty, to force short mode 1702 | %% ##8: content 1703 | %%% The argument is a minus. Like \zxZ-{\alpha}, goal is to typeset "-\alpha" in short mode. 1704 | \ifthenelse{\equal{##6}{-}}{% It's a minus! 1705 | \pgfkeysalso{% We update the content to "-content" 1706 | /zx/zx@shortModeForced/.initial={true},% 1707 | }% 1708 | }{}% 1709 | \ifthenelse{\equal{##7}{*}}{% We force short mode! 1710 | \pgfkeysalso{% 1711 | /zx/zx@shortModeForced/.initial={true},% 1712 | }% 1713 | }{}% 1714 | % It's a minus, and LaTeX is... grrrr. How to get a cleaner code? Tried def/let, not working. 1715 | \ifthenelse{\equal{##6}{-}}{% 1716 | \pgfkeysalso{% 1717 | add@Phase@Spider={##1}{##2}{##3}{##4}{\zxMinusInShort##8},% 1718 | }% 1719 | }{% 1720 | \pgfkeysalso{% 1721 | add@Phase@Spider={##1}{##2}{##3}{##4}{##8},% 1722 | }% 1723 | }% 1724 | \pgfkeysalso{% 1725 | /zx/post preparation labels, 1726 | /zx/user post preparation labels, 1727 | % /zx/user overlay nodes, 1728 | ##5, 1729 | }% 1730 | \ifthenelse{\equal{##6}{-}}{% It's a minus, and LaTeX is... grrrr 1731 | \pgfkeysalso{% 1732 | zx@Execute@Very@End={##1}{##2}{##3}{##4}{\zxMinusInShort##8},% 1733 | }% 1734 | }{% 1735 | \pgfkeysalso{% 1736 | zx@Execute@Very@End={##1}{##2}{##3}{##4}{##8},% 1737 | }% 1738 | }% 1739 | }, 1740 | %% ##1: additional tikz options 1741 | %% ##2: minus "-" or empty, like "-alpha" 1742 | %% ##3: star "*" or empty, to force short mode 1743 | %% ##4: content 1744 | zxZ4/.style n args={4}{ 1745 | zx@spider={zxNoPhaseZ}{zxShortZ}{zxLongZ}{stylePhaseInLabelZ}{##1}{##2}{##3}{##4} 1746 | }, 1747 | zxX4/.style n args={4}{ 1748 | zx@spider={zxNoPhaseX}{zxShortX}{zxLongX}{stylePhaseInLabelX}{##1}{##2}{##3}{##4} 1749 | }, 1750 | %% These take 6 arguments: additional style, sign (string "-" for minus, nothing for "+", 1751 | %% otherwise inserted directly), above fraction (no parens), below fraction (no parens), above fraction (parens), below fraction (parens). 1752 | zxFracZ6/.style n args={6}{ 1753 | add@Phase@Spider@Frac={zxNoPhaseZ}{zxShortZ,zxSpecificFrac}{stylePhaseInLabelZ}{##2}{##3}{##4}{##5}{##6}, 1754 | /zx/post preparation labels, 1755 | /zx/user post preparation labels, 1756 | ##1, 1757 | zx@Execute@Very@End@Frac={zxNoPhaseZ}{zxShortZ,zxSpecificFrac}{stylePhaseInLabelZ}{##2}{##3}{##4}{##5}{##6}, 1758 | }, 1759 | zxFracX6/.style n args={6}{ 1760 | add@Phase@Spider@Frac={zxNoPhaseX}{zxShortX}{stylePhaseInLabelX}{##2}{##3}{##4}{##5}{##6}, 1761 | /zx/post preparation labels, 1762 | /zx/user post preparation labels, 1763 | ##1, 1764 | zx@Execute@Very@End@Frac={zxNoPhaseX}{zxShortX}{stylePhaseInLabelX}{##2}{##3}{##4}{##5}{##6}, 1765 | }, 1766 | % For Hadamard 1767 | zxH/.style={ 1768 | zxAllNodes, 1769 | outer sep=0pt, 1770 | fill=colorZxH, 1771 | draw, 1772 | inner sep=0.6mm, 1773 | minimum height=1.5mm, 1774 | minimum width=1.5mm, 1775 | shape=rectangle}, 1776 | zxHSmall/.style={zxH}, 1777 | }, 1778 | % Default style. Can be changed by user 1779 | /zx/default style nodes/.style={ 1780 | /zx/styles/rounded style 1781 | }, 1782 | % Will be executed in tikzcd options. Useful to define a "global" option specific to a given style. 1783 | /zx/default style nodes preload/.style={ 1784 | /zx/styles/rounded style preload, 1785 | }, 1786 | % User can put here any additional property 1787 | /zx/user overlay nodes/.style={ 1788 | }, 1789 | % User can put here any global ZX options 1790 | /zx/user overlay/.style={ 1791 | }, 1792 | % Any additional property that needs to be loaded after add@Phase@Spider (by script, not by user). 1793 | /zx/post preparation labels/.style={ 1794 | }, 1795 | % User can put here any additional property that needs to be loaded after add@Phase@Spider 1796 | /zx/user post preparation labels/.style={ 1797 | }, 1798 | % Default wire style. Can be changed by user. 1799 | /zx/default style wires/.style={ 1800 | }, 1801 | % User can add stuff in this style to improve wire styles 1802 | /zx/user overlay wires/.style={ 1803 | }, 1804 | /zx/defaultEnv/.style={ 1805 | %tiny depends on the size of the font... which we want to keep consistent look 1806 | column sep=\zxDefaultColumnSep, 1807 | row sep=\zxDefaultRowSep, 1808 | zx column sep/.code={% 1809 | \def\zxDefaultColumnSep{##1}% 1810 | \pgfkeysalso{ 1811 | column sep=##1, 1812 | }% 1813 | }, 1814 | zx row sep/.code={% 1815 | \def\zxDefaultRowSep{##1}% 1816 | \pgfkeysalso{% 1817 | row sep=##1, 1818 | }% 1819 | }, 1820 | %column sep=tiny, 1821 | %row sep=tiny, 1822 | % center on the math axis 1823 | baseline={([yshift=-axis_height]current bounding box.center)}, 1824 | % Fix 1-row diagram baseline 1825 | % By default, 1-row diagrams have a different baseline... This package does not want a special case for 1-row diagrams. 1826 | 1-row diagram/.style={}, 1827 | %% usage: math baseline=wantedBaseline, where you have somewhere \zxX[a=wantedBaseline]{\beta} 1828 | math baseline/.style={baseline={([yshift=-axis_height]##1)}}, 1829 | math baseline row/.style={math baseline=\tikzcdmatrixname-##1-1}, 1830 | math baseline row/.default={1}, 1831 | mbr/.style={math baseline row={##1}}, 1832 | mbr/.default={1}, 1833 | debug mode/.code={\def\zxDebugMode{}}, 1834 | no debug mode/.code={\let\zxDebugMode\undefined}, 1835 | amp/.style={ 1836 | ampersand replacement=\&, 1837 | }, 1838 | %%% Include a diagram in another diagram. 1839 | use diagram/.style 2 args={ 1840 | execute at end picture={ 1841 | \node[fit=##2,anchor=center,inner sep=0pt,yshift=-axis_height]{\zxUseDiagram{##1}}; 1842 | } 1843 | }, 1844 | %%% Include a diagram in another diagram. 1845 | use diagram advanced/.style n args={3}{ 1846 | execute at end picture={ 1847 | \node[fit=##2,anchor=center,inner sep=0pt,yshift=-axis_height,##3]{\zxUseDiagram{##1}}; 1848 | } 1849 | }, 1850 | % Load (thanks ".search also") our own style 1851 | /tikz/every node/.style={% 1852 | % Otherwise, the empty nodes take some space… and create weird bugs. But I don't know how to add empties 1853 | % https://tex.stackexchange.com/questions/675958/tikz-empty-nodes-with-different-style-coordinate 1854 | % ==> solved, see "empty" 1855 | nodes={ 1856 | zxAllNodes, 1857 | inner sep=0pt, 1858 | outer sep=0mm, 1859 | }, 1860 | % For quickly adding alias, and displaying this alias in debug mode. 1861 | a/.code={% 1862 | \pgfkeysalso{% 1863 | % alias=####1,% 1864 | % alias seems to fail with nodes in pic… let's try another method. See also: 1865 | % https://tex.stackexchange.com/questions/679647/tikz-pic-alias-to-internal-node 1866 | %% TODO: according to the above discussion, this append after command should be done after the 1867 | %% add anchor to node is finished, as an alias is basically copying all the macros of the initial node, 1868 | %% so you want to do it once its finished (in particular to preserve the anchors). But maybe 1869 | %% append after command is already avoiding that issue. In any case it would be good to make it more 1870 | %% robust (\tikzlastnode might change, so defining my own \tikzlastnode might help, use link instead 1871 | %% of copy alias to be sure the anchors are preserved etc...) 1872 | append after command={\pgfextra{% 1873 | \pgfnodealias{####1}{\tikzlastnode}% 1874 | % There is no way anymore to remember the link between the alias and the non-alias. Let's rembember it 1875 | % manually 1876 | \expanded{\noexpand\gdef\csname zx@alias@\zxCurrentDiagram @####1\endcsname{\tikzlastnode}}% 1877 | }% 1878 | }, 1879 | }% 1880 | %% name path won't work with alias... So let's create two name path ^^ 1881 | %% https://tex.stackexchange.com/questions/619622 1882 | \ifdefined\zxEnableIntersectionsNodes% 1883 | \edef\zx@name@path{zx@name@path@####1}% 1884 | \zx@message{[ZX] Name given using an alias: \zx@name@path.}% 1885 | \pgfkeysalso{ 1886 | name path=\zx@name@path, % Used by intersection library 1887 | }% 1888 | \fi% 1889 | \ifdefined\zxDebugMode% 1890 | \pgfkeysalso{% 1891 | label={[inner sep=0pt,overlay,red,font={\fontsize{5}{6}}]-45:\scalebox{.5}{####1}} 1892 | }% 1893 | \fi% 1894 | }, 1895 | %% This allows nodes to specify styles for the arrows that start/end from them. 1896 | %% This style will be loaded last as otherwise we don't know yet the starting and ending point. 1897 | %% See how we apply it on the arrow side using "every arrow post" 1898 | post arrow style if start node/.style={% 1899 | append after command={% This expects a path, but we want to write a code without any path: 1900 | \pgfextra% this syntax with \endpgfextra completely turns off the tikz syntax, that might be safer than \pgfextra{...}. 1901 | \def\zx@arguments{####1}% 1902 | \edef\zx@tmp{% 1903 | /zx/internals/postRunIfIamStartNode-\tikzlastnode/.append style={\unexpanded\expandafter{\zx@arguments}},% 1904 | }% https://tex.stackexchange.com/questions/47905/how-to-globally-tikzset-styles 1905 | {% 1906 | \globaldefs=1\relax% 1907 | \pgfkeysalsofrom{\zx@tmp}% 1908 | }% 1909 | \endpgfextra% 1910 | },% 1911 | }, 1912 | post arrow style if end node/.style={% 1913 | append after command={% This expects a path, but we want to write a code without any path: 1914 | \pgfextra% this syntax with \endpgfextra completely turns off the tikz syntax, that might be safer than \pgfextra{...}. 1915 | \def\zx@arguments{####1}% 1916 | \edef\zx@tmp{% 1917 | /zx/internals/postRunIfIamEndNode-\tikzlastnode/.append style={\unexpanded\expandafter{\zx@arguments}},% 1918 | }% https://tex.stackexchange.com/questions/47905/how-to-globally-tikzset-styles 1919 | {% 1920 | \globaldefs=1\relax% 1921 | \pgfkeysalsofrom{\zx@tmp}% 1922 | }% 1923 | \endpgfextra% 1924 | },% 1925 | },% 1926 | /zx/default style nodes, 1927 | /zx/user overlay nodes, 1928 | }, 1929 | every arrow/.style={% 1930 | /zx/wires definition, 1931 | /zx/default style wires, 1932 | /zx/user overlay wires, 1933 | %%% Load the post arrow style at the end: 1934 | /tikz/commutative diagrams/every arrow post/.append style={% 1935 | /utils/exec={% We provide a way to disable the default behavior 1936 | \ifdefined\zxDisablePostRunStart\else% 1937 | %%% If it is an alias, we replace it with the original node: 1938 | \ifcsname zx@alias@\zxCurrentDiagram @\tikzcd@ar@start\endcsname% This is an alias: let's rename it to the original node 1939 | \edef\tikzcd@ar@start{\csname zx@alias@\zxCurrentDiagram @\tikzcd@ar@start\endcsname}% 1940 | \fi% 1941 | %%% Load the arrow style set by the start node: 1942 | \edef\zx@tmp{% Make sure that the style exists and load it: 1943 | /zx/internals/postRunIfIamStartNode-\tikzcd@ar@start/.append style={},% 1944 | /zx/internals/postRunIfIamStartNode-\tikzcd@ar@start,% 1945 | }% 1946 | \pgfkeysalsofrom{\zx@tmp}% 1947 | \fi% 1948 | %%% Load the arrow style set by the end node: 1949 | \ifdefined\zxDisablePostRunEnd\else% 1950 | %%% If it is an alias, we replace it with the original node: 1951 | \ifcsname zx@alias@\zxCurrentDiagram @\tikzcd@ar@target\endcsname% This is an alias: let's rename it to the original node 1952 | \edef\tikzcd@ar@target{\csname zx@alias@\zxCurrentDiagram @\tikzcd@ar@target\endcsname}% 1953 | \fi% 1954 | \edef\zx@tmp{% Make sure that the style exists and load it: 1955 | /zx/internals/postRunIfIamEndNode-\tikzcd@ar@target/.append style={},% 1956 | /zx/internals/postRunIfIamEndNode-\tikzcd@ar@target,% 1957 | }% 1958 | \pgfkeysalsofrom{\zx@tmp}% 1959 | \fi% 1960 | }% 1961 | },% 1962 | disable post run start/.code={\def\zxDisablePostRunStart{}}, 1963 | disable post run end/.code={\def\zxDisablePostRunEnd{}}, 1964 | disable post run/.style={ 1965 | disable post run start, 1966 | disable post run end, 1967 | }, 1968 | }, 1969 | %% We add an empty coordinate in every node. This has multiple advantages: first this avoids errors about 1970 | %% single ampersand when the matrix does not start with None, and it also avoids using \zxN{} everywhere. 1971 | %% However, we can't just use 'nodes in empty cells=true' or it will add nodes that might take some space: 1972 | /tikz/execute at empty cell={ 1973 | \coordinate[ 1974 | % yshift=axis_height, % We already do that elsewhere 1975 | name=\tikzmatrixname 1976 | -\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn]; 1977 | }, 1978 | % When an arrow is present, it will not detect it as an empty cell… The below code tries to avoid this issue, but actually has another issue as it removes all nodes without text in it, like |[circle, draw, inner sep=3pt]|, so 1979 | % we disable it for now. 1980 | %% https://tex.stackexchange.com/questions/675958/tikz-empty-nodes-with-different-style-coordinate/675971#675971 1981 | % /tikz/every node/.append code={% 1982 | % \tikz@addoption{% 1983 | % \ifdim\wd\pgfnodeparttextbox=0pt 1984 | % \pgfutil@ifx\tikz@shape\tikz@coordinate@text{}{% 1985 | % \def\tikz@shape{coordinate}% 1986 | % \pgftransformyshift{axis_height}}% 1987 | % \fi}% 1988 | % }, 1989 | %%% To be used only in \zx{...} environment. 1990 | %%% Exemple: 1991 | phase in content/.style={ 1992 | /zx/post preparation labels/.append style={ 1993 | phase in content, 1994 | } 1995 | }, 1996 | phase in label/.style={ 1997 | /zx/post preparation labels/.append style={ 1998 | phase in label={##1}, 1999 | } 2000 | }, 2001 | phase in label above/.style={ 2002 | /zx/post preparation labels/.append style={ 2003 | phase in label above={##1}, 2004 | } 2005 | }, 2006 | phase in label below/.style={ 2007 | /zx/post preparation labels/.append style={ 2008 | phase in label below={##1}, 2009 | } 2010 | }, 2011 | phase in label right/.style={ 2012 | /zx/post preparation labels/.append style={ 2013 | phase in label right={##1}, 2014 | } 2015 | }, 2016 | phase in label left/.style={ 2017 | /zx/post preparation labels/.append style={ 2018 | phase in label left={##1}, 2019 | } 2020 | }, 2021 | % for "Phase In Label" 2022 | pil/.style={phase in label={##1}}, 2023 | pilb/.style={phase in label below={##1}}, 2024 | pila/.style={phase in label above={##1}}, 2025 | pilr/.style={phase in label right={##1}}, 2026 | pill/.style={phase in label left={##1}}, 2027 | % Load the global options style-specific 2028 | /zx/default style nodes preload, 2029 | /zx/user overlay, 2030 | }, 2031 | } 2032 | 2033 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2034 | %%%% Helper functions 2035 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2036 | 2037 | 2038 | % Defines a "on layer=nameoflayer" style. TODO: check if better to move it in /zx/ 2039 | % https://tex.stackexchange.com/questions/20425/z-level-in-tikz/20426#20426 2040 | % For path: on layer=namelayer, for nodes "node on layer=..." 2041 | % /!\ node on layer fails in tikzcd: https://tex.stackexchange.com/questions/618823/node-on-layer-style-in-tikz-matrix-tikzcd 2042 | \pgfkeys{% 2043 | /tikz/on layer/.code={ 2044 | \pgfonlayer{#1}\begingroup 2045 | \aftergroup\endpgfonlayer 2046 | \aftergroup\endgroup 2047 | }, 2048 | /tikz/node on layer/.code={ 2049 | \gdef\node@@on@layer{% 2050 | \setbox\tikz@tempbox=\hbox\bgroup\pgfonlayer{#1}\unhbox\tikz@tempbox\endpgfonlayer\egroup} 2051 | \aftergroup\node@on@layer 2052 | }, 2053 | /tikz/end node on layer/.code={ 2054 | \endpgfonlayer\endgroup\endgroup 2055 | } 2056 | } 2057 | \def\node@on@layer{\aftergroup\node@@on@layer} 2058 | 2059 | %%% Declare a symbol for a short minus (useful in fractions) 2060 | \DeclareMathSymbol{\zxShortMinus}{\mathbin}{AMSa}{"39}% Requires amssymb. This version should not be redefined by the user to obtain a normal minus (or "small minus" won't work anymore) 2061 | \def\zxMinus{\zxShortMinus} 2062 | 2063 | %%% Checks if a function is a point or a node. 2064 | %%% Not sure if best solution (needed to dig into source of TeX), but can't find anything better in manual 2065 | %%% https://tex.stackexchange.com/questions/6189553 2066 | \def\ifPgfpointOrNode#1#2#3{% 2067 | \pgfutil@ifundefined{pgf@sh@ns@#1}{% 2068 | #2% 2069 | }{% 2070 | #3% 2071 | }% 2072 | } 2073 | 2074 | % shape anchor name if exists if not. Works, while doing \pgfutil@ifundefined{pgf@anchor@\shapenode{}@#2} fails. 2075 | % I guess it has to do with the way macro are expanded... 2076 | \def\ifAnchorExistsFromShape#1#2#3#4{% 2077 | \pgfutil@ifundefined{pgf@anchor@#1@#2}{% 2078 | #4% 2079 | }{% 2080 | #3% 2081 | }% 2082 | } 2083 | 2084 | % node name, anchor name, if exists, if not. 2085 | \def\ifAnchorExists#1#2#3#4{% 2086 | %%% First we extract the shape of the node: 2087 | \edef\pgf@node@name{#1}% 2088 | \edef\shapenode{\csname pgf@sh@ns@\pgf@node@name\endcsname}% e.g. rectangle 2089 | \ifAnchorExistsFromShape{\shapenode}{#2}{#3}{#4}% 2090 | } 2091 | 2092 | %% If we manually add an anchor to a note, \ifAnchorExists will not work. Hence this improved version: 2093 | %% Note that #3 and #4 will run in a group 2094 | \def\ifAnchorExistsNodeSpecific#1#2#3#4{% 2095 | \let\zxcalculus@tmp\undefined% This is used to run #3 and #4 outside the group 2096 | {% group not to pollute stuff with pgf@sh@ma 2097 | \ifcsname pgf@sh@ma@#1\endcsname% per node config 2098 | \csname pgf@sh@ma@#1\endcsname% we run the config 2099 | \fi% 2100 | %%% First we extract the shape of the node: 2101 | \edef\pgf@node@name{#1}% 2102 | \edef\shapenode{\csname pgf@sh@ns@\pgf@node@name\endcsname}% e.g. rectangle 2103 | \ifAnchorExistsFromShape{\shapenode}{#2}{\gdef\zxcalculus@tmp{}}{}% 2104 | }% 2105 | \ifdefined\zxcalculus@tmp% 2106 | #3% 2107 | \else% 2108 | #4% 2109 | \fi% 2110 | } 2111 | 2112 | %%% Create different kinds of dots... 2113 | %% https://tex.stackexchange.com/questions/617959 2114 | %% https://tex.stackexchange.com/questions/528774/excess-vertical-space-in-vdots/528775#528775 2115 | \DeclareRobustCommand\cvdotsAboveBaseline{% 2116 | \vbox{\baselineskip4\p@ \lineskiplimit\z@% 2117 | \hbox{.}\hbox{.}\hbox{.}} 2118 | } 2119 | 2120 | \DeclareRobustCommand{\cvdotsCenterMathline}{% 2121 | % vcenter is used to center the argument on the 'math axis', which is at half the height of an 'x', or about the position of a minus sign. 2122 | \vcenter{\cvdotsAboveBaseline}% 2123 | } 2124 | 2125 | \DeclareRobustCommand{\cvdotsCenterBaseline}{% 2126 | \raisebox{-.5\height}{% 2127 | $\cvdotsAboveBaseline$% 2128 | }% 2129 | } 2130 | 2131 | \DeclareRobustCommand{\chdots}{% 2132 | \raisebox{-.5\height}{% 2133 | \rotatebox{90}{% Maybe better options than rotatebox... 2134 | $\cvdotsAboveBaseline$% 2135 | }% 2136 | }% 2137 | } 2138 | 2139 | \DeclareRobustCommand{\cvdots}{\cvdotsCenterMathline} 2140 | 2141 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2142 | %%% Practical functions to nest diagrams 2143 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2144 | 2145 | \NewDocumentCommand{\zxSaveDiagram}{mO{}m}{ 2146 | \newsavebox{#1}% 2147 | \savebox{#1}{% 2148 | \ifdefined\tikz@library@external@loaded% Library external is loaded... 2149 | \tikzset{external/optimize=false}% Otherwise, tikz will try to optimize and replace the box with a text 2150 | \fi% 2151 | \begin{ZX}[#2]#3\end{ZX} 2152 | }% 2153 | } 2154 | 2155 | \NewDocumentCommand{\zxUseDiagram}{m}{ 2156 | \usebox{#1}% 2157 | } 2158 | 2159 | %%%%%%%%%%%%%%%%%%%%% 2160 | %%% Main environments 2161 | %%%%%%%%%%%%%%%%%%%%% 2162 | 2163 | % Quantikz has a bug which adds space automatically. 2164 | % https://tex.stackexchange.com/questions/618330 2165 | % Fixing that by copying the original (unpatched) functions, and reusing them later. 2166 | % Warning: you must load this package **before** quantikz otherwise the fix will not work. 2167 | \let\tikzcd@@originalCopyZx\tikzcd@ 2168 | \let\endtikzcd@originalCopyZx\endtikzcd 2169 | 2170 | %%%%% Main environment \begin{ZX}...\end{ZX}. However, we call it ZXNoExt because when using 2171 | %%%%% externalization (to save compilation time), we need to wrap it around a figure. 2172 | \NewDocumentEnvironment{ZXNoExt}{O{}}{% 2173 | \bgroup% 2174 | % Do not change the font size here or it will change axis_height... Use \fontsize{10}{12}\selectfont 2175 | % when drawing some texts instead. 2176 | % Add a switch in case someone really wants the current tikzcd version: 2177 | \ifdefined\doNotPatchQuantikz% Do not patch tikzcd. 2178 | \else% Restore locally original tikzcd. 2179 | \let\tikzcd@\tikzcd@@originalCopyZx% 2180 | \let\endtikzcd\endtikzcd@originalCopyZx% 2181 | \fi% 2182 | \ifdefined\zxDoNotPatchArrows% Do not patch arrows (we need sometimes "every arrow post") 2183 | \else% Copy/pasted from https://github.com/astoff/tikz-cd/blob/master/tikzlibrarycd.code.tex, just added "every arrow post". 2184 | %% I'm not sure which method is more resilient: patchcmd is likely to fail on minor library update, 2185 | %% while redefining \tikzcd@ar@new might not apply some major library upgrades (note that we redefine it 2186 | %% only locally). Since I don't know what is better, I do both depending on this macro 2187 | \ifdefined\zxUsePatchCmdToPatchArrows% 2188 | \patchcmd\tikzcd@ar@new% 2189 | {\path[/tikz/commutative diagrams/.cd,everyx arrow,#1]}% 2190 | {\path[/tikz/commutative diagrams/.cd,every arrow,#1,every arrow post]}% 2191 | {}% 2192 | {}% 2193 | \else% 2194 | \def\tikzcd@ar@new[##1]{% Make sure to turn #1 into ##1 as the command is nested 2195 | \pgfutil@g@addto@macro\tikzcd@savedpaths{% 2196 | \path[/tikz/commutative diagrams/.cd,every arrow,##1,every arrow post]%<--- we added every arrow post 2197 | (\tikzcd@ar@start\tikzcd@startanchor) to (\tikzcd@ar@target\tikzcd@endanchor); }}% 2198 | \fi% 2199 | \fi% 2200 | % We make sure "every arrow post" exists: 2201 | \tikzset{% 2202 | /tikz/commutative diagrams/every arrow post/.append style={}% 2203 | }% 2204 | \pgfsetlayers{background,belownodelayer,edgelayer,nodelayer,main,abovenodelayer,box,labellayer,foreground}% Layers are defined locally to avoid to disturb other drawings 2205 | %% Provide a way to reference the current diagram. This way it is for instance possible to do 2206 | %% \ar[from=Zbotright, to=\zxCurrentDiagram-1-1] 2207 | %% For this to work, you should not modify the name of the matrix. 2208 | \def\zxCurrentDiagram{tikz@f@\the\tikz@fig@count}%Does not exists yet... Hopefully it's updated soon enough 2209 | % We provide a way to get the current matrix name: 2210 | \begin{tikzcd}[% 2211 | /zx/defaultEnv,% 2212 | #1]% 2213 | }{\end{tikzcd}\egroup} 2214 | 2215 | % https://tex.stackexchange.com/a/619983/116348 2216 | \ExplSyntaxOn 2217 | %%%%% Shortcut macro \zxNoExt{...} equivalent to \begin{ZX}...\end{ZX} 2218 | %%%%% We will create an alias \zx, but when we use externalization we 2219 | %%%%% wrap it around a figure. 2220 | \NewDocumentCommand{\zxNoExt}{O{}+m}{% Warning, expl syntax removes space. 2221 | \tl_rescan:nn { \char_set_catcode_active:N \& } { \begin{ZXNoExt}[#1] #2 \end{ZXNoExt} } 2222 | } 2223 | \ExplSyntaxOff 2224 | 2225 | %% Version to use when using externalize (it wraps it around a 2226 | \NewDocumentCommand{\zxExt}{O{}O{}O{}+m}{% Warning, expl syntax removes space. 2227 | \begin{tikzpicture}[baseline=(zxlibrarymainnode.base),#2]% 2228 | \node(zxlibrarymainnode)[inner sep=0pt,outer sep=0pt,#3]{\zxNoExt[#1]{#4}};% 2229 | \end{tikzpicture}% 2230 | } 2231 | 2232 | \NewDocumentEnvironment{ZXExt}{O{}O{}O{}+b}{% 2233 | \zxExt[#1][#2][#2]{#4}% 2234 | }{}% 2235 | 2236 | \NewDocumentEnvironment{ZX}{O{}O{}O{}+b}{% 2237 | \zx[#1][#2][#3]{#4}% 2238 | }{} 2239 | 2240 | % The external library is not compatible with tikzcd directly. 2241 | % So if: 2242 | % \zx@external@mode is enabled, we wrap the figure into another figure to be compatible with tikz externalize 2243 | % otherwise, we check if the external library is loaded, and disable it temporarily. 2244 | \NewDocumentCommand\zx{O{}O{}O{}+m}{% 2245 | {% 2246 | % Suffix for pictures made only with zx when using the external library 2247 | \ifdefined\tikz@library@external@loaded% Library external is loaded... 2248 | \ifdefined\zx@external@suffix% 2249 | \tikzappendtofigurename{\zx@external@suffix}% 2250 | \fi% 2251 | \fi% 2252 | \ifdefined\zx@external@mode% 2253 | % We wrap everything around figures and enable tikz external (useful when many figures 2254 | % are not compatible with external): 2255 | \ifthenelse{\equal{\zx@external@mode}{wrapForceExt}}{% 2256 | {\tikzexternalenable\zxExt[#1][#2][#3]{#4}}% 2257 | }{ 2258 | \ifthenelse{\equal{\zx@external@mode}{wrap}}{% We wrap everything around figures to be compatible with external 2259 | \zxExt[#1][#2][#3]{#4}% 2260 | }{% We don't wrap anything inside figures, so we lose external compatibility. 2261 | \ifthenelse{\equal{\zx@external@mode}{noWrapNoExt}}{% 2262 | % We disable the tikz external library temporarily (tikzcd is not compatible with it) 2263 | \ifdefined\tikz@library@external@loaded% Library external is loaded... 2264 | \tikzexternaldisable% 2265 | \message{WARNING: you chose to disable temporarily the tikz external library.}% 2266 | \fi% 2267 | }{} 2268 | \zxNoExt[#1]{#4}% 2269 | }% 2270 | }% 2271 | \else% Mode auto enabled 2272 | {% If the tikz library is loaded: 2273 | \ifdefined\tikz@library@external@loaded% Library external is loaded... 2274 | \zxExt[#1][#2][#3]{#4}% 2275 | \else% 2276 | \zxNoExt[#1]{#4}% 2277 | \fi% 2278 | }% 2279 | \fi% 2280 | }% 2281 | } 2282 | 2283 | %% By default, the error displayed when compiling using "external" 2284 | %% is not meaningful and does not stop if a picture already exists. 2285 | %% https://tex.stackexchange.com/questions/633100/stop-at-error-meaningfull-errors-with-shell-escape-and-tikz-externalize/633121#633121 2286 | %% See also this bug, that shows that if you have an error and compile twice, the error disappears, but the old file is used instead. 2287 | %% https://github.com/pgf-tikz/pgf/issues/1137 2288 | \NewDocumentCommand\zxConfigureExternalSystemCall{O{}}{ 2289 | %% Code inspired by https://github.com/pgf-tikz/pgf/blob/a7b45b35e99af11bf7156aa3697b897b98870e5b/tex/generic/pgf/frontendlayer/tikz/libraries/tikzexternalshared.code.tex#L277 2290 | \expandafter\def\csname zx@driver@pgfsys-luatex.def\endcsname{% 2291 | \pgfkeyssetvalue{/tikz/external/system call}{% 2292 | lualatex \tikzexternalcheckshellescape #1 -jobname "\image" "\texsource"% 2293 | }% 2294 | }% 2295 | \expandafter\def\csname zx@driver@pgfsys-pdftex.def\endcsname{% 2296 | \pgfutil@IfUndefined{directlua}{% 2297 | \pgfkeyssetvalue{/tikz/external/system call}{% 2298 | pdflatex \tikzexternalcheckshellescape #1 -jobname "\image" "\texsource"% 2299 | }% 2300 | }{% 2301 | \pgfkeyssetvalue{/tikz/external/system call}{% 2302 | lualatex \tikzexternalcheckshellescape #1 -jobname "\image" "\texsource"% 2303 | }% 2304 | }% 2305 | }% 2306 | \expandafter\def\csname zx@driver@pgfsys-xetex.def\endcsname{% 2307 | \pgfkeyssetvalue{/tikz/external/system call}{% 2308 | xelatex \tikzexternalcheckshellescape #1 -jobname "\image" "\texsource"% 2309 | }% 2310 | }% 2311 | \expandafter\def\csname zx@driver@pgfsys-dvips.def\endcsname{% 2312 | \pgfkeyssetvalue{/tikz/external/system call}{% 2313 | latex \tikzexternalcheckshellescape #1 -jobname "\image" "\texsource" % 2314 | && dvips -o "\image".ps "\image".dvi % 2315 | }% 2316 | }% 2317 | % Auto-select a suitable default value fo 'system call': 2318 | \pgfutil@ifundefined{tikzexternal@driver@\pgfsysdriver}{% 2319 | % fallback. We do not know the driver here. 2320 | \csname zx@driver@pgfsys-pdftex.def\endcsname 2321 | }{% 2322 | \csname zx@driver@\pgfsysdriver\endcsname 2323 | }% 2324 | } 2325 | 2326 | % Call zxConfigureExternalSystemCall with the same system call as the calling program 2327 | % Useful otherwise the error may be missed (for instance errorstopmode works in pdflatex but not in 2328 | % emacs, and nonstopmode works in emacs, but not in pdflatex). 2329 | % The current mode is stored in \interactionmode, 0, 1, 2, 3 corresponding respectively to batch, nonstop, scroll or errorstop. 2330 | % https://tex.stackexchange.com/questions/91592/where-to-find-official-and-extended-documentation-for-tex-latexs-commandlin 2331 | \NewDocumentCommand\zxConfigureExternalSystemCallAuto{}{% 2332 | \message{XXX Configuring auto.} 2333 | \ifnum\interactionmode=0 % 2334 | \message{XXX Configuring auto 0.} 2335 | \zxConfigureExternalSystemCall[-interaction=batchmode]% 2336 | \fi% 2337 | \ifnum\interactionmode=1 % 2338 | \message{XXX Configuring auto 1.} 2339 | \zxConfigureExternalSystemCall[-interaction=nonstopmode]% emacs 2340 | \fi% 2341 | \ifnum\interactionmode=2 % 2342 | \message{XXX Configuring auto 2.} 2343 | \zxConfigureExternalSystemCall[-interaction=scrollmode]% 2344 | \fi% 2345 | \ifnum\interactionmode=3 % 2346 | \message{XXX Configuring auto 3.} 2347 | \zxConfigureExternalSystemCall[-interaction=errorstopmode]% pdflatex by default 2348 | \fi% 2349 | } 2350 | 2351 | 2352 | \ifdefined\zxDoNotPatchSystemCall\else% 2353 | \zxConfigureExternalSystemCallAuto 2354 | \fi 2355 | 2356 | % \zx@external@mode can be undefined (=auto), wrap or nowrap. 2357 | 2358 | %% Automatically check if the external library is loaded, and use it. 2359 | \NewDocumentCommand\zxExternalAuto{}{% 2360 | \let\zx@external@mode\undefined% 2361 | } 2362 | 2363 | %% Force to wrap the ZX figures around a figure to ensure compatibility with external. 2364 | \NewDocumentCommand\zxExternalWrap{}{% 2365 | \def\zx@external@mode{wrap}% 2366 | } 2367 | 2368 | %% Do not wrap the ZX figures around another figure (not compatible with external) 2369 | \NewDocumentCommand\zxExternalNoWrap{}{% 2370 | \def\zx@external@mode{nowrap}% 2371 | } 2372 | 2373 | %% Do not wrap the ZX figures, but disable external for these figures (semi-compatible with external) 2374 | \NewDocumentCommand\zxExternalNoWrapNoExt{}{% 2375 | \def\zx@external@mode{noWrapNoExt}% 2376 | } 2377 | 2378 | %% Wrap the ZX figures, and enable external for these figures (useful when most other environments 2379 | %% are not compatible with tikz external) 2380 | \NewDocumentCommand\zxExternalWrapForceExt{}{% 2381 | \def\zx@external@mode{wrapForceExt}% 2382 | } 2383 | 2384 | % Mode auto is enabled by default 2385 | \zxExternalAuto 2386 | 2387 | \NewDocumentCommand\zxExternalSuffix{m}{ 2388 | \ifthenelse{\equal{#1}{}}{% Nothing submitted: we erase the suffix 2389 | \let\zx@external@suffix\undefined% 2390 | }{% 2391 | \def\zx@external@suffix{#1} 2392 | }% 2393 | } 2394 | 2395 | \zxExternalSuffix{zx} 2396 | 2397 | 2398 | 2399 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2400 | %%% Custom nodes from Pic 2401 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2402 | %% It is quite complicated to define custom node shapes, especially when using anchors. Here, we define a 2403 | %% Way to easily create a custom node from a picture. 2404 | 2405 | %% This code allows to add a new anchor to a given node: 2406 | %% https://tex.stackexchange.com/a/676090/116348 2407 | \tikzset{ 2408 | zx add anchor to node/.code n args={3}{% 2409 | \edef\tikz@temp##1{% \tikz@pp@name/\tikzlastnode needs to be expanded 2410 | %% This codes does the following thing: 2411 | %% First, it modifies the "\pgf@anchor@rectangle@fake center west" macro (rectangle might be another shape, 2412 | %% same for anchor). But since this macro might be different between nodes sharing the same shape, 2413 | %% it adds it to a per-node macro called like \pgf@sh@ma@tikz@f@3-2-2 (tikz@f@3-2-2 is the name of the 2414 | %% node). 2415 | \noexpand\pgfutil@g@addto@macro\expandafter\noexpand\csname pgf@sh@ma@\tikz@pp@name{#1}\endcsname{% 2416 | \def\expandafter\noexpand\csname pgf@anchor@\csname pgf@sh@ns@\tikz@pp@name{#1}\endcsname @#2\endcsname{##1}% 2417 | }% 2418 | }% 2419 | \tikz@temp{#3}% 2420 | }, 2421 | zx add anchor to pic default/.style={/tikz/zx add anchor to pic={#1}{#1}}, 2422 | zx add anchor to pic/.code 2 args={% 2423 | % If base coordinate isn't created yet, do so at (0,0) 2424 | % in the current coordinate system! 2425 | \pgfutil@ifundefined{pgf@sh@ns@\tikz@pp@name{}}{% 2426 | \pgfcoordinate{\tikz@pp@name{}}{\pgfpointorigin}% 2427 | }{}% 2428 | \begingroup 2429 | % What is the distance between coordinate and base? 2430 | % We have to do this in the coordinate system of the base coordinate. 2431 | \pgfsettransform{\csname pgf@sh@nt@\tikz@pp@name{}\endcsname}% 2432 | \pgf@process{\pgfpointanchor{\tikz@pp@name{#2}}{center}}% 2433 | % This distance is the new anchors coordinate 2434 | % in the base's coordinate system. 2435 | % Adding an anchor to a node must be global 2436 | % which is why we can do this inside the group. 2437 | \pgfkeysalso{ 2438 | /tikz/zx add anchor to node/.expanded=% 2439 | {}{#1}{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}} 2440 | }% 2441 | \endgroup 2442 | }% 2443 | } 2444 | 2445 | %%% Create automatically a new pic-based node 2446 | %%% \zxNewNodeFromPic{nameOfNode}[default style before user][default style after user]{content of the pic} 2447 | %%% - In 'default style before user', we can put any style that is given to the pic (e.g. colors, rotate, scale…) 2448 | %%% or even custom properties that will be read by the pic (e.g. to allow the define the number of spikes of a 2449 | %%% star). This style can notably have "zx create anchors={a, list, of, coordinates, to, turn, into, anchors}" 2450 | %%% that will automatically turn any coordinate in the pic in the list of coordinates into an anchor of the 2451 | %%% parent node. 2452 | %%% - In 'default style after user', the style is run after the code provided by the user. In particular, you can 2453 | %%% use "invert top bottom" to invert the "top" version with the "bottom" version (rotation is minus 90 instead 2454 | %%% of 90 for instance). 2455 | \NewDocumentCommand{\zxNewNodeFromPic}{mO{}O{}O{}O{}m}{% 2456 | \tikzset{% 2457 | #1Pic/.pic={% 2458 | #6% 2459 | % The user can even add more stuff to draw after if needed by redefining this macro: 2460 | \ifdefined\zxCustomPicAdditionalPic\zxCustomPicAdditionalPic\fi% 2461 | \tikzset{% 2462 | % We store the list of anchors to create into \zxListOfNewAnchors. If it does not exist we create it: 2463 | /utils/exec={\ifdefined\zxListOfNewAnchors\else\def\zxListOfNewAnchors{}\fi}, 2464 | % We add the coordinates in \zxListOfNewAnchors as anchors for the node 2465 | zx add anchor to pic default/.list/.expanded={\zxListOfNewAnchors}}% 2466 | },% 2467 | #1/.style={% 2468 | %shape=coordinate, %yshift=axis_height, %% already applied 2469 | #4, 2470 | append after command={% 2471 | pic[ 2472 | % We configure the name and position of the pic 2473 | at=(\tikzlastnode), name=\tikzlastnode, 2474 | % We create a command to add anchors via zx create anchors={my, list, of, anchors}. This way, it also allows dynamic anchors using 2475 | % the default style after user. 2476 | zx create anchors/.store in={\zxListOfNewAnchors}, 2477 | zx create anchors={}, 2478 | % We create a new style to apply to the main node 2479 | zx main node/.style={ 2480 | name=, 2481 | zx forward to node/.append style={}, 2482 | zx forward to node, 2483 | }, 2484 | % We load the other default arguments: 2485 | #2, 2486 | % We try to load a potentially global style configured by the user (mostly used to override this library) 2487 | /zx/picCustomStyleBeforeUser#1/.append style={}, % Make sure it exists to avoid errors 2488 | /zx/picCustomStyleBeforeUser#1, 2489 | % We load the per-instance arguments: 2490 | ##1, 2491 | % We try to load a potentially global style configured by the user (mostly used to override this library) 2492 | /zx/picCustomStyleAfterUser#1/.append style={}, % Make sure it exists to avoid errors 2493 | /zx/picCustomStyleAfterUser#1, 2494 | #3, 2495 | % We try to load a potentially global style configured by the user (mostly used to override this library) 2496 | /zx/picCustomStyleLastPic#1/.append style={}, % Make sure it exists to avoid errors 2497 | /zx/picCustomStyleLastPic#1, 2498 | ]{#1Pic}% 2499 | }, 2500 | }% 2501 | }% 2502 | %% \ExpandArgs{c} is an equivalent of expandafter + csname, to expand the first argument before evaluating the function: 2503 | %% https://tex.stackexchange.com/a/676103/116348 2504 | %% ##1: pic additional style 2505 | %% ##2: node additional style 2506 | %% ##3: text to consume with \tikzpictext 2507 | % \ExpandArgs{c}\NewExpandableDocumentCommand{zx#1}{t.t-t'O{}O{}m}{% 2508 | % |[#1={pic text={##6}, ##4}, ##5]|% 2509 | % }% 2510 | \ExpandArgs{c}\NewExpandableDocumentCommand{zx#1}{O{}O{}t.t-t't/t*e_m}{% 2511 | |[#1={ 2512 | pic text={##9}, 2513 | %% The alias=… should rather be called on the second element. But it's quite handy to write it here, so here we go: 2514 | a/.style={% 2515 | zx forward to node/.append style={ 2516 | a={########1}, 2517 | }, 2518 | }, 2519 | %% The mode stored in \zxRotationMode contains the current rotation mode (i.e. the angle between 0 and 359, typically 0,90,180,270), 2520 | %% to allow further tweaks (for instance, a pic might be mirrored instead of rotated by 180° when using the parameter -, and this 2521 | %% can be configured by reading this variable). 2522 | /utils/exec={% 2523 | \def\zxCurrentRotationMode{0}% 2524 | %%% Fake center is mostly for curves like <', and true north/ is mostly for curves like C, C'... 2525 | %%% These anchor name are changed depending on the rotation: the north/… is before the rotation. 2526 | \def\zxVirtualCenterNorth{fake center north}% 2527 | \def\zxVirtualCenterSouth{fake center south}% 2528 | \def\zxVirtualCenterEast{fake center east}% 2529 | \def\zxVirtualCenterWest{fake center west}% 2530 | \def\zxTrueNorth{true north}% 2531 | \def\zxTrueSouth{true south}% 2532 | \def\zxTrueEast{true east}% 2533 | \def\zxTrueWest{true west}% 2534 | \IfBooleanT{##3}{% 2535 | \def\zxCurrentRotationMode{90}% 2536 | \def\zxVirtualCenterNorth{fake center west}% 2537 | \def\zxVirtualCenterSouth{fake center east}% 2538 | \def\zxVirtualCenterEast{fake center north}% 2539 | \def\zxVirtualCenterWest{fake center south}% 2540 | \def\zxTrueNorth{true west}% 2541 | \def\zxTrueSouth{true east}% 2542 | \def\zxTrueEast{true north}% 2543 | \def\zxTrueWest{true south}% 2544 | }% 2545 | \IfBooleanT{##4}{% 2546 | \def\zxCurrentRotationMode{180}% 2547 | \def\zxVirtualCenterNorth{fake center south}% 2548 | \def\zxVirtualCenterSouth{fake center north}% 2549 | \def\zxVirtualCenterEast{fake center west}% 2550 | \def\zxVirtualCenterWest{fake center east}% 2551 | \def\zxTrueNorth{true south}% 2552 | \def\zxTrueSouth{true north}% 2553 | \def\zxTrueEast{true west}% 2554 | \def\zxTrueWest{true east}% 2555 | }% 2556 | \IfBooleanT{##5}{% 2557 | \def\zxCurrentRotationMode{270}% 2558 | \def\zxVirtualCenterNorth{fake center east}% 2559 | \def\zxVirtualCenterSouth{fake center west}% 2560 | \def\zxVirtualCenterEast{fake center south}% 2561 | \def\zxVirtualCenterWest{fake center north}% 2562 | \def\zxTrueNorth{true east}% 2563 | \def\zxTrueSouth{true west}% 2564 | \def\zxTrueEast{true south}% 2565 | \def\zxTrueWest{true north}% 2566 | }% 2567 | \IfBooleanT{##6}{% 2568 | \def\zxModeSlash{}% 2569 | }% 2570 | \IfBooleanT{##7}{% 2571 | \def\zxModeStar{}% 2572 | }% 2573 | % Embellishments can contain something like \zxMynode_{Text A}{Text B} 2574 | \IfNoValueTF{##8}{}{% 2575 | \def\zxModeUnderscore{##8}% 2576 | }% 2577 | }, 2578 | rotate=\zxCurrentRotationMode,% 2579 | %%% Sometimes it can be quite handy to invert the top and the bottom version if it does not match with the 2580 | %%% intuitive position it should have. 2581 | %%% Make sure to call this in the second optional parameter (after user style) 2582 | invert top bottom/.style={ 2583 | rotate=-\zxCurrentRotationMode, 2584 | /utils/exec={% 2585 | \ifnum\zxCurrentRotationMode=90\relax 2586 | \def\zxCurrentRotationMode{270}% 2587 | \else 2588 | \ifnum\zxCurrentRotationMode=270\relax 2589 | \def\zxCurrentRotationMode{90}% 2590 | \fi 2591 | \fi 2592 | }, 2593 | rotate=\zxCurrentRotationMode,% 2594 | },% 2595 | invert right left/.style={ 2596 | rotate=-\zxCurrentRotationMode, 2597 | /utils/exec={% 2598 | \ifnum\zxCurrentRotationMode=0\relax 2599 | \def\zxCurrentRotationMode{180}% 2600 | \else 2601 | \ifnum\zxCurrentRotationMode=180\relax 2602 | \def\zxCurrentRotationMode{0}% 2603 | \fi 2604 | \fi 2605 | }, 2606 | rotate=\zxCurrentRotationMode,% 2607 | },% 2608 | ##1}, #5, ##2]|% 2609 | }% 2610 | }% 2611 | 2612 | %% Useful to increase or decrease the bounding box of a custom node. 2613 | %% Parameters are like extend=5mm (that extends on all directions), and similarly for top/bottom/left/right/horizontal/vertical 2614 | \NewExpandableDocumentCommand{\zxExtendBoundingBox}{m}{% 2615 | \pgfkeys{ 2616 | /zx/.cd, 2617 | left/.store in=\zx@left, 2618 | left=0pt, 2619 | right/.store in=\zx@right, 2620 | right=0pt, 2621 | top/.store in=\zx@top, 2622 | top=0pt, 2623 | bottom/.store in=\zx@bottom, 2624 | bottom=0pt, 2625 | horizontal/.style={ 2626 | left=##1, 2627 | right=##1, 2628 | }, 2629 | vertical/.style={ 2630 | /zx/top=##1, 2631 | /zx/bottom=##1, 2632 | }, 2633 | extend/.style={ 2634 | vertical=##1, 2635 | horizontal=##1, 2636 | }, 2637 | #1, 2638 | }% 2639 | \path[use as bounding box] ([xshift=-\zx@left,yshift=\zx@top]current bounding box.north west) 2640 | rectangle ([xshift=\zx@right,yshift=-\zx@bottom]current bounding box.south east);% 2641 | } 2642 | 2643 | 2644 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2645 | %%% Some special nodes based on \zxNewNodeFromPic 2646 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2647 | 2648 | %% Ground symbol 2649 | \zxNewNodeFromPic{Ground}[scale=\zxGroundScale][invert top bottom]{ 2650 | \draw[line width=\zxDefaultLineWidth] 2651 | (0,0) -- (1mm,0) 2652 | -- +(0,1mm) -- +(0,-1mm) 2653 | ++(.4mm,0) 2654 | -- +(0,.7mm) -- +(0,-.7mm) 2655 | ++(.4mm,0) 2656 | -- +(0,.35mm) -- +(0,-.35mm); 2657 | \coordinate() at (0,0); % Empty coordinate make the center start at the right position 2658 | } 2659 | 2660 | %% From scalable ZX calculus 2661 | \zxNewNodeFromPic{Divider}[][ 2662 | % Because of the rounded corners, the lines will stop before touching the shape when arriving on the angle. So we force such nodes to be drawn below 2663 | % the shape, targeting a point inside the node. 2664 | %post arrow style if end node/.expanded={% we need to expand everything before setting the style, as this style will be executed much later in the arrow, 2665 | post arrow style if end node={% if the text contains macro like \zxVirtualCenterWest use post arrow style if end node/.expanded instead as these macro 2666 | % will not exist anymore once the line is drawn 2667 | on layer=edgelayer,% 2668 | end anchor if not set=fake center north, 2669 | },% 2670 | post arrow style if start node={% if the text contains macro like \zxVirtualCenterWest use post arrow style if end node/.expanded instead as these macro 2671 | % will not exist anymore once the line is drawn 2672 | on layer=edgelayer,% 2673 | start anchor if not set=fake center south, 2674 | },% 2675 | zx create anchors={\zxVirtualCenterWest, \zxVirtualCenterEast, \zxVirtualCenterNorth, \zxVirtualCenterSouth}, 2676 | every node/.append style={transform shape} 2677 | ]{ 2678 | \node[regular polygon, regular polygon sides=3,shape border rotate=90, draw=black,fill=gray!50, inner sep=1.6pt, rounded corners=0.8mm,zx main node] {}; 2679 | \coordinate(\zxVirtualCenterEast) at (.2mm,0); % Used to start lines on the side of the shape 2680 | \coordinate(\zxVirtualCenterWest) at (-1mm,0); 2681 | \coordinate(\zxVirtualCenterNorth) at (\zxVirtualCenterWest); % Synonyme, useful to determine where to start 2682 | \coordinate(\zxVirtualCenterSouth) at (\zxVirtualCenterEast); % Synonyme, useful to determine where to start 2683 | } 2684 | 2685 | %% Matrix symbol 2686 | \zxNewNodeFromPic{Matrix} 2687 | [ 2688 | % As we want - to only swap the position of the label but not the rotation (we use * already for transpose) 2689 | % we disable the above rotation: 2690 | rotate=-\zxCurrentRotationMode, 2691 | % Otherwise the space between colums is too big 2692 | /utils/exec={\setlength\arraycolsep{1pt}}, 2693 | ][zx create anchors={true north,true south,true east,true west}]{ 2694 | \node[zx main node, draw, signal, fill=colorZxMatrix, inner sep=1pt, minimum height=6pt, transform shape, 2695 | % The direction of the shape is turned when using the * symbol (transpose). 2696 | signal to/.expanded={\ifdefined\zxModeStar west\else east\fi}, 2697 | signal from/.expanded={\ifdefined\zxModeStar east\else west\fi}, 2698 | % We disabled the default rotation (* is for transpose), but we still want to rotate it to read to/down: 2699 | rotate/.expanded={mod(-\zxCurrentRotationMode,180)}, 2700 | % If we want the syntax \zxMatrix{45:f} to put f at 45 degrees, we want to expand \tikzpictext 2701 | % *before* to read the key, hence the need for expanded. 2702 | label/.expanded={[ 2703 | inner sep=2pt, 2704 | % The position of the label is independent of the rotation, but depends on the rotation mode ('.-): 2705 | absolute, 2706 | label position=\ifdefined\zxLabelAngle \zxLabelAngle\else 90+\zxCurrentRotationMode\fi, 2707 | font=\noexpand\footnotesize, % We don't want to expand \footnotesize before defining the label 2708 | % we use the / decoration 2709 | overlay/.expanded={\ifdefined\zxModeSlash true\else false\fi}, 2710 | % Math mode by default: 2711 | execute at begin node=$, execute at end node=$, 2712 | /zx/picCustomStyleMatrixLabel/.append style={}, % Make sure it exists to avoid errors 2713 | /zx/picCustomStyleMatrixLabel, 2714 | ] 2715 | % We put as the label the text directly. Note that \unexpanded\expandafter expands the next token only once 2716 | % as if it gets expanded further, we can get errors (e.g.\ with pmatrix) 2717 | \unexpanded\expandafter{\tikzpictext} 2718 | \ifdefined\zxModeUnderscore\noexpand\begin{bmatrix}\noexpand\zxModeUnderscore\noexpand\end{bmatrix}\fi 2719 | }, 2720 | /zx/picCustomStyleMatrixMainNode/.append style={}, % Make sure it exists to avoid errors 2721 | /zx/picCustomStyleMatrixMainNode, 2722 | ]{}; 2723 | \coordinate(true east) at (.east); % Used to start lines on the side of the shape 2724 | \coordinate(true west) at (.west); 2725 | \coordinate(true north) at (true west); % Synonyme, useful to determine where to start 2726 | \coordinate(true south) at (true east); % Synonyme, useful to determine where to start 2727 | } 2728 | 2729 | % %% Box, that just draws... a box 2730 | \zxNewNodeFromPic{Box}[ 2731 | main/.style={ 2732 | /zx/picCustomStyleBoxMainNode/.append style={####1}, 2733 | }, 2734 | ][zx create anchors={fake center north,fake center south,fake center east,fake center west}]{% 2735 | \node[draw, inner sep=1.3mm, rectangle, zx main node, execute at begin node=$, execute at end node=$,alias=hello, 2736 | /zx/picCustomStyleBoxMainNode/.append style={}, % Make sure it exists to avoid errors 2737 | /zx/picCustomStyleBoxMainNode, 2738 | ]{\tikzpictext};% 2739 | \coordinate(fake center north) at (.north);% 2740 | \coordinate(fake center west) at (.west);% 2741 | \coordinate(fake center east) at (.east);% 2742 | \coordinate(fake center south) at (.south);% 2743 | } 2744 | 2745 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2746 | %%% 2747 | %%% Now using a special command for fractions (easier to code, and more customizable) 2748 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2749 | 2750 | 2751 | %%%%% Like \zx but uses \& instead of &. This WAS useful for instance in "align" environments 2752 | %%%%% since \zx{} was given an error (even without using &, changing the catcode was enough to 2753 | %%%%% break the function). However, in recent versions, \zx should work as it in align, and 2754 | %%%%% \begin{ZX}...\end{ZX} seems to always work in align without any issues. 2755 | %%%%% Anyway, if at some points you have troubles, either use 2756 | %%%%% \begin{ZX}[amp] ... \end{ZX} (amp is shortcut for "ampersand replacement=\&") or this function: 2757 | \NewDocumentCommand{\zxAmp}{O{}+m}{% 2758 | \begin{ZX}[ampersand replacement=\&, #1]% 2759 | #2% 2760 | \end{ZX}% 2761 | } 2762 | 2763 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2764 | %%% Practical macros to automatically choose appropriate style and arrows 2765 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2766 | % /!\ Warning: you should add {} at the end of all macros (except arrows)! 2767 | % Not using that may work for now, but it may break later... 2768 | % TODO: define them only in \zx environment. 2769 | 2770 | % A swap on one line... Practical mostly to gain space. Must be used with large nodes tough... 2771 | % \NewExpandableDocumentCommand{\OneLineSwap}{}{% 2772 | % \ar[r,s,start anchor=south,end anchor=north] \ar[r,s,start anchor=north,end anchor=south] 2773 | % } 2774 | 2775 | 2776 | \NewExpandableDocumentCommand{\zxLoop}{O{90}O{20}O{}m}{% 2777 | \ar[loop,in=#1-#2,out=#1+#2,looseness=8,min distance=3mm,#3] 2778 | } 2779 | 2780 | \NewExpandableDocumentCommand{\zxLoopAboveDots}{O{20}O{}m}{% 2781 | \ar[loop,in=90-#1,out=90+#1,looseness=8,min distance=3mm,"\cvdotsCenterMathline" {zxNormalFont,scale=.6,anchor=north,yshift=-0.25mm},#2] 2782 | } 2783 | 2784 | 2785 | % Usage: node without any style, but may have space. Default is no space, \zxNone+{} is both horizontal 2786 | % and vertical, \zxNone-{} is only horizontal space, \zxNone|{} is only vertical space. 2787 | \NewExpandableDocumentCommand{\zxNone}{t+t-t|O{}m}{ 2788 | \IfBooleanTF{#1}{% \zxNone+ 2789 | |[zxNone+,#4]| #5% 2790 | }{ 2791 | \IfBooleanTF{#2}{% \zxNone- 2792 | |[zxNone-,#4]| #5% 2793 | }{ 2794 | \IfBooleanTF{#3}{% \zxNone 2795 | |[zxNoneI,#4]| #5% 2796 | }{% \zxNone 2797 | |[zxNone,#4]| #5% 2798 | }% 2799 | }% 2800 | }% 2801 | } 2802 | 2803 | % Usage: alias of \zxNone... To bad token can't be easily forwarded to another function. 2804 | \NewExpandableDocumentCommand{\zxN}{t+t-t|O{}m}{ 2805 | \IfBooleanTF{#1}{% \zxNone+ 2806 | |[zxNone+,#4]| #5% 2807 | }{ 2808 | \IfBooleanTF{#2}{% \zxNone- 2809 | |[zxNone-,#4]| #5% 2810 | }{ 2811 | \IfBooleanTF{#3}{% \zxNone| 2812 | |[zxNoneI,#4]| #5% 2813 | }{% \zxNone 2814 | |[zxNone,#4]| #5% 2815 | }% 2816 | }% 2817 | }% 2818 | } 2819 | 2820 | 2821 | % Usage: can be used without {}. Wait, actually it MUST be used without {} which is disturbing… to fix 2822 | \def\zxNL{ 2823 | \zxN{} \rar \pgfmatrixnextcell[\zxwCol]% 2824 | } 2825 | 2826 | % Usage: can be used without {} 2827 | \def\zxNR{ 2828 | \pgfmatrixnextcell[\zxwCol] \zxN{} \ar[l] 2829 | } 2830 | 2831 | 2832 | 2833 | % Cf \zxNone, but with larger space. 2834 | \NewExpandableDocumentCommand{\zxNoneDouble}{t+t-t|O{}m}{ 2835 | \IfBooleanTF{#1}{% \zxNoneDouble+ 2836 | |[zxNoneDouble+,#4]| #5% 2837 | }{ 2838 | \IfBooleanTF{#2}{% \zxNoneDouble- 2839 | |[zxNoneDouble-,#4]| #5% 2840 | }{ 2841 | \IfBooleanTF{#3}{% \zxNoneDouble 2842 | |[zxNoneDoubleI,#4]| #5% 2843 | }{% \zxNoneDouble 2844 | |[zxNoneDouble,#4]| #5% 2845 | } 2846 | } 2847 | } 2848 | } 2849 | 2850 | %% For maximum styling liberty, the content is given directly to the style. 2851 | % It allows the style to put the phase in a label. 2852 | \NewExpandableDocumentCommand{\zxZ}{O{}t*t-m}{ 2853 | |[zxZ4={#1}{\IfBooleanTF{#3}{-}{}}{\IfBooleanTF{#2}{*}{}}{#4}]| % 2854 | } 2855 | 2856 | %% For maximum styling liberty, the content is given directly to the style. 2857 | %% It allows the style to put the phase in a label. 2858 | \NewExpandableDocumentCommand{\zxX}{O{}t*t-m}{ 2859 | |[zxX4={#1}{\IfBooleanTF{#3}{-}{}}{\IfBooleanTF{#2}{*}{}}{#4}]| % 2860 | } 2861 | 2862 | \NewExpandableDocumentCommand{\zxH}{O{}m}{ 2863 | |[zxH,#1]| {}% 2864 | } 2865 | 2866 | % Use like: \zxFracX{\pi}{4} for positive values or for negative \zxFracX-{\pi}{4} 2867 | \NewExpandableDocumentCommand{\zxFracZ}{O{}t-moom}{% 2868 | \IfNoValueTF{#5}{% 2 arguments like: \zxFracZ{\pi}{2} 2869 | |[zxFracZ6={#1}{\IfBooleanTF{#2}{\zxMinus}{}}{#3}{#6}{#3}{#6}]| % 2870 | }{% 4 arguments like \zxFracZ{a+b}[(a+b)][(c+d)]{c+d} 2871 | |[zxFracZ6={#1}{\IfBooleanTF{#2}{\zxMinus}{}}{#3}{#6}{#4}{#5}]| % 2872 | }% 2873 | } 2874 | 2875 | % Use like: \zxFracX{\pi}{4} for positive values or for negative \zxFracX-{\pi}{4} 2876 | \NewExpandableDocumentCommand{\zxFracX}{O{}t-moom}{% 2877 | \IfNoValueTF{#5}{% 2 arguments like: \zxFracZ{\pi}{2} 2878 | |[zxFracX6={#1}{\IfBooleanTF{#2}{\zxMinus}{}}{#3}{#6}{#3}{#6}]| % 2879 | }{% 4 arguments like \zxFracZ{a+b}[(a+b)][(c+d)]{c+d} 2880 | |[zxFracX6={#1}{\IfBooleanTF{#2}{\zxMinus}{}}{#3}{#6}{#4}{#5}]| % 2881 | }% 2882 | } 2883 | 2884 | \NewExpandableDocumentCommand{\zxEmptyDiagram}{}{ 2885 | |[zxEmptyDiagram]| {}% 2886 | } 2887 | 2888 | 2889 | % % Example: \leftManyDots{n} 2890 | % Useful to put on the left of a node like "n \vdots", linked to the next node. Example: \leftManyDots{n}. 2891 | % First optional argument is scale of text, second is scale of =. 2892 | \NewExpandableDocumentCommand{\leftManyDots}{O{1}O{\zxScaleDots}m}{% 2893 | |[zxNone+,inner xsep=0pt]| \scalebox{#1}{$#3$\,}\makebox[0pt][l]{\scalebox{#2}{$\cvdotsCenterMathline$}} \ar[r,-N.,start anchor=north east] \ar[r,-N',start anchor=south east] \pgfmatrixnextcell[\zxwCol]% 2894 | } 2895 | 2896 | % Useful to link two nodes and put a vdots in between. 2897 | \NewExpandableDocumentCommand{\middleManyDots}{}{% 2898 | \ar[r,3 vdots] \ar[o',r] \ar[o.,r]% 2899 | } 2900 | 2901 | % Like \leftManyDots but on the right. Do *not* create a new node, like in |[zxShortZ]| \alpha \rightManyDots{m} 2902 | \NewExpandableDocumentCommand{\rightManyDots}{O{1}O{\zxScaleDots}m}{% 2903 | \ar[r,N'-,end anchor=north west] \ar[r,N.-,end anchor=south west] \pgfmatrixnextcell[\zxwCol] |[zxNone+,inner xsep=0pt]| \makebox[0pt][r]{\scalebox{#2}{$\cvdotsCenterMathline$}}\scalebox{#1}{\,$#3$} 2904 | } 2905 | 2906 | % Shortcut for frequent wires 2907 | \NewExpandableDocumentCommand{\zxDoubleO}{O{}m}{% 2908 | \ar[r,o.,#1] \ar[r,o',#1] 2909 | } 2910 | 2911 | % Version going down 2912 | \NewExpandableDocumentCommand{\zxDoubleOD}{O{}m}{% 2913 | \ar[r,o-,#1] \ar[r,-o,#1] 2914 | } 2915 | 2916 | \NewExpandableDocumentCommand{\zxTtripleO}{O{}m}{% 2917 | \rar \ar[r,o.,#1] \ar[r,o',#1] 2918 | } 2919 | 2920 | \NewExpandableDocumentCommand{\zxTripleOD}{O{}m}{% 2921 | \rar \ar[r,-.,#1] \ar[r,o-,#1] 2922 | } 2923 | 2924 | 2925 | \NewExpandableDocumentCommand{\zxOneOverSqrtTwo}{O{}m}{% 2926 | \zxZ{} \rar[#1] \ar[r,o.,#1] \ar[r,o',#1] \pgfmatrixnextcell \zxX{} 2927 | } 2928 | 2929 | \NewExpandableDocumentCommand{\zxSqrtTwo}{O{}m}{% 2930 | \zxZ{} \rar[#1] \pgfmatrixnextcell \zxX{} 2931 | } 2932 | 2933 | 2934 | %% Need AfterEndPreamble otherwise there is an error when using tikzexternalize. 2935 | \AfterEndPreamble{ 2936 | \zxSaveDiagram{\zxCteOneOverSqrtTwo}{\zxZ{} \rar \ar[r,o.] \ar[r,o'] \pgfmatrixnextcell \zxX{}} 2937 | \zxSaveDiagram{\zxCteSqrtTwo}{\zxZ{} \rar \pgfmatrixnextcell \zxX{}} 2938 | } 2939 | 2940 | %% Useful to give name to box 2941 | %% \namedBox{(node1)(node2)}{text} 2942 | %% \namedBox[additional style][color]{(node1)(node2)}[additional label options]{optional position:text} 2943 | %% \begin{ZX}[ 2944 | %% execute at end picture={ 2945 | %% \zxNamedBox{(measZ)(measZ)}{right:Bell measure} 2946 | %% } 2947 | %% ] 2948 | %% \zxN{} \dar[C] \ar[rrr] & & & \zxN{} \\ 2949 | %% \zxN{} \ar[rr] &&\zxX[a=measX]{x\pi} \dar[C-]\\ 2950 | %% & \zxX{r\pi} \rar& \zxZ[a=measZ]{z\pi} 2951 | %% \end{ZX} 2952 | 2953 | %% Helper 2954 | %% https://tex.stackexchange.com/questions/523579/tikz-fit-inner-sep-seperate-values-for-all-4-directions 2955 | % \tikzset{fit margins/.style={ 2956 | % /tikz/afit/.cd, 2957 | % #1, 2958 | % /tikz/.cd, 2959 | % inner xsep=\pgfkeysvalueof{/tikz/afit/left}+\pgfkeysvalueof{/tikz/afit/right}, 2960 | % inner ysep=\pgfkeysvalueof{/tikz/afit/top}+\pgfkeysvalueof{/tikz/afit/bottom}, 2961 | % xshift=-\pgfkeysvalueof{/tikz/afit/left}+\pgfkeysvalueof{/tikz/afit/right}, 2962 | % yshift=-\pgfkeysvalueof{/tikz/afit/bottom}+\pgfkeysvalueof{/tikz/afit/top}, 2963 | % afit/.cd, 2964 | % left/.initial=1pt,right/.initial=1pt,bottom/.initial=1pt,top/.initial=1pt 2965 | % }} 2966 | 2967 | \tikzset{ 2968 | fit margins/.style={ 2969 | /tikz/afit/.cd,#1, 2970 | /tikz/.cd, 2971 | inner xsep=\pgfkeysvalueof{/tikz/afit/left}+\pgfkeysvalueof{/tikz/afit/right}, 2972 | inner ysep=\pgfkeysvalueof{/tikz/afit/top}+\pgfkeysvalueof{/tikz/afit/bottom}, 2973 | xshift=-\pgfkeysvalueof{/tikz/afit/left}+\pgfkeysvalueof{/tikz/afit/right}, 2974 | yshift=-\pgfkeysvalueof{/tikz/afit/bottom}+\pgfkeysvalueof{/tikz/afit/top} 2975 | }, 2976 | afit/.cd, 2977 | left/.initial=1pt, 2978 | right/.initial=1pt, 2979 | bottom/.initial=1pt, 2980 | top/.initial=1pt, 2981 | horizontal/.style={ 2982 | left=#1, 2983 | right=#1, 2984 | }, 2985 | vertical/.style={ 2986 | top=#1, 2987 | bottom=#1, 2988 | }, 2989 | all/.style={ 2990 | horizontal=#1, 2991 | vertical=#1, 2992 | }, 2993 | /tikz/.cd 2994 | } 2995 | 2996 | \NewExpandableDocumentCommand{\zxNamedBox}{O{}O{blue}mO{}m}{ 2997 | \node[inner sep=2pt, node on layer=background, rounded corners, draw=#2,dashed, fill={#2!50!white}, opacity=.5, fit=#3,label={[#4]#5},#1]{}; 2998 | %\node[fit margins={}, node on layer=background, rounded corners, draw=#2,dashed, fill={#2!50!white}, opacity=.5, fit=#3,label={[#4]#5},#1]{}; 2999 | %\node[inner sep=2pt, node on layer=background, rounded corners, draw=#2,dashed, fill={#2!50!white}, opacity=.5, fit=#3,label={[#4]#5},#1]{}; 3000 | } 3001 | 3002 | 3003 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3004 | %%% Old code that tried to automatically find if zxShort or zxLong should be used... 3005 | %%% Now using a special command for fractions (easier to code, and more customizable) 3006 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3007 | \newsavebox\zx@box % Temporary box to compute height/width/depth 3008 | 3009 | \newlength{\zxMaxDepthPlusHeight}\setlength{\zxMaxDepthPlusHeight}{2em} 3010 | \def\zxMaxRatio{1.3} % Ratio width/(height+depth) 3011 | 3012 | \NewExpandableDocumentCommand{\zxChooseStyle}{mmmm}{% 3013 | % #1=text,#2=empty style,#3=short style,#4=long style 3014 | \savebox\zx@box{#1}% 3015 | % Check if width is 0pt: 3016 | \ifdimcomp{\wd\zx@box}{=}{0pt}{% Return empty style if box is empty 3017 | #2% 3018 | }{% Else compute size of thext 3019 | % Check if height+depth < zxMaxDepthPlusHeight to see if short style applies 3020 | \ifdimcomp{\dimexpr\dp\zx@box+\ht\zx@box\relax}{<}{\zxMaxDepthPlusHeight}{% 3021 | % Check if width < ratio*(height+depth) to see if short style applies 3022 | \ifdimcomp{\wd\zx@box}{<}{\dimexpr \zxMaxRatio\ht\zx@box + \zxMaxRatio\dp\zx@box\relax}{% 3023 | #3% Short style is used 3024 | }{% Else 3025 | #4% Long style is used 3026 | }% 3027 | }{% 3028 | #4% Long style is used 3029 | }% 3030 | }% 3031 | } 3032 | --------------------------------------------------------------------------------