From 9608e590685bb87d511a137d0e36f51a69f656e9 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 5 Feb 2016 23:31:39 +0000 Subject: tikz-feynman (5feb16) git-svn-id: svn://tug.org/texlive/trunk@39582 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/tikz-feynman/LICENSE | 10 + Master/texmf-dist/doc/latex/tikz-feynman/README.md | 70 +- .../doc/latex/tikz-feynman/references.bib | 12 +- .../doc/latex/tikz-feynman/tikz-feynman.pdf | Bin 281261 -> 290598 bytes .../doc/latex/tikz-feynman/tikz-feynman.tex | 130 ++- .../tex/latex/tikz-feynman/tikz-feynman.sty | 5 +- .../latex/tikz-feynman/tikzfeynman.keys.code.tex | 235 +++-- .../latex/tikz-feynman/tikzfeynman.patch.3.0.0.lua | 1005 +++++++++++++++++++ .../latex/tikz-feynman/tikzfeynman.patch.3.0.1.lua | 1037 ++++++++++++++++++++ .../tex/latex/tikz-feynman/tikzfeynman.patch.lua | 1015 ------------------- .../latex/tikz-feynman/tikzlibraryfeynman.code.tex | 39 +- 11 files changed, 2385 insertions(+), 1173 deletions(-) create mode 100644 Master/texmf-dist/tex/latex/tikz-feynman/tikzfeynman.patch.3.0.0.lua create mode 100644 Master/texmf-dist/tex/latex/tikz-feynman/tikzfeynman.patch.3.0.1.lua delete mode 100644 Master/texmf-dist/tex/latex/tikz-feynman/tikzfeynman.patch.lua (limited to 'Master/texmf-dist') diff --git a/Master/texmf-dist/doc/latex/tikz-feynman/LICENSE b/Master/texmf-dist/doc/latex/tikz-feynman/LICENSE index 97d7150807d..7c85a26f9af 100644 --- a/Master/texmf-dist/doc/latex/tikz-feynman/LICENSE +++ b/Master/texmf-dist/doc/latex/tikz-feynman/LICENSE @@ -1,3 +1,13 @@ +This documentation may be redistributed and/or modified under the terms of the +GNU General Public License as published by the Free Software Foundation, either +version 3 of the License, or (at your option) any later version. + +The code of this package may be distributed and/or modified under the conditions +of the LaTeX Project Public License, either version 1.3 of this license or (at +your option) any later version. + +A copy of both licenses are included hereunder: + ################################################################################ GNU GENERAL PUBLIC LICENSE diff --git a/Master/texmf-dist/doc/latex/tikz-feynman/README.md b/Master/texmf-dist/doc/latex/tikz-feynman/README.md index 7d6f0c689da..d37e445bfdb 100644 --- a/Master/texmf-dist/doc/latex/tikz-feynman/README.md +++ b/Master/texmf-dist/doc/latex/tikz-feynman/README.md @@ -1,5 +1,5 @@ -Ti*k*Z-Feynman -============== +[Ti*k*Z-Feynman](http://www.jpellis.me/projects/tikz-feynman) [![ctan.org](https://img.shields.io/ctan/v/tikz-feynman.svg)](https://ctan.org/pkg/tikz-feynman) [![Travis](https://img.shields.io/travis/JP-Ellis/tikz-feynman/master.svg)](https://travis-ci.org/JP-Ellis/tikz-feynman) +============================================================= Ti*k*Z-Feynman is a LaTeX package allowing Feynman diagrams to be easily generated within LaTeX with minimal user instructions and without the need of @@ -17,6 +17,72 @@ Ti*k*Z-Feynman is open source and contribution are welcome. If you have any suggestions, feature requests, or have found any bugs, feel free to create a new issue or pull request on Github. +Below are a few example to demonstrate how easy diagram can be, and how +extensible it can be. Many more are given in the +[documentation][documentation]: + +

QED Example

+```latex +\feynmandiagram [horizontal=a to b] { + i1 -- [fermion] a -- [fermion] i2, + a -- [photon] b, + f1 -- [fermion] b -- [fermion] f2, +}; +``` + +

Penguin Example

+```latex +\feynmandiagram [large, vertical=e to f] { + a -- [fermion] b -- [photon, momentum=\(k\)] c -- [fermion] d, + b -- [fermion, momentum'=\(p_{1}\)] e -- [fermion, momentum'=\(p_{2}\)] c, + e -- [gluon] f, + h -- [fermion] f -- [fermion] i; +}; +``` + +

Mixing Example

+```latex +\begin{tikzpicture} + \begin{feynman} + \vertex (a1) {\(\overline b\)}; + \vertex[right=1cm of a1] (a2); + \vertex[right=1cm of a2] (a3); + \vertex[right=1cm of a3] (a4) {\(b\)}; + \vertex[right=1cm of a4] (a5); + \vertex[right=2cm of a5] (a6) {\(u\)}; + + \vertex[below=2em of a1] (b1) {\(d\)}; + \vertex[right=1cm of b1] (b2); + \vertex[right=1cm of b2] (b3); + \vertex[right=1cm of b3] (b4) {\(\overline d\)}; + \vertex[below=2em of a6] (b5) {\(\overline d\)}; + + \vertex[above=of a6] (c1) {\(\overline u\)}; + \vertex[above=2em of c1] (c3) {\(d\)}; + \vertex at ($(c1)!0.5!(c3) - (1cm, 0)$) (c2); + + \diagram* { + {[edges=fermion] + (b1) -- (b2) -- (a2) -- (a1), + (b5) -- (b4) -- (b3) -- (a3) -- (a4) -- (a5) -- (a6), + }, + (a2) -- [boson, edge label=\(W\)] (a3), + (b2) -- [boson, edge label'=\(W\)] (b3), + + (c1) -- [fermion, out=180, in=-45] (c2) -- [fermion, out=45, in=180] (c3), + (a5) -- [boson, bend left, edge label=\(W^{-}\)] (c2), + }; + + \draw [decoration={brace}, decorate] (b1.south west) -- (a1.north west) + node [pos=0.5, left] {\(B^{0}\)}; + \draw [decoration={brace}, decorate] (c3.north east) -- (c1.south east) + node [pos=0.5, right] {\(\pi^{-}\)}; + \draw [decoration={brace}, decorate] (a6.north east) -- (b5.south east) + node [pos=0.5, right] {\(\pi^{+}\)}; + \end{feynman} +\end{tikzpicture} +``` + [ctan]: https://ctan.org/pkg/tikz-feynman [documentation]: http://www.jpellis.me/projects/tikz-feynman/tikz-feynman/tikz-feynman.pdf [projectpage]: http://www.jpellis.me/projects/tikz-feynman diff --git a/Master/texmf-dist/doc/latex/tikz-feynman/references.bib b/Master/texmf-dist/doc/latex/tikz-feynman/references.bib index 8c0998e7638..7e222288ef5 100644 --- a/Master/texmf-dist/doc/latex/tikz-feynman/references.bib +++ b/Master/texmf-dist/doc/latex/tikz-feynman/references.bib @@ -71,7 +71,7 @@ @article{eades1991, author = "Peter,Eades and Kozo,Sugiyama", title = "How to Draw a Directed Graph", - journal = "Journal of Information Processing ", + journal = "Journal of Information Processing", year = 1991, volume = 13, number = 4, @@ -110,3 +110,13 @@ doi = {10.1103/PhysRev.76.769}, url = {http://link.aps.org/doi/10.1103/PhysRev.76.769} } + +@article{tikz-feynman, + title = {Tik{Z}-{F}eynman: {F}eynman diagrams with {T}ik{Z}}, + author = {Ellis, Joshua}, + archivePrefix = {arXiv}, + year = 2016, + eprint = {1601.05437}, + primaryClass = {hep-ph}, + url = {http://arxiv.org/abs/1601.05437}, +} \ No newline at end of file diff --git a/Master/texmf-dist/doc/latex/tikz-feynman/tikz-feynman.pdf b/Master/texmf-dist/doc/latex/tikz-feynman/tikz-feynman.pdf index 6e55eedc4e1..8b80a306ea5 100644 Binary files a/Master/texmf-dist/doc/latex/tikz-feynman/tikz-feynman.pdf and b/Master/texmf-dist/doc/latex/tikz-feynman/tikz-feynman.pdf differ diff --git a/Master/texmf-dist/doc/latex/tikz-feynman/tikz-feynman.tex b/Master/texmf-dist/doc/latex/tikz-feynman/tikz-feynman.tex index 98173d79845..c4c96d61aaa 100644 --- a/Master/texmf-dist/doc/latex/tikz-feynman/tikz-feynman.tex +++ b/Master/texmf-dist/doc/latex/tikz-feynman/tikz-feynman.tex @@ -124,6 +124,8 @@ %% Page breaks can be avoided at particular places by using \\* \allowdisplaybreaks[2] +\DeclarePairedDelimiter{\angles}{\langle}{\rangle} + %% Tables %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -158,9 +160,12 @@ %% hyperref should be loaded first \usepackage[ backend=biber, - autocite=inline, style=phys, + autocite=inline, biblabel=brackets, + eprint=true, + doi=true, + isbn=true, ]{biblatex} \addbibresource{references.bib} @@ -351,7 +356,7 @@ directory}{}} the need of external programs. It builds upon the \tikzname{} package and leverages the graph placement algorithms from \tikzname{} in order to automate the placement of many vertices. \tikzfeynmanname{} still allows fine-tuned - placement of vertices so that even complex diagrams can still be generated with + placement of vertices so that even complex diagrams can be generated with ease. \end{abstract} \fi @@ -362,6 +367,13 @@ directory}{}} \tikzfeynmanname{} provides a new way to draw Feynman diagrams in \LaTeX{} that does not rely on external programs and uses a clear extensible syntax. +\ifarxiv\else +If you use \tikzfeynmanname{} in an academic setting, please cite: +\begin{quote} + \fullcite{tikz-feynman} +\end{quote} +\fi + Feynman diagrams provide a description of interactions of subatomic particles in a form that is clearer and more succinct than the corresponding mathematical description. They were introduced by \citeauthor{PhysRev.76.769} and first @@ -446,9 +458,10 @@ changes but they should not change the output otherwise\footnote{That is, with backwards compatible. Finally, changes in the first number (|1.0.0| to |2.0.0|) indicates a major change in the package and code written for |1.0.0| is not guaranteed to work on |2.0.0|. The intended version of this package to use -should be indicated in the preamble with |\tikzfeynmanset{compat=x.y.z}| so the -user may be informed of any discrepancy. If needed, earlier versions may be -downloaded from the \href{http://www.jpellis.me/projects/tikz-feynman}{project +should be indicated when the package is loaded with +|\usepackage[compat=x.y.z]{tikz-feynman}| so the user may be informed of any +discrepancyx. If needed, earlier versions may be downloaded from the +\href{http://www.jpellis.me/projects/tikz-feynman}{project page}\footnote{\url{http://www.jpellis.me/projects/tikz-feynman}}. \subsection*{Licence} @@ -485,9 +498,10 @@ This package is distributed in the hope that it will be useful, but After installing the package, the \tikzfeynmanname{} package can be loaded with |\usepackage{tikz-feynman}| in the preamble. It is recommend that you also -place |\tikzfeynmanset{compat=1.0.0}| in the preamble to ensure that a new -versions of \tikzfeynmanname{} do not produce any undesirable changes without -warning. +specify the version of \tikzfeynmanname{} to use with the optional package +argument |compat|: |\usepackage[compat=1.1.0]{tikz-feynman}|. This ensures that +any new versions of \tikzfeynmanname{} do not produce any undesirable changes +without warning. \subsection{A First Diagram} \label{subsec:a_first_diagram} @@ -552,6 +566,12 @@ we named vertices is completely different): }; \end{codeexample} +As a final remark, the calculation of where vertices should be placed is usually +done through an algorithm written in Lua. As a result, \LuaTeX{} is required in +order to make use of these algorithms. If \LuaTeX{} is not used, +\tikzfeynmanname{} will default to a more rudimentary algorithm and will warn +the user instead. + \subsection{Adding Styles} \label{subsec:adding_styles} @@ -582,6 +602,16 @@ be used as well: For a list of all the various styles that \tikzname{} provides, have a look at the \pgfmanual; it is extremely thorough and provides many usage examples. +\tikzfeynmanname{} also supports combining styles together which can be useful +in certain new models such as supersymmetry: +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] { + i1 [particle=\(\tilde W\)] -- [plain, boson] a -- [anti fermion] i2 [particle=\(q\)], + a -- [charged scalar, edge label=\(\tilde q\)] b, + f1 [particle=\(\tilde g\)] -- [plain, gluon] b -- [fermion] [particle=\(q\)], +}; +\end{codeexample} + \subsection{When the Algorithm Isn't Enough} \label{subsec:when_the_algorithm_isnt_enough} @@ -870,14 +900,14 @@ which are particularly useful to \tikzfeynmanname{} are documented and these are prefixed with |/tikz| or |/graph drawing|. Please refer to the \pgfmanual{} for a more in thorough documentation of the \tikzname{} keys. -If you wish to modify the default \tikzfeynmanname{} styles, the best way to do -this is to use \meta{key}|/.append style={...}|. For example, to make every -diagram red except for small diagrams which remain black, one would add to the -preamble: + +\tikzfeynmanname{} provides many |every |\meta{key} which allow every instance +of \meta{key} to be modified. For example, to make every diagram red except for +small diagrams which should be blue, then one would add to the preamble: \begin{codeexample}[execute code=false] \tikzfeynmanset{ - every diagram/.append style={red}, - small/.append style={black}, + every diagram={red}, + every small={blue}, } \end{codeexample} If you are completely unhappy with a particular inbuilt style, you can define @@ -888,17 +918,11 @@ following example: myblob/.style={ shape=circle, draw=blue, - fill=red} + fill=red, + } } \end{codeexample} -All the |every |\meta{key} keys documented here are initially empty, so it is up -to you whether you use \meta{key}|/.append style| or \meta{key}|/.style|. The -predefined style keys (such as |small|, |particle|, |fermion|, etc.) should -\emph{never} by modified with \meta{key}|/.style| as that will overwrite the -style entirely. Instead, modify the appropriate |every |\meta{key} if available -or use \meta{key}|/.append style|. - All the keys defined here are made available inside the |{feynman}| environment and inside |\feynmandiagram|; but if you wish to access them outside of this (say, in a regular |{tikzpicture}| environment), you will need to specify the @@ -914,14 +938,14 @@ full path with the leading |/tikzfeynman|. environment. \end{keylist} -\begin{stylekey}{/tikzfeynman/every feynman} +\begin{key}{/tikzfeynman/every feynman=\meta{styles}} Set of styles which are applied to every |{feynman}| environments (and consequently, every apply inside all |\feynmandiagram| too). The style also applies to regular \tikzname{} commands used inside the |{feynman}| environment. \begin{codeexample}[] -\tikzfeynmanset{every feynman/.append style={red}} +\tikzfeynmanset{every feynman={red}} \begin{tikzpicture} \node at (0, 0.5) {This is not red}; \begin{feynman} @@ -929,7 +953,7 @@ full path with the leading |/tikzfeynman|. \end{feynman} \end{tikzpicture} \end{codeexample} -\end{stylekey} +\end{key} \begin{stylekey}{/tikzfeynman/inline=\meta{node}} A style used to display a Feynman diagram inline (typically in an equation), @@ -1022,19 +1046,19 @@ full path with the leading |/tikzfeynman|. \subsubsection{Diagram Keys} \label{subsubsec:diagram_keys} -\begin{stylekey}{/tikzfeynman/every diagram} +\begin{key}{/tikzfeynman/every diagram=\meta{styles}} Set of styles which are applied to every diagram; that is, to everything inside the |\feynmandiagram|, |\diagram| and |\diagram*| commands but not the general |{feynman}| environment (see \cref{subsubsec:feynman_keys} for that). \begin{codeexample}[] -\tikzfeynmanset{every diagram/.append style={red}} +\tikzfeynmanset{every diagram={red}} \feynmandiagram [small, horizontal=d to b] { a -- [fermion] b -- [fermion] c, b -- [boson] d, }; \end{codeexample} -\end{stylekey} +\end{key} \begin{keylist}{% /tikzfeynman/small, @@ -1068,7 +1092,10 @@ There are several algorithms which are available to place the vertices which are all provided within the |graph drawing| library from \tikzname. Below are listed a few of these layouts which are more relevant for drawing Feynman diagrams. For a more complete description of how these algorithm work, please -refer to the \pgfmanual{}. +refer to the \pgfmanual{}. Please note that most graph drawing algorithms are +implemented in Lua and thus require \LuaTeX{} in order to work. If \LuaTeX{} is +not used, \tikzfeynmanname{} will default to a more rudimentary algorithm and +will warn the user instead. \begin{key}{/graph drawing/spring layout=\opt{\meta{string}}} Uses Hu's spring layout \cite{hu2005} as implemented by Pohlmann @@ -1162,7 +1189,7 @@ refer to the \pgfmanual{}. that is, a null shape with no size or width. \end{key} -\begin{stylekey}{/tikzfeynman/every \meta{vertex shape} (initially \normalfont empty)} +\begin{key}{/tikzfeynman/every \meta{vertex shape}=\meta{styles}} The style of specific vertices can be modified by changing the appropriate |every |\meta{vertex shape} key. For example, in order to change the style of every |dot|-styled vertex, you can modify the |every dot| key, or to modify @@ -1170,16 +1197,16 @@ refer to the \pgfmanual{}. \begin{codeexample}[] \tikzfeynmanset{ - every vertex/.style={red, dot}, - every particle/.style={blue}, - every blob/.style={draw=green!40!black, pattern color=green!40!black}, + every vertex={red, dot}, + every particle={blue}, + every blob={draw=green!40!black, pattern color=green!40!black}, } \feynmandiagram [horizontal=a to b] { a [particle={\(\gamma, Z\)}] -- [boson] b [blob], c -- [fermion] b -- [fermion] d, }; \end{codeexample} -\end{stylekey} +\end{key} \begin{key}{/tikzfeynman/dot} Modifies the vertex so that it has a small filled circle. @@ -1258,32 +1285,47 @@ refer to the \pgfmanual{}. Just like with the various vertex keys, each edge type has a corresponding |every |\meta{edge type}; however, due to the existence of very similar keys such as |scalar|, |charged scalar| and |anti charged scalar|, more specific keys -inherit styles from less specific ones. For example, styles in -|every charged scalar| will apply to |charged scalar| and |anti charged scalar| -but not |scalar| whilst styles in |every scalar| will apply to all three. +inherit styles from less specific ones. For example, styles in |every scalar| +will apply to |charged scalar| and |anti charged scalar|. + +The edge styles do not override each other and instead stack. This means that +an edge styled with both |boson| and |fermion| will consist of a straight line +with a wavy line on top and an error. If not styles are provided, then a simple +solid line is drawn. -\begin{stylekey}{/tikzfeynman/every edge (initially \normalfont empty)} +\begin{key}{/tikzfeynman/every edge=\meta{styles}} A style to apply to every edge initially. -\end{stylekey} +\end{key} -\begin{stylekey}{/tikzfeynman/every \meta{edge style} (initially \normalfont empty)} +\begin{stylekey}{/tikzfeynman/every \meta{edge style}=\meta{styles}} The style of specific edges can be modified by changing the appropriate |every |\meta{edge style} key. For example, in order to make a global change to every |boson|, you can modify the |every boson| key. \begin{codeexample}[] \tikzfeynmanset{ - every edge/.style={fermion}, - every boson/.style={red}, - every photon/.style={blue}, + every edge={green}, + every boson={red}, + every photon={blue}, } \feynmandiagram [small] { a [particle=\(a\)] -- [boson] o -- [photon] b [particle=\(b\)], - f1 [particle=\(c\)] -- o -- f2 [particle=\(d\)], + f1 [particle=\(c\)] -- [fermion] o -- [scalar] f2 [particle=\(d\)], }; \end{codeexample} \end{stylekey} +\begin{key}{/tikzfeynman/plain} + Draws a simple solid line. This style is identical to the default style + applied if no other style is used, but is provided so that it can be combined + with other styles. + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] {a -- [plain] b}; +\feynmandiagram [horizontal=a to b] {a -- [plain, gluon] b}; +\end{codeexample} +\end{key} + \begin{key}{/tikzfeynman/boson} Draws a sinusoidal line to denote a boson. diff --git a/Master/texmf-dist/tex/latex/tikz-feynman/tikz-feynman.sty b/Master/texmf-dist/tex/latex/tikz-feynman/tikz-feynman.sty index 2b37196e6ad..4586f34c25b 100644 --- a/Master/texmf-dist/tex/latex/tikz-feynman/tikz-feynman.sty +++ b/Master/texmf-dist/tex/latex/tikz-feynman/tikz-feynman.sty @@ -20,9 +20,9 @@ % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\def\tikzfeynman@date{2016/01/19} +\def\tikzfeynman@date{2016/02/05} \def\tikzfeynman@version@major{1} -\def\tikzfeynman@version@minor{0} +\def\tikzfeynman@version@minor{1} \def\tikzfeynman@version@patch{0} \edef\tikzfeynman@version{\tikzfeynman@version@major.\tikzfeynman@version@minor.\tikzfeynman@version@patch} @@ -30,6 +30,7 @@ \RequirePackage{tikz}[2013/12/13] % v3.0.0 \RequirePackage{ifluatex} +\RequirePackage{pgfopts} \usetikzlibrary{feynman} diff --git a/Master/texmf-dist/tex/latex/tikz-feynman/tikzfeynman.keys.code.tex b/Master/texmf-dist/tex/latex/tikz-feynman/tikzfeynman.keys.code.tex index 2558325fc39..14e5f9315e8 100644 --- a/Master/texmf-dist/tex/latex/tikz-feynman/tikzfeynman.keys.code.tex +++ b/Master/texmf-dist/tex/latex/tikz-feynman/tikzfeynman.keys.code.tex @@ -129,24 +129,15 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Keys %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\pgfkeys{ - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - %% Family - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - /tikzfeynman/search path for tikz/.search also={/tikz,/tikzfeynman}, - /tikzfeynman/.is family, -} - \tikzfeynmanset{ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % Hooks + %% Hooks %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% execute at begin feynman/.code={}, execute at end feynman/.code={}, - every feynman/.style={}, + every feynman/.style={/tikzfeynman/every feynman@@/.append style={#1}}, every feynman@@/.style={ /tikzfeynman/.cd, - .search also={/tikz}, /tikzfeynman/medium, }, execute at begin feynman@@/.code={} %% Internal version @@ -154,7 +145,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Diagrams %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - every diagram/.style={}, + every diagram/.style={/tikzfeynman/every diagram@@/.append style={#1}}, every diagram@@/.style={ /tikzfeynman/.cd, .search also={/tikz/graphs, /tikz}, @@ -170,11 +161,16 @@ /tikzfeynman/every edge}, /tikzfeynman/medium, }, + every inline/.style={/tikzfeynman/inline@@/.append style={#1}}, + every inline@@/.style={ + /tikzfeynman/small, + }, inline/.style={ /tikz/baseline={#1}, - /tikzfeynman/small, + /tikzfeynman/every inline@@, }, - small/.style={ + every small/.style={/tikzfeynman/small@@/.append style={#1}}, + every small@@/.style={ /tikz/node distance=1cm, /graph drawing/node distance=1.25cm, /graph drawing/level distance=1cm, @@ -185,13 +181,17 @@ /tikzfeynman/arrow size=1.2pt, /tikzfeynman/insertion/size=2.5pt, }, - medium/.style={ + small/.style={/tikzfeynman/every small@@}, + every medium/.style={/tikzfeynman/medium@@/.append style={#1}}, + every medium@@/.style={ /tikz/node distance=1.5cm, /graph drawing/node distance=1.9cm, /graph drawing/level distance=1.5cm, /graph drawing/sibling distance=2.25cm, }, - large/.style={ + medium/.style={/tikzfeynman/every medium@@}, + every large/.style={/tikzfeynman/large@@/.append style={#1}}, + every large@@/.style={ /tikz/node distance=2cm, /graph drawing/node distance=2.5cm, /graph drawing/level distance=2cm, @@ -203,16 +203,16 @@ /tikzfeynman/arrow size=1.6pt, /tikzfeynman/insertion/size=4pt, }, + large/.style={/tikzfeynman/every large@@}, %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % Vertices + %% Vertices %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% every vertex@@/.style={ /tikz/shape=coordinate, }, - every vertex/.style={}, + every vertex/.style={/tikzfeynman/every vertex@@/.append style={#1}}, vertex/.style={ /tikzfeynman/every vertex@@, - /tikzfeynman/every vertex, }, every dot@@/.style={ /tikz/shape=circle, @@ -223,42 +223,35 @@ /tikz/outer sep=0pt, /tikz/minimum size=1.5mm, }, - every dot/.style={}, + every dot/.style={/tikzfeynman/every dot@@/.append style={#1}}, dot/.style={ /tikzfeynman/every dot@@, - /tikzfeynman/every dot, }, every square dot@@/.style={ /tikz/shape=rectangle, }, - every square dot/.style={}, + every square dot/.style={/tikzfeynman/every square dot@@/.append style={#1}}, square dot/.style={ /tikzfeynman/every dot@@, - /tikzfeynman/every dot, /tikzfeynman/every square dot@@, - /tikzfeynman/every square dot, }, every empty dot@@/.style={ /tikz/fill=none, }, - every empty dot/.style={}, + every empty dot/.style={/tikzfeynman/every empty dot@@/.append style={#1}}, empty dot/.style={ /tikzfeynman/every dot@@, - /tikzfeynman/every dot, /tikzfeynman/every empty dot@@, - /tikzfeynman/every empty dot, }, every crossed dot@@/.style={ /tikz/fill=none, /tikz/shape=crossed circle, /tikz/minimum size=3mm, }, - every crossed dot/.style={}, + every crossed dot/.style={/tikzfeynman/every crossed dot@@/.append style={#1}}, crossed dot/.style={ /tikzfeynman/every dot@@, - /tikzfeynman/every dot, /tikzfeynman/every crossed dot@@, - /tikzfeynman/every crossed dot, }, every blob@@/.style={ /tikz/shape=circle, @@ -270,10 +263,9 @@ /tikz/minimum size=0.75cm, /tikz/pattern=north west lines, }, - every blob/.style={}, + every blob/.style={/tikzfeynman/every blob@@/.append style={#1}}, blob/.style={ /tikzfeynman/every blob@@, - /tikzfeynman/every blob, }, every particle@@/.style={ /tikz/shape=rectangle, @@ -282,10 +274,9 @@ /tikz/inner sep=0.3333em, /tikz/outer sep=0.5\pgflinewidth, }, - every particle/.style={}, + every particle/.style={/tikzfeynman/every particle@@/.append style={#1}}, particle/.style args={#1}{ /tikzfeynman/every particle@@, - /tikzfeynman/every particle, /tikz/graphs/as={#1}, }, %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -335,9 +326,20 @@ %% Base Edge Styles %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% every edge@@/.style={}, - every edge/.style={}, + every edge/.style={/tikzfeynman/every edge@@/.append style={#1}}, %% Specific Styles %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + every plain@@/.style={ + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikz/draw + }, + }, + every plain/.style={/tikzfeynman/every plain@@/.append style={#1}}, + plain/.style={ + /tikzfeynman/every plain@@, + }, every boson@@/.style={ /tikz/draw=none, /tikz/decoration={name=none}, @@ -351,28 +353,25 @@ /tikz/decorate=true, }, }, - every boson/.style={}, + every boson/.style={/tikzfeynman/every boson@@/.append style={#1}}, boson/.style={ /tikzfeynman/every boson@@, - /tikzfeynman/every boson, }, every charged boson@@/.style={ /tikzfeynman/with arrow=0.5, }, - every charged boson/.style={}, + every charged boson/.style={/tikzfeynman/every charged boson@@/.append style={#1}}, charged boson/.style={ /tikzfeynman/boson, /tikzfeynman/every charged boson@@, - /tikzfeynman/every charged boson, }, every anti charged boson@@/.style={ /tikzfeynman/with reversed arrow=0.5, }, - every anti charged boson/.style={}, + every anti charged boson/.style={/tikzfeynman/every anti charged boson@@/.append style={#1}}, anti charged boson/.style={ /tikzfeynman/boson, /tikzfeynman/every anti charged boson@@, - /tikzfeynman/every anti charged boson, }, every photon@@/.style={ /tikz/draw=none, @@ -387,81 +386,108 @@ /tikz/decorate=true, }, }, - every photon/.style={}, + every photon/.style={/tikzfeynman/every photon@@/.append style={#1}}, photon/.style={ /tikzfeynman/every photon@@, - /tikzfeynman/every photon, }, every scalar@@/.style={ - /tikz/dashed, + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikz/draw, + /tikz/dashed, + }, }, - every scalar/.style={}, + every scalar/.style={/tikzfeynman/every scalar@@/.append style={#1}}, scalar/.style={ /tikzfeynman/every scalar@@, - /tikzfeynman/every scalar, }, every charged scalar@@/.style={ - /tikzfeynman/with arrow=0.5, + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikzfeynman/with arrow=0.5, + }, }, - every charged scalar/.style={}, + every charged scalar/.style={/tikzfeynman/every charged scalar@@/.append style={#1}}, charged scalar/.style={ /tikzfeynman/scalar, /tikzfeynman/every charged scalar@@, - /tikzfeynman/every charged scalar, }, every anti charged scalar@@/.style={ - /tikzfeynman/with reversed arrow=0.5, + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikzfeynman/with reversed arrow=0.5, + }, }, - every anti charged scalar/.style={}, + every anti charged scalar/.style={/tikzfeynman/every anti charged scalar@@/.append style={#1}}, anti charged scalar/.style={ /tikzfeynman/scalar, - /tikzfeynman/every charged scalar, /tikzfeynman/every anti charged scalar@@, - /tikzfeynman/every anti charged scalar, }, every ghost@@/.style={ - /tikz/dotted, - /tikz/thick, + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikz/draw, + /tikz/dotted, + /tikz/thick, + }, }, - every ghost/.style={}, + every ghost/.style={/tikzfeynman/every ghost@@/.append style={#1}}, ghost/.style={ /tikzfeynman/every ghost@@, - /tikzfeynman/every ghost, }, every fermion@@/.style={ - /tikzfeynman/with arrow=0.5, + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikz/draw, + /tikzfeynman/with arrow=0.5, + }, }, - every fermion/.style={}, + every fermion/.style={/tikzfeynman/every fermion@@/.append style={#1}}, fermion/.style={ /tikzfeynman/every fermion@@, - /tikzfeynman/every fermion, }, every anti fermion@@/.style={ - /tikzfeynman/with reversed arrow=0.5, + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikz/draw, + /tikzfeynman/with reversed arrow=0.5, + }, }, - every anti fermion/.style={}, + every anti fermion/.style={/tikzfeynman/every anti fermion@@/.append style={#1}}, anti fermion/.style={ - /tikzfeynman/every fermion, /tikzfeynman/every anti fermion@@, - /tikzfeynman/every anti fermion, }, every majorana@@/.style={ - /tikzfeynman/with arrow=0.33, - /tikzfeynman/with reversed arrow=0.73, + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikz/draw, + /tikzfeynman/with arrow=0.33, + /tikzfeynman/with reversed arrow=0.73, + }, }, - every majorana/.style={}, + every majorana/.style={/tikzfeynman/every majorana@@/.append style={#1}}, majorana/.style={ /tikzfeynman/every majorana@@, - /tikzfeynman/every majorana, }, every anti majorana@@/.style={ - /tikzfeynman/with reversed arrow=0.33, - /tikzfeynman/with arrow=0.73, + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikz/draw, + /tikzfeynman/with reversed arrow=0.33, + /tikzfeynman/with arrow=0.73, + }, }, - every anti majorana/.style={}, + every anti majorana/.style={/tikzfeynman/every anti majorana@@/.append style={#1}}, anti majorana/.style={ /tikzfeynman/every anti majorana@@, - /tikzfeynman/every anti majorana, }, every gluon@@/.style={ /tikz/draw=none, @@ -477,13 +503,13 @@ /tikz/decorate=true, }, }, - every gluon/.style={}, + every gluon/.style={/tikzfeynman/every gluon@@/.append style={#1}}, gluon/.style={ /tikzfeynman/every gluon@@, - /tikzfeynman/every gluon, }, %% Insertions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + insertion/.search also={/tikzfeynman,/tikz}, %% Parameters insertion/size/.store in=\tikzfeynman@insertion@size, insertion/size=3pt, @@ -494,7 +520,7 @@ /tikz/decoration={ markings, mark=at position #2 with { - \tikzfeynmanset{insertion/.cd, insertion/.search also={/tikz}, #1} + \tikzfeynmanset{insertion/.cd,#1} \draw [\tikzfeynman@insertion@style] (-\tikzfeynman@insertion@size, -\tikzfeynman@insertion@size) -- (\tikzfeynman@insertion@size, \tikzfeynman@insertion@size); \draw [\tikzfeynman@insertion@style] (-\tikzfeynman@insertion@size, \tikzfeynman@insertion@size) -- (\tikzfeynman@insertion@size, -\tikzfeynman@insertion@size); }, @@ -503,9 +529,11 @@ /tikz/decorate=true, }, }, + insertion@@/.default={[]0.5}, %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % Momentum arrows + %% Momentum arrows %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + momentum/.search also={/tikzfeynman,/tikz}, %% Parameters momentum/label distance/.store in=\tikzfeynman@momentum@label@distance, momentum/label distance=0pt, @@ -524,7 +552,7 @@ show path construction, moveto code={}, lineto code={ - \tikzfeynmanset{momentum/.cd, momentum/.search also={/tikz}, #1} + \tikzfeynmanset{momentum/.cd,#1} \path (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast) coordinate [pos=\tikzfeynman@momentum@arrow@shorten] (tf@m@1) coordinate [pos=1 - \tikzfeynman@momentum@arrow@shorten] (tf@m@2); @@ -536,7 +564,7 @@ \tikzfeynman@momentum@label@style] {#2}; }, curveto code={ - \tikzfeynmanset{momentum/.cd, #1} + \tikzfeynmanset{momentum/.cd,#1} \path (\tikzinputsegmentfirst) .. controls (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb) .. (\tikzinputsegmentlast) @@ -557,7 +585,7 @@ -- ($(tf@m@50)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@49)$); }, closepath code={ - \tikzfeynmanset{momentum/.cd, #1} + \tikzfeynmanset{momentum/.cd,#1} \path (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast) coordinate [pos=\tikzfeynman@momentum@arrow@shorten] (tf@m@1) coordinate [pos=1 - \tikzfeynman@momentum@arrow@shorten] (tf@m@2); @@ -578,7 +606,7 @@ show path construction, moveto code={}, lineto code={ - \tikzfeynmanset{momentum/.cd, #1} + \tikzfeynmanset{momentum/.cd,#1} \path (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast) coordinate [pos=\tikzfeynman@momentum@arrow@shorten] (tf@m@1) coordinate [pos=1 - \tikzfeynman@momentum@arrow@shorten] (tf@m@2); @@ -590,7 +618,7 @@ \tikzfeynman@momentum@label@style] {#2}; }, curveto code={ - \tikzfeynmanset{momentum/.cd, #1} + \tikzfeynmanset{momentum/.cd,#1} \path (\tikzinputsegmentfirst) .. controls (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb) .. (\tikzinputsegmentlast) @@ -611,7 +639,7 @@ -- ($(tf@m@50)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@49)$); }, closepath code={ - \tikzfeynmanset{momentum/.cd, #1} + \tikzfeynmanset{momentum/.cd,#1} \path (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast) coordinate [pos=\tikzfeynman@momentum@arrow@shorten] (tf@m@1) coordinate [pos=1 - \tikzfeynman@momentum@arrow@shorten] (tf@m@2); @@ -632,7 +660,7 @@ show path construction, moveto code={}, lineto code={ - \tikzfeynmanset{momentum/.cd, #1} + \tikzfeynmanset{momentum/.cd,#1} \path (\tikzinputsegmentlast) -- (\tikzinputsegmentfirst) coordinate [pos=\tikzfeynman@momentum@arrow@shorten] (tf@m@1) coordinate [pos=1 - \tikzfeynman@momentum@arrow@shorten] (tf@m@2); @@ -644,7 +672,7 @@ \tikzfeynman@momentum@label@style] {#2}; }, curveto code={ - \tikzfeynmanset{momentum/.cd, #1} + \tikzfeynmanset{momentum/.cd,#1} \path (\tikzinputsegmentlast) .. controls (\tikzinputsegmentsupportb) and (\tikzinputsegmentsupporta) .. (\tikzinputsegmentfirst) @@ -665,7 +693,7 @@ -- ($(tf@m@50)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@49)$); }, closepath code={ - \tikzfeynmanset{momentum/.cd, #1} + \tikzfeynmanset{momentum/.cd,#1} \path (\tikzinputsegmentlast) -- (\tikzinputsegmentfirst) coordinate [pos=\tikzfeynman@momentum@arrow@shorten] (tf@m@1) coordinate [pos=1 - \tikzfeynman@momentum@arrow@shorten] (tf@m@2); @@ -686,7 +714,7 @@ show path construction, moveto code={}, lineto code={ - \tikzfeynmanset{momentum/.cd, #1} + \tikzfeynmanset{momentum/.cd,#1} \path (\tikzinputsegmentlast) -- (\tikzinputsegmentfirst) coordinate [pos=\tikzfeynman@momentum@arrow@shorten] (tf@m@1) coordinate [pos=1 - \tikzfeynman@momentum@arrow@shorten] (tf@m@2); @@ -699,7 +727,7 @@ \tikzfeynman@momentum@label@style] {#2}; }, curveto code={ - \tikzfeynmanset{momentum/.cd, #1} + \tikzfeynmanset{momentum/.cd,#1} \path (\tikzinputsegmentlast) .. controls (\tikzinputsegmentsupportb) and (\tikzinputsegmentsupporta) .. (\tikzinputsegmentfirst) @@ -721,7 +749,7 @@ -- ($(tf@m@50)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@49)$); }, closepath code={ - \tikzfeynmanset{momentum/.cd, #1} + \tikzfeynmanset{momentum/.cd,#1} \path (\tikzinputsegmentlast) -- (\tikzinputsegmentfirst) coordinate [pos=\tikzfeynman@momentum@arrow@shorten] (tf@m@1) coordinate [pos=1 - \tikzfeynman@momentum@arrow@shorten] (tf@m@2); @@ -737,7 +765,7 @@ }, }, %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % Modifiers + %% Modifiers %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% half left/.style={ /tikz/bend left=90, @@ -755,4 +783,33 @@ }, } +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Graceful Failure of LuaTeX keys +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\tikzfeynman@luatex@required@path{ + \PackageWarning{tikz-feynman}{The key you tried to use '\pgfkeyscurrentpath/\pgfkeyscurrentname' requires LuaTeX. It will be ignored.} +} +\def\tikzfeynman@luatex@required@key{ + \PackageWarning{tikz-feynman}{The key you tried to use '\pgfkeyscurrentpath' requires LuaTeX. It will be ignored.} +} + +\ifluatex\else + \pgfkeys{ + /graph drawing/.unknown/.code=\tikzfeynman@luatex@required@path, + /tikz/graphs/.unknown/.code=\tikzfeynman@luatex@required@path, + /tikz/horizontal/.code=\tikzfeynman@luatex@required@key, + /tikz/horizontal'/.code=\tikzfeynman@luatex@required@key, + /tikz/vertical/.code=\tikzfeynman@luatex@required@key, + /tikz/vertical'/.code=\tikzfeynman@luatex@required@key, + /tikz/tree layout/.code=\tikzfeynman@luatex@required@key, + /tikz/spring layout/.code=\tikzfeynman@luatex@required@key, + /tikz/layered layout/.code=\tikzfeynman@luatex@required@key, + /tikz/spring electrical layout/.code=\tikzfeynman@luatex@required@key, + /tikz/electric charge/.code=\tikzfeynman@luatex@required@key, + } + % \tikzfeynmanset{ + % horizontal/.code={The key 'horizontal' requires LuaTeX. It will be ignored.}, + % } +\fi + \endinput \ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/tikz-feynman/tikzfeynman.patch.3.0.0.lua b/Master/texmf-dist/tex/latex/tikz-feynman/tikzfeynman.patch.3.0.0.lua new file mode 100644 index 00000000000..54f0da080e3 --- /dev/null +++ b/Master/texmf-dist/tex/latex/tikz-feynman/tikzfeynman.patch.3.0.0.lua @@ -0,0 +1,1005 @@ +-- This patched version of the createVertex function simply ensures that the +-- path is never empty. This works fine for TikZ version 3.0.0. +-- +-- Later versions (should) have a more thorough patch by Till which is +-- incompatible with this override unfortunately. +-- +-- ############################################################################# +-- +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua,v 1.12 2013/12/20 14:44:46 tantau Exp $ + + + +--- +-- This class provides the interface between a display +-- layer (like \tikzname\ or a graph editor) and graph drawing +-- system. Another class, |InterfaceToAlgorithms|, binds the algorithm +-- layer (which are written in Lua) to the graph drawing system. +-- +-- The functions declared here are independent of the actual display +-- layer. Rather, the differences between the layers are encapsulated +-- by subclasses of the |Binding| class, see that class for +-- details. Thus, when a new display layer is written, the present +-- class is \emph{used}, but not \emph{modified}. Instead, only a new +-- binding is created and all display layer specific interaction is +-- put there. +-- +-- The job of this class is to provide convenient methods that can be +-- called by the display layer. For instance, it provides methods for +-- starting a graph drawing scope, managing the stack of such scope, +-- adding a node to a graph and so on. + +local InterfaceToDisplay = {} + +-- Namespace +require("pgf.gd.interface").InterfaceToDisplay = InterfaceToDisplay + + +-- Imports +local InterfaceCore = require "pgf.gd.interface.InterfaceCore" +local Scope = require "pgf.gd.interface.Scope" + +local Binding = require "pgf.gd.bindings.Binding" + +local Sublayouts = require "pgf.gd.control.Sublayouts" +local LayoutPipeline = require "pgf.gd.control.LayoutPipeline" + +local Digraph = require "pgf.gd.model.Digraph" +local Vertex = require "pgf.gd.model.Vertex" +local Edge = require "pgf.gd.model.Edge" +local Collection = require "pgf.gd.model.Collection" + +local Storage = require "pgf.gd.lib.Storage" +local LookupTable = require "pgf.gd.lib.LookupTable" +local Event = require "pgf.gd.lib.Event" + +local lib = require "pgf.gd.lib" + + +-- Forward declarations +local get_current_options_table +local render_collections +local push_on_option_stack +local vertex_created + +-- Local objects + +local phase_unique = {} -- a unique handle +local collections_unique = {} -- a unique handle +local option_cache = nil -- The option cache + + + + +--- +-- Initiliaze the binding. This function is called once by the display +-- layer at the very beginning. For instance, \tikzname\ does the +-- following call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--InterfaceToDisplay.bind(require "pgf.gd.bindings.BindingToPGF") +--\end{codeexample} +-- +-- Inside this call, many standard declarations will be executed, that +-- is, the declared binding will be used immediately. +-- +-- Subsequently, the |binding| field of the |InterfaceCore| can be used. +-- +-- @param class A subclass of |Binding|. + +function InterfaceToDisplay.bind(class) + assert (not InterfaceCore.binding, "binding already initialized") + + -- Create a new object + InterfaceCore.binding = setmetatable({}, class) + + -- Load these libraries, which contain many standard declarations: + require "pgf.gd.model.library" + require "pgf.gd.control.library" +end + + + + +--- +-- Start a graph drawing scope. Note that this is not the same as +-- starting a subgraph / sublayout, which are local to a graph drawing +-- scope: When a new graph drawing scope is started, it is pushed on +-- top of a stack of graph drawing scopes and all other ``open'' +-- scopes are no longer directly accessible. All method calls to an +-- |Interface...| object will refer to this newly created scope until +-- either a new scope is opened or until the current scope is closed +-- once more. +-- +-- Each graph drawing scope comes with a syntactic digraph that is +-- build using methods like |addVertex| or |addEdge|. +-- +-- @param height The to-be-used height of the options stack. All +-- options above this height will be popped prior to attacking the +-- options to the syntactic digraph. + +function InterfaceToDisplay.beginGraphDrawingScope(height) + + -- Create a new scope table + local scope = Scope.new {} + + -- Setup syntactic digraph: + local g = scope.syntactic_digraph + + g.options = get_current_options_table(height) + g.syntactic_digraph = g + g.scope = scope + + -- Push scope: + InterfaceCore.scopes[#InterfaceCore.scopes + 1] = scope +end + + + +--- +-- Arranges the current graph using the specified algorithm and options. +-- +-- This function should be called after the graph drawing scope has +-- been opened and the syntactic digraph has been completely +-- specified. It will now start running the algorithm specified +-- through the |algorithm_phase| options. +-- +-- Internally, this function creates a coroutine that will run the current graph +-- drawing algorithm. Coroutines are needed since a graph drawing +-- algorithm may choose to create a new node. In this case, the +-- algorithm needs to be suspended and control must be returned back +-- to the display layer, so that the node can be typeset in order to +-- determine the precise size information. Once this is done, control +-- must be passed back to the exact point inside the algorithm where +-- the node was created. Clearly, all of these actions are exactly +-- what coroutines are for. +-- +-- @return Time it took to run the algorithm + +function InterfaceToDisplay.runGraphDrawingAlgorithm() + + -- Time things + local start = os.clock() + + -- Setup + local scope = InterfaceCore.topScope() + assert(not scope.coroutine, "coroutine already created for current gd scope") + + -- The actual drawing function + local function run () + if #scope.syntactic_digraph.vertices == 0 then + -- Nothing needs to be done + return + end + + LayoutPipeline.run(scope) + end + + scope.coroutine = coroutine.create(run) + + -- Run it: + InterfaceToDisplay.resumeGraphDrawingCoroutine() + + -- End timing: + local stop = os.clock() + + return stop - start +end + + +--- +-- Resume the graph drawing coroutine. +-- +-- This function is the work horse of the coroutine management. It +-- gets called whenever control passes back from the display layer to +-- the algorithm level. We resume the graph drawing coroutine so that the +-- algorithm can start/proceed. The tricky part is when the algorithm +-- yields, but is not done. In this case, the code needed for creating +-- a new node is passed back to the display layer through the binding, +-- which must then execute the code and then resuming the coroutine. +-- +function InterfaceToDisplay.resumeGraphDrawingCoroutine() + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Asserts + assert(scope.coroutine, "coroutine not created for current gd scope") + + -- Run + local ok, text = coroutine.resume(scope.coroutine) + assert(ok, text) + if coroutine.status(scope.coroutine) ~= "dead" then + -- Ok, ask binding to continue + binding:resumeGraphDrawingCoroutine(text) + end +end + + + +--- Ends the current graph drawing scope. +-- +function InterfaceToDisplay.endGraphDrawingScope() + assert(#InterfaceCore.scopes > 0, "no gd scope open") + InterfaceCore.scopes[#InterfaceCore.scopes] = nil -- pop +end + + + + +--- +-- Creates a new vertex in the syntactic graph of the current graph +-- drawing scope. The display layer should call this function for each +-- node of the graph. The |name| must be a unique string identifying +-- the node. The newly created vertex will be added to the syntactic +-- digraph. The binding function |everyVertexCreation| will then be +-- called, allowing the binding to store information regarding the newly +-- created vertex. +-- +-- For each vertex an event will be created in the event +-- sequence. This event will have the kind |"node"| and its +-- |parameter| will be the vertex. +-- +-- @param name Name of the vertex. +-- +-- @param shape The shape of the vertex such as |"circle"| or +-- |"rectangle"|. This shape may help a graph drawing algorithm +-- figuring out how the node should be placed. +-- +-- @param path A |Path| object representing the vertex's path. +-- +-- @param height The to-be-used height of the options stack. All +-- options above this height will be popped prior to attacking the +-- options to the syntactic digraph. +-- +-- @param binding_infos These options are passed to and are specific +-- to the current |Binding|. +-- +-- @param anchors A table of anchors (mapping anchor positions to +-- |Coordinates|). + + +function InterfaceToDisplay.createVertex(name, shape, path, height, binding_infos, anchors) + + -- The path should never be empty, so we create a trivial path in the provided + -- path is empty. This occurs with the ‘coordinate‘ shape for example. + if #path == 0 then + path:appendMoveto(0, 0) + path:appendClosepath() + end + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Does vertex already exist? + local v = scope.node_names[name] + assert (not v or not v.created_on_display_layer, "node already created") + + -- Create vertex + if not v then + v = Vertex.new { + name = name, + shape = shape, + kind = "node", + path = path, + options = get_current_options_table(height), + anchors = anchors, + } + + vertex_created(v,scope) + else + assert(v.kind == "subgraph node", "subgraph node expected") + v.shape = shape + v.path = path + v.anchors = anchors + end + + v.created_on_display_layer = true + + -- Call binding + binding.storage[v] = binding_infos + binding:everyVertexCreation(v) +end + + +-- This is a helper function +function vertex_created(v,scope) + + -- Create Event + local e = InterfaceToDisplay.createEvent ("node", v) + v.event = e + + -- Create name lookup + scope.node_names[v.name] = v + + -- Add vertex to graph + scope.syntactic_digraph:add {v} + + -- Add to collections + for _,c in ipairs(v.options.collections) do + LookupTable.addOne(c.vertices, v) + end + +end + + + +--- +-- Creates a new vertex in the syntactic graph of the current graph +-- drawing scope that is a subgraph vertex. Such a vertex +-- ``surrounds'' the vertices of a subgraph. The special property of a +-- subgraph node opposed to a normal node is that it is created only +-- after the subgraph has been laid out. However, the difference to a +-- collection like |hyper| is that the node is availble immediately as +-- a normal node in the sense that you can connect edges to it. +-- +-- What happens internally is that subgraph nodes get ``registered'' +-- immediately both on the display level and on the algorithm level, +-- but the actual node is only created inside the layout pipeline +-- using a callback of the binding. The present function is used to +-- perform this registering. The node creation happens when the +-- innermost layout in which the subgraph node is declared has +-- finished. For each subgraph node, a collection is created that +-- contains all vertices (and edges) being part of the subgraph. For +-- this reason, this method is a |push...| method, since it pushes +-- something on the options stack. +-- +-- The |init| parameter will be used during the creation of the node, +-- see |Binding:createVertex| for details on the fields. Note that +-- |init.text| is often not displayed for such ``vast'' nodes as those +-- created for whole subgraphs, but a shape may use it nevertheless +-- (for instance, one might display this text at the top of the node +-- or, in case of a \textsc{uml} package, in a special box above the +-- actual node). +-- +-- The |init.generated_options| will be augmented by additional +-- key--value pairs when the vertex is created: +-- +-- \begin{itemize} +-- \item The key |subgraph point cloud| will have as its value a +-- string that is be a list of points (without +-- separating commas) like |"(10pt,20pt)(0pt,0pt)(30pt,40pt)"|, always in +-- this syntax. The list will contain all points inside the +-- subgraph. In particular, a bounding box around these points will +-- encompass all nodes and bend points of the subgraph. +-- The bounding box of this point cloud is guaranteed to be centered on +-- the origin. +-- \item The key |subgraph bounding box width| will have as its value +-- the width of a bounding box (in \TeX\ points, as a string with the +-- suffix |"pt"|). +-- \item The key |subgraph bounding box height| stores the height of a +-- bounding box. +-- \end{itemize} +-- +-- @param name The name of the node. +-- @param height Height of the options stack. Note that this method +-- pushes something (namely a collection) on the options stack. +-- @param info A table passed to |Binding:createVertex|, see that function. +-- +function InterfaceToDisplay.pushSubgraphVertex(name, height, info) + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Does vertex already exist? + assert (not scope.node_names[name], "node already created") + + -- Create vertex + local v = Vertex.new { + name = name, + kind = "subgraph node", + options = get_current_options_table(height-1) + } + + vertex_created(v,scope) + + -- Store info + info.generated_options = info.generated_options or {} + info.name = name + v.subgraph_info = info + + -- Create collection and link it to v + local _, _, entry = InterfaceToDisplay.pushOption(InterfaceCore.subgraph_node_kind, nil, height) + v.subgraph_collection = entry.value + v.subgraph_collection.subgraph_node = v + + -- Find parent collection in options stack: + local collections = v.options.collections + for i=#collections,1,-1 do + if collections[i].kind == InterfaceCore.sublayout_kind then + v.subgraph_collection.parent_layout = collections[i] + break + end + end +end + + + +--- +-- Add options for an already existing vertex. +-- +-- This function allows you to add options to an already existing +-- vertex. The options that will be added are all options on the +-- current options stack; they will overwrite existing options of the +-- same name. For collections, the vertex stays in all collections it +-- used to, it is only added to all collections that are currently on +-- the options stack. +-- +-- @param name Name of the vertex. +-- @param height The option stack height. + +function InterfaceToDisplay.addToVertexOptions(name, height) + + -- Setup + local scope = InterfaceCore.topScope() + + -- Does vertex already exist? + local v = assert (scope.node_names[name], "node is missing, cannot add options") + + v.options = get_current_options_table(height, v.options) + + -- Add to collections + for _,c in ipairs(v.options.collections) do + LookupTable.addOne(c.vertices, v) + end + +end + + + + + +--- +-- Creates a new edge in the syntactic graph of the current graph +-- drawing scope. The display layer should call this function for each +-- edge that is created. Both the |from| vertex and the |to| vertex +-- must exist (have been created through |createVertex|) prior to your +-- being able to call this function. +-- +-- After the edge has been created, the binding layer's function +-- |everyEdgeCreation| will be called, allowing the binding layer to +-- store information about the edge. +-- +-- For each edge an event is created, whose kind is |"edge"| and whose +-- |parameter| is a two-element array whose first entry is the edge's +-- arc in the syntactic digraph and whose second entry is the position +-- of the edge in the arc's array of syntactic edges. +-- +-- @param tail Name of the node the edge begins at. +-- @param head Name of the node the edge ends at. +-- @param direction Direction of the edge (e.g. |--| for an undirected edge +-- or |->| for a directed edge from the first to the second +-- node). +-- @param height The option stack height, see for instance |createVertex|. +-- +-- @param binding_infos These options will be stored in the |storage| +-- of the vertex at the field index by the binding. + +function InterfaceToDisplay.createEdge(tail, head, direction, height, binding_infos) + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Does vertex already exist? + local h = scope.node_names[head] + local t = scope.node_names[tail] + assert (h and t, "attempting to create edge between nodes that are not in the graph") + + -- Create Arc object + local arc = scope.syntactic_digraph:connect(t, h) + + -- Create Edge object + local edge = Edge.new { + head = h, + tail = t, + direction = direction, + options = get_current_options_table(height) + } + + -- Add to arc + arc.syntactic_edges[#arc.syntactic_edges+1] = edge + + -- Create Event + local e = InterfaceToDisplay.createEvent ("edge", { arc, #arc.syntactic_edges }) + edge.event = e + + -- Make part of collections + for _,c in ipairs(edge.options.collections) do + LookupTable.addOne(c.edges, edge) + end + + -- Call binding + binding.storage[edge] = binding_infos + binding:everyEdgeCreation(edge) + +end + + + + + +--- +-- Push an option to the stack of options. +-- +-- As a graph is parsed, a stack of ``current options'' +-- is created. To add something to this table, the display layers may +-- call the method |pushOption|. To pop something from this stack, +-- just set the |height| value during the next push to the position to +-- which you actually wish to push something; everything above and +-- including this position will be popped from the stack. +-- +-- When an option is pushed, several additional options may also be +-- pushed, namely whenever the option has a |use| field set. These +-- additional options may, in turn, also push new options. Because of +-- this, this function returns a new stack height, representing the +-- resulting stack height. +-- +-- In addition to this stack height, this function returns a Boolean +-- value indicating whether a ``main algorithm phase was set.'' This +-- happens whenever a key is executed (directly or indirectly through +-- the |use| field) that selects an algorithm for the ``main'' +-- algorithm phase. This information may help the caller to setup the +-- graph drawing scopes correctly. +-- +-- @param key A parameter (must be a string). +-- @param value A value (can be anything). If it is a string, it will +-- be converted to whatever the key expects. +-- @param height A stack height at which to insert the key. Everything +-- above this height will be removed. +-- +-- @return A new stack height +-- @return A Boolean that is |true| iff the main algorithm phase was +-- set by the option or one option |use|d by it. +-- @return The newly created entry on the stack. If more entries are +-- created through the use of the |use| field, the original entry is +-- returned nevertheless. + + +function InterfaceToDisplay.pushOption(key, value, height) + assert(type(key) == "string", "illegal key") + + local key_record = assert(InterfaceCore.keys[key], "unknown key") + local main_phase_set = false + + if value == nil and key_record.default then + value = key_record.default + end + + -- Find out what kind of key we are pushing: + + if key_record.algorithm then + -- Push a phase + if type(InterfaceCore.algorithm_classes[key]) == "function" then + -- Call the constructor function + InterfaceCore.algorithm_classes[key] = InterfaceCore.algorithm_classes[key]() + end + + local algorithm = InterfaceCore.algorithm_classes[key] + + assert (algorithm, "algorithm class not found") + + push_on_option_stack(phase_unique, + { phase = key_record.phase, algorithm = algorithm }, + height) + + if key_record.phase == "main" then + main_phase_set = true + end + + elseif key_record.layer then + -- Push a collection + local stack = InterfaceCore.option_stack + local scope = InterfaceCore.topScope() + + -- Get the stack above "height": + local options = get_current_options_table(height-1) + + -- Create the collection event + local event = InterfaceToDisplay.createEvent ("collection", key) + + -- Create collection object: + local collection = Collection.new { kind = key, options = options, event = event } + + -- Store in collections table of current scope: + local collections = scope.collections[key] or {} + collections[#collections + 1] = collection + scope.collections[key] = collections + + -- Build collection tree + collection:registerAsChildOf(options.collections[#options.collections]) + + -- Push on stack + push_on_option_stack(collections_unique, collection, height) + + else + + -- A normal key + push_on_option_stack(key, InterfaceCore.convert(value, InterfaceCore.keys[key].type), height) + + end + + local newly_created = InterfaceCore.option_stack[#InterfaceCore.option_stack] + + -- Now, push use keys: + local use = key_record.use + if key_record.use then + local flag + for _,u in ipairs(InterfaceCore.keys[key].use) do + local use_k = u.key + local use_v = u.value + if type(use_k) == "function" then + use_k = use_k(value) + end + if type(use_v) == "function" then + use_v = use_v(value) + end + height, flag = InterfaceToDisplay.pushOption(use_k, use_v, height+1) + main_phase_set = main_phase_set or flag + end + end + + return height, main_phase_set, newly_created +end + + +--- +-- Push a layout on the stack of options. As long as this layout is on +-- the stack, all vertices and edges will be part of this layout. For +-- details on layouts, please see |Sublayouts|. +-- +-- @param height A stack height at which to insert the key. Everything +-- above this height will be removed. + +function InterfaceToDisplay.pushLayout(height) + InterfaceToDisplay.pushOption(InterfaceCore.sublayout_kind, nil, height) +end + + + +--- +-- Creates an event and adds it to the event string of the current scope. +-- +-- @param kind Name/kind of the event. +-- @param parameters Parameters of the event. +-- +-- @return The newly pushed event +-- +function InterfaceToDisplay.createEvent(kind, param) + local scope = InterfaceCore.topScope() + local n = #scope.events + 1 + local e = Event.new { kind = kind, parameters = param, index = n } + scope.events[n] = e + + return e +end + + + +--- +-- This method allows you to query the table of all declared keys. It +-- contains them both as an array and also as a table index by the +-- keys's names. In particular, you can then iterate over it using +-- |ipairs| and you can check whether a key is defined by accessing +-- the table at the key's name. Each entry of the table is the +-- original table passed to |InterfaceToAlgorithms.declare|. +-- +-- @return A lookup table of all declared keys. + +function InterfaceToDisplay.getDeclaredKeys() + return InterfaceCore.keys +end + + + + +--- +-- Renders the graph. +-- +-- This function is called after the graph has been laid out by the +-- graph drawing algorithms. It will trigger a sequence of calls to +-- the binding layer that will, via callbacks, start rendering the +-- whole graph. +-- +-- In detail, this function calls: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local binding = InterfaceCore.binding +-- +--binding:renderStart() +--render_vertices() +--render_edges() +--render_collections() +--binding:renderStop() +--\end{codeexample} +-- +-- Here, the |render_...| functions are local, internal functions that are, +-- nevertheless, documented here. +-- +-- @param name Returns the algorithm class that has been declared using +-- |declare| under the given name. + +function InterfaceToDisplay.renderGraph() + local scope = InterfaceCore.topScope() + local syntactic_digraph = scope.syntactic_digraph + + local binding = InterfaceCore.binding + + binding:renderStart() + render_vertices(syntactic_digraph.vertices) + render_edges(syntactic_digraph.arcs) + render_collections(scope.collections) + binding:renderStop() +end + + + + + +--- +-- Render the vertices after the graph drawing algorithm has +-- finished. This function is local and internal and included only for +-- documenting the call graph. +-- +-- When the graph drawing algorithm is done, the interface will start +-- rendering the vertices by calling appropriate callbacks of the +-- binding layer. +-- +-- Consider the following code: +--\begin{codeexample}[code only] +--\graph [... layout] { +-- a -- b -- c -- d; +--}; +--\end{codeexample} +-- +-- In this case, after the graph drawing algorithm has run, the +-- present function will call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local binding = InterfaceCore.binding +-- +--binding:renderVerticesStart() +--binding:renderVertex(vertex_a) +--binding:renderVertex(vertex_b) +--binding:renderVertex(vertex_c) +--binding:renderVertex(vertex_d) +--binding:renderVerticesStop() +--\end{codeexample} +-- +-- @param vertices An array of all vertices in the syntactic digraph. + +function render_vertices(vertices) + InterfaceCore.binding:renderVerticesStart() + for _,vertex in ipairs(vertices) do + InterfaceCore.binding:renderVertex(vertex) + end + InterfaceCore.binding:renderVerticesStop() +end + + +--- +-- Render the collections whose layer is not |0|. This local, internal +-- function is called to render the different collection kinds. +-- +-- Collection kinds rendered in the order provided by the |layer| +-- field passed to |declare| during the declaration of the colleciton +-- kind, see also |declare_collection|. If several collection kinds +-- have the same layer, they are rendered in lexicographical ordering +-- (to ensure that they are always rendered in the same order). +-- +-- Consider the following code: +--\begin{codeexample}[code only, tikz syntax=false] +--declare { key = "hyper", layer = 1 } +--\end{codeexample} +-- you can say on the \tikzname\ layer +--\begin{codeexample}[code only] +--\graph { +-- a, b, c, d; +-- { [hyper] a, b, c } +-- { [hyper] b, c, d } +--}; +--\end{codeexample} +-- +-- In this case, after the graph drawing algorithm has run, the +-- present function will call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local binding = InterfaceCore.binding +-- +--binding:renderCollectionStartKind("hyper", 1) +--binding:renderCollection(collection_containing_abc) +--binding:renderCollection(collection_containing_bcd) +--binding:renderCollectionStopKind("hyper", 1) +--\end{codeexample} +-- +-- @param collections The |collections| table of the current scope. + +function render_collections(collections) + local kinds = InterfaceCore.collection_kinds + local binding = InterfaceCore.binding + + for i=1,#kinds do + local kind = kinds[i].kind + local layer = kinds[i].layer + + if layer ~= 0 then + binding:renderCollectionStartKind(kind, layer) + for _,c in ipairs(collections[kind] or {}) do + binding:renderCollection(c) + end + binding:renderCollectionStopKind(kind, layer) + end + end +end + + +--- +-- Render the syntactic edges of a graph after the graph drawing +-- algorithm has finished. This function is local and internal and included only +-- for documenting the call graph. +-- +-- When the graph drawing algorithm is done, the interface will first +-- rendering the vertices using |render_vertices|, followed by calling +-- this function, which in turn calls appropriate callbacks to the +-- binding layer. +-- +-- Consider the following code: +--\begin{codeexample}[code only] +-- \graph [... layout] { +-- a -- b -- c -- d; +-- }; +--\end{codeexample} +-- +-- In this case, after the graph drawing algorithm has run, the +-- present function will call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- local binding = InterfaceCore.binding +-- +-- binding:renderEdgesStart() +-- binding:renderEdge(edge_from_a_to_b) +-- binding:renderEdge(edge_from_b_to_c) +-- binding:renderEdge(edge_from_c_to_d) +-- binding:renderEdgesStop() +--\end{codeexample} +-- +-- @param arcs The array of arcs of the syntactic digraph. + +function render_edges(arcs) + InterfaceCore.binding:renderEdgesStart() + for _,a in ipairs(arcs) do + for _,e in ipairs (a.syntactic_edges) do + InterfaceCore.binding:renderEdge(e) + end + end + InterfaceCore.binding:renderEdgesStop() +end + + +local aliases = InterfaceCore.option_aliases +local option_initial = InterfaceCore.option_initial + +local option_metatable = { + __index = + function (t, key) + local k = aliases[key] + if k then + local v = (type(k) == "string" and t[k]) or (type(k) == "function" and k(t)) or nil + if v ~= nil then + return v + end + end + return option_initial[key] + end +} + + +--- +-- Get the current options table. +-- +-- An option table can be accessed like a normal table; however, there +-- is a global fallback for this table. If an index is not defined, +-- the value of this index in the global fallback table is used. (This +-- reduces the overall amount of option keys that need to be stored +-- with object.) +-- +-- (This function is local and internal and included only for documentation +-- purposes.) +-- +-- @param height The stack height for which the option table is +-- required. +-- @param table If non |nil|, the options will be added to this +-- table. +-- +-- @return The option table as described above. + +function get_current_options_table (height, table) + local stack = InterfaceCore.option_stack + assert (height >= 0 and height <= #stack, "height value out of bounds") + + if height == InterfaceCore.option_cache_height and not table then + return option_cache + else + -- Clear superfluous part of stack + for i=#stack,height+1,-1 do + stack[i] = nil + end + + -- Build options table + local cache + if not table then + cache = setmetatable( + { + algorithm_phases = setmetatable({}, InterfaceCore.option_initial.algorithm_phases), + collections = {} + }, option_metatable) + else + cache = lib.copy(table) + cache.algorithm_phases = lib.copy(cache.algorithm_phases) + cache.collections = lib.copy(cache.collections) + end + + local algorithm_phases = cache.algorithm_phases + local collections = cache.collections + local keys = InterfaceCore.keys + + local function handle (k, v) + if k == phase_unique then + algorithm_phases[v.phase] = v.algorithm + elseif k == collections_unique then + LookupTable.addOne(collections, v) + else + cache[k] = v + end + end + + for _,s in ipairs(stack) do + handle (s.key, s.value) + end + + -- Cache it, if this was not added: + if not table then + InterfaceCore.option_cache_height = height + option_cache = cache + end + + return cache + end +end + + + +-- A helper function + +function push_on_option_stack(key, value, height) + local stack = InterfaceCore.option_stack + + assert (type(height) == "number" and height > 0 and height <= #stack + 1, + "height value out of bounds") + + -- Clear superfluous part of stack + for i=#stack,height+1,-1 do + stack[i] = nil + end + + stack[height] = { key = key, value = value } + InterfaceCore.option_cache_height = nil -- invalidate cache +end + + + +-- Done + +return InterfaceToDisplay diff --git a/Master/texmf-dist/tex/latex/tikz-feynman/tikzfeynman.patch.3.0.1.lua b/Master/texmf-dist/tex/latex/tikz-feynman/tikzfeynman.patch.3.0.1.lua new file mode 100644 index 00000000000..acecd80b995 --- /dev/null +++ b/Master/texmf-dist/tex/latex/tikz-feynman/tikzfeynman.patch.3.0.1.lua @@ -0,0 +1,1037 @@ +-- This patched version of the createVertex function simply ensures that the +-- path is never empty. This works fine for TikZ version 3.0.1 and 3.0.1a. +-- +-- Later versions (should) have a more thorough patch by Till which is +-- incompatible with this override unfortunately. +-- +-- ############################################################################# +-- +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua,v 1.14 2014/03/19 09:20:59 tantau Exp $ + +-- Print anything - including nested tables +function table_print (tt, indent, done) + done = done or {} + indent = indent or 0 + if type(tt) == "table" then + for key, value in pairs (tt) do + io.write(string.rep (" ", indent)) -- indent it + if type (value) == "table" and not done [value] then + done [value] = true + io.write(string.format("[%s] => table\n", tostring (key))); + io.write(string.rep (" ", indent+2)) -- indent it + io.write("(\n"); + table_print (value, indent + 4, done) + io.write(string.rep (" ", indent+2)) -- indent it + io.write(")\n"); + else + io.write(string.format("[%s] => %s\n", + tostring (key), tostring(value))) + end + end + else + io.write(tt .. "\n") + end +end + +--- +-- This class provides the interface between a display +-- layer (like \tikzname\ or a graph editor) and graph drawing +-- system. Another class, |InterfaceToAlgorithms|, binds the algorithm +-- layer (which are written in Lua) to the graph drawing system. +-- +-- The functions declared here are independent of the actual display +-- layer. Rather, the differences between the layers are encapsulated +-- by subclasses of the |Binding| class, see that class for +-- details. Thus, when a new display layer is written, the present +-- class is \emph{used}, but not \emph{modified}. Instead, only a new +-- binding is created and all display layer specific interaction is +-- put there. +-- +-- The job of this class is to provide convenient methods that can be +-- called by the display layer. For instance, it provides methods for +-- starting a graph drawing scope, managing the stack of such scope, +-- adding a node to a graph and so on. + +local InterfaceToDisplay = {} + +-- Namespace +require("pgf.gd.interface").InterfaceToDisplay = InterfaceToDisplay + + +-- Imports +local InterfaceCore = require "pgf.gd.interface.InterfaceCore" +local Scope = require "pgf.gd.interface.Scope" + +local Binding = require "pgf.gd.bindings.Binding" + +local Sublayouts = require "pgf.gd.control.Sublayouts" +local LayoutPipeline = require "pgf.gd.control.LayoutPipeline" + +local Digraph = require "pgf.gd.model.Digraph" +local Vertex = require "pgf.gd.model.Vertex" +local Edge = require "pgf.gd.model.Edge" +local Collection = require "pgf.gd.model.Collection" + +local Storage = require "pgf.gd.lib.Storage" +local LookupTable = require "pgf.gd.lib.LookupTable" +local Event = require "pgf.gd.lib.Event" + +local lib = require "pgf.gd.lib" + + +-- Forward declarations +local get_current_options_table +local render_collections +local push_on_option_stack +local vertex_created + +-- Local objects + +local phase_unique = {} -- a unique handle +local collections_unique = {} -- a unique handle +local option_cache = nil -- The option cache + + + + +--- +-- Initiliaze the binding. This function is called once by the display +-- layer at the very beginning. For instance, \tikzname\ does the +-- following call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--InterfaceToDisplay.bind(require "pgf.gd.bindings.BindingToPGF") +--\end{codeexample} +-- +-- Inside this call, many standard declarations will be executed, that +-- is, the declared binding will be used immediately. +-- +-- Subsequently, the |binding| field of the |InterfaceCore| can be used. +-- +-- @param class A subclass of |Binding|. + +function InterfaceToDisplay.bind(class) + assert (not InterfaceCore.binding, "binding already initialized") + + -- Create a new object + InterfaceCore.binding = setmetatable({}, class) + + -- Load these libraries, which contain many standard declarations: + require "pgf.gd.model.library" + require "pgf.gd.control.library" +end + + + + +--- +-- Start a graph drawing scope. Note that this is not the same as +-- starting a subgraph / sublayout, which are local to a graph drawing +-- scope: When a new graph drawing scope is started, it is pushed on +-- top of a stack of graph drawing scopes and all other ``open'' +-- scopes are no longer directly accessible. All method calls to an +-- |Interface...| object will refer to this newly created scope until +-- either a new scope is opened or until the current scope is closed +-- once more. +-- +-- Each graph drawing scope comes with a syntactic digraph that is +-- build using methods like |addVertex| or |addEdge|. +-- +-- @param height The to-be-used height of the options stack. All +-- options above this height will be popped prior to attacking the +-- options to the syntactic digraph. + +function InterfaceToDisplay.beginGraphDrawingScope(height) + + -- Create a new scope table + local scope = Scope.new {} + + -- Setup syntactic digraph: + local g = scope.syntactic_digraph + + g.options = get_current_options_table(height) + g.syntactic_digraph = g + g.scope = scope + + -- Push scope: + InterfaceCore.scopes[#InterfaceCore.scopes + 1] = scope +end + + + +--- +-- Arranges the current graph using the specified algorithm and options. +-- +-- This function should be called after the graph drawing scope has +-- been opened and the syntactic digraph has been completely +-- specified. It will now start running the algorithm specified +-- through the |algorithm_phase| options. +-- +-- Internally, this function creates a coroutine that will run the current graph +-- drawing algorithm. Coroutines are needed since a graph drawing +-- algorithm may choose to create a new node. In this case, the +-- algorithm needs to be suspended and control must be returned back +-- to the display layer, so that the node can be typeset in order to +-- determine the precise size information. Once this is done, control +-- must be passed back to the exact point inside the algorithm where +-- the node was created. Clearly, all of these actions are exactly +-- what coroutines are for. +-- +-- @return Time it took to run the algorithm + +function InterfaceToDisplay.runGraphDrawingAlgorithm() + + -- Time things + local start = os.clock() + + -- Setup + local scope = InterfaceCore.topScope() + assert(not scope.coroutine, "coroutine already created for current gd scope") + + -- The actual drawing function + local function run () + if #scope.syntactic_digraph.vertices == 0 then + -- Nothing needs to be done + return + end + + LayoutPipeline.run(scope) + end + + scope.coroutine = coroutine.create(run) + + -- Run it: + InterfaceToDisplay.resumeGraphDrawingCoroutine() + + -- End timing: + local stop = os.clock() + + return stop - start +end + + +--- +-- Resume the graph drawing coroutine. +-- +-- This function is the work horse of the coroutine management. It +-- gets called whenever control passes back from the display layer to +-- the algorithm level. We resume the graph drawing coroutine so that the +-- algorithm can start/proceed. The tricky part is when the algorithm +-- yields, but is not done. In this case, the code needed for creating +-- a new node is passed back to the display layer through the binding, +-- which must then execute the code and then resuming the coroutine. +-- +function InterfaceToDisplay.resumeGraphDrawingCoroutine() + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Asserts + assert(scope.coroutine, "coroutine not created for current gd scope") + + -- Run + local ok, text = coroutine.resume(scope.coroutine) + assert(ok, text) + if coroutine.status(scope.coroutine) ~= "dead" then + -- Ok, ask binding to continue + binding:resumeGraphDrawingCoroutine(text) + end +end + + + +--- Ends the current graph drawing scope. +-- +function InterfaceToDisplay.endGraphDrawingScope() + assert(#InterfaceCore.scopes > 0, "no gd scope open") + InterfaceCore.scopes[#InterfaceCore.scopes] = nil -- pop +end + + + + +--- +-- Creates a new vertex in the syntactic graph of the current graph +-- drawing scope. The display layer should call this function for each +-- node of the graph. The |name| must be a unique string identifying +-- the node. The newly created vertex will be added to the syntactic +-- digraph. The binding function |everyVertexCreation| will then be +-- called, allowing the binding to store information regarding the newly +-- created vertex. +-- +-- For each vertex an event will be created in the event +-- sequence. This event will have the kind |"node"| and its +-- |parameter| will be the vertex. +-- +-- @param name Name of the vertex. +-- +-- @param shape The shape of the vertex such as |"circle"| or +-- |"rectangle"|. This shape may help a graph drawing algorithm +-- figuring out how the node should be placed. +-- +-- @param path A |Path| object representing the vertex's path. +-- +-- @param height The to-be-used height of the options stack. All +-- options above this height will be popped prior to attacking the +-- options to the syntactic digraph. +-- +-- @param binding_infos These options are passed to and are specific +-- to the current |Binding|. +-- +-- @param anchors A table of anchors (mapping anchor positions to +-- |Coordinates|). + + +function InterfaceToDisplay.createVertex(name, shape, path, height, binding_infos, anchors) + + -- The path should never be empty, so we create a trivial path in the provided + -- path is empty. This occurs with the ‘coordinate‘ shape for example. + if #path == 0 then + path:appendMoveto(0, 0) + path:appendClosepath() + end + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Does vertex already exist? + local v = scope.node_names[name] + assert (not v or not v.created_on_display_layer, "node already created") + + -- Create vertex + if not v then + v = Vertex.new { + name = name, + shape = shape, + kind = "node", + path = path, + options = get_current_options_table(height), + anchors = anchors, + } + + vertex_created(v,scope) + else + assert(v.kind == "subgraph node", "subgraph node expected") + v.shape = shape + v.path = path + v.anchors = anchors + end + + v.created_on_display_layer = true + + -- Call binding + binding.storage[v] = binding_infos + binding:everyVertexCreation(v) +end + + +-- This is a helper function +function vertex_created(v,scope) + + -- Create Event + local e = InterfaceToDisplay.createEvent ("node", v) + v.event = e + + -- Create name lookup + scope.node_names[v.name] = v + + -- Add vertex to graph + scope.syntactic_digraph:add {v} + + -- Add to collections + for _,c in ipairs(v.options.collections) do + LookupTable.addOne(c.vertices, v) + end + +end + + + +--- +-- Creates a new vertex in the syntactic graph of the current graph +-- drawing scope that is a subgraph vertex. Such a vertex +-- ``surrounds'' the vertices of a subgraph. The special property of a +-- subgraph node opposed to a normal node is that it is created only +-- after the subgraph has been laid out. However, the difference to a +-- collection like |hyper| is that the node is availble immediately as +-- a normal node in the sense that you can connect edges to it. +-- +-- What happens internally is that subgraph nodes get ``registered'' +-- immediately both on the display level and on the algorithm level, +-- but the actual node is only created inside the layout pipeline +-- using a callback of the binding. The present function is used to +-- perform this registering. The node creation happens when the +-- innermost layout in which the subgraph node is declared has +-- finished. For each subgraph node, a collection is created that +-- contains all vertices (and edges) being part of the subgraph. For +-- this reason, this method is a |push...| method, since it pushes +-- something on the options stack. +-- +-- The |init| parameter will be used during the creation of the node, +-- see |Binding:createVertex| for details on the fields. Note that +-- |init.text| is often not displayed for such ``vast'' nodes as those +-- created for whole subgraphs, but a shape may use it nevertheless +-- (for instance, one might display this text at the top of the node +-- or, in case of a \textsc{uml} package, in a special box above the +-- actual node). +-- +-- The |init.generated_options| will be augmented by additional +-- key--value pairs when the vertex is created: +-- +-- \begin{itemize} +-- \item The key |subgraph point cloud| will have as its value a +-- string that is be a list of points (without +-- separating commas) like |"(10pt,20pt)(0pt,0pt)(30pt,40pt)"|, always in +-- this syntax. The list will contain all points inside the +-- subgraph. In particular, a bounding box around these points will +-- encompass all nodes and bend points of the subgraph. +-- The bounding box of this point cloud is guaranteed to be centered on +-- the origin. +-- \item The key |subgraph bounding box width| will have as its value +-- the width of a bounding box (in \TeX\ points, as a string with the +-- suffix |"pt"|). +-- \item The key |subgraph bounding box height| stores the height of a +-- bounding box. +-- \end{itemize} +-- +-- @param name The name of the node. +-- @param height Height of the options stack. Note that this method +-- pushes something (namely a collection) on the options stack. +-- @param info A table passed to |Binding:createVertex|, see that function. +-- +function InterfaceToDisplay.pushSubgraphVertex(name, height, info) + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Does vertex already exist? + assert (not scope.node_names[name], "node already created") + + -- Create vertex + local v = Vertex.new { + name = name, + kind = "subgraph node", + options = get_current_options_table(height-1) + } + + vertex_created(v,scope) + + -- Store info + info.generated_options = info.generated_options or {} + info.name = name + v.subgraph_info = info + + -- Create collection and link it to v + local _, _, entry = InterfaceToDisplay.pushOption(InterfaceCore.subgraph_node_kind, nil, height) + v.subgraph_collection = entry.value + v.subgraph_collection.subgraph_node = v + + -- Find parent collection in options stack: + local collections = v.options.collections + for i=#collections,1,-1 do + if collections[i].kind == InterfaceCore.sublayout_kind then + v.subgraph_collection.parent_layout = collections[i] + break + end + end +end + + + +--- +-- Add options for an already existing vertex. +-- +-- This function allows you to add options to an already existing +-- vertex. The options that will be added are all options on the +-- current options stack; they will overwrite existing options of the +-- same name. For collections, the vertex stays in all collections it +-- used to, it is only added to all collections that are currently on +-- the options stack. +-- +-- @param name Name of the vertex. +-- @param height The option stack height. + +function InterfaceToDisplay.addToVertexOptions(name, height) + + -- Setup + local scope = InterfaceCore.topScope() + + -- Does vertex already exist? + local v = assert (scope.node_names[name], "node is missing, cannot add options") + + v.options = get_current_options_table(height, v.options) + + -- Add to collections + for _,c in ipairs(v.options.collections) do + LookupTable.addOne(c.vertices, v) + end + +end + + + + + +--- +-- Creates a new edge in the syntactic graph of the current graph +-- drawing scope. The display layer should call this function for each +-- edge that is created. Both the |from| vertex and the |to| vertex +-- must exist (have been created through |createVertex|) prior to your +-- being able to call this function. +-- +-- After the edge has been created, the binding layer's function +-- |everyEdgeCreation| will be called, allowing the binding layer to +-- store information about the edge. +-- +-- For each edge an event is created, whose kind is |"edge"| and whose +-- |parameter| is a two-element array whose first entry is the edge's +-- arc in the syntactic digraph and whose second entry is the position +-- of the edge in the arc's array of syntactic edges. +-- +-- @param tail Name of the node the edge begins at. +-- @param head Name of the node the edge ends at. +-- @param direction Direction of the edge (e.g. |--| for an undirected edge +-- or |->| for a directed edge from the first to the second +-- node). +-- @param height The option stack height, see for instance |createVertex|. +-- +-- @param binding_infos These options will be stored in the |storage| +-- of the vertex at the field index by the binding. + +function InterfaceToDisplay.createEdge(tail, head, direction, height, binding_infos) + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Does vertex already exist? + local h = scope.node_names[head] + local t = scope.node_names[tail] + assert (h and t, "attempting to create edge between nodes that are not in the graph") + + -- Create Arc object + local arc = scope.syntactic_digraph:connect(t, h) + + -- Create Edge object + local edge = Edge.new { + head = h, + tail = t, + direction = direction, + options = get_current_options_table(height) + } + + -- Add to arc + arc.syntactic_edges[#arc.syntactic_edges+1] = edge + + -- Create Event + local e = InterfaceToDisplay.createEvent ("edge", { arc, #arc.syntactic_edges }) + edge.event = e + + -- Make part of collections + for _,c in ipairs(edge.options.collections) do + LookupTable.addOne(c.edges, edge) + end + + -- Call binding + binding.storage[edge] = binding_infos + binding:everyEdgeCreation(edge) + +end + + + + + +--- +-- Push an option to the stack of options. +-- +-- As a graph is parsed, a stack of ``current options'' +-- is created. To add something to this table, the display layers may +-- call the method |pushOption|. To pop something from this stack, +-- just set the |height| value during the next push to the position to +-- which you actually wish to push something; everything above and +-- including this position will be popped from the stack. +-- +-- When an option is pushed, several additional options may also be +-- pushed, namely whenever the option has a |use| field set. These +-- additional options may, in turn, also push new options. Because of +-- this, this function returns a new stack height, representing the +-- resulting stack height. +-- +-- In addition to this stack height, this function returns a Boolean +-- value indicating whether a ``main algorithm phase was set.'' This +-- happens whenever a key is executed (directly or indirectly through +-- the |use| field) that selects an algorithm for the ``main'' +-- algorithm phase. This information may help the caller to setup the +-- graph drawing scopes correctly. +-- +-- @param key A parameter (must be a string). +-- @param value A value (can be anything). If it is a string, it will +-- be converted to whatever the key expects. +-- @param height A stack height at which to insert the key. Everything +-- above this height will be removed. +-- +-- @return A new stack height +-- @return A Boolean that is |true| iff the main algorithm phase was +-- set by the option or one option |use|d by it. +-- @return The newly created entry on the stack. If more entries are +-- created through the use of the |use| field, the original entry is +-- returned nevertheless. + + +function InterfaceToDisplay.pushOption(key, value, height) + assert(type(key) == "string", "illegal key") + + local key_record = assert(InterfaceCore.keys[key], "unknown key") + local main_phase_set = false + + if value == nil and key_record.default then + value = key_record.default + end + + -- Find out what kind of key we are pushing: + + if key_record.algorithm then + -- Push a phase + if type(InterfaceCore.algorithm_classes[key]) == "function" then + -- Call the constructor function + InterfaceCore.algorithm_classes[key] = InterfaceCore.algorithm_classes[key]() + end + + local algorithm = InterfaceCore.algorithm_classes[key] + + assert (algorithm, "algorithm class not found") + + push_on_option_stack(phase_unique, + { phase = value or key_record.phase, algorithm = algorithm }, + height) + + if key_record.phase == "main" then + main_phase_set = true + end + + elseif key_record.layer then + -- Push a collection + local stack = InterfaceCore.option_stack + local scope = InterfaceCore.topScope() + + -- Get the stack above "height": + local options = get_current_options_table(height-1) + + -- Create the collection event + local event = InterfaceToDisplay.createEvent ("collection", key) + + -- Create collection object: + local collection = Collection.new { kind = key, options = options, event = event } + + -- Store in collections table of current scope: + local collections = scope.collections[key] or {} + collections[#collections + 1] = collection + scope.collections[key] = collections + + -- Build collection tree + collection:registerAsChildOf(options.collections[#options.collections]) + + -- Push on stack + push_on_option_stack(collections_unique, collection, height) + + else + + -- A normal key + push_on_option_stack(key, InterfaceCore.convert(value, InterfaceCore.keys[key].type), height) + + end + + local newly_created = InterfaceCore.option_stack[#InterfaceCore.option_stack] + + -- Now, push use keys: + local use = key_record.use + if key_record.use then + local flag + for _,u in ipairs(InterfaceCore.keys[key].use) do + local use_k = u.key + local use_v = u.value + if type(use_k) == "function" then + use_k = use_k(value) + end + if type(use_v) == "function" then + use_v = use_v(value) + end + height, flag = InterfaceToDisplay.pushOption(use_k, use_v, height+1) + main_phase_set = main_phase_set or flag + end + end + + return height, main_phase_set, newly_created +end + + +--- +-- Push a layout on the stack of options. As long as this layout is on +-- the stack, all vertices and edges will be part of this layout. For +-- details on layouts, please see |Sublayouts|. +-- +-- @param height A stack height at which to insert the key. Everything +-- above this height will be removed. + +function InterfaceToDisplay.pushLayout(height) + InterfaceToDisplay.pushOption(InterfaceCore.sublayout_kind, nil, height) +end + + + +--- +-- Creates an event and adds it to the event string of the current scope. +-- +-- @param kind Name/kind of the event. +-- @param parameters Parameters of the event. +-- +-- @return The newly pushed event +-- +function InterfaceToDisplay.createEvent(kind, param) + local scope = InterfaceCore.topScope() + local n = #scope.events + 1 + local e = Event.new { kind = kind, parameters = param, index = n } + scope.events[n] = e + + return e +end + + + +--- +-- This method allows you to query the table of all declared keys. It +-- contains them both as an array and also as a table index by the +-- keys's names. In particular, you can then iterate over it using +-- |ipairs| and you can check whether a key is defined by accessing +-- the table at the key's name. Each entry of the table is the +-- original table passed to |InterfaceToAlgorithms.declare|. +-- +-- @return A lookup table of all declared keys. + +function InterfaceToDisplay.getDeclaredKeys() + return InterfaceCore.keys +end + + + + +--- +-- Renders the graph. +-- +-- This function is called after the graph has been laid out by the +-- graph drawing algorithms. It will trigger a sequence of calls to +-- the binding layer that will, via callbacks, start rendering the +-- whole graph. +-- +-- In detail, this function calls: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local binding = InterfaceCore.binding +-- +--binding:renderStart() +--render_vertices() +--render_edges() +--render_collections() +--binding:renderStop() +--\end{codeexample} +-- +-- Here, the |render_...| functions are local, internal functions that are, +-- nevertheless, documented here. +-- +-- @param name Returns the algorithm class that has been declared using +-- |declare| under the given name. + +function InterfaceToDisplay.renderGraph() + local scope = InterfaceCore.topScope() + local syntactic_digraph = scope.syntactic_digraph + + local binding = InterfaceCore.binding + + binding:renderStart() + render_vertices(syntactic_digraph.vertices) + render_edges(syntactic_digraph.arcs) + render_collections(scope.collections) + binding:renderStop() +end + + + + + +--- +-- Render the vertices after the graph drawing algorithm has +-- finished. This function is local and internal and included only for +-- documenting the call graph. +-- +-- When the graph drawing algorithm is done, the interface will start +-- rendering the vertices by calling appropriate callbacks of the +-- binding layer. +-- +-- Consider the following code: +--\begin{codeexample}[code only] +--\graph [... layout] { +-- a -- b -- c -- d; +--}; +--\end{codeexample} +-- +-- In this case, after the graph drawing algorithm has run, the +-- present function will call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local binding = InterfaceCore.binding +-- +--binding:renderVerticesStart() +--binding:renderVertex(vertex_a) +--binding:renderVertex(vertex_b) +--binding:renderVertex(vertex_c) +--binding:renderVertex(vertex_d) +--binding:renderVerticesStop() +--\end{codeexample} +-- +-- @param vertices An array of all vertices in the syntactic digraph. + +function render_vertices(vertices) + InterfaceCore.binding:renderVerticesStart() + for _,vertex in ipairs(vertices) do + InterfaceCore.binding:renderVertex(vertex) + end + InterfaceCore.binding:renderVerticesStop() +end + + +--- +-- Render the collections whose layer is not |0|. This local, internal +-- function is called to render the different collection kinds. +-- +-- Collection kinds rendered in the order provided by the |layer| +-- field passed to |declare| during the declaration of the colleciton +-- kind, see also |declare_collection|. If several collection kinds +-- have the same layer, they are rendered in lexicographical ordering +-- (to ensure that they are always rendered in the same order). +-- +-- Consider the following code: +--\begin{codeexample}[code only, tikz syntax=false] +--declare { key = "hyper", layer = 1 } +--\end{codeexample} +-- you can say on the \tikzname\ layer +--\begin{codeexample}[code only] +--\graph { +-- a, b, c, d; +-- { [hyper] a, b, c } +-- { [hyper] b, c, d } +--}; +--\end{codeexample} +-- +-- In this case, after the graph drawing algorithm has run, the +-- present function will call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local binding = InterfaceCore.binding +-- +--binding:renderCollectionStartKind("hyper", 1) +--binding:renderCollection(collection_containing_abc) +--binding:renderCollection(collection_containing_bcd) +--binding:renderCollectionStopKind("hyper", 1) +--\end{codeexample} +-- +-- @param collections The |collections| table of the current scope. + +function render_collections(collections) + local kinds = InterfaceCore.collection_kinds + local binding = InterfaceCore.binding + + for i=1,#kinds do + local kind = kinds[i].kind + local layer = kinds[i].layer + + if layer ~= 0 then + binding:renderCollectionStartKind(kind, layer) + for _,c in ipairs(collections[kind] or {}) do + binding:renderCollection(c) + end + binding:renderCollectionStopKind(kind, layer) + end + end +end + + +--- +-- Render the syntactic edges of a graph after the graph drawing +-- algorithm has finished. This function is local and internal and included only +-- for documenting the call graph. +-- +-- When the graph drawing algorithm is done, the interface will first +-- rendering the vertices using |render_vertices|, followed by calling +-- this function, which in turn calls appropriate callbacks to the +-- binding layer. +-- +-- Consider the following code: +--\begin{codeexample}[code only] +-- \graph [... layout] { +-- a -- b -- c -- d; +-- }; +--\end{codeexample} +-- +-- In this case, after the graph drawing algorithm has run, the +-- present function will call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- local binding = InterfaceCore.binding +-- +-- binding:renderEdgesStart() +-- binding:renderEdge(edge_from_a_to_b) +-- binding:renderEdge(edge_from_b_to_c) +-- binding:renderEdge(edge_from_c_to_d) +-- binding:renderEdgesStop() +--\end{codeexample} +-- +-- @param arcs The array of arcs of the syntactic digraph. + +function render_edges(arcs) + InterfaceCore.binding:renderEdgesStart() + for _,a in ipairs(arcs) do + for _,e in ipairs (a.syntactic_edges) do + InterfaceCore.binding:renderEdge(e) + end + end + InterfaceCore.binding:renderEdgesStop() +end + + +local aliases = InterfaceCore.option_aliases +local option_initial = InterfaceCore.option_initial + +local option_metatable = { + __index = + function (t, key) + local k = aliases[key] + if k then + local v = (type(k) == "string" and t[k]) or (type(k) == "function" and k(t)) or nil + if v ~= nil then + return v + end + end + return option_initial[key] + end +} + + +--- +-- Get the current options table. +-- +-- An option table can be accessed like a normal table; however, there +-- is a global fallback for this table. If an index is not defined, +-- the value of this index in the global fallback table is used. (This +-- reduces the overall amount of option keys that need to be stored +-- with object.) +-- +-- (This function is local and internal and included only for documentation +-- purposes.) +-- +-- @param height The stack height for which the option table is +-- required. +-- @param table If non |nil|, the options will be added to this +-- table. +-- +-- @return The option table as described above. + +function get_current_options_table (height, table) + local stack = InterfaceCore.option_stack + assert (height >= 0 and height <= #stack, "height value out of bounds") + + if height == InterfaceCore.option_cache_height and not table then + return option_cache + else + -- Clear superfluous part of stack + for i=#stack,height+1,-1 do + stack[i] = nil + end + + -- Build options table + local cache + if not table then + cache = setmetatable( + { + algorithm_phases = setmetatable({}, InterfaceCore.option_initial.algorithm_phases), + collections = {} + }, option_metatable) + else + cache = lib.copy(table) + cache.algorithm_phases = lib.copy(cache.algorithm_phases) + cache.collections = lib.copy(cache.collections) + end + + local algorithm_phases = cache.algorithm_phases + local collections = cache.collections + local keys = InterfaceCore.keys + + local function handle (k, v) + if k == phase_unique then + algorithm_phases[v.phase] = v.algorithm + local phase_stack = v.phase .. " stack" + local t = rawget(algorithm_phases, phase_stack) + if not t then + t = algorithm_phases[phase_stack] + assert(type(t) == "table", "unknown phase") + t = lib.copy(t) + algorithm_phases[phase_stack] = t + end + t[#t + 1] = v.algorithm + elseif k == collections_unique then + LookupTable.addOne(collections, v) + else + cache[k] = v + end + end + + for _,s in ipairs(stack) do + handle (s.key, s.value) + end + + -- Cache it, if this was not added: + if not table then + InterfaceCore.option_cache_height = height + option_cache = cache + end + + return cache + end +end + + + +-- A helper function + +function push_on_option_stack(key, value, height) + local stack = InterfaceCore.option_stack + + assert (type(height) == "number" and height > 0 and height <= #stack + 1, + "height value out of bounds") + + -- Clear superfluous part of stack + for i=#stack,height+1,-1 do + stack[i] = nil + end + + stack[height] = { key = key, value = value } + InterfaceCore.option_cache_height = nil -- invalidate cache +end + + + +-- Done + +return InterfaceToDisplay diff --git a/Master/texmf-dist/tex/latex/tikz-feynman/tikzfeynman.patch.lua b/Master/texmf-dist/tex/latex/tikz-feynman/tikzfeynman.patch.lua deleted file mode 100644 index 8201af6d5b8..00000000000 --- a/Master/texmf-dist/tex/latex/tikz-feynman/tikzfeynman.patch.lua +++ /dev/null @@ -1,1015 +0,0 @@ --- This patched version of the createVertex function simply ensures that the --- path is never empty. This works fine for TikZ version 3.0.0, 3.0.1 and --- 3.0.1a as far as I know. --- --- Later versions (should) have a more thorough patch by Till which is --- incompatible with this override unfortunately. --- --- ############################################################################# --- --- Copyright 2012 by Till Tantau --- --- This file may be distributed an/or modified --- --- 1. under the LaTeX Project Public License and/or --- 2. under the GNU Public License --- --- See the file doc/generic/pgf/licenses/LICENSE for more information - --- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua,v 1.14 2014/03/19 09:20:59 tantau Exp $ - - - ---- --- This class provides the interface between a display --- layer (like \tikzname\ or a graph editor) and graph drawing --- system. Another class, |InterfaceToAlgorithms|, binds the algorithm --- layer (which are written in Lua) to the graph drawing system. --- --- The functions declared here are independent of the actual display --- layer. Rather, the differences between the layers are encapsulated --- by subclasses of the |Binding| class, see that class for --- details. Thus, when a new display layer is written, the present --- class is \emph{used}, but not \emph{modified}. Instead, only a new --- binding is created and all display layer specific interaction is --- put there. --- --- The job of this class is to provide convenient methods that can be --- called by the display layer. For instance, it provides methods for --- starting a graph drawing scope, managing the stack of such scope, --- adding a node to a graph and so on. - -local InterfaceToDisplay = {} - --- Namespace -require("pgf.gd.interface").InterfaceToDisplay = InterfaceToDisplay - - --- Imports -local InterfaceCore = require "pgf.gd.interface.InterfaceCore" -local Scope = require "pgf.gd.interface.Scope" - -local Binding = require "pgf.gd.bindings.Binding" - -local Sublayouts = require "pgf.gd.control.Sublayouts" -local LayoutPipeline = require "pgf.gd.control.LayoutPipeline" - -local Digraph = require "pgf.gd.model.Digraph" -local Vertex = require "pgf.gd.model.Vertex" -local Edge = require "pgf.gd.model.Edge" -local Collection = require "pgf.gd.model.Collection" - -local Storage = require "pgf.gd.lib.Storage" -local LookupTable = require "pgf.gd.lib.LookupTable" -local Event = require "pgf.gd.lib.Event" - -local lib = require "pgf.gd.lib" - - --- Forward declarations -local get_current_options_table -local render_collections -local push_on_option_stack -local vertex_created - --- Local objects - -local phase_unique = {} -- a unique handle -local collections_unique = {} -- a unique handle -local option_cache = nil -- The option cache - - - - ---- --- Initiliaze the binding. This function is called once by the display --- layer at the very beginning. For instance, \tikzname\ does the --- following call: --- ---\begin{codeexample}[code only, tikz syntax=false] ---InterfaceToDisplay.bind(require "pgf.gd.bindings.BindingToPGF") ---\end{codeexample} --- --- Inside this call, many standard declarations will be executed, that --- is, the declared binding will be used immediately. --- --- Subsequently, the |binding| field of the |InterfaceCore| can be used. --- --- @param class A subclass of |Binding|. - -function InterfaceToDisplay.bind(class) - assert (not InterfaceCore.binding, "binding already initialized") - - -- Create a new object - InterfaceCore.binding = setmetatable({}, class) - - -- Load these libraries, which contain many standard declarations: - require "pgf.gd.model.library" - require "pgf.gd.control.library" -end - - - - ---- --- Start a graph drawing scope. Note that this is not the same as --- starting a subgraph / sublayout, which are local to a graph drawing --- scope: When a new graph drawing scope is started, it is pushed on --- top of a stack of graph drawing scopes and all other ``open'' --- scopes are no longer directly accessible. All method calls to an --- |Interface...| object will refer to this newly created scope until --- either a new scope is opened or until the current scope is closed --- once more. --- --- Each graph drawing scope comes with a syntactic digraph that is --- build using methods like |addVertex| or |addEdge|. --- --- @param height The to-be-used height of the options stack. All --- options above this height will be popped prior to attacking the --- options to the syntactic digraph. - -function InterfaceToDisplay.beginGraphDrawingScope(height) - - -- Create a new scope table - local scope = Scope.new {} - - -- Setup syntactic digraph: - local g = scope.syntactic_digraph - - g.options = get_current_options_table(height) - g.syntactic_digraph = g - g.scope = scope - - -- Push scope: - InterfaceCore.scopes[#InterfaceCore.scopes + 1] = scope -end - - - ---- --- Arranges the current graph using the specified algorithm and options. --- --- This function should be called after the graph drawing scope has --- been opened and the syntactic digraph has been completely --- specified. It will now start running the algorithm specified --- through the |algorithm_phase| options. --- --- Internally, this function creates a coroutine that will run the current graph --- drawing algorithm. Coroutines are needed since a graph drawing --- algorithm may choose to create a new node. In this case, the --- algorithm needs to be suspended and control must be returned back --- to the display layer, so that the node can be typeset in order to --- determine the precise size information. Once this is done, control --- must be passed back to the exact point inside the algorithm where --- the node was created. Clearly, all of these actions are exactly --- what coroutines are for. --- --- @return Time it took to run the algorithm - -function InterfaceToDisplay.runGraphDrawingAlgorithm() - - -- Time things - local start = os.clock() - - -- Setup - local scope = InterfaceCore.topScope() - assert(not scope.coroutine, "coroutine already created for current gd scope") - - -- The actual drawing function - local function run () - if #scope.syntactic_digraph.vertices == 0 then - -- Nothing needs to be done - return - end - - LayoutPipeline.run(scope) - end - - scope.coroutine = coroutine.create(run) - - -- Run it: - InterfaceToDisplay.resumeGraphDrawingCoroutine() - - -- End timing: - local stop = os.clock() - - return stop - start -end - - ---- --- Resume the graph drawing coroutine. --- --- This function is the work horse of the coroutine management. It --- gets called whenever control passes back from the display layer to --- the algorithm level. We resume the graph drawing coroutine so that the --- algorithm can start/proceed. The tricky part is when the algorithm --- yields, but is not done. In this case, the code needed for creating --- a new node is passed back to the display layer through the binding, --- which must then execute the code and then resuming the coroutine. --- -function InterfaceToDisplay.resumeGraphDrawingCoroutine() - - -- Setup - local scope = InterfaceCore.topScope() - local binding = InterfaceCore.binding - - -- Asserts - assert(scope.coroutine, "coroutine not created for current gd scope") - - -- Run - local ok, text = coroutine.resume(scope.coroutine) - assert(ok, text) - if coroutine.status(scope.coroutine) ~= "dead" then - -- Ok, ask binding to continue - binding:resumeGraphDrawingCoroutine(text) - end -end - - - ---- Ends the current graph drawing scope. --- -function InterfaceToDisplay.endGraphDrawingScope() - assert(#InterfaceCore.scopes > 0, "no gd scope open") - InterfaceCore.scopes[#InterfaceCore.scopes] = nil -- pop -end - - - - ---- --- Creates a new vertex in the syntactic graph of the current graph --- drawing scope. The display layer should call this function for each --- node of the graph. The |name| must be a unique string identifying --- the node. The newly created vertex will be added to the syntactic --- digraph. The binding function |everyVertexCreation| will then be --- called, allowing the binding to store information regarding the newly --- created vertex. --- --- For each vertex an event will be created in the event --- sequence. This event will have the kind |"node"| and its --- |parameter| will be the vertex. --- --- @param name Name of the vertex. --- --- @param shape The shape of the vertex such as |"circle"| or --- |"rectangle"|. This shape may help a graph drawing algorithm --- figuring out how the node should be placed. --- --- @param path A |Path| object representing the vertex's path. --- --- @param height The to-be-used height of the options stack. All --- options above this height will be popped prior to attacking the --- options to the syntactic digraph. --- --- @param binding_infos These options are passed to and are specific --- to the current |Binding|. --- --- @param anchors A table of anchors (mapping anchor positions to --- |Coordinates|). - - -function InterfaceToDisplay.createVertex(name, shape, path, height, binding_infos, anchors) - - -- The path should never be empty, so we create a trivial path in the provided - -- path is empty. This occurs with the ‘coordinate‘ shape for example. - if #path == 0 then - path:appendMoveto(0, 0) - path:appendClosepath() - end - - -- Setup - local scope = InterfaceCore.topScope() - local binding = InterfaceCore.binding - - -- Does vertex already exist? - local v = scope.node_names[name] - assert (not v or not v.created_on_display_layer, "node already created") - - -- Create vertex - if not v then - v = Vertex.new { - name = name, - shape = shape, - kind = "node", - path = path, - options = get_current_options_table(height), - anchors = anchors, - } - - vertex_created(v,scope) - else - assert(v.kind == "subgraph node", "subgraph node expected") - v.shape = shape - v.path = path - v.anchors = anchors - end - - v.created_on_display_layer = true - - -- Call binding - binding.storage[v] = binding_infos - binding:everyVertexCreation(v) -end - - --- This is a helper function -function vertex_created(v,scope) - - -- Create Event - local e = InterfaceToDisplay.createEvent ("node", v) - v.event = e - - -- Create name lookup - scope.node_names[v.name] = v - - -- Add vertex to graph - scope.syntactic_digraph:add {v} - - -- Add to collections - for _,c in ipairs(v.options.collections) do - LookupTable.addOne(c.vertices, v) - end - -end - - - ---- --- Creates a new vertex in the syntactic graph of the current graph --- drawing scope that is a subgraph vertex. Such a vertex --- ``surrounds'' the vertices of a subgraph. The special property of a --- subgraph node opposed to a normal node is that it is created only --- after the subgraph has been laid out. However, the difference to a --- collection like |hyper| is that the node is availble immediately as --- a normal node in the sense that you can connect edges to it. --- --- What happens internally is that subgraph nodes get ``registered'' --- immediately both on the display level and on the algorithm level, --- but the actual node is only created inside the layout pipeline --- using a callback of the binding. The present function is used to --- perform this registering. The node creation happens when the --- innermost layout in which the subgraph node is declared has --- finished. For each subgraph node, a collection is created that --- contains all vertices (and edges) being part of the subgraph. For --- this reason, this method is a |push...| method, since it pushes --- something on the options stack. --- --- The |init| parameter will be used during the creation of the node, --- see |Binding:createVertex| for details on the fields. Note that --- |init.text| is often not displayed for such ``vast'' nodes as those --- created for whole subgraphs, but a shape may use it nevertheless --- (for instance, one might display this text at the top of the node --- or, in case of a \textsc{uml} package, in a special box above the --- actual node). --- --- The |init.generated_options| will be augmented by additional --- key--value pairs when the vertex is created: --- --- \begin{itemize} --- \item The key |subgraph point cloud| will have as its value a --- string that is be a list of points (without --- separating commas) like |"(10pt,20pt)(0pt,0pt)(30pt,40pt)"|, always in --- this syntax. The list will contain all points inside the --- subgraph. In particular, a bounding box around these points will --- encompass all nodes and bend points of the subgraph. --- The bounding box of this point cloud is guaranteed to be centered on --- the origin. --- \item The key |subgraph bounding box width| will have as its value --- the width of a bounding box (in \TeX\ points, as a string with the --- suffix |"pt"|). --- \item The key |subgraph bounding box height| stores the height of a --- bounding box. --- \end{itemize} --- --- @param name The name of the node. --- @param height Height of the options stack. Note that this method --- pushes something (namely a collection) on the options stack. --- @param info A table passed to |Binding:createVertex|, see that function. --- -function InterfaceToDisplay.pushSubgraphVertex(name, height, info) - - -- Setup - local scope = InterfaceCore.topScope() - local binding = InterfaceCore.binding - - -- Does vertex already exist? - assert (not scope.node_names[name], "node already created") - - -- Create vertex - local v = Vertex.new { - name = name, - kind = "subgraph node", - options = get_current_options_table(height-1) - } - - vertex_created(v,scope) - - -- Store info - info.generated_options = info.generated_options or {} - info.name = name - v.subgraph_info = info - - -- Create collection and link it to v - local _, _, entry = InterfaceToDisplay.pushOption(InterfaceCore.subgraph_node_kind, nil, height) - v.subgraph_collection = entry.value - v.subgraph_collection.subgraph_node = v - - -- Find parent collection in options stack: - local collections = v.options.collections - for i=#collections,1,-1 do - if collections[i].kind == InterfaceCore.sublayout_kind then - v.subgraph_collection.parent_layout = collections[i] - break - end - end -end - - - ---- --- Add options for an already existing vertex. --- --- This function allows you to add options to an already existing --- vertex. The options that will be added are all options on the --- current options stack; they will overwrite existing options of the --- same name. For collections, the vertex stays in all collections it --- used to, it is only added to all collections that are currently on --- the options stack. --- --- @param name Name of the vertex. --- @param height The option stack height. - -function InterfaceToDisplay.addToVertexOptions(name, height) - - -- Setup - local scope = InterfaceCore.topScope() - - -- Does vertex already exist? - local v = assert (scope.node_names[name], "node is missing, cannot add options") - - v.options = get_current_options_table(height, v.options) - - -- Add to collections - for _,c in ipairs(v.options.collections) do - LookupTable.addOne(c.vertices, v) - end - -end - - - - - ---- --- Creates a new edge in the syntactic graph of the current graph --- drawing scope. The display layer should call this function for each --- edge that is created. Both the |from| vertex and the |to| vertex --- must exist (have been created through |createVertex|) prior to your --- being able to call this function. --- --- After the edge has been created, the binding layer's function --- |everyEdgeCreation| will be called, allowing the binding layer to --- store information about the edge. --- --- For each edge an event is created, whose kind is |"edge"| and whose --- |parameter| is a two-element array whose first entry is the edge's --- arc in the syntactic digraph and whose second entry is the position --- of the edge in the arc's array of syntactic edges. --- --- @param tail Name of the node the edge begins at. --- @param head Name of the node the edge ends at. --- @param direction Direction of the edge (e.g. |--| for an undirected edge --- or |->| for a directed edge from the first to the second --- node). --- @param height The option stack height, see for instance |createVertex|. --- --- @param binding_infos These options will be stored in the |storage| --- of the vertex at the field index by the binding. - -function InterfaceToDisplay.createEdge(tail, head, direction, height, binding_infos) - - -- Setup - local scope = InterfaceCore.topScope() - local binding = InterfaceCore.binding - - -- Does vertex already exist? - local h = scope.node_names[head] - local t = scope.node_names[tail] - assert (h and t, "attempting to create edge between nodes that are not in the graph") - - -- Create Arc object - local arc = scope.syntactic_digraph:connect(t, h) - - -- Create Edge object - local edge = Edge.new { - head = h, - tail = t, - direction = direction, - options = get_current_options_table(height) - } - - -- Add to arc - arc.syntactic_edges[#arc.syntactic_edges+1] = edge - - -- Create Event - local e = InterfaceToDisplay.createEvent ("edge", { arc, #arc.syntactic_edges }) - edge.event = e - - -- Make part of collections - for _,c in ipairs(edge.options.collections) do - LookupTable.addOne(c.edges, edge) - end - - -- Call binding - binding.storage[edge] = binding_infos - binding:everyEdgeCreation(edge) - -end - - - - - ---- --- Push an option to the stack of options. --- --- As a graph is parsed, a stack of ``current options'' --- is created. To add something to this table, the display layers may --- call the method |pushOption|. To pop something from this stack, --- just set the |height| value during the next push to the position to --- which you actually wish to push something; everything above and --- including this position will be popped from the stack. --- --- When an option is pushed, several additional options may also be --- pushed, namely whenever the option has a |use| field set. These --- additional options may, in turn, also push new options. Because of --- this, this function returns a new stack height, representing the --- resulting stack height. --- --- In addition to this stack height, this function returns a Boolean --- value indicating whether a ``main algorithm phase was set.'' This --- happens whenever a key is executed (directly or indirectly through --- the |use| field) that selects an algorithm for the ``main'' --- algorithm phase. This information may help the caller to setup the --- graph drawing scopes correctly. --- --- @param key A parameter (must be a string). --- @param value A value (can be anything). If it is a string, it will --- be converted to whatever the key expects. --- @param height A stack height at which to insert the key. Everything --- above this height will be removed. --- --- @return A new stack height --- @return A Boolean that is |true| iff the main algorithm phase was --- set by the option or one option |use|d by it. --- @return The newly created entry on the stack. If more entries are --- created through the use of the |use| field, the original entry is --- returned nevertheless. - - -function InterfaceToDisplay.pushOption(key, value, height) - assert(type(key) == "string", "illegal key") - - local key_record = assert(InterfaceCore.keys[key], "unknown key") - local main_phase_set = false - - if value == nil and key_record.default then - value = key_record.default - end - - -- Find out what kind of key we are pushing: - - if key_record.algorithm then - -- Push a phase - if type(InterfaceCore.algorithm_classes[key]) == "function" then - -- Call the constructor function - InterfaceCore.algorithm_classes[key] = InterfaceCore.algorithm_classes[key]() - end - - local algorithm = InterfaceCore.algorithm_classes[key] - - assert (algorithm, "algorithm class not found") - - push_on_option_stack(phase_unique, - { phase = value or key_record.phase, algorithm = algorithm }, - height) - - if key_record.phase == "main" then - main_phase_set = true - end - - elseif key_record.layer then - -- Push a collection - local stack = InterfaceCore.option_stack - local scope = InterfaceCore.topScope() - - -- Get the stack above "height": - local options = get_current_options_table(height-1) - - -- Create the collection event - local event = InterfaceToDisplay.createEvent ("collection", key) - - -- Create collection object: - local collection = Collection.new { kind = key, options = options, event = event } - - -- Store in collections table of current scope: - local collections = scope.collections[key] or {} - collections[#collections + 1] = collection - scope.collections[key] = collections - - -- Build collection tree - collection:registerAsChildOf(options.collections[#options.collections]) - - -- Push on stack - push_on_option_stack(collections_unique, collection, height) - - else - - -- A normal key - push_on_option_stack(key, InterfaceCore.convert(value, InterfaceCore.keys[key].type), height) - - end - - local newly_created = InterfaceCore.option_stack[#InterfaceCore.option_stack] - - -- Now, push use keys: - local use = key_record.use - if key_record.use then - local flag - for _,u in ipairs(InterfaceCore.keys[key].use) do - local use_k = u.key - local use_v = u.value - if type(use_k) == "function" then - use_k = use_k(value) - end - if type(use_v) == "function" then - use_v = use_v(value) - end - height, flag = InterfaceToDisplay.pushOption(use_k, use_v, height+1) - main_phase_set = main_phase_set or flag - end - end - - return height, main_phase_set, newly_created -end - - ---- --- Push a layout on the stack of options. As long as this layout is on --- the stack, all vertices and edges will be part of this layout. For --- details on layouts, please see |Sublayouts|. --- --- @param height A stack height at which to insert the key. Everything --- above this height will be removed. - -function InterfaceToDisplay.pushLayout(height) - InterfaceToDisplay.pushOption(InterfaceCore.sublayout_kind, nil, height) -end - - - ---- --- Creates an event and adds it to the event string of the current scope. --- --- @param kind Name/kind of the event. --- @param parameters Parameters of the event. --- --- @return The newly pushed event --- -function InterfaceToDisplay.createEvent(kind, param) - local scope = InterfaceCore.topScope() - local n = #scope.events + 1 - local e = Event.new { kind = kind, parameters = param, index = n } - scope.events[n] = e - - return e -end - - - ---- --- This method allows you to query the table of all declared keys. It --- contains them both as an array and also as a table index by the --- keys's names. In particular, you can then iterate over it using --- |ipairs| and you can check whether a key is defined by accessing --- the table at the key's name. Each entry of the table is the --- original table passed to |InterfaceToAlgorithms.declare|. --- --- @return A lookup table of all declared keys. - -function InterfaceToDisplay.getDeclaredKeys() - return InterfaceCore.keys -end - - - - ---- --- Renders the graph. --- --- This function is called after the graph has been laid out by the --- graph drawing algorithms. It will trigger a sequence of calls to --- the binding layer that will, via callbacks, start rendering the --- whole graph. --- --- In detail, this function calls: --- ---\begin{codeexample}[code only, tikz syntax=false] ---local binding = InterfaceCore.binding --- ---binding:renderStart() ---render_vertices() ---render_edges() ---render_collections() ---binding:renderStop() ---\end{codeexample} --- --- Here, the |render_...| functions are local, internal functions that are, --- nevertheless, documented here. --- --- @param name Returns the algorithm class that has been declared using --- |declare| under the given name. - -function InterfaceToDisplay.renderGraph() - local scope = InterfaceCore.topScope() - local syntactic_digraph = scope.syntactic_digraph - - local binding = InterfaceCore.binding - - binding:renderStart() - render_vertices(syntactic_digraph.vertices) - render_edges(syntactic_digraph.arcs) - render_collections(scope.collections) - binding:renderStop() -end - - - - - ---- --- Render the vertices after the graph drawing algorithm has --- finished. This function is local and internal and included only for --- documenting the call graph. --- --- When the graph drawing algorithm is done, the interface will start --- rendering the vertices by calling appropriate callbacks of the --- binding layer. --- --- Consider the following code: ---\begin{codeexample}[code only] ---\graph [... layout] { --- a -- b -- c -- d; ---}; ---\end{codeexample} --- --- In this case, after the graph drawing algorithm has run, the --- present function will call: --- ---\begin{codeexample}[code only, tikz syntax=false] ---local binding = InterfaceCore.binding --- ---binding:renderVerticesStart() ---binding:renderVertex(vertex_a) ---binding:renderVertex(vertex_b) ---binding:renderVertex(vertex_c) ---binding:renderVertex(vertex_d) ---binding:renderVerticesStop() ---\end{codeexample} --- --- @param vertices An array of all vertices in the syntactic digraph. - -function render_vertices(vertices) - InterfaceCore.binding:renderVerticesStart() - for _,vertex in ipairs(vertices) do - InterfaceCore.binding:renderVertex(vertex) - end - InterfaceCore.binding:renderVerticesStop() -end - - ---- --- Render the collections whose layer is not |0|. This local, internal --- function is called to render the different collection kinds. --- --- Collection kinds rendered in the order provided by the |layer| --- field passed to |declare| during the declaration of the colleciton --- kind, see also |declare_collection|. If several collection kinds --- have the same layer, they are rendered in lexicographical ordering --- (to ensure that they are always rendered in the same order). --- --- Consider the following code: ---\begin{codeexample}[code only, tikz syntax=false] ---declare { key = "hyper", layer = 1 } ---\end{codeexample} --- you can say on the \tikzname\ layer ---\begin{codeexample}[code only] ---\graph { --- a, b, c, d; --- { [hyper] a, b, c } --- { [hyper] b, c, d } ---}; ---\end{codeexample} --- --- In this case, after the graph drawing algorithm has run, the --- present function will call: --- ---\begin{codeexample}[code only, tikz syntax=false] ---local binding = InterfaceCore.binding --- ---binding:renderCollectionStartKind("hyper", 1) ---binding:renderCollection(collection_containing_abc) ---binding:renderCollection(collection_containing_bcd) ---binding:renderCollectionStopKind("hyper", 1) ---\end{codeexample} --- --- @param collections The |collections| table of the current scope. - -function render_collections(collections) - local kinds = InterfaceCore.collection_kinds - local binding = InterfaceCore.binding - - for i=1,#kinds do - local kind = kinds[i].kind - local layer = kinds[i].layer - - if layer ~= 0 then - binding:renderCollectionStartKind(kind, layer) - for _,c in ipairs(collections[kind] or {}) do - binding:renderCollection(c) - end - binding:renderCollectionStopKind(kind, layer) - end - end -end - - ---- --- Render the syntactic edges of a graph after the graph drawing --- algorithm has finished. This function is local and internal and included only --- for documenting the call graph. --- --- When the graph drawing algorithm is done, the interface will first --- rendering the vertices using |render_vertices|, followed by calling --- this function, which in turn calls appropriate callbacks to the --- binding layer. --- --- Consider the following code: ---\begin{codeexample}[code only] --- \graph [... layout] { --- a -- b -- c -- d; --- }; ---\end{codeexample} --- --- In this case, after the graph drawing algorithm has run, the --- present function will call: --- ---\begin{codeexample}[code only, tikz syntax=false] --- local binding = InterfaceCore.binding --- --- binding:renderEdgesStart() --- binding:renderEdge(edge_from_a_to_b) --- binding:renderEdge(edge_from_b_to_c) --- binding:renderEdge(edge_from_c_to_d) --- binding:renderEdgesStop() ---\end{codeexample} --- --- @param arcs The array of arcs of the syntactic digraph. - -function render_edges(arcs) - InterfaceCore.binding:renderEdgesStart() - for _,a in ipairs(arcs) do - for _,e in ipairs (a.syntactic_edges) do - InterfaceCore.binding:renderEdge(e) - end - end - InterfaceCore.binding:renderEdgesStop() -end - - -local aliases = InterfaceCore.option_aliases -local option_initial = InterfaceCore.option_initial - -local option_metatable = { - __index = - function (t, key) - local k = aliases[key] - if k then - local v = (type(k) == "string" and t[k]) or (type(k) == "function" and k(t)) or nil - if v ~= nil then - return v - end - end - return option_initial[key] - end -} - - ---- --- Get the current options table. --- --- An option table can be accessed like a normal table; however, there --- is a global fallback for this table. If an index is not defined, --- the value of this index in the global fallback table is used. (This --- reduces the overall amount of option keys that need to be stored --- with object.) --- --- (This function is local and internal and included only for documentation --- purposes.) --- --- @param height The stack height for which the option table is --- required. --- @param table If non |nil|, the options will be added to this --- table. --- --- @return The option table as described above. - -function get_current_options_table (height, table) - local stack = InterfaceCore.option_stack - assert (height >= 0 and height <= #stack, "height value out of bounds") - - if height == InterfaceCore.option_cache_height and not table then - return option_cache - else - -- Clear superfluous part of stack - for i=#stack,height+1,-1 do - stack[i] = nil - end - - -- Build options table - local cache - if not table then - cache = setmetatable( - { - algorithm_phases = setmetatable({}, InterfaceCore.option_initial.algorithm_phases), - collections = {} - }, option_metatable) - else - cache = lib.copy(table) - cache.algorithm_phases = lib.copy(cache.algorithm_phases) - cache.collections = lib.copy(cache.collections) - end - - local algorithm_phases = cache.algorithm_phases - local collections = cache.collections - local keys = InterfaceCore.keys - - local function handle (k, v) - if k == phase_unique then - algorithm_phases[v.phase] = v.algorithm - local phase_stack = v.phase .. " stack" - local t = rawget(algorithm_phases, phase_stack) - if not t then - t = algorithm_phases[phase_stack] - assert(type(t) == "table", "unknown phase") - t = lib.copy(t) - algorithm_phases[phase_stack] = t - end - t[#t + 1] = v.algorithm - elseif k == collections_unique then - LookupTable.addOne(collections, v) - else - cache[k] = v - end - end - - for _,s in ipairs(stack) do - handle (s.key, s.value) - end - - -- Cache it, if this was not added: - if not table then - InterfaceCore.option_cache_height = height - option_cache = cache - end - - return cache - end -end - - - --- A helper function - -function push_on_option_stack(key, value, height) - local stack = InterfaceCore.option_stack - - assert (type(height) == "number" and height > 0 and height <= #stack + 1, - "height value out of bounds") - - -- Clear superfluous part of stack - for i=#stack,height+1,-1 do - stack[i] = nil - end - - stack[height] = { key = key, value = value } - InterfaceCore.option_cache_height = nil -- invalidate cache -end - - - --- Done - -return InterfaceToDisplay diff --git a/Master/texmf-dist/tex/latex/tikz-feynman/tikzlibraryfeynman.code.tex b/Master/texmf-dist/tex/latex/tikz-feynman/tikzlibraryfeynman.code.tex index 380f7125096..76ca76e5ea4 100644 --- a/Master/texmf-dist/tex/latex/tikz-feynman/tikzlibraryfeynman.code.tex +++ b/Master/texmf-dist/tex/latex/tikz-feynman/tikzlibraryfeynman.code.tex @@ -58,7 +58,10 @@ %% Key Manager %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Setup the tikz-feynman key family -\pgfkeys{/tikzfeynman/.is family} +\pgfkeys{ + /tikzfeynman/.is family, + /tikzfeynman/.search also={/tikz}, +} %% |\tikzfeynmanset| allows keys that belong with tikz-feynman to be easily set. \def\tikzfeynmanset{\pgfqkeys{/tikzfeynman}} @@ -91,11 +94,12 @@ } \let\tikzfeynman@compat=\tikzfeynman@empty \pgfkeyslet{/tikzfeynman/compat/.@cmd}{\tikzfeynman@compat@parse} +\ProcessPgfPackageOptions{/tikzfeynman} \AtBeginDocument{ \ifx\tikzfeynman@version\tikzfeynman@compat\else \ifx\tikzfeynman@compat\tikzfeynman@empty - \PackageWarning{tikz-feynman}{Consider adding \string\tikzfeynmanset{compat=\tikzfeynman@version} to your preamble so that you can be warned if TikZ-Feynman changes.} + \PackageWarning{tikz-feynman}{Consider loading TikZ-Feynman with \string\usepackage[compat=\tikzfeynman@version]{tikz-feynman} so that you can be warned if TikZ-Feynman changes.} \else \ifx\tikzfeynman@compat@major\tikzfeynman@version@major \ifx\tikzfeynman@compat@minor\tikzfeynman@version@minor @@ -106,7 +110,7 @@ \PackageWarning{tikz-feynman}{The preamble requested version \tikzfeynman@compat, but the system version is \tikzfeynman@version. This may change some diagrams.} \fi \else - \PackageError{tikz-feynman}{The preamble requested version \tikzfeynman@compat, but the system version is \tikzfeynman@version. They are most likely incompatible. Please download the appropriate version at github.com/JP-Ellis/tikz-feynman.} + \PackageError{tikz-feynman}{The preamble requested version \tikzfeynman@compat, but the system version is \tikzfeynman@version. They are most likely incompatible. Please download the appropriate version from jpellis.me/projects/tikz-feynman.} \fi \fi \fi @@ -114,23 +118,23 @@ %% Override Lua code if necessary %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\def\tikzfeynman@apply@patch{ - \directlua{require("tikzfeynman.patch.lua")} +\def\tikzfeynman@apply@patch#1{ + \directlua{require("tikzfeynman.patch.#1.lua")} } %% Version 3.0.0, 3.0.1 and 3.0.1a need to be patched. \ifluatex \def\tikzfeynman@temp{3.0.0} \ifx\pgfversion\tikzfeynman@temp - \tikzfeynman@apply@patch + \tikzfeynman@apply@patch{3.0.0} \else \def\tikzfeynman@temp{3.0.1} \ifx\pgfversion\tikzfeynman@temp - \tikzfeynman@apply@patch + \tikzfeynman@apply@patch{3.0.1} \else \def\tikzfeynman@temp{3.0.1a} \ifx\pgfversion\tikzfeynman@temp - \tikzfeynman@apply@patch + \tikzfeynman@apply@patch{3.0.1} \fi \fi \fi @@ -161,10 +165,7 @@ \scope \tikz@lib@ignore@sizetrue \tikzfeynman@tikz@search@tikzfeynman - \pgfkeys{ - /tikzfeynman/every feynman@@, - /tikzfeynman/every feynman, - #1} + \pgfkeys{/tikzfeynman/every feynman@@,#1} \pgfkeysvalueof{/tikzfeynman/execute at begin feynman@@}% \pgfkeysvalueof{/tikzfeynman/execute at begin feynman}% } @@ -185,8 +186,8 @@ \pgfutil@ifnextchar[{\feynmandiagram@opt@opt[#1]} {\feynmandiagram@opt@opt[#1][#1]}} \def\feynmandiagram@opt@opt[#1][#2]{% - \tikz [/tikzfeynman/.cd, .search also={/tikz}, #1] - \graph [/tikzfeynman/every diagram@@, /tikzfeynman/every diagram, /tikz/graphs/spring layout, #2]} + \tikz [/tikzfeynman/.cd,#1] + \graph [/tikzfeynman/.cd,/tikzfeynman/every diagram@@,/tikz/graphs/spring layout,#2]} %% Allow empty nodes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -198,9 +199,7 @@ {\pgfutil@ifnextchar[{\tikz@fig@scan@options}% {\pgfutil@ifnextchar\bgroup{\tikz@fig@main}% {\iftikzfeynmanvertex% - \tikzset{ - /tikzfeynman/every vertex@@, - /tikzfeynman/every vertex}% + \tikzset{/tikzfeynman/every vertex@@}% \iftikzfeynmanallowemptynode% \else% \tikzset{/tikzfeynman/particle}% @@ -274,13 +273,13 @@ \pgfutil@ifnextchar[{\tikzfeynman@commands@diagram@nostar@opt} {\tikzfeynman@commands@diagram@nostar@opt[]}} \def\tikzfeynman@commands@diagram@nostar@opt[#1]{% - \tikzfeynman@orig@graph [/tikzfeynman/every diagram@@, /tikzfeynman/every diagram, /tikz/graphs/spring layout, #1]} + \tikzfeynman@orig@graph [/tikzfeynman/every diagram@@,/tikz/graphs/spring layout,#1]} \def\tikzfeynman@commands@diagram@star{% \pgfutil@ifnextchar[{\tikzfeynman@commands@diagram@star@opt} {\tikzfeynman@commands@diagram@star@opt[]}} \def\tikzfeynman@commands@diagram@star@opt[#1]{% - \tikzfeynman@orig@graph [/tikzfeynman/every diagram@@, /tikzfeynman/every diagram, #1]} + \tikzfeynman@orig@graph [/tikzfeynman/every diagram@@,#1]} %% Graph %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -289,7 +288,7 @@ {\tikzfeynman@commands@graph@opt[]}} \def\tikzfeynman@commands@graph@opt[#1]{% \PackageWarning{tikz-feynman}{It is not recommended to use \string\graph. Use \string\diagram\space or \string\diagram* instead.} - \tikzfeynman@orig@graph [/tikzfeynman/every diagram@@, /tikzfeynman/every diagram, #1]} + \tikzfeynman@orig@graph [/tikzfeynman/every diagram@@,#1]} %% Optional argument in style key %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -- cgit v1.2.3