diff options
author | Karl Berry <karl@freefriends.org> | 2014-02-27 00:01:50 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2014-02-27 00:01:50 +0000 |
commit | 90ae413a94da014dbf7a6a8ab584f7c668483a5a (patch) | |
tree | 4e0528a2b2fb2004988e7fc804ea2f1354f1f5d5 | |
parent | 800cc56380d1edfe567a6a66bef13e8950eb2b0c (diff) |
pgf 3.0.0
git-svn-id: svn://tug.org/texlive/trunk@33057 c570f23f-e606-0410-a88d-b1316a301751
540 files changed, 91039 insertions, 20530 deletions
diff --git a/Master/texmf-dist/doc/generic/pgf/ChangeLog b/Master/texmf-dist/doc/generic/pgf/ChangeLog index 6b0704d18ca..d4dc120c045 100644 --- a/Master/texmf-dist/doc/generic/pgf/ChangeLog +++ b/Master/texmf-dist/doc/generic/pgf/ChangeLog @@ -1,3 +1,1098 @@ +2013-12-20 Till Tantau <tantau@users.sourceforge.net> + + - Release 3.0.0! + +2013-12-20 Till Tantau <tantau@users.sourceforge.net> + + - In preparation for the release 3.0.0, I pimped the manual a + bit. It will now automatically detect whether graph drawing + C libs are available or not. Also, syntax hilighting is now + always switched on. I also some subtle optical hints to + crossreferenced words in the code examples; this is pretty + useful, I think. + - Did a lot of cleaning up for the release. + +2013-12-18 Till Tantau <tantau@users.sourceforge.net> + + - Fixed a bug in Vertex.lua that returned wrong anchor + positions for non-centered vertices. + +2013-12-13 Till Tantau <tantau@users.sourceforge.net> + + - Fixed bug #280 "Layered layout" produces unknown key with graphs library. + - Fixed bug #279 "Some parts of arguments in foreach macro are lost". + - Fixed bug #258 "Default arrow edge style puts circumflex in + drawn end node" by now allowing people to say tip=on proper draw. + +2013-12-08 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + + - intersections lib: ensured that 'name path global' is reset between main paths. + +2013-11-30 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + + - worked on intersections lib (internals only); added O(N) list + append/prepend utilities + +2013-11-18 Mark Wibrow <vibrovski@users.sourceforge.net> + + - Added keys 'rotate around x', 'rotate around y' and + 'rotate around z' to rotate the xyz coordinate system + around the x, y, or z axis. + +2013-11-17 Mark Wibrow <vibrovski@users.sourceforge.net> + + - Fixes for 'text effects along path' decoration and docs. + +2013-11-16 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + + - external lib: added support for 'up to date check=md5' for lualatex. + Now, lualatex and pdftex both result in the same checksums (by means of + \usepackage{pdftexcmds}) + +2013-11-16 Mark Wibrow <vibrovski@users.sourceforge.net> + + - Finalised 'text effects along path' decoration and docs. + +2013-11-11 Mark Wibrow <vibrovski@users.sourceforge.net> + + - Changed keyval example (and references to define@key) + in pgfcalendar documentation to pgfkeys stuff. + +2013-11-08 Mark Wibrow <vibrovski@users.sourceforge.net> + + - Minor fixes to decorations.text and math libraries documentation + +2013-11-07 Mark Wibrow <vibrovski@users.sourceforge.net> + + - Added 'text effects along path' decoration. + +2013-11-01 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + + - Fixed regression/bug in 'name path global'. + +2013-10-31 Till Tantau <tantau@users.sourceforge.net> + + - Applied path for bug #277 "\beforeforegroundpath not working". + +2013-10-09 Till Tantau <tantau@users.sourceforge.net> + + - Prepared manual for new release (fixed overful boxes and + index problems). + +2013-10-08 Mark Wibrow <vibrovski@users.sourceforge.net> + + - Updated math library (minor fixes). + +2013-10-07 Till Tantau <tantau@users.sourceforge.net> + + - Applied some fixes so that C code for graph drawing works + once more. + - Arrow tips and their doc are now officially finished! + - Added documentation of nonlinear transformations. + +2013-10-06 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + + - modified release script to allow uploads of unstable TDS + zips to http://pgf.sourceforge.net using + make -f pgf/scripts/pgf/Makefile.pgf_release upload USER=cfeuersaenger + +2013-10-02 Mark Wibrow <vibrovski@users.sourceforge.net> + + - Fixed problem with math parser inserting extraneous + spaces when parsing \dimenexpr + +2013-09-30 Till Tantau <tantau@users.sourceforge.net> + + - Changed blend mode syntax to standard pgf syntax (since PDF + and SVG do not agree on names...). + - Added scale and slant options for arrow tips. + - Added more generic arrow tips. + +2013-09-24 Till Tantau <tantau@users.sourceforge.net> + + - First version of comlete arrow documentation finished. Still + need to document the arrows.meta library, though. + - Added "tips" option for drawing arrow tips without drawing + paths. + +2013-09-23 Till Tantau <tantau@users.sourceforge.net> + + - Fixed bug #273 "Graph drawing sublayouts fails". + - Incorporated first partial documentation of the arrow tips + into the main documentation. + - Fixed bug bugs:#272 "SVG parser error after close path" as + suggested by Mark Wibrow. + - Also changed the default syntax for svg path command so that + it uses braces instead of quotation marks. (Quotation marks + still work, of course.) + +2013-09-22 Till Tantau <tantau@users.sourceforge.net> + + - Started working on arrow doc. + +2013-09-20 Mark Wibrow <vibrovski@users.sourceforge.net> + + - Added macro to convert string of digits to comma separated list. + +2013-09-18 Till Tantau <tantau@users.sourceforge.net> + + - First version of new arrow tip management done. Up and + running! Still needs documentation and the old arrow tip + codes should (but need not) be ported. + - Did some porting of old code, added fixes. Doc still missing. + +2013-09-17 Till Tantau <tantau@users.sourceforge.net> + + - Fixed bug #264: "\pgfkeys /errors/unknown key should (?) expand first argument" + - Fixed bug #268: "`matrix of nodes' isn't working properly any more" + +2013-09-11 Mark Wibrow <vibrovski@users.sourceforge.net> + + - Corrected typos (bug #266 and bug #265) + +2013-09-11 Mark Wibrow <vibrovski@users.sourceforge.net> + + - added magnetic tape shape. + +2013-09-09 Till Tantau <tantau@users.sourceforge.net> + + - Fixed bug #262/267: "Line breaks are not working in labels anyy more." + - Fixed bug #260: "TikZ node on background in pgfextra" + - Started work on bending arrows. + +2013-09-05 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + + - external lib: fixed bug: file dependency handling was incorrect and + suffered from regression caused by MD5 checks + +2013-08-31 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + + - repaired incompatibility with pgfplots <= 1.8: samples key was + evaluated in context of floating point unit and new pgf code relied on dimension + registers. + +2013-08-29 Till Tantau <tantau@users.sourceforge.net> + + - Added "turn" key. + +2013-08-28 Till Tantau <tantau@users.sourceforge.net> + + - Added "angle" pic type and "angles" library. + - Patched gd loader code so that it works with context mark IV. + +2013-08-27 Till Tantau <tantau@users.sourceforge.net> + + - Added new pic path command. + - Patched pgfsys-dvipdfmx.def to step around the bug in + (x)dvipdfmx that caused scaled boxes (including scaled + graphics) inside nodes to be displayed incorrectly. + +2013-08-24 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + + - fixed bug in fpu: 0^0 and 0^x both produced nan. Now we get + 0^0=1 and 0^x = 0. + +2013-08-22 Till Tantau <tantua@users.sourceforge.net> + + - Removed claims from manual (not by me...) that TikZ does not + work with Mark IV of context. I just tried it and everything + I tried (including advanced stuff like shadings) worked fine. + +2013-08-18 Mark Wibrow <vibrovski@users.sourceforge.net> + + - Fixed pgf intersection library to ensure that + specialround tokens are processed. + +2013-08-06 Till Tantau <tantua@users.sourceforge.net> + + - Added support for dvisvgm. Quite nice... + +2013-08-05 Till Tantau <tantua@users.sourceforge.net> + + - Worked on tex4ht code. Works reasonably well know and even + graph drawing is possible (when luatex is used for + typesetting; for this I needed to fix some latin1 characters in + html4.4ht). Also, I renamed /tikz/tex4ht... to /pgf/tex4ht + (someone else added that) since tikz has nothing to do with + that stuff. + Typesetting the manual in tex4ht no longer works, but that seems + like too much bother for my taste. + +2013-08-02 Till Tantau <tantua@users.sourceforge.net> + + - Fixed bug #256 "The special \pgfcoordinate macro doesn't + expand \pgfpictureid." + +2013-08-04 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + + - external lib: fixed incompatibility of pdflscape with + external lib + +2013-08-01 Till Tantau <tantua@users.sourceforge.net> + + - Fixed a problem with pdf resources of transparency groups in + dvipdfmx. + +2013-07-31 Till Tantau <tantua@users.sourceforge.net> + + - Fixed bug #149 "/tikz/raw gnuplot ignoring segmented plot" + by introducing a new way of handling plot streams. There are + now new kinds of points (outliers and undefined points) and + "new data sets" commands inside streams. Handlers (like the + lineto and curve handlers) can be configured to interpret + these as jumps (this is the default). + - Fixed bug #255 "Trig computations offend fp via fixedpointarithmetic lib" + +2013-07-31 Mark Wibrow <vibrovski@users.sourceforge.net> + - Added "math" library. Could be integrated with calc library. + +2013-07-26 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + + - Fixed bug in external lib: mode=list and make did not cope well with + \ref in externalized images. These will be remade now. + +2013-07-24 Till Tantau <tantua@users.sourceforge.net> + + - Fixed bug #162 "PGF manual examples use undefined "shape example" style" + - Fixed bug #169 "ghostscript error: /undefined in pgfo" + - Concerning bug #167 "node pin option sets + inconsistent/incorrect angle" I added some clarification in + the manual that explains the observed behaviour. + - Fixed bug #158 "\pgfmathparse does not support e-TeXs + \numexpr and \dimexpr". You can now also use + \pgfmathsetlength to assign a muskip a value. Internally, + "mu" is treated like "pt", but if an expression contains + "mu", \pgfmathsetlength and \pgfmathaddtolength will convert + the number to "mu" before the assignment. + +2013-07-22 Till Tantau <tantua@users.sourceforge.net> + + - Fixed bug #173 "Tikz's transparency, xelatex and preview + package" by adding a specific fix for the interaction + between preview.sty and everyshi.sty in pgfutil-latex.def. + +2013-07-19 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + + - optimized mark=* and mark=o (q path versions lead to 10% time reduction) + - adopted new pgfkeys feature to /handler config/full or existing ( + required when /.search also is used to find the correct key path) + +2013-07-19 Till Tantau <tantua@users.sourceforge.net> + + - Fixed bug #175 "In PGF oo module, calling a method strips grouping" + - Fixed bug #181 "Need to document |- coordinates using calc notation" + - Fixed bug #187 "\pgfmathanglebetweenpoints is not documented" + - Increased accuracy of atan, atan2 and + \pgfmathanglebetweenpoints. + +2013-07-18 Till Tantau <tantua@users.sourceforge.net> + + - Fixed bug "#168 PGF is sensitive to dollar catcode" + - Fixed bug "#186 pgfonlayer makes pgf forget options" and + added "every on background layer" option. + - Fixed bug "#192 pgffor scope iteration is buggy" + - Fixed bug "#196 Incoherent syntax for Bézier curves" + - Fixed bug "#199 Drawing error for chamfered rectangle" + - Fixed bug "#201 Markings fail with "Dimension too Large" on + certain paths" by fixing a mistake and the decoration core + and, additionally, in pgfmathanglebetweenpoints. + - Fixed bug "#254 building currenct CVS version fails on + graphdrawing with current luatex": Will now work nicely with + TeXLive 2013 and Lua 5.2. + - Added feature request "bug #203 Blending modes and better transparency" + +2013-07-17 Till Tantau <tantua@users.sourceforge.net> + + - Fixed bug #204 "strange influence of \baselinestretch on + tikz figure" by no longer sharing \pgfutil@tempa with latex: + This register gets changed by LaTeX in a fontchange, which, in + turn can happen at the beginning of every + \pgfmathsetlength. + - Fixed bug #207 "Decoration markings not on path on large + lines" by using a more precise computation of positions on + straight lines in decorations. Also, the angle computation + is now much more precise by fixedin bug #201. + - Fixed bug #212 "Error if using plot into a \foreach loop in + a single path" by making \pgffor@beginhook and friends local + to the current \foreach. A nice side-effect is that one can + now nest \foreach statements on a path and also mix in the + plots. Hopefully, no one relied on the (undocumented, + unsupported) old bevahiour of the hooks. + - Fixed bug #213 "pgfmathsetcounter only works in local scope" + by adding a note in the documentation. + - Fixed bug #211 "\nodepart ignores text transparency" + - Fixed bug #220 "Transformations ignored in edge decoration." + - Fixed bug #221 "xyz spherical and cylindrical coordinate, radius not defined" + - Fixed bug #225 "pgfkeys "/errors/unknown choice value" ignores parameters" + - Fixed bug #253 "\pgfkeysfiltered cannot accept long arguments" + - Fixed bug #252 "I'm not able to build the current CVS + version". This included a number of patches to fix problems + introduced with the bugfixes introduced recently + +2013-07-16 Till Tantau <tantua@users.sourceforge.net> + + - Fixed bug #226 "matrix column sep=-\pgflinewidth changes after empty cell" + - Fixed bug #229 "pgfpagesuselayout breaks beamer class" + (hopefully, setting page sizes is really messy in TeX!). + - Fixed bug #232 "pow function broken for 0^x for non-integer values of x" + - Fixed bug #165 "\draw with empty domain results in infinite calculation" + - Added better error message to adress bug #244 "mindmap-style + "invalidates" coordinate shape." + - Fixed bug #235 "\def\costhirty{0.8660256} not really used" + +2013-07-15 Till Tantau <tantua@users.sourceforge.net> + + - Fixed bug "#237 CVS-version: pdfimage error: key interpolate undefined" + - Fixed bug "#245 broken key /pgf/decoration/reset marks" + - Fixed bug "#239 picture disappear after a zero-width rectangle width shading" + - Fixed bug "#247 Error messages hard to catch in plain TeX/ConTeXt" + - Fixed bug "#166 Possibly typos in circuits.logic.IEC" + - Fixed bug "#249 pgfkeys: /handlers/first char syntax is not + 'self-contained' (CVS version)" + - Fixed bug "#248 circuits adjustable annotation improperly placed" + +2013-07-13 Till Tantau <tantua@users.sourceforge.net> + + - Fixed bug "#250 pgfkyes: .append style and similar undouble # tokens" + - Fixed bug "#143 label changes center of a matrix node" + +2013-07-12 Till Tantau <tantau@users.sourceforge.net> + + - Fixed bug #128 "fit does not scale if used in scaled scope" + - Fixed bug #136 "\hrulefill inherits or not pgf line styles" + - Fixed bug #224 "Including Tikzpicture in third part of + multipart node" + +2013-07-11 Till Tantau <tantau@users.sourceforge.net> + + - Fixed bug #251 "cross out shape interacts with path options of path it is drawn on" + - Fixed bug #139 "Placement of node inside matix environment" + - Fixed bug #131 "text centering calculates wrong" and added + new "node font" option. + - Fixed bug #121 "Annoying "Underfull \hbox (badness 10000)" message" + - Fixed bug #134 "Edge node style affecting arrowhead". + +2013-07-08 Till Tantau <tantau@users.sourceforge.net> + + - Fixed bug #132 "Error in matrix with column sep "between" + origins" + - Fixed bug #133 "\draw[-<<,>=stealth] (10,45) -- (40,45); does + not work." However, this introduces a (small, only visual) + incompatibility with previous versions. If you need the visual + effect "-<<" used to have (which, in a sense, was wrong), use + "-< <" instead. The new "-> >" is also quite handy. + +2013-06-28 Till Tantau <tantau@users.sourceforge.net> + + - Fixed bug #116 "Decorations can't be repositioned when + pre/post used." + +2013-06-25 Till Tantau <tantau@users.sourceforge.net> + + - Fixed bug #241 "div/null error by (270:length) and a fading line." + - Fixed bug #126 "Incorrect placed labels for inplicite positioned nodes." + - Added foreach syntax to nodes. This is useful and also + needed to fix the problem that the foreach statement cannot + be used after a to path. + +2013-06-24 Till Tantau <tantau@users.sourceforge.net> + + - Fixed bug #18 and #74 (active characters and tikz) by virtue + of the new "babel" library, which deactivates catcodes at the + beginning of tikz pictures and reactivates them in nodes. + +2013-06-21 Till Tantau <tantau@users.sourceforge.net> + + - Fixed bug #110 "cannot add node after cycle operation" + - Fixed bug #88 "\pgftransformarrow does not rotate with \pgfpointanchor" + - Fixed bug #86 "macro-expanded tree node has bad edge anchor" + - Fixed bug #85 "PGF + Crop package, at least for pdftex." + +2013-06-20 Till Tantau <tantau@users.sourceforge.net> + + - Fixed bug #83 "Transparency Problem with \usepackage{endfloat}." + - Applied patch #19 pgfkeys: ".search also" fails at unbalanced "\if" values + - Applied patch #18 Missing grid lines with + negative increment + - Applied patch #17 TikZ folding library + - Applied patch #14 inheritance in the oo module + - Applied patch #13 leaking space in \pgfpointintersectionoflines + - Applied patch #11 Patch for Bug #3165961 (\pgfmathmax and \pgfmathmin) + - Fixed problem of patch #9 Add papersize to XeTeX driver + - Applied patch #8 Support for changing physical page size with XeTeX + (also added position saving support, while I was at it...) + - Applied patches #3, #4, #5, #6 (typos in manual) as far as possible + +2013-06-18 Till Tantau <tantau@users.sourceforge.net> + + - Fixed bug #236 "Scaled closed paths, start/end points dont exactly match": + "cycle" can now be used with all path operations where it + makes sense, not only with --. In particular, things like + ".. cycle" or "to [bend right] cycle" are now allowed. + +2013-05-23 Till Tantau <tantau@users.sourceforge.net> + + - Reworked handling of edge and vertex paths in gd. In + particular, edge--vertex intersections are now computed in + Lua, rather than in TikZ. This is much more powerful and + allows beautiful arcs between vertices. It is also very + useful for planar graph drawings when several edges leave a + vertex in the same direction. + +2013-04-08 Till Tantau <tantau@users.sourceforge.net> + + - Did away with luadoc, now using simple handcoded documentor + that will also work with Lua 5.2 + - Redid OGDF support. Resonably stable base now. + - Added better C support. + - Should now work with both Lua 5.1 and 5.2 + +2013-03-15 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + + - fixed incompatibility of fixltx2e and external lib + +2013-02-08 Till Tantau <tantau@users.sourceforge.net> + + - Reworked Storage mechanism of graph drawing system. + - Added phylogenetics library for graph drawing; documentation + still only rudimentary. + +2012-12-30 Till Tantau <tantau@users.sourceforge.net> + + - Started adding support for calling C graph drawing functions + from Lua. + - First proof of concept for OGDF finished. + - Must still address luatex shared library link problems. + +2012-12-25 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + + - fixed bug in external lib: \tikzexternalgetnextfilename did reset the + value of \tikzsetnextfilename and 'export next' + +2012-11-30 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + + - updated driver pgfsys-xetex: now, it supports all that the new driver + for dvipdfmx does which includes fadings, functional shadings, and + patterns. + +2012-11-30 Till Tantau <tantau@users.sourceforge.net> + + - First complete documentation of the graph drawing + system. (Finally!) + +2012-11-27 Till Tantau <tantau@users.sourceforge.net> + + - Renamed gd files to shorter versions: instead of + pgf/gd/model/pgf.gd.model.Edges.lua we now have + pgf/gd/model/Edge.lua and so on. + - Worked on gd documentation. Only binding doc is still a + mess. + +2012-11-26 Till Tantau <tantau@users.sourceforge.net> + + - Worked on gd documentation. + +2012-11-21 Till Tantau <tantau@users.sourceforge.net> + + - New version of gd lib. The internals have been completely + redone. In particular, no tikz libraries are needed for the + individual algorithms any longer, all declarations are now + done completely inside Lua. This makes gd usable (in + principle) independently of tikz and pgf. + - Because of this, all declarations of algorithms need to be + redone. + +2012-11-10 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + + - external lib: fixed spurious white space (caused by 'up to date check') + +2012-11-01 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + + - manual styles: improved robustness of auto cross references & active spaces + +2012-10-18 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - Fixed a bug with active colon in circuits lib. Probably more to + fix in other libraries. + +2012-10-11 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + + - Improved precision of math functions asin and acos (using linear + interpolation instead of constant interpolation) + +2012-09-27 Till Tantau <tantau@users.sourceforge.net> + + - Worked on gd. + +2012-09-26 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + - fixed pgfsys-pdftex.def : very old regression with \setbeamercovered{transparent} and \pause + Patch by Hendrik Vogt + +2012-08-29 Till Tantau <tantau@users.sourceforge.net> + + - Added support for sublayouts in gd (not yet fully + documented). This allows one to use several algorithms inside + a single graph. + +2012-06-28 Till Tantau <tantau@users.sourceforge.net> + + - Redone handling of clusters in gd yet again. Renamed them to + "collections". Much better system now, can handle hyperedges, + subgraphs and other stuff (in principle). + - Nodes generated by a gd algorithm now have correct size + information (this one was tricky!). + +2012-06-22 Till Tantau <tantau@users.sourceforge.net> + + - Redone handling of clusters in gd. + - Worked on gd documentation. + +2012-06-18 Christian Feuersaenger <cfeuersaenger@users.sourceforge.net> + - fixed minor expansion issue \foreach \x in {a,...,d} lead to unexpanded value \x + +2012-06-18 Christian Feuersaenger <ludewich@users.sourceforge.net> + + - externalization: added special switch to deactivate incompatible + geometry drivers during externalization + +2012-05-31 Till Tantau <tantau@users.sourceforge.net> + + - Redone pgf.gd.model.Arc + - Added documentation for said class. + +2012-05-23 Till Tantau <tantau@users.sourceforge.net> + + - Worked on gd documentation. + - Replaced old luadoc by customized version. Gets called + directly from tex. + +2012-05-17 Christian Feuersaenger <ludewich@users.sourceforge.net> + + - external lib: added support for MD5/diff based up-to-date checks. + Changes to a picture will automatically result in a remake of the + respective external graphics. + +2012-05-03 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - Fix bug #3527068 (\pgfmathatantwo did not exist) + +2012-05-14 Till Tantau <tantau@users.sourceforge.net> + + - Changed pgf.gd.new_graph_drawing_algorithm syntax. Not + likely to change again... + - Added support for algorithms to create nodes and edge in the + syntactic digraph. + - Introduced library graphdrawing.examples that includes some + code demonstrating how "things are done". + + +2012-05-13 Christian Feuersaenger <ludewich@users.sourceforge.net> + + - context: fixed catcode issues by means of suitable module + \protect/\unprotect statements. + +2012-05-06 Till Tantau <tantau@users.sourceforge.net> + + - Introduced a new class model for graph drawing (Digraph, + Arc, and Vertex instead of Graph, Edge, Node). I'm currently + porting all the old code, but it takes a while and it's a + bit messy right now. Some easy algorithms are already based + on the new system, old ones not. In the end, things should + be significantly faster and also easier to program. + +2012-05-03 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - Attempt to fix bug in calc lib when '!' or ':' are active (not + fully tested but should work). + +2012-05-02 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - Attempt to fix bug with label and pin when ':' is active (not + fully tested but should work). + +2012-04-19 Till Tantau <tantau@users.sourceforge.net> + + - Finished the first two chapters of the documentation of gd + (overview and tikz usage). + - Module system is now redone and the directory structure + has been reorganized. No more messing around with lua + modules, everything is perfectly portable now. + +2012-04-17 Till Tantau <tantau@users.sourceforge.net> + + - Started to completely redo the module system of graph + drawing in lua. I'm in the middle of it, so its currently + messy, but it works. + +2012-04-12 Till Tantau <tantau@users.sourceforge.net> + + - Implemented packing procedure for graph drawing. + - Cleaned up graph drawing source some more. + - Renamed lots of files (still not happy with it, though). + +2012-04-11 Till Tantau <tantau@users.sourceforge.net> + + - Implemented Reingold-Tilford tree layout. + +2012-04-05 Till Tantau <tantau@users.sourceforge.net> + + - Implemented my first graph drawing algorithm: circular layout. + +2012-04-03 Till Tantau <tantau@users.sourceforge.net> + + - Introduced new declaration mechanism for graph drawing + algorithm classes + - Implemented preprocessing step of decomposing a graph into + connected components. + +2012-04-02 Till Tantau <tantau@users.sourceforge.net> + + - Cleaned up graph drawing algorithm directories: Moved + obsolete algorithms to special directory. + - Switched graph drawing calling interface from function-base + to object-based: All graph drawing algorithms must now be + implemented in a class + - Cleaned up file and class names of graph drawing engine. + +2012-03-30 Till Tantau <tantau@users.sourceforge.net> + + - Fixed problem that in case math library is loaded before pgf + some math functions were broken (because \pgfmath@xa and + \pgf@xa were different registers, which they should not be). + +2012-03-29 Till Tantau <tantau@users.sourceforge.net> + + - Added anchoring and orientation to graph drawing library. + +2012-03-21 Till Tantau <tantau@users.sourceforge.net> + + - Added arrows.spaced library. + - Added quotation syntax to graph lib. + - Renamed some graph drawing layouts. + - Worked on documentation of graph drawing lib. + +2012-03-07 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - Moved wrappers for luatex primitives (\pgfutil@directlua, + \pgfutil@ifluatex, \pgfutil@luaescapestring) to pgfutil-common.tex + - Added support for luatex to the profiler library by emulating + \pdfelapsedtime. + +2012-02-27 Till Tantau <tantau@users.sourceforge.net> + + - Fixed wrong edef in graph lib that broke the /-syntax when + text contained expandable stuff. + +2012-02-21 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - More work on the luamath parser and evaluator. + +2012-01-24 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - Fix a bug in tikz polar coordinates (reported on tex.se + http://tex.stackexchange.com/questions/41828/using-math-in-tikz): + braces around a delimited argument are removed. + +2012-01-10 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - Fix a bug in pgfmath != operator (reported and fixed on tex.se + http://tex.stackexchange.com/questions/40605/using-in-pgfmathparse) + +2012-01-09 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - Fix a pgfmath dependency for pgffor. + +2012-01-03 Till Tantau <tantau@users.sourceforge.net> + + - Added pos support to the arc command (finally...). + - Added support to the graph library for drawing tries. + - Added support to the graph library for adding edge labels in + an easier way. + +2011-12-29 Christian Feuersaenger <ludewich@users.sourceforge.net> + + - Added the 'fixed relative' number formatting style. + +2011-12-28 Christian Feuersaenger <ludewich@users.sourceforge.net> + + - Added 'const plot mark mid' and 'jump mark mid' plot handlers. + +2011-12-02 Till Tantau <tantau@users.sourceforge.net> + + - Renamed "layered drawing" to "layered layout" for + consistency. + +2011-11-12 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - More work on the lua math parser and evaluator. + - Added wrappers for luatex primitives: \pgfutil@directlua, + \pgfutil@ifluatex, \pgfutil@luaescapestring + - Make lua code more lua 5.2 compatible + +2011-11-11 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - Work on the lua math parser and evaluator. Begin to merge Mark's + code with mine. + +2011-11-03 Christian Feuersaenger <ludewich@users.sourceforge.net> + + - added FPU support for ==, !=, <=, >=, ? + +2011-10-29 Christian Feuersaenger <ludewich@users.sourceforge.net> + + - fixed problem with pgf number printer: it introduced spurious spaces + tracker id 3430171. Thanks to Clemens Koppensteiner for the bugfix. + +2011-09-25 Christian Feuersaenger <ludewich@users.sourceforge.net> + + - \pgfsetlayers can now be given inside of a pgfpicture (or tikzpicture) + +2011-06-22 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - The lua math parser now works on basic expressions (no units, no + arrays, no strings, no functions, ...?). + +2011-06-02 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - Some work on a lua (lpeg based) math parser. + +2011-05-31 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - Added a gnuplot call key to pgfmoduleplot.code.tex (feature + request #3308340). + +2011-05-30 Jannis Pohlmann <jannis@xfce.org> + + - graph drawing: + - Initial work on layered drawing algorithms. + +2011-05-25 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - Added dim function for array to pgfmath (to be documented) + - Some work on a ODE solver + +2011-05-20 Christian Feuersaenger <ludewich@users.sourceforge.net> + + - removed spurious white spaces in my bugfix for pgfmathdivide + +2011-05-19 Till Tantau <tantau@users.sourceforge.net> + + - Second attempt at fixing spy lib... + +2011-05-18 Matthias Schulz <ma.schulz@email.de> + + - graph drawing: + - added short overview for nodes and edges (lua class documentation) + +2011-05-17 Jannis Pohlmann <jannis@xfce.org> + + - graph drawing: + - Separate 'spring layout' and 'spring electrical layout' families. + Rename existing algorithms accordingly. + - Add an implementation of the Floyd-Warshall algorithm. + - Add a new 'Hu2006 spring' algorithm based solely on springs. + - Improve the initial layout of 'Hu2006 spring electrical' by + taking the graph size and diameter into account. + - Rework existing spring electrical algorithms and improve + documentation. + - Catch -!- edges and remove them from the Lua graph when detected. + +2011-05-14 Jannis Pohlmann <jannis@xfce.org> + + - graph drawing: + - Update documentation of spring and spring-electrical parameters. + Add TODO items where things are missing, unclear or need to be + worked on. + - Make initial step dimension and the electric charge of nodes + configurable. Both, Walshaw2000 and Hu2006 support this. + - Improve the approximation of the repulsive force. + +2011-05-13 Till Tantau <tantau@users.sourceforge.net> + + - Fixed bug 3297817 (spy postscript problem). + - Fixed bug of missing newpath in postscript and opacity + settings. + +2011-05-13 Jannis Pohlmann <jannis@xfce.org> + + - graph drawing: + - Rename graphdrawing.spring to graphdrawing.force. + - Fix NaN bug in the orientation helper. + - Initial work on improving and documenting the parameters for + spring and spring-electrical algorithms. + - Properly forward default node and edge parameters to Lua. + +2011-05-12 Jannis Pohlmann <jannis@xfce.org> + + - graph drawing: + - Add Fibonacci heap and priority queue classes. + - Add Lua file for common graph algorithms. Implement Dijkstra. + - Add method Graph:getPseudoDiameter(). + - Hu2006: Scale coordinations of nodes in a coarse graph based on + the quotient of its pseudo diameters and that of the parent coarse + graph, as described in the paper. + +2011-05-11 Jannis Pohlmann <jannis@xfce.org> + + - graph drawing: + - Fix several interpolation bugs in the coarse graph class. + - Use the coarse graph class in the Walshaw2000 algorithm. + +2011-05-11 Till Tantau <tantau@users.sourceforge.net> + + - Worked on documentation of gd backend. Still need to + document graph parameters. + +2011-05-10 Jannis Pohlmann <jannis@xfce.org> + + - graph drawing: + - Remove files from the old graph drawing library tree. + - Disable verbose logging by default. + - Specify sane initial values for spring algorithm parameters. + +2011-05-10 Till Tantau <tantau@users.sourceforge.net> + + - Added .graph drawing parameter initial key. + +2011-05-09 Jannis Pohlmann <jannis@xfce.org> + + - graph drawing: + - Implement graph coarsening in the Hu2006 algorithm. + - Name force-based algorithms after the paper author and year. + +2011-05-09 Till Tantau <tantau@users.sourceforge.net> + + - Reorganized graph drawing documentation. + +2011-05-06 Jannis Pohlmann <jannis@xfce.org> + + - Finished the graph drawing library reorganization started by Till. + +2011-05-06 Till Tantau <tantau@users.sourceforge.net> + + - Reorganized the graph drawing key and directory + structure. The documentation is still missing. Also, lots of + files still need to be moved, but I'll leave that to Jannis. + +2011-05-06 Jannis Pohlmann <jannis@xfce.org> + + - graph drawing: + - implement a quadtree optimization in the Walshaw algorithm. + - add a simple version of the Hu spring-electrical algorithm that + seems to work almost as good as the Walshaw even without + the multilevel approach implemented (which is the only thing + that really makes the Walshaw algorithm useful). + +2011-05-04 Jannis Pohlmann <jannis@xfce.org> + + - graph drawing: + - Initial work on a quad tree implementation for spring and spring + electrical algorithms, with unit test. + - Improve the internals of the Vector class. + +2011-05-03 Till Tantau <tantau@users.sourceforge.net> + + - graph drawing: Started to cleanup pgf and tikz layers. Ongoing... + +2011-05-03 Jannis Pohlmann <jannis@xfce.org> + + - graph drawing: + - Fix Walshaw algorithm to properly set the subnodes when copying + the coarse graphs. Simplify the code that updates the node + coordinates. + +2011-05-02 Jannis Pohlmann <jannis@xfce.org> + + - graph drawing: + - Modify the doclet to allow underscores in parameter names. + - Document the Vector class as well as the table, iter and traversal + helpers. + - Remove old table and iterator helpers. Rename helper files. Rename + table.merge() and table.copy() to table.custom_merge() and + table.custom_copy() to avoid name clashes with luatools. Add + string helpers, including string.parse_braces(). Update algorithms + to work with these changes. + - Allow vectors to have an origin vector, similar to the Position + class. Introduce new alternative table-based syntax for + Vector:set() that is much easier to read. Update unit tests + and algorithms. + +2011-05-02 Christian Feuersaenger <ludewich@users.sourceforge.net> + + - fpu: added support for log10 and log2 + +2011-05-02 Jannis Pohlmann <jannis@xfce.org> + + - graph drawing: + - Drop the 'not yet positionedPGFGDINTERNAL' node name prefix + internally. It's stripped off now when nodes are passed over to + Lua and its added back again when shipping the node out to TeX. + - Drop the Node:shortname() method which is no longer needed. + - Improve coding style and documentation of the Interface, Sys, + Node, Edge and Graph classes. + - Rename Sys:logMessage() to Sys:log(). + - Make parameter labels in the API docs not appear in bold. + - Disable verbose logging by default. + - Add methods Edge:getNodes() and Node:getEdges(). + +2011-05-02 Jannis Pohlmann <jannis@xfce.org> + + - graph drawing: + - Initial work on spring-electrical and layered drawing algorithms. + - Major rework of the Lua code of the graphdrawing library: added + a Vector class for improved math operations and node positioning, + added quite a number of table and iterator helpers, added + post-processing code for fixing the orientation of graph drawings, + updated the graph/node/edge data structures to store nodes in the order + they appear instead of storing them in a random order, implement + coordinate keys for nodes, and much more. + +2011-04-30 Christian Feuersaenger <ludewich@users.sourceforge.net> + + - number printing: added '1000 sep in fractionals' switch + +2011-04-29 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - Work on pgflibraryluamath (added pgfpointnormalised) + +2011-04-27 Matthias Schulz <ma.schulz@email.de> + + - Graphdrawing library documentation, split into two files, removed + noluatex file, reworked the text (added information). + +2011-04-25 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - First attempt to do math with lua (very basical): pgflibraryluamath + +2011-04-18 Christian Feuersaenger <ludewich@users.sourceforge.net> + + - bugfix for rounding error in \pgfmathdivide{83.407811000}{16.68156400} + was 4.10, is now 5.0: it could happen in rare cases that digits where + appended where they shouldhave been than added (4 + .10 instead of 4 + 1.0) + +2011-04-22 Jannis Pohlmann <jannis@xfce.org> + + - Implemented a G_n subgraph for creating grid (or: mesh) graphs. + This also introduces a new key /tikz/graphs/wrap after=<number> that + configures how the nodes in such a grid graph are connected. Some of + the common subgraph keys such as /tikz/graphs/V and /tikz/graphs/n + can be used with G_n subgraphs as well. + - Added a simple grid placement strategy. It currently does not + support the chain shift and group shift keys properly and does not + implement any placement order other than left-to-right, so there is + room for improvement. + +2011-04-18 Christian Feuersaenger <ludewich@users.sourceforge.net> + + - external lib: reduced number of \newwrite allocations and allowed to disable features + to safe more of them (aux in dpth=false,disable dependency files) + +2011-04-17 Christian Feuersaenger <ludewich@users.sourceforge.net> + + - added '/pgf/number format/relative' formatting style. + +2011-03-22 Till Tantau <tantau@users.sourceforge.net> + + - Finished documentation of data visualization (sort of)! + - First usable version of data visualization! + +2011-03-15 Till Tantau <tantau@users.sourceforge.net> + + - Worked on dv documentation. Finished chapter on visualizers, + style sheets. Legends still missing + +2011-03-07 Till Tantau <tantau@users.sourceforge.net> + + - Worked on dv documentation. Finished chapter on axes. + +2011-03-07 Christian Feuersaenger <ludewich@users.sourceforge.net> + + - Incorporated a bugfix of Hans Hagen which makes pgf compatible with + Context Mk IV. + Verified: the patch is backwards compatible with TL 2009 and TL 2010 + i.e. Context MkII and it works with Context Mk IV. + +2011-01-22 Till Tantau <tantau@users.sourceforge.net> + + - Worked on dv documentation. + +2011-01-05 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - Attempt to fix a bug #1911195 with pgfpages and rotation (fix + contributed by Mark Wibrow). Note: Mark was not sure it has side + effects. + +2010-12-17 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - Documentation will now compile with auto-xref enabled (a problem + with \_ in the graph lib not handled correctly by + pgfmanual.pdflinks.code.tex). + - Fix bug #3104978 thanks to Heiko Oberdiek patch on ctt. + +2010-12-17 Till Tantau <tantau@users.sourceforge.net> + + - Changed the graph syntax for anonymous nodes in the graph + library and simplified the as= syntax. + - Added fresh nodes options to graph library. + +2010-12-14 Till Tantau <tantau@users.sourceforge.net> + + - Fixed graph lib so that it compiles with plain TeX. + +2010-12-10 Till Tantau <tantau@users.sourceforge.net> + + - Small fixed in the graph library. + +2010-12-07 Till Tantau <tantau@users.sourceforge.net> + + - Finished graph library! + +2010-12-06 Till Tantau <tantau@users.sourceforge.net> + + - Nearly finished graph lib and its documentation. + +2010-11-30 Till Tantau <tantau@users.sourceforge.net> + + - Fixed bug #3123605 (hopefully...). + - Worked on graph lib. + +2010-11-19 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - Some integer arithmetics functions for the math parser + (contributed by Alain Matthes): gcd, isprime, isodd, iseven + +2010-11-19 Till Tantau <tantau@users.sourceforge.net> + + - Second attempt at making \tikz work also with fragile stuff + following. The new code will no longer fail in a situation + like \tikz \foreach ... + - Worked on graph lib stuff. + +2010-11-06 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - A luatex version of the doc is available (fixed inputenc issues + since luatex works with utf8 by default). + +2010-11-04 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - Fix bug in pgfmathfunctions.basic.code.tex (bug reported by + Alain Matthes and fixed by Paul Gaborit on fctt): wrong + interaction between pow and exp (linked to \pgfmath@x modified + outside macro call). + +2010-11-01 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - Make \pgfkeys@exp@call long (bug reported by Florent Chervet on + fctt) + - Fix bug in pgflibraryshapes.callouts.code.tex: \pgf@test changed + to \pgf@node@name (bug reported by Zarko F. Cucej on ctt and fix + contributed by Mark Wibrow) + +2010-10-27 Christophe Jorssen <cjorssen@users.sourceforge.net> + + - fixed bug 3096333 (Fix contributed by Mark Wibrow): pgffor + failed to update \lastx in some cases + 2010-10-25 Christian Feuersaenger <ludewich@users.sourceforge.net> Released version 2.10 @@ -2265,3 +3360,7 @@ - Added pgfshade.sty + +;;; Local Variables: +;;; coding: undecided-unix +;;; End: diff --git a/Master/texmf-dist/doc/generic/pgf/FILES b/Master/texmf-dist/doc/generic/pgf/FILES index 941e8a18ab7..551504ed0a3 100644 --- a/Master/texmf-dist/doc/generic/pgf/FILES +++ b/Master/texmf-dist/doc/generic/pgf/FILES @@ -1,52 +1,44 @@ -pgf/doc/generic/pgf/images/brave-gnu-world-logo-mask.jpg +pgf/doc/generic/pgf/AUTHORS +pgf/doc/generic/pgf/ChangeLog +pgf/doc/generic/pgf/FILES pgf/doc/generic/pgf/images/brave-gnu-world-logo-mask.bb +pgf/doc/generic/pgf/images/brave-gnu-world-logo-mask.jpg pgf/doc/generic/pgf/images/brave-gnu-world-logo.25.bb pgf/doc/generic/pgf/images/brave-gnu-world-logo.25.eps pgf/doc/generic/pgf/images/brave-gnu-world-logo.25.jpg pgf/doc/generic/pgf/images/brave-gnu-world-logo.bb pgf/doc/generic/pgf/images/brave-gnu-world-logo.eps pgf/doc/generic/pgf/images/brave-gnu-world-logo.jpg +pgf/doc/generic/pgf/images/brave-gnu-world-logo.xbb pgf/doc/generic/pgf/images/pgfmanual-mindmap-1.pdf pgf/doc/generic/pgf/images/pgfmanual-mindmap-2.pdf -pgf/doc/generic/pgf/licenses/LICENSE +pgf/doc/generic/pgf/INSTALL pgf/doc/generic/pgf/licenses/gnu-free-documentation-license-1.2.txt pgf/doc/generic/pgf/licenses/gnu-public-license-2.txt pgf/doc/generic/pgf/licenses/latex-project-public-license-1.3c.txt +pgf/doc/generic/pgf/licenses/LICENSE pgf/doc/generic/pgf/licenses/manifest-code.txt pgf/doc/generic/pgf/licenses/manifest-documentation.txt pgf/doc/generic/pgf/macros/pgfmanual-en-macros.tex -pgf/doc/generic/pgf/text-en/plots/pgfmanual-sine.table -pgf/doc/generic/pgf/text-en/plots/pgf-x.table -pgf/doc/generic/pgf/text-en/plots/pgf-asymptotic-example.gnuplot -pgf/doc/generic/pgf/text-en/plots/pgf-asymptotic-example.table -pgf/doc/generic/pgf/text-en/plots/pgf-exp.gnuplot -pgf/doc/generic/pgf/text-en/plots/pgf-exp.table -pgf/doc/generic/pgf/text-en/plots/pgf-parametric-example.gnuplot -pgf/doc/generic/pgf/text-en/plots/pgf-parametric-example.table -pgf/doc/generic/pgf/text-en/plots/pgf-sin.gnuplot -pgf/doc/generic/pgf/text-en/plots/pgf-sin.table -pgf/doc/generic/pgf/text-en/plots/pgf-x.gnuplot -pgf/doc/generic/pgf/text-en/plots/pgfplotgnuplot-example.gnuplot -pgf/doc/generic/pgf/text-en/plots/pgfmanual-sine.gnuplot -pgf/doc/generic/pgf/text-en/plots/pgfplotgnuplot-example.table -pgf/doc/generic/pgf/text-en/pgfmanual-en-base-decorations.tex +pgf/doc/generic/pgf/pgfmanual.pdf +pgf/doc/generic/pgf/README pgf/doc/generic/pgf/text-en/pgfmanual-en-base-actions.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-base-arrows.tex -pgf/doc/generic/pgf/text-en/pgfmanual-en-base-external.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-base-decorations.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-base-design.tex -pgf/doc/generic/pgf/text-en/pgfmanual-en-base-matrices.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-base-external.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-base-images.tex -pgf/doc/generic/pgf/text-en/pgfmanual-en-base-layers.tex -pgf/doc/generic/pgf/text-en/texmf.cnf pgf/doc/generic/pgf/text-en/pgfmanual-en-base-internalregisters.tex -pgf/doc/generic/pgf/text-en/pgfmanual-en-base-patterns.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-base-layers.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-base-matrices.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-base-nodes.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-base-paths.tex -pgf/doc/generic/pgf/text-en/pgfmanual-en-base-shadings.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-base-patterns.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-base-plots.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-base-points.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-base-quick.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-base-scopes.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-base-shadings.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-base-transformations.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-base-transparency.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-drivers.tex @@ -56,12 +48,29 @@ pgf/doc/generic/pgf/text-en/pgfmanual-en-dv-examples.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-dv-formats.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-dv-introduction.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-dv-main.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-dv-polar.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-dv-stylesheets.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-dv-visualizers.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-gd-algorithm-layer.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-gd-algorithms-in-c.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-gd-binding-layer.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-gd-circular.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-gd-display-layer.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-gd-examples.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-gd-force.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-gd-layered.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-gd-misc.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-gd-ogdf.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-gd-overview.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-gd-phylogenetics.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-gd-trees.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-gd-usage-pgf.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-gd-usage-tikz.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-guidelines.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-installation.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-introduction.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-library-3d.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-library-angles.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-library-arrows.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-library-automata.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-library-backgrounds.tex @@ -79,6 +88,7 @@ pgf/doc/generic/pgf/text-en/pgfmanual-en-library-fixedpoint.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-library-folding.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-library-fpu.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-library-lsystems.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-library-math.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-library-matrices.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-library-mindmaps.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-library-patterns.tex @@ -95,6 +105,8 @@ pgf/doc/generic/pgf/text-en/pgfmanual-en-library-through.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-library-trees.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-library-turtle.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-license.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-main-body.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-main-preamble.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-main.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-math-algorithms.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-math-commands.tex @@ -113,53 +125,132 @@ pgf/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-overview.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-paths.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-protocol.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-tikz-actions.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-tikz-arrows.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-tikz-coordinates.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-tikz-decorations.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-tikz-design.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-tikz-graphs.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-tikz-matrices.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-tikz-paths.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-tikz-pics.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-tikz-plots.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-tikz-scopes.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-tikz-shapes.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-tikz-transformations.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-tikz-transparency.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-tikz-trees.tex -pgf/doc/generic/pgf/text-en/pgfmanual-en-tutorial-Euclid.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-tutorial-chains.tex +pgf/doc/generic/pgf/text-en/pgfmanual-en-tutorial-Euclid.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-tutorial-map.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-tutorial-nodes.tex -pgf/doc/generic/pgf/text-en/pgfmanual-en-tutorial-nodes.tex.orig pgf/doc/generic/pgf/text-en/pgfmanual-en-tutorial.tex pgf/doc/generic/pgf/text-en/pgfmanual-en-xxcolor.tex -pgf/doc/generic/pgf/version-for-dvipdfm/en/pgfmanual.tex +pgf/doc/generic/pgf/text-en/plots/pgf-asymptotic-example.gnuplot +pgf/doc/generic/pgf/text-en/plots/pgf-asymptotic-example.table +pgf/doc/generic/pgf/text-en/plots/pgf-exp.gnuplot +pgf/doc/generic/pgf/text-en/plots/pgf-exp.table +pgf/doc/generic/pgf/text-en/plots/pgf-parametric-example.gnuplot +pgf/doc/generic/pgf/text-en/plots/pgf-parametric-example.table +pgf/doc/generic/pgf/text-en/plots/pgf-sin.gnuplot +pgf/doc/generic/pgf/text-en/plots/pgf-sin.table +pgf/doc/generic/pgf/text-en/plots/pgf-tan-example.gnuplot +pgf/doc/generic/pgf/text-en/plots/pgf-tan-example.table +pgf/doc/generic/pgf/text-en/plots/pgf-x.gnuplot +pgf/doc/generic/pgf/text-en/plots/pgf-x.table +pgf/doc/generic/pgf/text-en/plots/pgfmanual-sine.gnuplot +pgf/doc/generic/pgf/text-en/plots/pgfmanual-sine.table +pgf/doc/generic/pgf/text-en/plots/pgfplotgnuplot-example.gnuplot +pgf/doc/generic/pgf/text-en/plots/pgfplotgnuplot-example.table pgf/doc/generic/pgf/version-for-dvipdfm/en/Makefile +pgf/doc/generic/pgf/version-for-dvipdfm/en/pgfmanual.tex pgf/doc/generic/pgf/version-for-dvipdfm/pgfmanual-dvipdfm.cfg -pgf/doc/generic/pgf/version-for-dvipdfmx/en/pgfmanual.tex pgf/doc/generic/pgf/version-for-dvipdfmx/en/Makefile +pgf/doc/generic/pgf/version-for-dvipdfmx/en/pgfmanual-test.tex +pgf/doc/generic/pgf/version-for-dvipdfmx/en/pgfmanual.tex pgf/doc/generic/pgf/version-for-dvipdfmx/pgfmanual-dvipdfmx.cfg pgf/doc/generic/pgf/version-for-dvips/en/Makefile pgf/doc/generic/pgf/version-for-dvips/en/pgfmanual.tex pgf/doc/generic/pgf/version-for-dvips/pgfmanual-dvips.cfg +pgf/doc/generic/pgf/version-for-luatex/en/Makefile +pgf/doc/generic/pgf/version-for-luatex/en/pgfmanual-test.tex +pgf/doc/generic/pgf/version-for-luatex/en/pgfmanual.tex +pgf/doc/generic/pgf/version-for-luatex/pgfmanual-luatex.cfg pgf/doc/generic/pgf/version-for-pdftex/en/Makefile -pgf/doc/generic/pgf/version-for-pdftex/en/pgfmanual.figlist pgf/doc/generic/pgf/version-for-pdftex/en/pgfmanual.tex pgf/doc/generic/pgf/version-for-pdftex/pgfmanual-pdftex.cfg -pgf/doc/generic/pgf/version-for-tex4ht/en/pgfmanual.tex pgf/doc/generic/pgf/version-for-tex4ht/en/Makefile +pgf/doc/generic/pgf/version-for-tex4ht/en/pgfmanual.tex pgf/doc/generic/pgf/version-for-tex4ht/pgfmanual-tex4ht.cfg -pgf/doc/generic/pgf/version-for-vtex/en/pgfmanual.tex pgf/doc/generic/pgf/version-for-vtex/en/Makefile +pgf/doc/generic/pgf/version-for-vtex/en/pgfmanual.tex pgf/doc/generic/pgf/version-for-vtex/pgfmanual-vtex.cfg -pgf/doc/generic/pgf/version-for-xetex/en/pgfmanual.tex pgf/doc/generic/pgf/version-for-xetex/en/Makefile +pgf/doc/generic/pgf/version-for-xetex/en/pgfmanual.tex pgf/doc/generic/pgf/version-for-xetex/pgfmanual-xetex.cfg -pgf/doc/generic/pgf/ChangeLog -pgf/doc/generic/pgf/AUTHORS -pgf/doc/generic/pgf/pgfmanual.pdf -pgf/doc/generic/pgf/FILES -pgf/doc/generic/pgf/INSTALL -pgf/doc/generic/pgf/README -pgf/doc/generic/pgf/TODO +pgf/source/generic/pgf/c/config/ExampleLocalMakefileConfig.mk +pgf/source/generic/pgf/c/config/MakefileConfig.mk +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/examples/c/Makefile +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/examples/c/SimpleDemoC.c +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/examples/c/SimpleDemoCPlusPlus.c++ +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/InterfaceFromC++.c++ +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/InterfaceFromC++.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/InterfaceFromC.c +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/InterfaceFromC.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/Makefile +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/energybased_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/FastMultipoleEmbedder_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/FMMMLayout_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/GEMLayout_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/MultilevelLayout_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/BarycenterPlacer_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/CirclePlacer_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/EdgeCoverMerger_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/IndependentSetMerger_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/LocalBiconnectedMerger_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/MatchingMerger_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/MedianPlacer_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/multilevelmixer_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/RandomMerger_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/RandomPlacer_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/SolarMerger_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/SolarPlacer_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/ZeroPlacer_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/SpringEmbedderFR_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/SpringEmbedderFRExact_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/SpringEmbedderKK_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/InterfaceFromOGDF.c++ +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/InterfaceFromOGDF.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/BarycenterHeuristic_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/CoffmanGrahamRanking_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/DfsAcyclicSubgraph_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/FastHierarchyLayout_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/FastSimpleHierarchyLayout_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/GreedyCycleRemoval_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/GreedyInsertHeuristic_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/layered_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/LongestPathRanking_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/MedianHeuristic_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/OptimalRanking_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/SiftingHeuristic_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/SplitHeuristic_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/SugiyamaLayout_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/Makefile +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/misclayout/BalloonLayout_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/misclayout/CircularLayout_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/misclayout/misclayout_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/module/module_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/ogdf_script.c++ +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/planarity/planarity_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/planarity/PlanarizationLayout_script.h +pgf/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/SimpleDemoOGDF.c++ +pgf/source/generic/pgf/c/INSTALL +pgf/source/generic/pgf/c/Makefile +pgf/source/generic/pgf/testsuite/external/Makefile +pgf/source/generic/pgf/testsuite/external/tikzexternaltest.code.tex +pgf/source/generic/pgf/testsuite/external/tikzexternaltest.sharedpreamble.tex +pgf/source/generic/pgf/testsuite/external/tikzexternaltest.tex +pgf/source/generic/pgf/testsuite/external/tikzexternaltestmakefile.tex +pgf/source/generic/pgf/testsuite/mathtest/pgfmathtestsuite.tex pgf/tex/context/third/pgf/basiclayer/t-pgf.tex pgf/tex/context/third/pgf/basiclayer/t-pgfbim.tex pgf/tex/context/third/pgf/basiclayer/t-pgfbla.tex @@ -177,70 +268,14 @@ pgf/tex/context/third/pgf/utilities/t-pgffor.tex pgf/tex/context/third/pgf/utilities/t-pgfkey.tex pgf/tex/context/third/pgf/utilities/t-pgfmod.tex pgf/tex/context/third/pgf/utilities/t-pgfrcs.tex -pgf/tex/latex/pgf/basiclayer/pgfbaseimage.sty -pgf/tex/latex/pgf/basiclayer/pgf.sty -pgf/tex/latex/pgf/basiclayer/pgfbaselayers.sty -pgf/tex/latex/pgf/basiclayer/pgfbasematrix.sty -pgf/tex/latex/pgf/basiclayer/pgfbasepatterns.sty -pgf/tex/latex/pgf/basiclayer/pgfbaseplot.sty -pgf/tex/latex/pgf/basiclayer/pgfbaseshapes.sty -pgf/tex/latex/pgf/basiclayer/pgfbasesnakes.sty -pgf/tex/latex/pgf/basiclayer/pgfcore.sty -pgf/tex/latex/pgf/compatibility/pgfcomp-version-0-65.sty -pgf/tex/latex/pgf/compatibility/pgfarrows.sty -pgf/tex/latex/pgf/compatibility/pgfautomata.sty -pgf/tex/latex/pgf/compatibility/pgflibraryplothandlers.sty -pgf/tex/latex/pgf/compatibility/pgfcomp-version-1-18.sty -pgf/tex/latex/pgf/compatibility/pgfheaps.sty -pgf/tex/latex/pgf/compatibility/pgflibraryarrows.sty -pgf/tex/latex/pgf/compatibility/pgflibraryautomata.sty -pgf/tex/latex/pgf/compatibility/pgflibrarytikzbackgrounds.sty -pgf/tex/latex/pgf/compatibility/pgflibraryplotmarks.sty -pgf/tex/latex/pgf/compatibility/pgflibraryshapes.sty -pgf/tex/latex/pgf/compatibility/pgflibrarysnakes.sty -pgf/tex/latex/pgf/compatibility/pgflibrarytikztrees.sty -pgf/tex/latex/pgf/compatibility/pgfnodes.sty -pgf/tex/latex/pgf/compatibility/pgfshade.sty -pgf/tex/latex/pgf/doc/pgfmanual.pdflinks.code.tex -pgf/tex/latex/pgf/doc/pgfmanual.code.tex -pgf/tex/latex/pgf/doc/pgfmanual.prettyprinter.code.tex -pgf/tex/latex/pgf/doc/pgfmanual.sty -pgf/tex/latex/pgf/frontendlayer/libraries/tikzlibraryexternal.code.tex -pgf/tex/latex/pgf/frontendlayer/pgfpict2e.sty -pgf/tex/latex/pgf/frontendlayer/tikz.sty -pgf/tex/latex/pgf/math/pgfmath.sty -pgf/tex/latex/pgf/systemlayer/pgfsys.sty -pgf/tex/latex/pgf/utilities/pgfcalendar.sty -pgf/tex/latex/pgf/utilities/pgffor.sty -pgf/tex/latex/pgf/utilities/pgfkeys.sty -pgf/tex/latex/pgf/utilities/pgfpages.sty -pgf/tex/latex/pgf/utilities/pgfrcs.sty -pgf/tex/latex/pgf/utilities/tikzexternal.sty -pgf/tex/latex/pgf/utilities/xxcolor.sty -pgf/tex/plain/pgf/basiclayer/pgfbaseimage.tex -pgf/tex/plain/pgf/basiclayer/pgf.tex -pgf/tex/plain/pgf/basiclayer/pgfbaselayers.tex -pgf/tex/plain/pgf/basiclayer/pgfbasematrix.tex -pgf/tex/plain/pgf/basiclayer/pgfbasepatterns.tex -pgf/tex/plain/pgf/basiclayer/pgfbaseplot.tex -pgf/tex/plain/pgf/basiclayer/pgfbaseshapes.tex -pgf/tex/plain/pgf/basiclayer/pgfbasesnakes.tex -pgf/tex/plain/pgf/basiclayer/pgfcore.tex -pgf/tex/plain/pgf/frontendlayer/tikz.tex -pgf/tex/plain/pgf/math/pgfmath.tex -pgf/tex/plain/pgf/systemlayer/pgfsys.tex -pgf/tex/plain/pgf/utilities/pgfcalendar.tex -pgf/tex/plain/pgf/utilities/pgffor.tex -pgf/tex/plain/pgf/utilities/pgfkeys.tex -pgf/tex/plain/pgf/utilities/pgfrcs.tex -pgf/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex pgf/tex/generic/pgf/basiclayer/pgfcore.code.tex -pgf/tex/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex +pgf/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex pgf/tex/generic/pgf/basiclayer/pgfcoreexternal.code.tex -pgf/tex/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex +pgf/tex/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex pgf/tex/generic/pgf/basiclayer/pgfcoreimage.code.tex pgf/tex/generic/pgf/basiclayer/pgfcorelayers.code.tex pgf/tex/generic/pgf/basiclayer/pgfcoreobjects.code.tex +pgf/tex/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex pgf/tex/generic/pgf/basiclayer/pgfcorepathprocessing.code.tex pgf/tex/generic/pgf/basiclayer/pgfcorepathusage.code.tex pgf/tex/generic/pgf/basiclayer/pgfcorepatterns.code.tex @@ -250,41 +285,38 @@ pgf/tex/generic/pgf/basiclayer/pgfcorescopes.code.tex pgf/tex/generic/pgf/basiclayer/pgfcoreshade.code.tex pgf/tex/generic/pgf/basiclayer/pgfcoretransformations.code.tex pgf/tex/generic/pgf/basiclayer/pgfcoretransparency.code.tex -pgf/tex/generic/pgf/frontendlayer/svg/svgpgf.cfg -pgf/tex/generic/pgf/frontendlayer/svg/svgpgf.xmt -pgf/tex/generic/pgf/frontendlayer/svg/svgtest.cfg -pgf/tex/generic/pgf/frontendlayer/svg/svgtest.tex -pgf/tex/generic/pgf/frontendlayer/svg/svgtest.xml -pgf/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.IEC.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.code.tex -pgf/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.CDH.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.code.tex +pgf/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.IEC.code.tex +pgf/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.CDH.code.tex +pgf/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.IEC.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.US.code.tex -pgf/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.logic.code.tex -pgf/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.barcharts.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.3d.code.tex -pgf/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.polar.code.tex +pgf/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.barcharts.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.formats.functions.code.tex +pgf/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.polar.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.sparklines.code.tex -pgf/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.basic.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.code.tex -pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex +pgf/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.standard.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzexternalshared.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary3d.code.tex +pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryangles.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryarrows.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryautomata.code.tex -pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalendar.code.tex +pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybabel.code.tex +pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex +pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybending.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalc.code.tex -pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.code.tex +pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalendar.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarychains.code.tex -pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.pathreplacing.code.tex +pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.footprints.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.fractals.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.markings.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.pathmorphing.code.tex -pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryshapes.gates.logic.IEC.code.tex +pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.pathreplacing.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.shapes.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.text.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryer.code.tex @@ -295,6 +327,7 @@ pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfolding.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfpu.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarylindenmayersystems.code.tex +pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymath.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymatrix.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymindmap.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarypatterns.code.tex @@ -302,12 +335,14 @@ pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarypetri.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryplothandlers.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryplotmarks.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarypositioning.code.tex +pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryquotes.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryscopes.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryshadings.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryshadows.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryshapes.arrows.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryshapes.callouts.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryshapes.code.tex +pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryshapes.gates.logic.IEC.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryshapes.gates.logic.US.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryshapes.geometric.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryshapes.misc.code.tex @@ -321,8 +356,180 @@ pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarytopaths.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarytrees.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryturtle.code.tex pgf/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex -pgf/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.formats.functions.code.tex +pgf/tex/generic/pgf/graphdrawing/lua/LUA_CODING_STYLE +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/Binding.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular/library.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular/Tantau2012.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Anchoring.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentAlign.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentDirection.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentDistance.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentOrder.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Components.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Distances.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/FineTune.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/LayoutPipeline.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/library.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/NodeAnchors.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Orientation.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Sublayouts.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/control.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Cluster.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Edge.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Graph.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Iterators.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Node.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Vector.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/circular/Tantau2012.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/control/Anchoring.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FastMultipoleEmbedder.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FMMMLayout.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/GEMLayout.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/MultilevelLayout.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/BarycenterPlacer.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/CirclePlacer.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/EdgeCoverMerger.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/IndependentSetMerger.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/LocalBiconnectedMerger.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MatchingMerger.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MedianPlacer.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomMerger.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomPlacer.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarMerger.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarPlacer.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/ZeroPlacer.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFR.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFRExact.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderKK.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/BarycenterHeuristic.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/CoffmanGrahamRanking.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/DfsAcyclicSubgraph.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastHierarchyLayout.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastSimpleHierarchyLayout.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyCycleRemoval.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyInsertHeuristic.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/LongestPathRanking.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/MedianHeuristic.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/OptimalRanking.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SiftingHeuristic.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SplitHeuristic.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SugiyamaLayout.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/BalloonLayout.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/CircularLayout.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/AcyclicSubgraphModule.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/HierarchyLayoutModule.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/InitialPlacer.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/MultilevelBuilder.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/RankingModule.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/TwoLayerCrossMin.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/planarity/PlanarizationLayout.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/planarity.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/trees/ReingoldTilford1981.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/ASCIIDisplayer.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/BindingToASCII.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/example_graph_for_ascii_displayer.txt +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/library.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleDemo.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleEdgeDemo.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleHuffman.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/CoarseGraph.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/Control.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlCoarsening.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlElectric.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlIteration.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlSprings.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlStart.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/library.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/QuadTree.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalHu2006.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalLayouts.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalWalshaw2000.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringHu2006.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringLayouts.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/force.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceCore.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToAlgorithms.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToC.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/Scope.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/crossing_minimization.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CrossingMinimizationGansnerKNV1993.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/cycle_removal.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990a.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990b.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalEadesLS1993.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalGansnerKNV1993.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/edge_routing.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/EdgeRoutingGansnerKNV1993.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/library.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NetworkSimplex.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/node_positioning.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/node_ranking.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodePositioningGansnerKNV1993.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodeRankingGansnerKNV1993.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodeRankingMinimumHeight.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/Ranking.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/Sugiyama.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Bezier.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/DepthFirstSearch.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Direct.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Event.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/LookupTable.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/PathLengths.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/PriorityQueue.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Simplifiers.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Stack.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Storage.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Transform.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Arc.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Collection.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Coordinate.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Digraph.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Edge.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Hyperedge.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/library.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Path.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Vertex.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/model.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/ogdf/library.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/ogdf.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/AuthorDefinedPhylogeny.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/BalancedMinimumEvolution.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/BalancedNearestNeighbourInterchange.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/DistanceMatrix.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/library.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/Maeusle2012.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/PhylogeneticTree.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/SokalMichener1958.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/tools/make_gd_wrap.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/ChildSpec.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/library.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/ReingoldTilford1981.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/SpanningTreeComputation.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf/gd.lua +pgf/tex/generic/pgf/graphdrawing/lua/pgf.lua +pgf/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.circular.code.tex +pgf/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.code.tex +pgf/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.examples.code.tex +pgf/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.force.code.tex +pgf/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.layered.code.tex +pgf/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.trees.code.tex +pgf/tex/generic/pgf/graphdrawing/tex/tikzlibrarygraphdrawing.code.tex pgf/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.barcharts.code.tex +pgf/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.formats.functions.code.tex pgf/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.polar.code.tex pgf/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.footprints.code.tex pgf/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.fractals.code.tex @@ -331,23 +538,17 @@ pgf/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.pathmorphing.cod pgf/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.pathreplacing.code.tex pgf/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.shapes.code.tex pgf/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.text.code.tex -pgf/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.IEC.code.tex -pgf/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.ee.IEC.code.tex -pgf/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.ee.code.tex -pgf/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.US.code.tex -pgf/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.code.tex -pgf/tex/generic/pgf/libraries/shapes/pgflibraryshapes.callouts.code.tex -pgf/tex/generic/pgf/libraries/shapes/pgflibraryshapes.arrows.code.tex -pgf/tex/generic/pgf/libraries/shapes/pgflibraryshapes.geometric.code.tex -pgf/tex/generic/pgf/libraries/shapes/pgflibraryshapes.code.tex -pgf/tex/generic/pgf/libraries/shapes/pgflibraryshapes.multipart.code.tex -pgf/tex/generic/pgf/libraries/shapes/pgflibraryshapes.misc.code.tex -pgf/tex/generic/pgf/libraries/shapes/pgflibraryshapes.symbols.code.tex -pgf/tex/generic/pgf/libraries/pgflibraryintersections.code.tex +pgf/tex/generic/pgf/libraries/luamath/pgflibraryluamath.code.tex +pgf/tex/generic/pgf/libraries/luamath/pgfluamath.functions.lua +pgf/tex/generic/pgf/libraries/luamath/pgfluamath.parser.lua pgf/tex/generic/pgf/libraries/pgflibraryarrows.code.tex +pgf/tex/generic/pgf/libraries/pgflibraryarrows.meta.code.tex +pgf/tex/generic/pgf/libraries/pgflibraryarrows.spaced.code.tex +pgf/tex/generic/pgf/libraries/pgflibrarycurvilinear.code.tex pgf/tex/generic/pgf/libraries/pgflibraryfadings.code.tex -pgf/tex/generic/pgf/libraries/pgflibraryfpu.code.tex pgf/tex/generic/pgf/libraries/pgflibraryfixedpointarithmetic.code.tex +pgf/tex/generic/pgf/libraries/pgflibraryfpu.code.tex +pgf/tex/generic/pgf/libraries/pgflibraryintersections.code.tex pgf/tex/generic/pgf/libraries/pgflibrarylindenmayersystems.code.tex pgf/tex/generic/pgf/libraries/pgflibrarypatterns.code.tex pgf/tex/generic/pgf/libraries/pgflibraryplothandlers.code.tex @@ -356,39 +557,56 @@ pgf/tex/generic/pgf/libraries/pgflibraryprofiler.code.tex pgf/tex/generic/pgf/libraries/pgflibraryshadings.code.tex pgf/tex/generic/pgf/libraries/pgflibrarysnakes.code.tex pgf/tex/generic/pgf/libraries/pgflibrarysvg.path.code.tex -pgf/tex/generic/pgf/math/pgfmathcalc.code.tex +pgf/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.ee.code.tex +pgf/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.ee.IEC.code.tex +pgf/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.code.tex +pgf/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.IEC.code.tex +pgf/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.US.code.tex +pgf/tex/generic/pgf/libraries/shapes/pgflibraryshapes.arrows.code.tex +pgf/tex/generic/pgf/libraries/shapes/pgflibraryshapes.callouts.code.tex +pgf/tex/generic/pgf/libraries/shapes/pgflibraryshapes.code.tex +pgf/tex/generic/pgf/libraries/shapes/pgflibraryshapes.geometric.code.tex +pgf/tex/generic/pgf/libraries/shapes/pgflibraryshapes.misc.code.tex +pgf/tex/generic/pgf/libraries/shapes/pgflibraryshapes.multipart.code.tex +pgf/tex/generic/pgf/libraries/shapes/pgflibraryshapes.symbols.code.tex +pgf/tex/generic/pgf/lua/pgf/manual/DocumentParser.lua +pgf/tex/generic/pgf/lua/pgf/manual.lua pgf/tex/generic/pgf/math/pgfmath.code.tex -pgf/tex/generic/pgf/math/pgfmathfunctions.base.code.tex +pgf/tex/generic/pgf/math/pgfmathcalc.code.tex pgf/tex/generic/pgf/math/pgfmathfloat.code.tex -pgf/tex/generic/pgf/math/pgfmathfunctions.comparison.code.tex +pgf/tex/generic/pgf/math/pgfmathfunctions.base.code.tex pgf/tex/generic/pgf/math/pgfmathfunctions.basic.code.tex pgf/tex/generic/pgf/math/pgfmathfunctions.code.tex -pgf/tex/generic/pgf/math/pgfmathfunctions.trigonometric.code.tex +pgf/tex/generic/pgf/math/pgfmathfunctions.comparison.code.tex +pgf/tex/generic/pgf/math/pgfmathfunctions.integerarithmetics.code.tex pgf/tex/generic/pgf/math/pgfmathfunctions.misc.code.tex pgf/tex/generic/pgf/math/pgfmathfunctions.random.code.tex pgf/tex/generic/pgf/math/pgfmathfunctions.round.code.tex +pgf/tex/generic/pgf/math/pgfmathfunctions.trigonometric.code.tex +pgf/tex/generic/pgf/math/pgfmathode.code.tex pgf/tex/generic/pgf/math/pgfmathparser.code.tex pgf/tex/generic/pgf/math/pgfmathutil.code.tex +pgf/tex/generic/pgf/modules/pgfmodulebending.code.tex pgf/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex pgf/tex/generic/pgf/modules/pgfmoduledecorations.code.tex pgf/tex/generic/pgf/modules/pgfmodulematrix.code.tex +pgf/tex/generic/pgf/modules/pgfmodulenonlineartransformations.code.tex pgf/tex/generic/pgf/modules/pgfmoduleoo.code.tex pgf/tex/generic/pgf/modules/pgfmoduleparser.code.tex pgf/tex/generic/pgf/modules/pgfmoduleplot.code.tex pgf/tex/generic/pgf/modules/pgfmoduleshapes.code.tex pgf/tex/generic/pgf/modules/pgfmodulesnakes.code.tex pgf/tex/generic/pgf/modules/pgfmodulesorting.code.tex -pgf/tex/generic/pgf/rendering/pgfrendertransform.code.tex -pgf/tex/generic/pgf/rendering/pgfrenderpoints.code.tex -pgf/tex/generic/pgf/systemlayer/pgfsys-dvi.def pgf/tex/generic/pgf/systemlayer/pgf.cfg pgf/tex/generic/pgf/systemlayer/pgfsys-common-pdf-via-dvi.def pgf/tex/generic/pgf/systemlayer/pgfsys-common-pdf.def pgf/tex/generic/pgf/systemlayer/pgfsys-common-postscript.def pgf/tex/generic/pgf/systemlayer/pgfsys-common-svg.def +pgf/tex/generic/pgf/systemlayer/pgfsys-dvi.def pgf/tex/generic/pgf/systemlayer/pgfsys-dvipdfm.def pgf/tex/generic/pgf/systemlayer/pgfsys-dvipdfmx.def pgf/tex/generic/pgf/systemlayer/pgfsys-dvips.def +pgf/tex/generic/pgf/systemlayer/pgfsys-dvisvgm.def pgf/tex/generic/pgf/systemlayer/pgfsys-pdftex.def pgf/tex/generic/pgf/systemlayer/pgfsys-tex4ht.def pgf/tex/generic/pgf/systemlayer/pgfsys-textures.def @@ -397,38 +615,71 @@ pgf/tex/generic/pgf/systemlayer/pgfsys-xetex.def pgf/tex/generic/pgf/systemlayer/pgfsys.code.tex pgf/tex/generic/pgf/systemlayer/pgfsysprotocol.code.tex pgf/tex/generic/pgf/systemlayer/pgfsyssoftpath.code.tex -pgf/tex/generic/pgf/utilities/pgfexternalwithdepth.tex pgf/tex/generic/pgf/utilities/pgfcalendar.code.tex pgf/tex/generic/pgf/utilities/pgfexternal.tex -pgf/tex/generic/pgf/utilities/pgfkeysfiltered.code.tex +pgf/tex/generic/pgf/utilities/pgfexternalwithdepth.tex pgf/tex/generic/pgf/utilities/pgffor.code.tex pgf/tex/generic/pgf/utilities/pgfkeys.code.tex -pgf/tex/generic/pgf/utilities/pgfutil-common.tex +pgf/tex/generic/pgf/utilities/pgfkeysfiltered.code.tex pgf/tex/generic/pgf/utilities/pgfrcs.code.tex +pgf/tex/generic/pgf/utilities/pgfutil-common-lists.tex +pgf/tex/generic/pgf/utilities/pgfutil-common.tex pgf/tex/generic/pgf/utilities/pgfutil-context.def pgf/tex/generic/pgf/utilities/pgfutil-latex.def pgf/tex/generic/pgf/utilities/pgfutil-plain.def -pgf/README -pgf/source/latex/pgf/incoming/GrzegorzMurzynowski/pgfdatabasearrows.pdf -pgf/source/latex/pgf/incoming/GrzegorzMurzynowski/pgfdatabasearrows.sty -pgf/source/latex/pgf/incoming/GrzegorzMurzynowski/pgfdatabasearrows.tex -pgf/source/latex/pgf/incoming/KarlheinzOchs/interconnection.pdf -pgf/source/latex/pgf/incoming/KarlheinzOchs/basics.pdf -pgf/source/latex/pgf/incoming/KarlheinzOchs/basics.tex -pgf/source/latex/pgf/incoming/KarlheinzOchs/fir.pdf -pgf/source/latex/pgf/incoming/KarlheinzOchs/fir.tex -pgf/source/latex/pgf/incoming/KarlheinzOchs/signalflowdiagram.sty -pgf/source/latex/pgf/incoming/KarlheinzOchs/interconnection.tex -pgf/source/latex/pgf/incoming/KarlheinzOchs/macros.sty -pgf/source/latex/pgf/incoming/KarlheinzOchs/pgflibrarytikzsignalflowoperators.code.tex -pgf/source/latex/pgf/incoming/KarlheinzOchs/pgflibrarytikzsignalflowarrows.code.tex -pgf/source/latex/pgf/incoming/KarlheinzOchs/pgflibrarytikzsignalflowblocks.code.tex -pgf/source/latex/pgf/incoming/KarlheinzOchs/pgflibrarytikzsignalflowdiagram.code.tex -pgf/source/latex/pgf/incoming/KarlheinzOchs/placement.pdf -pgf/source/latex/pgf/incoming/KarlheinzOchs/placement.tex -pgf/source/latex/pgf/testsuite/external/Makefile -pgf/source/latex/pgf/testsuite/external/tikzexternaltest.code.tex -pgf/source/latex/pgf/testsuite/external/tikzexternaltest.sharedpreamble.tex -pgf/source/latex/pgf/testsuite/external/tikzexternaltest.tex -pgf/source/latex/pgf/testsuite/external/tikzexternaltestmakefile.tex -pgf/source/latex/pgf/testsuite/mathtest/pgfmathtestsuite.tex +pgf/tex/latex/pgf/basiclayer/pgf.sty +pgf/tex/latex/pgf/basiclayer/pgfbaseimage.sty +pgf/tex/latex/pgf/basiclayer/pgfbaselayers.sty +pgf/tex/latex/pgf/basiclayer/pgfbasematrix.sty +pgf/tex/latex/pgf/basiclayer/pgfbasepatterns.sty +pgf/tex/latex/pgf/basiclayer/pgfbaseplot.sty +pgf/tex/latex/pgf/basiclayer/pgfbaseshapes.sty +pgf/tex/latex/pgf/basiclayer/pgfbasesnakes.sty +pgf/tex/latex/pgf/basiclayer/pgfcore.sty +pgf/tex/latex/pgf/compatibility/pgfarrows.sty +pgf/tex/latex/pgf/compatibility/pgfautomata.sty +pgf/tex/latex/pgf/compatibility/pgfcomp-version-0-65.sty +pgf/tex/latex/pgf/compatibility/pgfcomp-version-1-18.sty +pgf/tex/latex/pgf/compatibility/pgfheaps.sty +pgf/tex/latex/pgf/compatibility/pgflibraryarrows.sty +pgf/tex/latex/pgf/compatibility/pgflibraryautomata.sty +pgf/tex/latex/pgf/compatibility/pgflibraryplothandlers.sty +pgf/tex/latex/pgf/compatibility/pgflibraryplotmarks.sty +pgf/tex/latex/pgf/compatibility/pgflibraryshapes.sty +pgf/tex/latex/pgf/compatibility/pgflibrarysnakes.sty +pgf/tex/latex/pgf/compatibility/pgflibrarytikzbackgrounds.sty +pgf/tex/latex/pgf/compatibility/pgflibrarytikztrees.sty +pgf/tex/latex/pgf/compatibility/pgfnodes.sty +pgf/tex/latex/pgf/compatibility/pgfshade.sty +pgf/tex/latex/pgf/doc/pgfmanual.code.tex +pgf/tex/latex/pgf/doc/pgfmanual.pdflinks.code.tex +pgf/tex/latex/pgf/doc/pgfmanual.prettyprinter.code.tex +pgf/tex/latex/pgf/doc/pgfmanual.sty +pgf/tex/latex/pgf/frontendlayer/libraries/tikzlibraryexternal.code.tex +pgf/tex/latex/pgf/frontendlayer/pgfpict2e.sty +pgf/tex/latex/pgf/frontendlayer/tikz.sty +pgf/tex/latex/pgf/math/pgfmath.sty +pgf/tex/latex/pgf/systemlayer/pgfsys.sty +pgf/tex/latex/pgf/utilities/pgfcalendar.sty +pgf/tex/latex/pgf/utilities/pgffor.sty +pgf/tex/latex/pgf/utilities/pgfkeys.sty +pgf/tex/latex/pgf/utilities/pgfpages.sty +pgf/tex/latex/pgf/utilities/pgfrcs.sty +pgf/tex/latex/pgf/utilities/tikzexternal.sty +pgf/tex/latex/pgf/utilities/xxcolor.sty +pgf/tex/plain/pgf/basiclayer/pgf.tex +pgf/tex/plain/pgf/basiclayer/pgfbaseimage.tex +pgf/tex/plain/pgf/basiclayer/pgfbaselayers.tex +pgf/tex/plain/pgf/basiclayer/pgfbasematrix.tex +pgf/tex/plain/pgf/basiclayer/pgfbasepatterns.tex +pgf/tex/plain/pgf/basiclayer/pgfbaseplot.tex +pgf/tex/plain/pgf/basiclayer/pgfbaseshapes.tex +pgf/tex/plain/pgf/basiclayer/pgfbasesnakes.tex +pgf/tex/plain/pgf/basiclayer/pgfcore.tex +pgf/tex/plain/pgf/frontendlayer/tikz.tex +pgf/tex/plain/pgf/math/pgfmath.tex +pgf/tex/plain/pgf/systemlayer/pgfsys.tex +pgf/tex/plain/pgf/utilities/pgfcalendar.tex +pgf/tex/plain/pgf/utilities/pgffor.tex +pgf/tex/plain/pgf/utilities/pgfkeys.tex +pgf/tex/plain/pgf/utilities/pgfrcs.tex diff --git a/Master/texmf-dist/doc/generic/pgf/TODO b/Master/texmf-dist/doc/generic/pgf/TODO deleted file mode 100644 index 1c391261d33..00000000000 --- a/Master/texmf-dist/doc/generic/pgf/TODO +++ /dev/null @@ -1,5 +0,0 @@ -1) Allow midway placement of nodes on arcs. -2) Write RiesZ (RiesZ ist ein schönes Zeichenprogramm), a Java-GUI for TikZ. - (Good students's project!!!) -3) Fix text problems in SVG. - diff --git a/Master/texmf-dist/doc/generic/pgf/images/brave-gnu-world-logo.25.eps b/Master/texmf-dist/doc/generic/pgf/images/brave-gnu-world-logo.25.eps index 7fc67685fa9..9c02410d1d2 100644 --- a/Master/texmf-dist/doc/generic/pgf/images/brave-gnu-world-logo.25.eps +++ b/Master/texmf-dist/doc/generic/pgf/images/brave-gnu-world-logo.25.eps @@ -1,469 +1,4 @@ -%!PS-Adobe-3.0 EPSF-3.0 -%%Title: brave-gnu-world-logo.25.eps -%%CreationDate: 09.10.2006 22:09 Uhr -%%BoundingBox: 0 0 342 387 -%%HiResBoundingBox: 0 0 342 387 -%%SuppressDotGainCompensation -%%EndComments -%%BeginProlog -%%EndProlog -%%BeginSetup -%%EndSetup -%ImageData: 342 387 8 3 0 1 3 "beginimage" -%BeginPhotoshop: 13952 -% 3842494D0425000000000010000000000000000000000000000000003842494D -% 03EA000000001DA63C3F786D6C2076657273696F6E3D22312E302220656E636F -% 64696E673D225554462D38223F3E0A3C21444F435459504520706C6973742050 -% 55424C494320222D2F2F4170706C6520436F6D70757465722F2F44544420504C -% 49535420312E302F2F454E222022687474703A2F2F7777772E6170706C652E63 -% 6F6D2F445444732F50726F70657274794C6973742D312E302E647464223E0A3C -% 706C6973742076657273696F6E3D22312E30223E0A3C646963743E0A093C6B65 -% 793E636F6D2E6170706C652E7072696E742E50616765466F726D61742E504D48 -% 6F72697A6F6E74616C5265733C2F6B65793E0A093C646963743E0A09093C6B65 -% 793E636F6D2E6170706C652E7072696E742E7469636B65742E63726561746F72 -% 3C2F6B65793E0A09093C737472696E673E636F6D2E6170706C652E7072696E74 -% 696E676D616E616765723C2F737472696E673E0A09093C6B65793E636F6D2E61 -% 70706C652E7072696E742E7469636B65742E6974656D41727261793C2F6B6579 -% 3E0A09093C61727261793E0A0909093C646963743E0A090909093C6B65793E63 -% 6F6D2E6170706C652E7072696E742E50616765466F726D61742E504D486F7269 -% 7A6F6E74616C5265733C2F6B65793E0A090909093C7265616C3E37323C2F7265 -% 616C3E0A090909093C6B65793E636F6D2E6170706C652E7072696E742E746963 -% 6B65742E636C69656E743C2F6B65793E0A090909093C737472696E673E636F6D -% 2E6170706C652E7072696E74696E676D616E616765723C2F737472696E673E0A -% 090909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E -% 6D6F64446174653C2F6B65793E0A090909093C646174653E323030362D31302D -% 30395432303A30333A33365A3C2F646174653E0A090909093C6B65793E636F6D -% 2E6170706C652E7072696E742E7469636B65742E7374617465466C61673C2F6B -% 65793E0A090909093C696E74656765723E303C2F696E74656765723E0A090909 -% 3C2F646963743E0A09093C2F61727261793E0A093C2F646963743E0A093C6B65 -% 793E636F6D2E6170706C652E7072696E742E50616765466F726D61742E504D4F -% 7269656E746174696F6E3C2F6B65793E0A093C646963743E0A09093C6B65793E -% 636F6D2E6170706C652E7072696E742E7469636B65742E63726561746F723C2F -% 6B65793E0A09093C737472696E673E636F6D2E6170706C652E7072696E74696E -% 676D616E616765723C2F737472696E673E0A09093C6B65793E636F6D2E617070 -% 6C652E7072696E742E7469636B65742E6974656D41727261793C2F6B65793E0A -% 09093C61727261793E0A0909093C646963743E0A090909093C6B65793E636F6D -% 2E6170706C652E7072696E742E50616765466F726D61742E504D4F7269656E74 -% 6174696F6E3C2F6B65793E0A090909093C696E74656765723E313C2F696E7465 -% 6765723E0A090909093C6B65793E636F6D2E6170706C652E7072696E742E7469 -% 636B65742E636C69656E743C2F6B65793E0A090909093C737472696E673E636F -% 6D2E6170706C652E7072696E74696E676D616E616765723C2F737472696E673E -% 0A090909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B6574 -% 2E6D6F64446174653C2F6B65793E0A090909093C646174653E323030362D3130 -% 2D30395432303A30333A33365A3C2F646174653E0A090909093C6B65793E636F -% 6D2E6170706C652E7072696E742E7469636B65742E7374617465466C61673C2F -% 6B65793E0A090909093C696E74656765723E303C2F696E74656765723E0A0909 -% 093C2F646963743E0A09093C2F61727261793E0A093C2F646963743E0A093C6B -% 65793E636F6D2E6170706C652E7072696E742E50616765466F726D61742E504D -% 5363616C696E673C2F6B65793E0A093C646963743E0A09093C6B65793E636F6D -% 2E6170706C652E7072696E742E7469636B65742E63726561746F723C2F6B6579 -% 3E0A09093C737472696E673E636F6D2E6170706C652E7072696E74696E676D61 -% 6E616765723C2F737472696E673E0A09093C6B65793E636F6D2E6170706C652E -% 7072696E742E7469636B65742E6974656D41727261793C2F6B65793E0A09093C -% 61727261793E0A0909093C646963743E0A090909093C6B65793E636F6D2E6170 -% 706C652E7072696E742E50616765466F726D61742E504D5363616C696E673C2F -% 6B65793E0A090909093C7265616C3E313C2F7265616C3E0A090909093C6B6579 -% 3E636F6D2E6170706C652E7072696E742E7469636B65742E636C69656E743C2F -% 6B65793E0A090909093C737472696E673E636F6D2E6170706C652E7072696E74 -% 696E676D616E616765723C2F737472696E673E0A090909093C6B65793E636F6D -% 2E6170706C652E7072696E742E7469636B65742E6D6F64446174653C2F6B6579 -% 3E0A090909093C646174653E323030362D31302D30395432303A30333A33365A -% 3C2F646174653E0A090909093C6B65793E636F6D2E6170706C652E7072696E74 -% 2E7469636B65742E7374617465466C61673C2F6B65793E0A090909093C696E74 -% 656765723E303C2F696E74656765723E0A0909093C2F646963743E0A09093C2F -% 61727261793E0A093C2F646963743E0A093C6B65793E636F6D2E6170706C652E -% 7072696E742E50616765466F726D61742E504D566572746963616C5265733C2F -% 6B65793E0A093C646963743E0A09093C6B65793E636F6D2E6170706C652E7072 -% 696E742E7469636B65742E63726561746F723C2F6B65793E0A09093C73747269 -% 6E673E636F6D2E6170706C652E7072696E74696E676D616E616765723C2F7374 -% 72696E673E0A09093C6B65793E636F6D2E6170706C652E7072696E742E746963 -% 6B65742E6974656D41727261793C2F6B65793E0A09093C61727261793E0A0909 -% 093C646963743E0A090909093C6B65793E636F6D2E6170706C652E7072696E74 -% 2E50616765466F726D61742E504D566572746963616C5265733C2F6B65793E0A -% 090909093C7265616C3E37323C2F7265616C3E0A090909093C6B65793E636F6D -% 2E6170706C652E7072696E742E7469636B65742E636C69656E743C2F6B65793E -% 0A090909093C737472696E673E636F6D2E6170706C652E7072696E74696E676D -% 616E616765723C2F737472696E673E0A090909093C6B65793E636F6D2E617070 -% 6C652E7072696E742E7469636B65742E6D6F64446174653C2F6B65793E0A0909 -% 09093C646174653E323030362D31302D30395432303A30333A33365A3C2F6461 -% 74653E0A090909093C6B65793E636F6D2E6170706C652E7072696E742E746963 -% 6B65742E7374617465466C61673C2F6B65793E0A090909093C696E7465676572 -% 3E303C2F696E74656765723E0A0909093C2F646963743E0A09093C2F61727261 -% 793E0A093C2F646963743E0A093C6B65793E636F6D2E6170706C652E7072696E -% 742E50616765466F726D61742E504D566572746963616C5363616C696E673C2F -% 6B65793E0A093C646963743E0A09093C6B65793E636F6D2E6170706C652E7072 -% 696E742E7469636B65742E63726561746F723C2F6B65793E0A09093C73747269 -% 6E673E636F6D2E6170706C652E7072696E74696E676D616E616765723C2F7374 -% 72696E673E0A09093C6B65793E636F6D2E6170706C652E7072696E742E746963 -% 6B65742E6974656D41727261793C2F6B65793E0A09093C61727261793E0A0909 -% 093C646963743E0A090909093C6B65793E636F6D2E6170706C652E7072696E74 -% 2E50616765466F726D61742E504D566572746963616C5363616C696E673C2F6B -% 65793E0A090909093C7265616C3E313C2F7265616C3E0A090909093C6B65793E -% 636F6D2E6170706C652E7072696E742E7469636B65742E636C69656E743C2F6B -% 65793E0A090909093C737472696E673E636F6D2E6170706C652E7072696E7469 -% 6E676D616E616765723C2F737472696E673E0A090909093C6B65793E636F6D2E -% 6170706C652E7072696E742E7469636B65742E6D6F64446174653C2F6B65793E -% 0A090909093C646174653E323030362D31302D30395432303A30333A33365A3C -% 2F646174653E0A090909093C6B65793E636F6D2E6170706C652E7072696E742E -% 7469636B65742E7374617465466C61673C2F6B65793E0A090909093C696E7465 -% 6765723E303C2F696E74656765723E0A0909093C2F646963743E0A09093C2F61 -% 727261793E0A093C2F646963743E0A093C6B65793E636F6D2E6170706C652E70 -% 72696E742E7375625469636B65742E70617065725F696E666F5F7469636B6574 -% 3C2F6B65793E0A093C646963743E0A09093C6B65793E636F6D2E6170706C652E -% 7072696E742E50616765466F726D61742E504D41646A75737465645061676552 -% 6563743C2F6B65793E0A09093C646963743E0A0909093C6B65793E636F6D2E61 -% 70706C652E7072696E742E7469636B65742E63726561746F723C2F6B65793E0A -% 0909093C737472696E673E636F6D2E6170706C652E7072696E74696E676D616E -% 616765723C2F737472696E673E0A0909093C6B65793E636F6D2E6170706C652E -% 7072696E742E7469636B65742E6974656D41727261793C2F6B65793E0A090909 -% 3C61727261793E0A090909093C646963743E0A09090909093C6B65793E636F6D -% 2E6170706C652E7072696E742E50616765466F726D61742E504D41646A757374 -% 656450616765526563743C2F6B65793E0A09090909093C61727261793E0A0909 -% 090909093C7265616C3E302E303C2F7265616C3E0A0909090909093C7265616C -% 3E302E303C2F7265616C3E0A0909090909093C7265616C3E3738333C2F726561 -% 6C3E0A0909090909093C7265616C3E3535393C2F7265616C3E0A09090909093C -% 2F61727261793E0A09090909093C6B65793E636F6D2E6170706C652E7072696E -% 742E7469636B65742E636C69656E743C2F6B65793E0A09090909093C73747269 -% 6E673E636F6D2E6170706C652E7072696E74696E676D616E616765723C2F7374 -% 72696E673E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E -% 7469636B65742E6D6F64446174653C2F6B65793E0A09090909093C646174653E -% 323030362D31302D30395432303A30333A33365A3C2F646174653E0A09090909 -% 093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E737461 -% 7465466C61673C2F6B65793E0A09090909093C696E74656765723E303C2F696E -% 74656765723E0A090909093C2F646963743E0A0909093C2F61727261793E0A09 -% 093C2F646963743E0A09093C6B65793E636F6D2E6170706C652E7072696E742E -% 50616765466F726D61742E504D41646A75737465645061706572526563743C2F -% 6B65793E0A09093C646963743E0A0909093C6B65793E636F6D2E6170706C652E -% 7072696E742E7469636B65742E63726561746F723C2F6B65793E0A0909093C73 -% 7472696E673E636F6D2E6170706C652E7072696E74696E676D616E616765723C -% 2F737472696E673E0A0909093C6B65793E636F6D2E6170706C652E7072696E74 -% 2E7469636B65742E6974656D41727261793C2F6B65793E0A0909093C61727261 -% 793E0A090909093C646963743E0A09090909093C6B65793E636F6D2E6170706C -% 652E7072696E742E50616765466F726D61742E504D41646A7573746564506170 -% 6572526563743C2F6B65793E0A09090909093C61727261793E0A090909090909 -% 3C7265616C3E2D31383C2F7265616C3E0A0909090909093C7265616C3E2D3138 -% 3C2F7265616C3E0A0909090909093C7265616C3E3832343C2F7265616C3E0A09 -% 09090909093C7265616C3E3537373C2F7265616C3E0A09090909093C2F617272 -% 61793E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E7469 -% 636B65742E636C69656E743C2F6B65793E0A09090909093C737472696E673E63 -% 6F6D2E6170706C652E7072696E74696E676D616E616765723C2F737472696E67 -% 3E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B -% 65742E6D6F64446174653C2F6B65793E0A09090909093C646174653E32303036 -% 2D31302D30395432303A30333A33365A3C2F646174653E0A09090909093C6B65 -% 793E636F6D2E6170706C652E7072696E742E7469636B65742E7374617465466C -% 61673C2F6B65793E0A09090909093C696E74656765723E303C2F696E74656765 -% 723E0A090909093C2F646963743E0A0909093C2F61727261793E0A09093C2F64 -% 6963743E0A09093C6B65793E636F6D2E6170706C652E7072696E742E50617065 -% 72496E666F2E504D50617065724E616D653C2F6B65793E0A09093C646963743E -% 0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E -% 63726561746F723C2F6B65793E0A0909093C737472696E673E636F6D2E617070 -% 6C652E7072696E742E706D2E506F73745363726970743C2F737472696E673E0A -% 0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E69 -% 74656D41727261793C2F6B65793E0A0909093C61727261793E0A090909093C64 -% 6963743E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E50 -% 61706572496E666F2E504D50617065724E616D653C2F6B65793E0A0909090909 -% 3C737472696E673E69736F2D61343C2F737472696E673E0A09090909093C6B65 -% 793E636F6D2E6170706C652E7072696E742E7469636B65742E636C69656E743C -% 2F6B65793E0A09090909093C737472696E673E636F6D2E6170706C652E707269 -% 6E742E706D2E506F73745363726970743C2F737472696E673E0A09090909093C -% 6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E6D6F644461 -% 74653C2F6B65793E0A09090909093C646174653E323030332D30372D30315431 -% 373A34393A33365A3C2F646174653E0A09090909093C6B65793E636F6D2E6170 -% 706C652E7072696E742E7469636B65742E7374617465466C61673C2F6B65793E -% 0A09090909093C696E74656765723E313C2F696E74656765723E0A090909093C -% 2F646963743E0A0909093C2F61727261793E0A09093C2F646963743E0A09093C -% 6B65793E636F6D2E6170706C652E7072696E742E5061706572496E666F2E504D -% 556E61646A757374656450616765526563743C2F6B65793E0A09093C64696374 -% 3E0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B6574 -% 2E63726561746F723C2F6B65793E0A0909093C737472696E673E636F6D2E6170 -% 706C652E7072696E742E706D2E506F73745363726970743C2F737472696E673E -% 0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E -% 6974656D41727261793C2F6B65793E0A0909093C61727261793E0A090909093C -% 646963743E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E -% 5061706572496E666F2E504D556E61646A757374656450616765526563743C2F -% 6B65793E0A09090909093C61727261793E0A0909090909093C7265616C3E302E -% 303C2F7265616C3E0A0909090909093C7265616C3E302E303C2F7265616C3E0A -% 0909090909093C7265616C3E3738333C2F7265616C3E0A0909090909093C7265 -% 616C3E3535393C2F7265616C3E0A09090909093C2F61727261793E0A09090909 -% 093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E636C69 -% 656E743C2F6B65793E0A09090909093C737472696E673E636F6D2E6170706C65 -% 2E7072696E74696E676D616E616765723C2F737472696E673E0A09090909093C -% 6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E6D6F644461 -% 74653C2F6B65793E0A09090909093C646174653E323030362D31302D30395432 -% 303A30333A33365A3C2F646174653E0A09090909093C6B65793E636F6D2E6170 -% 706C652E7072696E742E7469636B65742E7374617465466C61673C2F6B65793E -% 0A09090909093C696E74656765723E303C2F696E74656765723E0A090909093C -% 2F646963743E0A0909093C2F61727261793E0A09093C2F646963743E0A09093C -% 6B65793E636F6D2E6170706C652E7072696E742E5061706572496E666F2E504D -% 556E61646A75737465645061706572526563743C2F6B65793E0A09093C646963 -% 743E0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65 -% 742E63726561746F723C2F6B65793E0A0909093C737472696E673E636F6D2E61 -% 70706C652E7072696E742E706D2E506F73745363726970743C2F737472696E67 -% 3E0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B6574 -% 2E6974656D41727261793C2F6B65793E0A0909093C61727261793E0A09090909 -% 3C646963743E0A09090909093C6B65793E636F6D2E6170706C652E7072696E74 -% 2E5061706572496E666F2E504D556E61646A7573746564506170657252656374 -% 3C2F6B65793E0A09090909093C61727261793E0A0909090909093C7265616C3E -% 2D31383C2F7265616C3E0A0909090909093C7265616C3E2D31383C2F7265616C -% 3E0A0909090909093C7265616C3E3832343C2F7265616C3E0A0909090909093C -% 7265616C3E3537373C2F7265616C3E0A09090909093C2F61727261793E0A0909 -% 0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E63 -% 6C69656E743C2F6B65793E0A09090909093C737472696E673E636F6D2E617070 -% 6C652E7072696E74696E676D616E616765723C2F737472696E673E0A09090909 -% 093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E6D6F64 -% 446174653C2F6B65793E0A09090909093C646174653E323030362D31302D3039 -% 5432303A30333A33365A3C2F646174653E0A09090909093C6B65793E636F6D2E -% 6170706C652E7072696E742E7469636B65742E7374617465466C61673C2F6B65 -% 793E0A09090909093C696E74656765723E303C2F696E74656765723E0A090909 -% 093C2F646963743E0A0909093C2F61727261793E0A09093C2F646963743E0A09 -% 093C6B65793E636F6D2E6170706C652E7072696E742E5061706572496E666F2E -% 7070642E504D50617065724E616D653C2F6B65793E0A09093C646963743E0A09 -% 09093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E6372 -% 6561746F723C2F6B65793E0A0909093C737472696E673E636F6D2E6170706C65 -% 2E7072696E742E706D2E506F73745363726970743C2F737472696E673E0A0909 -% 093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E697465 -% 6D41727261793C2F6B65793E0A0909093C61727261793E0A090909093C646963 -% 743E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E506170 -% 6572496E666F2E7070642E504D50617065724E616D653C2F6B65793E0A090909 -% 09093C737472696E673E41343C2F737472696E673E0A09090909093C6B65793E -% 636F6D2E6170706C652E7072696E742E7469636B65742E636C69656E743C2F6B -% 65793E0A09090909093C737472696E673E636F6D2E6170706C652E7072696E74 -% 2E706D2E506F73745363726970743C2F737472696E673E0A09090909093C6B65 -% 793E636F6D2E6170706C652E7072696E742E7469636B65742E6D6F6444617465 -% 3C2F6B65793E0A09090909093C646174653E323030332D30372D30315431373A -% 34393A33365A3C2F646174653E0A09090909093C6B65793E636F6D2E6170706C -% 652E7072696E742E7469636B65742E7374617465466C61673C2F6B65793E0A09 -% 090909093C696E74656765723E313C2F696E74656765723E0A090909093C2F64 -% 6963743E0A0909093C2F61727261793E0A09093C2F646963743E0A09093C6B65 -% 793E636F6D2E6170706C652E7072696E742E7469636B65742E41504956657273 -% 696F6E3C2F6B65793E0A09093C737472696E673E30302E32303C2F737472696E -% 673E0A09093C6B65793E636F6D2E6170706C652E7072696E742E7469636B6574 -% 2E707269766174654C6F636B3C2F6B65793E0A09093C66616C73652F3E0A0909 -% 3C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E74797065 -% 3C2F6B65793E0A09093C737472696E673E636F6D2E6170706C652E7072696E74 -% 2E5061706572496E666F5469636B65743C2F737472696E673E0A093C2F646963 -% 743E0A093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E -% 41504956657273696F6E3C2F6B65793E0A093C737472696E673E30302E32303C -% 2F737472696E673E0A093C6B65793E636F6D2E6170706C652E7072696E742E74 -% 69636B65742E707269766174654C6F636B3C2F6B65793E0A093C66616C73652F -% 3E0A093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E74 -% 7970653C2F6B65793E0A093C737472696E673E636F6D2E6170706C652E707269 -% 6E742E50616765466F726D61745469636B65743C2F737472696E673E0A3C2F64 -% 6963743E0A3C2F706C6973743E0A3842494D03E9000000000078000300000048 -% 004800000000030F022FFFEEFFEE033802410367057B03E00002000000480048 -% 0000000002D802280001000000640000000100030303000000017FFF00010001 -% 0000000000000000000000006808001901900000000000200000000000000000 -% 0000000000000000000000000000000000003842494D03ED0000000000100048 -% 00000001000200480000000100023842494D042600000000000E000000000000 -% 000000003F8000003842494D040D0000000000040000001E3842494D04190000 -% 000000040000001E3842494D03F3000000000009000000000000000001003842 -% 494D040A00000000000100003842494D271000000000000A0001000000000000 -% 00023842494D03F5000000000048002F66660001006C66660006000000000001 -% 002F6666000100A1999A0006000000000001003200000001005A000000060000 -% 00000001003500000001002D000000060000000000013842494D03F800000000 -% 00700000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800000000 -% FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800000000FFFFFFFF -% FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800000000FFFFFFFFFFFFFFFF -% FFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800003842494D04080000000000100000 -% 00010000024000000240000000003842494D041E000000000004000000003842 -% 494D041A00000000036300000006000000000000000000000183000001560000 -% 001700620072006100760065002D0067006E0075002D0077006F0072006C0064 -% 002D006C006F0067006F002E0032003500000001000000000000000000000000 -% 0000000000000001000000000000000000000156000001830000000000000000 -% 0000000000000000010000000000000000000000000000000000000010000000 -% 010000000000006E756C6C0000000200000006626F756E64734F626A63000000 -% 01000000000000526374310000000400000000546F70206C6F6E670000000000 -% 0000004C6566746C6F6E67000000000000000042746F6D6C6F6E670000018300 -% 000000526768746C6F6E670000015600000006736C69636573566C4C73000000 -% 014F626A6300000001000000000005736C6963650000001200000007736C6963 -% 6549446C6F6E67000000000000000767726F757049446C6F6E67000000000000 -% 00066F726967696E656E756D0000000C45536C6963654F726967696E0000000D -% 6175746F47656E6572617465640000000054797065656E756D0000000A45536C -% 6963655479706500000000496D672000000006626F756E64734F626A63000000 -% 01000000000000526374310000000400000000546F70206C6F6E670000000000 -% 0000004C6566746C6F6E67000000000000000042746F6D6C6F6E670000018300 -% 000000526768746C6F6E67000001560000000375726C54455854000000010000 -% 000000006E756C6C54455854000000010000000000004D736765544558540000 -% 0001000000000006616C74546167544558540000000100000000000E63656C6C -% 54657874497348544D4C626F6F6C010000000863656C6C546578745445585400 -% 000001000000000009686F727A416C69676E656E756D0000000F45536C696365 -% 486F727A416C69676E0000000764656661756C740000000976657274416C6967 -% 6E656E756D0000000F45536C69636556657274416C69676E0000000764656661 -% 756C740000000B6267436F6C6F7254797065656E756D0000001145536C696365 -% 4247436F6C6F7254797065000000004E6F6E6500000009746F704F7574736574 -% 6C6F6E67000000000000000A6C6566744F75747365746C6F6E67000000000000 -% 000C626F74746F6D4F75747365746C6F6E67000000000000000B72696768744F -% 75747365746C6F6E6700000000003842494D041100000000000101003842494D -% 0414000000000004000000013842494D040C0000000011340000000100000071 -% 00000080000001540000AA000000111800180001FFD8FFE000104A4649460001 -% 0201004800480000FFED000C41646F62655F434D0002FFEE000E41646F626500 -% 648000000001FFDB0084000C08080809080C09090C110B0A0B11150F0C0C0F15 -% 18131315131318110C0C0C0C0C0C110C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C -% 0C0C0C0C0C0C0C0C0C0C0C010D0B0B0D0E0D100E0E10140E0E0E14140E0E0E0E -% 14110C0C0C0C0C11110C0C0C0C0C0C110C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C -% 0C0C0C0C0C0C0C0C0C0C0C0CFFC00011080080007103012200021101031101FF -% DD00040008FFC4013F0000010501010101010100000000000000030001020405 -% 060708090A0B0100010501010101010100000000000000010002030405060708 -% 090A0B1000010401030204020507060805030C33010002110304211231054151 -% 611322718132061491A1B14223241552C16233347282D14307259253F0E1F163 -% 733516A2B283264493546445C2A3743617D255E265F2B384C3D375E3F3462794 -% A485B495C4D4E4F4A5B5C5D5E5F55666768696A6B6C6D6E6F637475767778797 -% A7B7C7D7E7F71100020201020404030405060707060535010002110321311204 -% 4151617122130532819114A1B14223C152D1F0332462E1728292435315637334 -% F1250616A2B283072635C2D2449354A317644555367465E2F2B384C3D375E3F3 -% 4694A485B495C4D4E4F4A5B5C5D5E5F55666768696A6B6C6D6E6F62737475767 -% 778797A7B7C7FFDA000C03010002110311003F00F5549249252952EA5D6303A6 -% B01C9B3F48E04D74B06EB1D1FBACFDCFCDF56CD94FEFD8A9F5AEB8EC4B1B8182 -% CF5BA85A040896B377D17387B7D4B1DB7D94FF00D72EF4AA50E93F57C54F766F -% 513F69CDB4EE739E43849FECB5AE733E87B7F435FD0A2AAAA494969FAC06FD6A -% C0CA73791ED64F9E82C72B9566DF63B6FD8EE66B05CF35868F3FE777BBFB0C56 -% 80F979240009294275911E09D2492535322DEA35585D5555E4526206E2C7B74F -% 76ED2C6DBEEFDDF4FF00E2FF00C22A77F51EAFF46BC7C7A9C7F3ADB6C81F9DF4 -% 7D0ABF35BFBEB5D2494E5E066E7DAE8BDF8CFD09D94EEDC60EDFCF73BF3BF796 -% 931E1ED04692260F2151EA1D1E9CB3EAD4EFB3E50D45AD120FFC755F46DFFCF9 -% FCB553A7F53BC669E9FD440A731809601F42D1AFE998FF00F09BA3D9FF00A53D -% 8929DB49327494A49249253FFFD0F55599D77ABFECDA18DA5A2CCCC825B8EC3A -% 8111BEE7810E732ADECF637F9DB5F553FA3F53D5669AE4F12D6F53EB36752B3D -% F57A831F10088D8D163FD4DDB7E8B696DD97F43E9E4D74FF00A2494E8740E91E -% 8B1F999536655F2E7BDC649DC439DBB46B7DDB7F37FF003C7A55ADBF34CC6ED6 -% 86F8052494A49258791F59EB7DBF67E9349EA16FFA469DB5027DA3F4B0EF57FA -% D5B7D1FF0086494EE24B370733A8D8FDB96CA5A4CC8ADD3B6086EDE5DB9FB9DF -% C853EA3D6FA7F4EDADBDE4DCF12CA2B05D6113B6767E637F9566C494DF4967E2 -% F59AB206EFB3DF5375F73DA3B6A67D373DCAF32C658DDCC70703DC24A64B3BAD -% F4A6F52C4DAC8665D277E2DA646D7FEEB8B7FC15BFCDDBFF006E7F395D6B4524 -% 94E3F42EA8FCEA032F9664D07D3B6B321DB99ED79B3E97FEAE5B0B987B8627D6 -% 6CCF4CED65B48B1FB7B13E9B777F9C3D477F5D74CD208D381A7DDA24A5D24924 -% 94FF00FFD1F547025A434C3A343E6B95FAAAE68C4A75DA7DF519D00B1E2835EF -% 67B7E936A733DDF9F52EAD60E574BC9C0CBBB3701A6EC6CA9765E20FA41C4973 -% EDA3F7F7B8EED9F4FD4FE6FE9FE8D29DB37541BBDCE01BC1713027E2A166661D -% 4D2FB6FAEB6375739CF6803E24959B5E4D790C635AE9DA76D8DB25C5A63F384B -% 1CFB2BDAA4DE89D2FD3F57228640F77BF489ECFF00A2D494E65D9197F59AF763 -% 636EA3A55662C79106D3CFBDA47B5BFB98EFFF00D0BFFB8AB6B1FA562E352296 -% B4069FCD048DC63DDB8B8EF7EEFCFF007FFE05FA34B1EE6399E874F6B1B4D6ED -% 81EC1EC6E81EE867B3F7FF007D068E9F6FDAB7643DD786C1208105C3875BEEF7 -% 7FC055FA5F47F9CFE752009DBF15A6755E2DD6D0DADB0D6C37521ADD00D1C36B -% 581BB550B6BC1392F71654ECD11BC020DAD6E9B7D92EB7DCDFDDF52C7AD0B1AD -% 9DE40DEE01AEE4CB44BB6FE6AAB8A5D91634E562D7518B1ECF7377B06E6ED63D -% A3DDEA58D77AB76DFD1D7FCDFBD2063746FE8A24F4AFF0BD281D958ED690F2EA -% F7E9B4CC03EDFD1EDFF02E74B37D5F4FDFFA556A9C864876E0D6C7B23BE9FB8D -% FA5FF93FF068EDA61CE6C35CC70F708E67F7964BB1FD5C9B7EC47EC81AFF004D -% A1DB832C786C96FA2F1ED6FF0053FEDBB13B849BAD695C7FBDE9E8EC5993454D -% 9BAC6543C5CE0047C5D0B3737EB3F4BC7696D160CCC8FCCA68F749FE5DAD9AEB -% FF00ABFDCAEC556DC9739FF63EA558AED322B9FE69F103D967B7F44DF67A9EE6 -% 7FD6958C7C66B59EC6358ED443181A07F298FF00D35D637DDFA3F4DBFF006D26 -% AE73B031B2ADCD7E56701F6ACA2CB1F5813B6B043AA6ECFCDF5ACA29AAADDF4F -% 1E9CABAEFF0008BA7ADBB5B1E249FBC9720518B5B786901C4971792E738E8DDC -% F73FDDEEDBB7FE2995D7FCD2B49294924924A7FFD2F55492492520BB131AD70B -% 2CAC1B1BC5834788F0B1BB5EAB64E48345C08FB5381DAFC6ADA1E040DCEA4EEF -% DE6BBDCFB91731D9EF70A30C32ADD05F91619869277368A5BEEB2EF6FF0085F4 -% AAFD27F86F7D4876E217EFB3A85E3ECC047A0D3B6B826375EF9DF91EDF66C7FE -% 87FE0AD40D9D00DFAA083DE97C66E558FAEDC9BAB68FA5563E39961046DF7DAF -% DAFC86B5AEF66DAA867F215AB9C5AD0448931204F6EEA149AC173995892434B9 -% A002E81B771FCD4AE739DB1F503635AE2486380D60B750EDAD7FF9E8C850D100 -% 820EBDDCCBD96BAC739D7FA75D624B18DFFA565B61FF00A0C594EEB1496EFA1B -% 6B9F4BA77BB6B5AE274DB66DDCEDBFC9DAB6ADE9F8F98D7D598CB5C09DE2A712 -% CD3F976D2FD963777F2D3E1BF16B2DAF02B365434229D82961F377B773FF007F -% 6FA8A200750C03181F30D7C3F97A9CEFB45D9353AABDE0525A1F153C8D9DB67E -% 8EB2E66DFA75D9BFF46B55D9CEAF2EBA2DA5EFA5EC97646D90D33B5A5E59F98F -% 9FFAC7FC56FF0042A757EA34E2B4D2D6B6DC8B012E635DED6B4FB77E44FD062A -% 755DD66DC57D8D76350C8F4BD67B9CD718FCEADCF6BAB73754E8896E02E88978 -% 70F8BB39189899B43314B89A5B04110E0E05AEDA196582CF7B7F9CDECFD325D2 -% 31DD46132AB2CF55ED2438F8104FE8F977F37F450BA6613DB41BAFBBD7C8BD8C -% 6DEE6BB4696496D34D94FA7FA3A9F659EFDBEA588F45D915BC372FD30EB6368A -% C1FA41BFA5DEE27DDF454B44824EFD596EA8550D9B8924926AE524924929FFD3 -% F554C74D53A8BDA1ED2D3C1E47924A44CB1FF69B1AF2D02016346A4B40D6C7FB -% 7DBB9FEC6FFC5A0BB3706CCC6E31BEB75C06E65421CE691FE11DF4B67F21567E -% 0DD915BDF97A5971F731A4B9AD00FE8AA6CFEEB7F9DFF4967A8957F64E9EE656 -% DDAD2E92F7C06807F96EFDE530803B1B95550FE2D696522C513ADBA2DC7A8012 -% DDC7C5DA93F1944F6B60683B008745ECB9BB9A6478F8A8B1EF0FF4DD5B84925D -% 669B493FD53BFF00CE6A866640D166870571446FD833B68A6D20D8D0E2D9027C -% 0FD26FF55CA9D580FC2A5CDC67B4971DCEB2FDC63C5DB1AE6D7F47F36BF415C6 -% 58C2D1E9CB9BC0238FF3BF393DAF656C2EB012D04030D2EE4EDFA2D0EFFCC134 -% 709D579DABBBCE3F0F2B3DD7065FEB536C7AD94DFD1B1DE9977A7563D156F73E -% A6EFFD25B65D67A9FF0017B158FB0E261DB4D977A7EA39BB2AF6973811FE8F76 -% E72D2A3AB74FBC5A59688A1CE6DA4F0DDBF9CE7FF36D67F2B77FE09BD1DD451B -% 8DA58DDF1F4C8D614D0C911A01A3164C529697FF0072D2C3ADF4836DAF739D61 -% 009768E33A37467B559C8B1B5D4D6BD9BD847B817098FA3A6FFA7F4BF7D1DA1A -% 00DBC762B23AC6506D4D0F6C5AED6AD636C3873FBDBFD9FA2FF0B67E8D899932 -% 13B685118184753C44BAB8F732FA596B0CB5C3BE864687FE9222CCFABC727F67 -% 4640877A961699E5AE77A9C7E66C73FD2DBFF06B4D0F3661B6AA49249253FFD4 -% F5550B63D27CC81B4EA2678EDB21FF00E6A9A6735AE696B84B5C2083C1052521 -% 756DB7D37133B007026473DF669EE5917B76BDF6BEB796D7616D4C716D758FE5 -% 0FCEB372D2B32DEC6D0D6D42CB6DD1E1AE68637696B6EF7D858E77A5BBF32BFC -% C51FD9D5BB25F9169F56C71258481B5A3B358DFDEDBF9EA6C79044907A7460CB -% 8CCA363525AACCBCD758DAEB6358D03DDB89E4FEEED5A34D8F6B0BAF78D3BC6D -% 1F892A4DA76C00040F1D4A1370DDB8BAD7FAAE719F701007EEB1A94A5097411F -% CD8F1C32C28EFE1D190BECB2C0DA9AD2CFCE7870D3FAAD83B9584014EC3B8B8B -% 8766E908A663DC62398D1472AD299E065AF10D5AD7D599BB6D26B7D446A2E930 -% 7F77D9FCE31DFCBFA1FF000BBFF461AB1B230B1B2AE786E55AE3BEBC7AC7A758 -% DAD8AE9AD8E758DDCE7FB9F77E7FFDB6AF36D63EB0FACEF69E0B759F8154F32E -% C8C70F758F636A26597381DACFE45CDDDF4BFD1DDFF5BFD17E8FD5611C3A81AA -% FB02CD5F7F1497DD15C5A62752C64C9FE40DB0EFF5FA0B16D75965B664871391 -% EB86D0D0FDD5D15967A5F687532DFD2BB75DE9FF00C27E8FFD221E5E5B9DF67B -% CD576CB5F1481A3AD77954E76F6334FF00468DD3F14D4CB2ECD0319D63CD950B -% 1BC47E84DB65BA535DB6BEFDB8D5DBF99FE0FF009DF4C63F9AE4C71E33648E9A -% 7F55D2E867761B9ED9F49D63853BB9D8C8A013FD6755B968A0E1D031F16AA75F -% 6B759E64FB9DFF0049193E5B9F3648EC1492492097FFD5F5549249252175465C -% 19A171DED9D4077E77B7F95FF56B2197E4B6E353AD3894D0F1E8D75ED797B662 -% E65CCDB635B56EFE6FD3F4ED62DB7B43DA5A6402224120EBE0E6C39AB2BA80B3 -% 1EA631F63D9481FA7CA76E76CAC37F4AF73EBDBFA6DAC6ECBACFD1D7FCF7E93F -% 997B67777F4639020831BBFC1B14F53ADD98EC176E7DD24B0B58E03601BF758E -% 70D9FF0007BD8EFF0047FBEACE564371A875EFFA0C8DE7B35A486BAC77EED75B -% 7F4967F2163538169F4FA8623ADB5EC8153B29C5E367D0F5D94511BDDE9BECF4 -% BDCCFE73E82D5C7C877A7B0EEB6C61DAE716ECDC47EEB53C4254B84C0AE22906 -% 454FAEBBEBB05955801ACD7EF0F0ED5AE6B99BB7336AA7D40D97B4B585D536A9 -% 2E7176D0EFE4EC66EB1EADDEF2C754E86EA483B84BBE8B9D0CD5BFBAA961F56F -% B56406331DCEC7B1FB29BC35DB5C035EFB2F2EDA6AF437B19456EF57D4B2CFF0 -% 7E9FA6FB146601DB50A944CAC0F36A60D79877B8D8E73C18697CB8347FC1876D -% 5A7EADE1BE98607088758490493FBAC60F77F9EC44BD8E6B41A9BE32D02499FE -% DD6D6AA96E6D58A7D323ED196D689AEB074DDF47D5B0EF652D77F2FF00EB75A9 -% 8C8486C3CBAB008CE32278BFB12E174F38F90FCAB6C375D635B5EE7B40735838 -% ADAE6FE6EEF7BFFE11553D359665D7451FA3E9F4B8BDD8EC02BAA49F58C56D1F -% A675B92EDF63FF0099F4FF0043E9FE96E49D5E5E639A2D787020C5357B6B0276 -% D85EF796D96ECFE6FE87FD67F48B4B1B1ABC6ABD3AC47771F13F3DCA23103CFB -% 766789BD3A2649249357292492494FFFD6F554924925290EEA59706EED0B0EE6 -% 38685AE1F9CD3FF47F96CFD1BFF4688924A73FA937A836B73B1ACFA65A37113E -% 9025AC7BEBAEB0DF53FD2FE9ACFF00C013E167E2DEC0DA6C6BAD76E06C6B086B -% 9ECF6DBDBE96EFF07BD5F42BB1E9BD8596B0381F9107F79AF6FB98EFE53521D7 -% B1457F22E4E7E46654FF00758DA5BCBDF638C081BBD9B5BB76FB7E9D8F546BEA -% B936D95DD48BEE6BA41706BEBADC08D3D371FF00C8FBD6FB7A7630209DEF8FA3 -% EA3DCF23FAAFB0B9FDFF0079577742C7B06CBEFC8BABEF5BAD2D0E3FBD61A7D2 -% 7D9FBBB1EFF4BFE0D33835DD8C62FE56E659D4F305753ADB61ECD59435E1BBDC -% DFA2EC87B9DEB3F1B77D3F47F4977FC5AD46306535DE9D64B490E36BC1ADAF71 -% 078AA1B6BABAFD9FF1BFE9559C5C0C2C36918D4B6A9E481A9FEB3CFB9CAC27C6 -% E3B15E23A51D50D18B5504B9A25EE0017F7DADFA15B7F72AAF77E8EB6A324924 -% B94924924A524924929FFFD93842494D04210000000000790000000101000000 -% 1800410064006F00620065002000500068006F0074006F00730068006F007000 -% 200045006C0065006D0065006E007400730000001C00410064006F0062006500 -% 2000500068006F0074006F00730068006F007000200045006C0065006D006500 -% 6E0074007300200032002E003000000001003842494D042200000000012E4D4D -% 002A000000080007011200030000000100010000011A00050000000100000062 -% 011B0005000000010000006A012800030000000100020000013100020000001D -% 0000007201320002000000140000008F8769000400000001000000A4000000D0 -% 0000004800000001000000480000000141646F62652050686F746F73686F7020 -% 456C656D656E747320322E3000323030363A31303A30392032323A30393A3238 -% 00000003A001000300000001FFFF0000A00200040000000100000156A0030004 -% 00000001000001830000000000000006010300030000000100060000011A0005 -% 000000010000011E011B00050000000100000126012800030000000100020000 -% 02010004000000010000012E0202000400000001000000000000000000000048 -% 0000000100000048000000013842494D03FD0000000000070000000000000000 -%EndPhotoshop -%begin_xml_code -/pdfmark where {pop true} {false} ifelse -/currentdistillerparams where {pop currentdistillerparams -/CoreDistVersion get 5000 ge } {false} ifelse -and not {userdict /pdfmark /cleartomark load put} if -[/NamespacePush pdfmark -[/_objdef {photoshop_metadata_stream} /type /stream /OBJ pdfmark -/MetadataString 5038 string def % exact length of metadata -/TempString 100 string def -/ConsumeMetadata { -currentfile TempString readline pop pop -currentfile MetadataString readstring pop pop -} bind def -ConsumeMetadata -%begin_xml_packet: 5038 -<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?> +%!PS-Adobe-3.0 EPSF-3.0
%%Title: brave-gnu-world-logo.25.eps
%%CreationDate: 09.10.2006 22:09 Uhr
%%BoundingBox: 0 0 342 387
%%HiResBoundingBox: 0 0 342 387
%%SuppressDotGainCompensation
%%EndComments
%%BeginProlog
%%EndProlog
%%BeginSetup
%%EndSetup
%ImageData: 342 387 8 3 0 1 3 "beginimage"
%BeginPhotoshop: 13952
% 3842494D0425000000000010000000000000000000000000000000003842494D
% 03EA000000001DA63C3F786D6C2076657273696F6E3D22312E302220656E636F
% 64696E673D225554462D38223F3E0A3C21444F435459504520706C6973742050
% 55424C494320222D2F2F4170706C6520436F6D70757465722F2F44544420504C
% 49535420312E302F2F454E222022687474703A2F2F7777772E6170706C652E63
% 6F6D2F445444732F50726F70657274794C6973742D312E302E647464223E0A3C
% 706C6973742076657273696F6E3D22312E30223E0A3C646963743E0A093C6B65
% 793E636F6D2E6170706C652E7072696E742E50616765466F726D61742E504D48
% 6F72697A6F6E74616C5265733C2F6B65793E0A093C646963743E0A09093C6B65
% 793E636F6D2E6170706C652E7072696E742E7469636B65742E63726561746F72
% 3C2F6B65793E0A09093C737472696E673E636F6D2E6170706C652E7072696E74
% 696E676D616E616765723C2F737472696E673E0A09093C6B65793E636F6D2E61
% 70706C652E7072696E742E7469636B65742E6974656D41727261793C2F6B6579
% 3E0A09093C61727261793E0A0909093C646963743E0A090909093C6B65793E63
% 6F6D2E6170706C652E7072696E742E50616765466F726D61742E504D486F7269
% 7A6F6E74616C5265733C2F6B65793E0A090909093C7265616C3E37323C2F7265
% 616C3E0A090909093C6B65793E636F6D2E6170706C652E7072696E742E746963
% 6B65742E636C69656E743C2F6B65793E0A090909093C737472696E673E636F6D
% 2E6170706C652E7072696E74696E676D616E616765723C2F737472696E673E0A
% 090909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E
% 6D6F64446174653C2F6B65793E0A090909093C646174653E323030362D31302D
% 30395432303A30333A33365A3C2F646174653E0A090909093C6B65793E636F6D
% 2E6170706C652E7072696E742E7469636B65742E7374617465466C61673C2F6B
% 65793E0A090909093C696E74656765723E303C2F696E74656765723E0A090909
% 3C2F646963743E0A09093C2F61727261793E0A093C2F646963743E0A093C6B65
% 793E636F6D2E6170706C652E7072696E742E50616765466F726D61742E504D4F
% 7269656E746174696F6E3C2F6B65793E0A093C646963743E0A09093C6B65793E
% 636F6D2E6170706C652E7072696E742E7469636B65742E63726561746F723C2F
% 6B65793E0A09093C737472696E673E636F6D2E6170706C652E7072696E74696E
% 676D616E616765723C2F737472696E673E0A09093C6B65793E636F6D2E617070
% 6C652E7072696E742E7469636B65742E6974656D41727261793C2F6B65793E0A
% 09093C61727261793E0A0909093C646963743E0A090909093C6B65793E636F6D
% 2E6170706C652E7072696E742E50616765466F726D61742E504D4F7269656E74
% 6174696F6E3C2F6B65793E0A090909093C696E74656765723E313C2F696E7465
% 6765723E0A090909093C6B65793E636F6D2E6170706C652E7072696E742E7469
% 636B65742E636C69656E743C2F6B65793E0A090909093C737472696E673E636F
% 6D2E6170706C652E7072696E74696E676D616E616765723C2F737472696E673E
% 0A090909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B6574
% 2E6D6F64446174653C2F6B65793E0A090909093C646174653E323030362D3130
% 2D30395432303A30333A33365A3C2F646174653E0A090909093C6B65793E636F
% 6D2E6170706C652E7072696E742E7469636B65742E7374617465466C61673C2F
% 6B65793E0A090909093C696E74656765723E303C2F696E74656765723E0A0909
% 093C2F646963743E0A09093C2F61727261793E0A093C2F646963743E0A093C6B
% 65793E636F6D2E6170706C652E7072696E742E50616765466F726D61742E504D
% 5363616C696E673C2F6B65793E0A093C646963743E0A09093C6B65793E636F6D
% 2E6170706C652E7072696E742E7469636B65742E63726561746F723C2F6B6579
% 3E0A09093C737472696E673E636F6D2E6170706C652E7072696E74696E676D61
% 6E616765723C2F737472696E673E0A09093C6B65793E636F6D2E6170706C652E
% 7072696E742E7469636B65742E6974656D41727261793C2F6B65793E0A09093C
% 61727261793E0A0909093C646963743E0A090909093C6B65793E636F6D2E6170
% 706C652E7072696E742E50616765466F726D61742E504D5363616C696E673C2F
% 6B65793E0A090909093C7265616C3E313C2F7265616C3E0A090909093C6B6579
% 3E636F6D2E6170706C652E7072696E742E7469636B65742E636C69656E743C2F
% 6B65793E0A090909093C737472696E673E636F6D2E6170706C652E7072696E74
% 696E676D616E616765723C2F737472696E673E0A090909093C6B65793E636F6D
% 2E6170706C652E7072696E742E7469636B65742E6D6F64446174653C2F6B6579
% 3E0A090909093C646174653E323030362D31302D30395432303A30333A33365A
% 3C2F646174653E0A090909093C6B65793E636F6D2E6170706C652E7072696E74
% 2E7469636B65742E7374617465466C61673C2F6B65793E0A090909093C696E74
% 656765723E303C2F696E74656765723E0A0909093C2F646963743E0A09093C2F
% 61727261793E0A093C2F646963743E0A093C6B65793E636F6D2E6170706C652E
% 7072696E742E50616765466F726D61742E504D566572746963616C5265733C2F
% 6B65793E0A093C646963743E0A09093C6B65793E636F6D2E6170706C652E7072
% 696E742E7469636B65742E63726561746F723C2F6B65793E0A09093C73747269
% 6E673E636F6D2E6170706C652E7072696E74696E676D616E616765723C2F7374
% 72696E673E0A09093C6B65793E636F6D2E6170706C652E7072696E742E746963
% 6B65742E6974656D41727261793C2F6B65793E0A09093C61727261793E0A0909
% 093C646963743E0A090909093C6B65793E636F6D2E6170706C652E7072696E74
% 2E50616765466F726D61742E504D566572746963616C5265733C2F6B65793E0A
% 090909093C7265616C3E37323C2F7265616C3E0A090909093C6B65793E636F6D
% 2E6170706C652E7072696E742E7469636B65742E636C69656E743C2F6B65793E
% 0A090909093C737472696E673E636F6D2E6170706C652E7072696E74696E676D
% 616E616765723C2F737472696E673E0A090909093C6B65793E636F6D2E617070
% 6C652E7072696E742E7469636B65742E6D6F64446174653C2F6B65793E0A0909
% 09093C646174653E323030362D31302D30395432303A30333A33365A3C2F6461
% 74653E0A090909093C6B65793E636F6D2E6170706C652E7072696E742E746963
% 6B65742E7374617465466C61673C2F6B65793E0A090909093C696E7465676572
% 3E303C2F696E74656765723E0A0909093C2F646963743E0A09093C2F61727261
% 793E0A093C2F646963743E0A093C6B65793E636F6D2E6170706C652E7072696E
% 742E50616765466F726D61742E504D566572746963616C5363616C696E673C2F
% 6B65793E0A093C646963743E0A09093C6B65793E636F6D2E6170706C652E7072
% 696E742E7469636B65742E63726561746F723C2F6B65793E0A09093C73747269
% 6E673E636F6D2E6170706C652E7072696E74696E676D616E616765723C2F7374
% 72696E673E0A09093C6B65793E636F6D2E6170706C652E7072696E742E746963
% 6B65742E6974656D41727261793C2F6B65793E0A09093C61727261793E0A0909
% 093C646963743E0A090909093C6B65793E636F6D2E6170706C652E7072696E74
% 2E50616765466F726D61742E504D566572746963616C5363616C696E673C2F6B
% 65793E0A090909093C7265616C3E313C2F7265616C3E0A090909093C6B65793E
% 636F6D2E6170706C652E7072696E742E7469636B65742E636C69656E743C2F6B
% 65793E0A090909093C737472696E673E636F6D2E6170706C652E7072696E7469
% 6E676D616E616765723C2F737472696E673E0A090909093C6B65793E636F6D2E
% 6170706C652E7072696E742E7469636B65742E6D6F64446174653C2F6B65793E
% 0A090909093C646174653E323030362D31302D30395432303A30333A33365A3C
% 2F646174653E0A090909093C6B65793E636F6D2E6170706C652E7072696E742E
% 7469636B65742E7374617465466C61673C2F6B65793E0A090909093C696E7465
% 6765723E303C2F696E74656765723E0A0909093C2F646963743E0A09093C2F61
% 727261793E0A093C2F646963743E0A093C6B65793E636F6D2E6170706C652E70
% 72696E742E7375625469636B65742E70617065725F696E666F5F7469636B6574
% 3C2F6B65793E0A093C646963743E0A09093C6B65793E636F6D2E6170706C652E
% 7072696E742E50616765466F726D61742E504D41646A75737465645061676552
% 6563743C2F6B65793E0A09093C646963743E0A0909093C6B65793E636F6D2E61
% 70706C652E7072696E742E7469636B65742E63726561746F723C2F6B65793E0A
% 0909093C737472696E673E636F6D2E6170706C652E7072696E74696E676D616E
% 616765723C2F737472696E673E0A0909093C6B65793E636F6D2E6170706C652E
% 7072696E742E7469636B65742E6974656D41727261793C2F6B65793E0A090909
% 3C61727261793E0A090909093C646963743E0A09090909093C6B65793E636F6D
% 2E6170706C652E7072696E742E50616765466F726D61742E504D41646A757374
% 656450616765526563743C2F6B65793E0A09090909093C61727261793E0A0909
% 090909093C7265616C3E302E303C2F7265616C3E0A0909090909093C7265616C
% 3E302E303C2F7265616C3E0A0909090909093C7265616C3E3738333C2F726561
% 6C3E0A0909090909093C7265616C3E3535393C2F7265616C3E0A09090909093C
% 2F61727261793E0A09090909093C6B65793E636F6D2E6170706C652E7072696E
% 742E7469636B65742E636C69656E743C2F6B65793E0A09090909093C73747269
% 6E673E636F6D2E6170706C652E7072696E74696E676D616E616765723C2F7374
% 72696E673E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E
% 7469636B65742E6D6F64446174653C2F6B65793E0A09090909093C646174653E
% 323030362D31302D30395432303A30333A33365A3C2F646174653E0A09090909
% 093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E737461
% 7465466C61673C2F6B65793E0A09090909093C696E74656765723E303C2F696E
% 74656765723E0A090909093C2F646963743E0A0909093C2F61727261793E0A09
% 093C2F646963743E0A09093C6B65793E636F6D2E6170706C652E7072696E742E
% 50616765466F726D61742E504D41646A75737465645061706572526563743C2F
% 6B65793E0A09093C646963743E0A0909093C6B65793E636F6D2E6170706C652E
% 7072696E742E7469636B65742E63726561746F723C2F6B65793E0A0909093C73
% 7472696E673E636F6D2E6170706C652E7072696E74696E676D616E616765723C
% 2F737472696E673E0A0909093C6B65793E636F6D2E6170706C652E7072696E74
% 2E7469636B65742E6974656D41727261793C2F6B65793E0A0909093C61727261
% 793E0A090909093C646963743E0A09090909093C6B65793E636F6D2E6170706C
% 652E7072696E742E50616765466F726D61742E504D41646A7573746564506170
% 6572526563743C2F6B65793E0A09090909093C61727261793E0A090909090909
% 3C7265616C3E2D31383C2F7265616C3E0A0909090909093C7265616C3E2D3138
% 3C2F7265616C3E0A0909090909093C7265616C3E3832343C2F7265616C3E0A09
% 09090909093C7265616C3E3537373C2F7265616C3E0A09090909093C2F617272
% 61793E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E7469
% 636B65742E636C69656E743C2F6B65793E0A09090909093C737472696E673E63
% 6F6D2E6170706C652E7072696E74696E676D616E616765723C2F737472696E67
% 3E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B
% 65742E6D6F64446174653C2F6B65793E0A09090909093C646174653E32303036
% 2D31302D30395432303A30333A33365A3C2F646174653E0A09090909093C6B65
% 793E636F6D2E6170706C652E7072696E742E7469636B65742E7374617465466C
% 61673C2F6B65793E0A09090909093C696E74656765723E303C2F696E74656765
% 723E0A090909093C2F646963743E0A0909093C2F61727261793E0A09093C2F64
% 6963743E0A09093C6B65793E636F6D2E6170706C652E7072696E742E50617065
% 72496E666F2E504D50617065724E616D653C2F6B65793E0A09093C646963743E
% 0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E
% 63726561746F723C2F6B65793E0A0909093C737472696E673E636F6D2E617070
% 6C652E7072696E742E706D2E506F73745363726970743C2F737472696E673E0A
% 0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E69
% 74656D41727261793C2F6B65793E0A0909093C61727261793E0A090909093C64
% 6963743E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E50
% 61706572496E666F2E504D50617065724E616D653C2F6B65793E0A0909090909
% 3C737472696E673E69736F2D61343C2F737472696E673E0A09090909093C6B65
% 793E636F6D2E6170706C652E7072696E742E7469636B65742E636C69656E743C
% 2F6B65793E0A09090909093C737472696E673E636F6D2E6170706C652E707269
% 6E742E706D2E506F73745363726970743C2F737472696E673E0A09090909093C
% 6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E6D6F644461
% 74653C2F6B65793E0A09090909093C646174653E323030332D30372D30315431
% 373A34393A33365A3C2F646174653E0A09090909093C6B65793E636F6D2E6170
% 706C652E7072696E742E7469636B65742E7374617465466C61673C2F6B65793E
% 0A09090909093C696E74656765723E313C2F696E74656765723E0A090909093C
% 2F646963743E0A0909093C2F61727261793E0A09093C2F646963743E0A09093C
% 6B65793E636F6D2E6170706C652E7072696E742E5061706572496E666F2E504D
% 556E61646A757374656450616765526563743C2F6B65793E0A09093C64696374
% 3E0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B6574
% 2E63726561746F723C2F6B65793E0A0909093C737472696E673E636F6D2E6170
% 706C652E7072696E742E706D2E506F73745363726970743C2F737472696E673E
% 0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E
% 6974656D41727261793C2F6B65793E0A0909093C61727261793E0A090909093C
% 646963743E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E
% 5061706572496E666F2E504D556E61646A757374656450616765526563743C2F
% 6B65793E0A09090909093C61727261793E0A0909090909093C7265616C3E302E
% 303C2F7265616C3E0A0909090909093C7265616C3E302E303C2F7265616C3E0A
% 0909090909093C7265616C3E3738333C2F7265616C3E0A0909090909093C7265
% 616C3E3535393C2F7265616C3E0A09090909093C2F61727261793E0A09090909
% 093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E636C69
% 656E743C2F6B65793E0A09090909093C737472696E673E636F6D2E6170706C65
% 2E7072696E74696E676D616E616765723C2F737472696E673E0A09090909093C
% 6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E6D6F644461
% 74653C2F6B65793E0A09090909093C646174653E323030362D31302D30395432
% 303A30333A33365A3C2F646174653E0A09090909093C6B65793E636F6D2E6170
% 706C652E7072696E742E7469636B65742E7374617465466C61673C2F6B65793E
% 0A09090909093C696E74656765723E303C2F696E74656765723E0A090909093C
% 2F646963743E0A0909093C2F61727261793E0A09093C2F646963743E0A09093C
% 6B65793E636F6D2E6170706C652E7072696E742E5061706572496E666F2E504D
% 556E61646A75737465645061706572526563743C2F6B65793E0A09093C646963
% 743E0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65
% 742E63726561746F723C2F6B65793E0A0909093C737472696E673E636F6D2E61
% 70706C652E7072696E742E706D2E506F73745363726970743C2F737472696E67
% 3E0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B6574
% 2E6974656D41727261793C2F6B65793E0A0909093C61727261793E0A09090909
% 3C646963743E0A09090909093C6B65793E636F6D2E6170706C652E7072696E74
% 2E5061706572496E666F2E504D556E61646A7573746564506170657252656374
% 3C2F6B65793E0A09090909093C61727261793E0A0909090909093C7265616C3E
% 2D31383C2F7265616C3E0A0909090909093C7265616C3E2D31383C2F7265616C
% 3E0A0909090909093C7265616C3E3832343C2F7265616C3E0A0909090909093C
% 7265616C3E3537373C2F7265616C3E0A09090909093C2F61727261793E0A0909
% 0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E63
% 6C69656E743C2F6B65793E0A09090909093C737472696E673E636F6D2E617070
% 6C652E7072696E74696E676D616E616765723C2F737472696E673E0A09090909
% 093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E6D6F64
% 446174653C2F6B65793E0A09090909093C646174653E323030362D31302D3039
% 5432303A30333A33365A3C2F646174653E0A09090909093C6B65793E636F6D2E
% 6170706C652E7072696E742E7469636B65742E7374617465466C61673C2F6B65
% 793E0A09090909093C696E74656765723E303C2F696E74656765723E0A090909
% 093C2F646963743E0A0909093C2F61727261793E0A09093C2F646963743E0A09
% 093C6B65793E636F6D2E6170706C652E7072696E742E5061706572496E666F2E
% 7070642E504D50617065724E616D653C2F6B65793E0A09093C646963743E0A09
% 09093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E6372
% 6561746F723C2F6B65793E0A0909093C737472696E673E636F6D2E6170706C65
% 2E7072696E742E706D2E506F73745363726970743C2F737472696E673E0A0909
% 093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E697465
% 6D41727261793C2F6B65793E0A0909093C61727261793E0A090909093C646963
% 743E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E506170
% 6572496E666F2E7070642E504D50617065724E616D653C2F6B65793E0A090909
% 09093C737472696E673E41343C2F737472696E673E0A09090909093C6B65793E
% 636F6D2E6170706C652E7072696E742E7469636B65742E636C69656E743C2F6B
% 65793E0A09090909093C737472696E673E636F6D2E6170706C652E7072696E74
% 2E706D2E506F73745363726970743C2F737472696E673E0A09090909093C6B65
% 793E636F6D2E6170706C652E7072696E742E7469636B65742E6D6F6444617465
% 3C2F6B65793E0A09090909093C646174653E323030332D30372D30315431373A
% 34393A33365A3C2F646174653E0A09090909093C6B65793E636F6D2E6170706C
% 652E7072696E742E7469636B65742E7374617465466C61673C2F6B65793E0A09
% 090909093C696E74656765723E313C2F696E74656765723E0A090909093C2F64
% 6963743E0A0909093C2F61727261793E0A09093C2F646963743E0A09093C6B65
% 793E636F6D2E6170706C652E7072696E742E7469636B65742E41504956657273
% 696F6E3C2F6B65793E0A09093C737472696E673E30302E32303C2F737472696E
% 673E0A09093C6B65793E636F6D2E6170706C652E7072696E742E7469636B6574
% 2E707269766174654C6F636B3C2F6B65793E0A09093C66616C73652F3E0A0909
% 3C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E74797065
% 3C2F6B65793E0A09093C737472696E673E636F6D2E6170706C652E7072696E74
% 2E5061706572496E666F5469636B65743C2F737472696E673E0A093C2F646963
% 743E0A093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E
% 41504956657273696F6E3C2F6B65793E0A093C737472696E673E30302E32303C
% 2F737472696E673E0A093C6B65793E636F6D2E6170706C652E7072696E742E74
% 69636B65742E707269766174654C6F636B3C2F6B65793E0A093C66616C73652F
% 3E0A093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E74
% 7970653C2F6B65793E0A093C737472696E673E636F6D2E6170706C652E707269
% 6E742E50616765466F726D61745469636B65743C2F737472696E673E0A3C2F64
% 6963743E0A3C2F706C6973743E0A3842494D03E9000000000078000300000048
% 004800000000030F022FFFEEFFEE033802410367057B03E00002000000480048
% 0000000002D802280001000000640000000100030303000000017FFF00010001
% 0000000000000000000000006808001901900000000000200000000000000000
% 0000000000000000000000000000000000003842494D03ED0000000000100048
% 00000001000200480000000100023842494D042600000000000E000000000000
% 000000003F8000003842494D040D0000000000040000001E3842494D04190000
% 000000040000001E3842494D03F3000000000009000000000000000001003842
% 494D040A00000000000100003842494D271000000000000A0001000000000000
% 00023842494D03F5000000000048002F66660001006C66660006000000000001
% 002F6666000100A1999A0006000000000001003200000001005A000000060000
% 00000001003500000001002D000000060000000000013842494D03F800000000
% 00700000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800000000
% FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800000000FFFFFFFF
% FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800000000FFFFFFFFFFFFFFFF
% FFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800003842494D04080000000000100000
% 00010000024000000240000000003842494D041E000000000004000000003842
% 494D041A00000000036300000006000000000000000000000183000001560000
% 001700620072006100760065002D0067006E0075002D0077006F0072006C0064
% 002D006C006F0067006F002E0032003500000001000000000000000000000000
% 0000000000000001000000000000000000000156000001830000000000000000
% 0000000000000000010000000000000000000000000000000000000010000000
% 010000000000006E756C6C0000000200000006626F756E64734F626A63000000
% 01000000000000526374310000000400000000546F70206C6F6E670000000000
% 0000004C6566746C6F6E67000000000000000042746F6D6C6F6E670000018300
% 000000526768746C6F6E670000015600000006736C69636573566C4C73000000
% 014F626A6300000001000000000005736C6963650000001200000007736C6963
% 6549446C6F6E67000000000000000767726F757049446C6F6E67000000000000
% 00066F726967696E656E756D0000000C45536C6963654F726967696E0000000D
% 6175746F47656E6572617465640000000054797065656E756D0000000A45536C
% 6963655479706500000000496D672000000006626F756E64734F626A63000000
% 01000000000000526374310000000400000000546F70206C6F6E670000000000
% 0000004C6566746C6F6E67000000000000000042746F6D6C6F6E670000018300
% 000000526768746C6F6E67000001560000000375726C54455854000000010000
% 000000006E756C6C54455854000000010000000000004D736765544558540000
% 0001000000000006616C74546167544558540000000100000000000E63656C6C
% 54657874497348544D4C626F6F6C010000000863656C6C546578745445585400
% 000001000000000009686F727A416C69676E656E756D0000000F45536C696365
% 486F727A416C69676E0000000764656661756C740000000976657274416C6967
% 6E656E756D0000000F45536C69636556657274416C69676E0000000764656661
% 756C740000000B6267436F6C6F7254797065656E756D0000001145536C696365
% 4247436F6C6F7254797065000000004E6F6E6500000009746F704F7574736574
% 6C6F6E67000000000000000A6C6566744F75747365746C6F6E67000000000000
% 000C626F74746F6D4F75747365746C6F6E67000000000000000B72696768744F
% 75747365746C6F6E6700000000003842494D041100000000000101003842494D
% 0414000000000004000000013842494D040C0000000011340000000100000071
% 00000080000001540000AA000000111800180001FFD8FFE000104A4649460001
% 0201004800480000FFED000C41646F62655F434D0002FFEE000E41646F626500
% 648000000001FFDB0084000C08080809080C09090C110B0A0B11150F0C0C0F15
% 18131315131318110C0C0C0C0C0C110C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C
% 0C0C0C0C0C0C0C0C0C0C0C010D0B0B0D0E0D100E0E10140E0E0E14140E0E0E0E
% 14110C0C0C0C0C11110C0C0C0C0C0C110C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C
% 0C0C0C0C0C0C0C0C0C0C0C0CFFC00011080080007103012200021101031101FF
% DD00040008FFC4013F0000010501010101010100000000000000030001020405
% 060708090A0B0100010501010101010100000000000000010002030405060708
% 090A0B1000010401030204020507060805030C33010002110304211231054151
% 611322718132061491A1B14223241552C16233347282D14307259253F0E1F163
% 733516A2B283264493546445C2A3743617D255E265F2B384C3D375E3F3462794
% A485B495C4D4E4F4A5B5C5D5E5F55666768696A6B6C6D6E6F637475767778797
% A7B7C7D7E7F71100020201020404030405060707060535010002110321311204
% 4151617122130532819114A1B14223C152D1F0332462E1728292435315637334
% F1250616A2B283072635C2D2449354A317644555367465E2F2B384C3D375E3F3
% 4694A485B495C4D4E4F4A5B5C5D5E5F55666768696A6B6C6D6E6F62737475767
% 778797A7B7C7FFDA000C03010002110311003F00F5549249252952EA5D6303A6
% B01C9B3F48E04D74B06EB1D1FBACFDCFCDF56CD94FEFD8A9F5AEB8EC4B1B8182
% CF5BA85A040896B377D17387B7D4B1DB7D94FF00D72EF4AA50E93F57C54F766F
% 513F69CDB4EE739E43849FECB5AE733E87B7F435FD0A2AAAA494969FAC06FD6A
% C0CA73791ED64F9E82C72B9566DF63B6FD8EE66B05CF35868F3FE777BBFB0C56
% 80F979240009294275911E09D2492535322DEA35585D5555E4526206E2C7B74F
% 76ED2C6DBEEFDDF4FF00E2FF00C22A77F51EAFF46BC7C7A9C7F3ADB6C81F9DF4
% 7D0ABF35BFBEB5D2494E5E066E7DAE8BDF8CFD09D94EEDC60EDFCF73BF3BF796
% 931E1ED04692260F2151EA1D1E9CB3EAD4EFB3E50D45AD120FFC755F46DFFCF9
% FCB553A7F53BC669E9FD440A731809601F42D1AFE998FF00F09BA3D9FF00A53D
% 8929DB49327494A49249253FFFD0F55599D77ABFECDA18DA5A2CCCC825B8EC3A
% 8111BEE7810E732ADECF637F9DB5F553FA3F53D5669AE4F12D6F53EB36752B3D
% F57A831F10088D8D163FD4DDB7E8B696DD97F43E9E4D74FF00A2494E8740E91E
% 8B1F999536655F2E7BDC649DC439DBB46B7DDB7F37FF003C7A55ADBF34CC6ED6
% 86F8052494A49258791F59EB7DBF67E9349EA16FFA469DB5027DA3F4B0EF57FA
% D5B7D1FF0086494EE24B370733A8D8FDB96CA5A4CC8ADD3B6086EDE5DB9FB9DF
% C853EA3D6FA7F4EDADBDE4DCF12CA2B05D6113B6767E637F9566C494DF4967E2
% F59AB206EFB3DF5375F73DA3B6A67D373DCAF32C658DDCC70703DC24A64B3BAD
% F4A6F52C4DAC8665D277E2DA646D7FEEB8B7FC15BFCDDBFF006E7F395D6B4524
% 94E3F42EA8FCEA032F9664D07D3B6B321DB99ED79B3E97FEAE5B0B987B8627D6
% 6CCF4CED65B48B1FB7B13E9B777F9C3D477F5D74CD208D381A7DDA24A5D24924
% 94FF00FFD1F547025A434C3A343E6B95FAAAE68C4A75DA7DF519D00B1E2835EF
% 67B7E936A733DDF9F52EAD60E574BC9C0CBBB3701A6EC6CA9765E20FA41C4973
% EDA3F7F7B8EED9F4FD4FE6FE9FE8D29DB37541BBDCE01BC1713027E2A166661D
% 4D2FB6FAEB6375739CF6803E24959B5E4D790C635AE9DA76D8DB25C5A63F384B
% 1CFB2BDAA4DE89D2FD3F57228640F77BF489ECFF00A2D494E65D9197F59AF763
% 636EA3A55662C79106D3CFBDA47B5BFB98EFFF00D0BFFB8AB6B1FA562E352296
% B4069FCD048DC63DDB8B8EF7EEFCFF007FFE05FA34B1EE6399E874F6B1B4D6ED
% 81EC1EC6E81EE867B3F7FF007D068E9F6FDAB7643DD786C1208105C3875BEEF7
% 7FC055FA5F47F9CFE752009DBF15A6755E2DD6D0DADB0D6C37521ADD00D1C36B
% 581BB550B6BC1392F71654ECD11BC020DAD6E9B7D92EB7DCDFDDF52C7AD0B1AD
% 9DE40DEE01AEE4CB44BB6FE6AAB8A5D91634E562D7518B1ECF7377B06E6ED63D
% A3DDEA58D77AB76DFD1D7FCDFBD2063746FE8A24F4AFF0BD281D958ED690F2EA
% F7E9B4CC03EDFD1EDFF02E74B37D5F4FDFFA556A9C864876E0D6C7B23BE9FB8D
% FA5FF93FF068EDA61CE6C35CC70F708E67F7964BB1FD5C9B7EC47EC81AFF004D
% A1DB832C786C96FA2F1ED6FF0053FEDBB13B849BAD695C7FBDE9E8EC5993454D
% 9BAC6543C5CE0047C5D0B3737EB3F4BC7696D160CCC8FCCA68F749FE5DAD9AEB
% FF00ABFDCAEC556DC9739FF63EA558AED322B9FE69F103D967B7F44DF67A9EE6
% 7FD6958C7C66B59EC6358ED443181A07F298FF00D35D637DDFA3F4DBFF006D26
% AE73B031B2ADCD7E56701F6ACA2CB1F5813B6B043AA6ECFCDF5ACA29AAADDF4F
% 1E9CABAEFF0008BA7ADBB5B1E249FBC9720518B5B786901C4971792E738E8DDC
% F73FDDEEDBB7FE2995D7FCD2B49294924924A7FFD2F55492492520BB131AD70B
% 2CAC1B1BC5834788F0B1BB5EAB64E48345C08FB5381DAFC6ADA1E040DCEA4EEF
% DE6BBDCFB91731D9EF70A30C32ADD05F91619869277368A5BEEB2EF6FF0085F4
% AAFD27F86F7D4876E217EFB3A85E3ECC047A0D3B6B826375EF9DF91EDF66C7FE
% 87FE0AD40D9D00DFAA083DE97C66E558FAEDC9BAB68FA5563E39961046DF7DAF
% DAFC86B5AEF66DAA867F215AB9C5AD0448931204F6EEA149AC173995892434B9
% A002E81B771FCD4AE739DB1F503635AE2486380D60B750EDAD7FF9E8C850D100
% 820EBDDCCBD96BAC739D7FA75D624B18DFFA565B61FF00A0C594EEB1496EFA1B
% 6B9F4BA77BB6B5AE274DB66DDCEDBFC9DAB6ADE9F8F98D7D598CB5C09DE2A712
% CD3F976D2FD963777F2D3E1BF16B2DAF02B365434229D82961F377B773FF007F
% 6FA8A200750C03181F30D7C3F97A9CEFB45D9353AABDE0525A1F153C8D9DB67E
% 8EB2E66DFA75D9BFF46B55D9CEAF2EBA2DA5EFA5EC97646D90D33B5A5E59F98F
% 9FFAC7FC56FF0042A757EA34E2B4D2D6B6DC8B012E635DED6B4FB77E44FD062A
% 755DD66DC57D8D76350C8F4BD67B9CD718FCEADCF6BAB73754E8896E02E88978
% 70F8BB39189899B43314B89A5B04110E0E05AEDA196582CF7B7F9CDECFD325D2
% 31DD46132AB2CF55ED2438F8104FE8F977F37F450BA6613DB41BAFBBD7C8BD8C
% 6DEE6BB4696496D34D94FA7FA3A9F659EFDBEA588F45D915BC372FD30EB6368A
% C1FA41BFA5DEE27DDF454B44824EFD596EA8550D9B8924926AE524924929FFD3
% F554C74D53A8BDA1ED2D3C1E47924A44CB1FF69B1AF2D02016346A4B40D6C7FB
% 7DBB9FEC6FFC5A0BB3706CCC6E31BEB75C06E65421CE691FE11DF4B67F21567E
% 0DD915BDF97A5971F731A4B9AD00FE8AA6CFEEB7F9DFF4967A8957F64E9EE656
% DDAD2E92F7C06807F96EFDE530803B1B95550FE2D696522C513ADBA2DC7A8012
% DDC7C5DA93F1944F6B60683B008745ECB9BB9A6478F8A8B1EF0FF4DD5B84925D
% 669B493FD53BFF00CE6A866640D166870571446FD833B68A6D20D8D0E2D9027C
% 0FD26FF55CA9D580FC2A5CDC67B4971DCEB2FDC63C5DB1AE6D7F47F36BF415C6
% 58C2D1E9CB9BC0238FF3BF393DAF656C2EB012D04030D2EE4EDFA2D0EFFCC134
% 709D579DABBBCE3F0F2B3DD7065FEB536C7AD94DFD1B1DE9977A7563D156F73E
% A6EFFD25B65D67A9FF0017B158FB0E261DB4D977A7EA39BB2AF6973811FE8F76
% E72D2A3AB74FBC5A59688A1CE6DA4F0DDBF9CE7FF36D67F2B77FE09BD1DD451B
% 8DA58DDF1F4C8D614D0C911A01A3164C529697FF0072D2C3ADF4836DAF739D61
% 009768E33A37467B559C8B1B5D4D6BD9BD847B817098FA3A6FFA7F4BF7D1DA1A
% 00DBC762B23AC6506D4D0F6C5AED6AD636C3873FBDBFD9FA2FF0B67E8D899932
% 13B685118184753C44BAB8F732FA596B0CB5C3BE864687FE9222CCFABC727F67
% 4640877A961699E5AE77A9C7E66C73FD2DBFF06B4D0F3661B6AA49249253FFD4
% F5550B63D27CC81B4EA2678EDB21FF00E6A9A6735AE696B84B5C2083C1052521
% 756DB7D37133B007026473DF669EE5917B76BDF6BEB796D7616D4C716D758FE5
% 0FCEB372D2B32DEC6D0D6D42CB6DD1E1AE68637696B6EF7D858E77A5BBF32BFC
% C51FD9D5BB25F9169F56C71258481B5A3B358DFDEDBF9EA6C79044907A7460CB
% 8CCA363525AACCBCD758DAEB6358D03DDB89E4FEEED5A34D8F6B0BAF78D3BC6D
% 1F892A4DA76C00040F1D4A1370DDB8BAD7FAAE719F701007EEB1A94A5097411F
% CD8F1C32C28EFE1D190BECB2C0DA9AD2CFCE7870D3FAAD83B9584014EC3B8B8B
% 8766E908A663DC62398D1472AD299E065AF10D5AD7D599BB6D26B7D446A2E930
% 7F77D9FCE31DFCBFA1FF000BBFF461AB1B230B1B2AE786E55AE3BEBC7AC7A758
% DAD8AE9AD8E758DDCE7FB9F77E7FFDB6AF36D63EB0FACEF69E0B759F8154F32E
% C8C70F758F636A26597381DACFE45CDDDF4BFD1DDFF5BFD17E8FD5611C3A81AA
% FB02CD5F7F1497DD15C5A62752C64C9FE40DB0EFF5FA0B16D75965B664871391
% EB86D0D0FDD5D15967A5F687532DFD2BB75DE9FF00C27E8FFD221E5E5B9DF67B
% CD576CB5F1481A3AD77954E76F6334FF00468DD3F14D4CB2ECD0319D63CD950B
% 1BC47E84DB65BA535DB6BEFDB8D5DBF99FE0FF009DF4C63F9AE4C71E33648E9A
% 7F55D2E867761B9ED9F49D63853BB9D8C8A013FD6755B968A0E1D031F16AA75F
% 6B759E64FB9DFF0049193E5B9F3648EC1492492097FFD5F5549249252175465C
% 19A171DED9D4077E77B7F95FF56B2197E4B6E353AD3894D0F1E8D75ED797B662
% E65CCDB635B56EFE6FD3F4ED62DB7B43DA5A6402224120EBE0E6C39AB2BA80B3
% 1EA631F63D9481FA7CA76E76CAC37F4AF73EBDBFA6DAC6ECBACFD1D7FCF7E93F
% 997B67777F4639020831BBFC1B14F53ADD98EC176E7DD24B0B58E03601BF758E
% 70D9FF0007BD8EFF0047FBEACE564371A875EFFA0C8DE7B35A486BAC77EED75B
% 7F4967F2163538169F4FA8623ADB5EC8153B29C5E367D0F5D94511BDDE9BECF4
% BDCCFE73E82D5C7C877A7B0EEB6C61DAE716ECDC47EEB53C4254B84C0AE22906
% 454FAEBBEBB05955801ACD7EF0F0ED5AE6B99BB7336AA7D40D97B4B585D536A9
% 2E7176D0EFE4EC66EB1EADDEF2C754E86EA483B84BBE8B9D0CD5BFBAA961F56F
% B56406331DCEC7B1FB29BC35DB5C035EFB2F2EDA6AF437B19456EF57D4B2CFF0
% 7E9FA6FB146601DB50A944CAC0F36A60D79877B8D8E73C18697CB8347FC1876D
% 5A7EADE1BE98607088758490493FBAC60F77F9EC44BD8E6B41A9BE32D02499FE
% DD6D6AA96E6D58A7D323ED196D689AEB074DDF47D5B0EF652D77F2FF00EB75A9
% 8C8486C3CBAB008CE32278BFB12E174F38F90FCAB6C375D635B5EE7B40735838
% ADAE6FE6EEF7BFFE11553D359665D7451FA3E9F4B8BDD8EC02BAA49F58C56D1F
% A675B92EDF63FF0099F4FF0043E9FE96E49D5E5E639A2D787020C5357B6B0276
% D85EF796D96ECFE6FE87FD67F48B4B1B1ABC6ABD3AC47771F13F3DCA23103CFB
% 766789BD3A2649249357292492494FFFD6F554924925290EEA59706EED0B0EE6
% 38685AE1F9CD3FF47F96CFD1BFF4688924A73FA937A836B73B1ACFA65A37113E
% 9025AC7BEBAEB0DF53FD2FE9ACFF00C013E167E2DEC0DA6C6BAD76E06C6B086B
% 9ECF6DBDBE96EFF07BD5F42BB1E9BD8596B0381F9107F79AF6FB98EFE53521D7
% B1457F22E4E7E46654FF00758DA5BCBDF638C081BBD9B5BB76FB7E9D8F546BEA
% B936D95DD48BEE6BA41706BEBADC08D3D371FF00C8FBD6FB7A7630209DEF8FA3
% EA3DCF23FAAFB0B9FDFF0079577742C7B06CBEFC8BABEF5BAD2D0E3FBD61A7D2
% 7D9FBBB1EFF4BFE0D33835DD8C62FE56E659D4F305753ADB61ECD59435E1BBDC
% DFA2EC87B9DEB3F1B77D3F47F4977FC5AD46306535DE9D64B490E36BC1ADAF71
% 078AA1B6BABAFD9FF1BFE9559C5C0C2C36918D4B6A9E481A9FEB3CFB9CAC27C6
% E3B15E23A51D50D18B5504B9A25EE0017F7DADFA15B7F72AAF77E8EB6A324924
% B94924924A524924929FFFD93842494D04210000000000790000000101000000
% 1800410064006F00620065002000500068006F0074006F00730068006F007000
% 200045006C0065006D0065006E007400730000001C00410064006F0062006500
% 2000500068006F0074006F00730068006F007000200045006C0065006D006500
% 6E0074007300200032002E003000000001003842494D042200000000012E4D4D
% 002A000000080007011200030000000100010000011A00050000000100000062
% 011B0005000000010000006A012800030000000100020000013100020000001D
% 0000007201320002000000140000008F8769000400000001000000A4000000D0
% 0000004800000001000000480000000141646F62652050686F746F73686F7020
% 456C656D656E747320322E3000323030363A31303A30392032323A30393A3238
% 00000003A001000300000001FFFF0000A00200040000000100000156A0030004
% 00000001000001830000000000000006010300030000000100060000011A0005
% 000000010000011E011B00050000000100000126012800030000000100020000
% 02010004000000010000012E0202000400000001000000000000000000000048
% 0000000100000048000000013842494D03FD0000000000070000000000000000
%EndPhotoshop
%begin_xml_code
/pdfmark where {pop true} {false} ifelse
/currentdistillerparams where {pop currentdistillerparams
/CoreDistVersion get 5000 ge } {false} ifelse
and not {userdict /pdfmark /cleartomark load put} if
[/NamespacePush pdfmark
[/_objdef {photoshop_metadata_stream} /type /stream /OBJ pdfmark
/MetadataString 5038 string def % exact length of metadata
/TempString 100 string def
/ConsumeMetadata {
currentfile TempString readline pop pop
currentfile MetadataString readstring pop pop
} bind def
ConsumeMetadata
%begin_xml_packet: 5038
<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?> <?adobe-xap-filters esc="CR"?> <x:xapmeta xmlns:x='adobe:ns:meta/' x:xaptk='XMP toolkit 2.8.2-33, framework 1.5'> <rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:iX='http://ns.adobe.com/iX/1.0/'> @@ -526,77 +61,7 @@ ConsumeMetadata -<?xpacket end='w'?> -%end_xml_packet -[{photoshop_metadata_stream} 2 dict begin /Type /Metadata def /Subtype /XML def currentdict end /PUT pdfmark -[{photoshop_metadata_stream} MetadataString /PUT pdfmark -[/_objdef {nextImage} /NI pdfmark -%end_xml_code -gsave % EPS gsave -/hascolor -/deviceinfo where -{pop deviceinfo /Colors known -{deviceinfo /Colors get exec 1 gt} -{false} ifelse} -{/statusdict where -{pop statusdict /processcolors known -{statusdict /processcolors get exec 1 gt} -{false} ifelse} -{false} ifelse} -ifelse -def -40 dict begin -/_image systemdict /image get def -/_setgray systemdict /setgray get def -/_currentgray systemdict /currentgray get def -/_settransfer systemdict /settransfer get def -/_currenttransfer systemdict /currenttransfer get def -/blank 0 _currenttransfer exec -1 _currenttransfer exec eq def -/negative blank -{0 _currenttransfer exec 0.5 lt} -{0 _currenttransfer exec 1 _currenttransfer exec gt} -ifelse def -/inverted? negative def -/level2 systemdict /languagelevel known -{languagelevel 2 ge} {false} ifelse def -/level3 systemdict /languagelevel known -{languagelevel 3 ge} {false} ifelse def -level2 {/band 0 def} {/band 5 def} ifelse -gsave % Image Header gsave -/rows 387 def -/cols 342 def -342 387 scale -level2 { -/DeviceRGB -setcolorspace currentdict /PhotoshopDuotoneColorSpace undef currentdict /PhotoshopDuotoneAltColorSpace undef } if -/beginimage level2 -{/image load def} -{{pop .9 setgray 0 0 moveto 0 1 lineto -1 1 lineto 1 0 lineto fill 0 setgray -0 1 translate 1 cols div 1 rows div scale -/ratio {cols 400 div mul} def -/Helvetica findfont 15 ratio scalefont setfont -5 ratio -20 ratio moveto -(Mit JPEG komprimierte Bilder ben\232tigen PostScript Level 2) show -/x 128 string def -{currentfile x readline {} {pop exit} ifelse -(~>) search {pop pop pop exit} {pop} ifelse -} loop } def} -ifelse -12 dict begin -/ImageType 1 def -/Width cols def -/Height rows def -/ImageMatrix [cols 0 0 rows neg 0 rows] def -/BitsPerComponent 8 def -/Decode [0 1 0 1 0 1] def -/DataSource currentfile /ASCII85Decode filter -/DCTDecode filter def -currentdict end -%%BeginBinary: 12801 -beginimage -s4IA0!"_al8O`[\!W`9l!([(is6]js6"FnCAH67k!!!!"s4[O,!"obO%M0*b&.fQt +<?xpacket end='w'?>
%end_xml_packet
[{photoshop_metadata_stream} 2 dict begin /Type /Metadata def /Subtype /XML def currentdict end /PUT pdfmark
[{photoshop_metadata_stream} MetadataString /PUT pdfmark
[/_objdef {nextImage} /NI pdfmark
%end_xml_code
gsave % EPS gsave
/hascolor
/deviceinfo where
{pop deviceinfo /Colors known
{deviceinfo /Colors get exec 1 gt}
{false} ifelse}
{/statusdict where
{pop statusdict /processcolors known
{statusdict /processcolors get exec 1 gt}
{false} ifelse}
{false} ifelse}
ifelse
def
40 dict begin
/_image systemdict /image get def
/_setgray systemdict /setgray get def
/_currentgray systemdict /currentgray get def
/_settransfer systemdict /settransfer get def
/_currenttransfer systemdict /currenttransfer get def
/blank 0 _currenttransfer exec
1 _currenttransfer exec eq def
/negative blank
{0 _currenttransfer exec 0.5 lt}
{0 _currenttransfer exec 1 _currenttransfer exec gt}
ifelse def
/inverted? negative def
/level2 systemdict /languagelevel known
{languagelevel 2 ge} {false} ifelse def
/level3 systemdict /languagelevel known
{languagelevel 3 ge} {false} ifelse def
level2 {/band 0 def} {/band 5 def} ifelse
gsave % Image Header gsave
/rows 387 def
/cols 342 def
342 387 scale
level2 {
/DeviceRGB
setcolorspace currentdict /PhotoshopDuotoneColorSpace undef currentdict /PhotoshopDuotoneAltColorSpace undef } if
/beginimage level2
{/image load def}
{{pop .9 setgray 0 0 moveto 0 1 lineto
1 1 lineto 1 0 lineto fill 0 setgray
0 1 translate 1 cols div 1 rows div scale
/ratio {cols 400 div mul} def
/Helvetica findfont 15 ratio scalefont setfont
5 ratio -20 ratio moveto
(Mit JPEG komprimierte Bilder ben\232tigen PostScript Level 2) show
/x 128 string def
{currentfile x readline {} {pop exit} ifelse
(~>) search {pop pop pop exit} {pop} ifelse
} loop } def}
ifelse
12 dict begin
/ImageType 1 def
/Width cols def
/Height rows def
/ImageMatrix [cols 0 0 rows neg 0 rows] def
/BitsPerComponent 8 def
/Decode [0 1 0 1 0 1] def
/DataSource currentfile /ASCII85Decode filter
/DCTDecode filter def
currentdict end
%%BeginBinary: 12801
beginimage
s4IA0!"_al8O`[\!W`9l!([(is6]js6"FnCAH67k!!!!"s4[O,!"obO%M0*b&.fQt '+km!,8q:3)C$FB(Ddl(+qY4l$k*OQ&I]'V$k*OQ$k*OQ$k*OQ$k*OQ$k*OQ$k*OQ $iq%U',DH$)]';0'FkT_'GM#e%Ls0b$k*OQ$kX'[$k*OQ$kWmV$k*OQ$k*OQ$k*OQ $k*OQ$k*OQ$k*OQ$k30O!"fJ;K)o!T!?qLF&HMtG!WUsU"995;_uW(&!!*6(!<E3% @@ -789,9 +254,4 @@ P"?rK,a(_k8L0HsP"?p`Uln:q.3t'J8kC:k;NaTsPekl!n"d`jmi)3+S>%b'+%/FF (5C.cK]sbFP`eT`V'M3q.7keJ8lA5+P*D,$,c)cL8L[4VP"JVD,a+CT8L156fBs8X *0NpB`?jKb,cBEq?6#,#IDmMkaX!e>;I1?+8q"Z)iQ3@CgeqGuP"L/A-/lrkVqb0V *0NpB`?jKb,cBEq?6#,#IDmMkaX!e>;I1?+8q"Z)iQ3@CgeqGuP"L/A-/lrkVqb0V -*0NpB`?jKb,cBEq?6#,#IDmMkaX!e>;I1?+8q"Z)iQ3@Cs4I~> -%%EndBinary -grestore end % Image Trailer grestore -grestore % EPS grestore -[{nextImage} 1 dict begin /Metadata {photoshop_metadata_stream} def currentdict end /PUT pdfmark -[/NamespacePop pdfmark +*0NpB`?jKb,cBEq?6#,#IDmMkaX!e>;I1?+8q"Z)iQ3@Cs4I~>
%%EndBinary
grestore end % Image Trailer grestore
grestore % EPS grestore
[{nextImage} 1 dict begin /Metadata {photoshop_metadata_stream} def currentdict end /PUT pdfmark
[/NamespacePop pdfmark
\ No newline at end of file diff --git a/Master/texmf-dist/doc/generic/pgf/images/brave-gnu-world-logo.eps b/Master/texmf-dist/doc/generic/pgf/images/brave-gnu-world-logo.eps index 680ee260892..1c5f93cff22 100644 --- a/Master/texmf-dist/doc/generic/pgf/images/brave-gnu-world-logo.eps +++ b/Master/texmf-dist/doc/generic/pgf/images/brave-gnu-world-logo.eps @@ -1,541 +1,4 @@ -%!PS-Adobe-3.0 EPSF-3.0 -%%Title: brave-gnu-world-logo.eps -%%CreationDate: 09.10.2006 22:10 Uhr -%%BoundingBox: 0 0 342 387 -%%HiResBoundingBox: 0 0 342 387 -%%SuppressDotGainCompensation -%%EndComments -%%BeginProlog -%%EndProlog -%%BeginSetup -%%EndSetup -%ImageData: 342 387 8 3 0 1 3 "beginimage" -%BeginPhotoshop: 16252 -% 3842494D0425000000000010000000000000000000000000000000003842494D -% 03EA000000001DA63C3F786D6C2076657273696F6E3D22312E302220656E636F -% 64696E673D225554462D38223F3E0A3C21444F435459504520706C6973742050 -% 55424C494320222D2F2F4170706C6520436F6D70757465722F2F44544420504C -% 49535420312E302F2F454E222022687474703A2F2F7777772E6170706C652E63 -% 6F6D2F445444732F50726F70657274794C6973742D312E302E647464223E0A3C -% 706C6973742076657273696F6E3D22312E30223E0A3C646963743E0A093C6B65 -% 793E636F6D2E6170706C652E7072696E742E50616765466F726D61742E504D48 -% 6F72697A6F6E74616C5265733C2F6B65793E0A093C646963743E0A09093C6B65 -% 793E636F6D2E6170706C652E7072696E742E7469636B65742E63726561746F72 -% 3C2F6B65793E0A09093C737472696E673E636F6D2E6170706C652E7072696E74 -% 696E676D616E616765723C2F737472696E673E0A09093C6B65793E636F6D2E61 -% 70706C652E7072696E742E7469636B65742E6974656D41727261793C2F6B6579 -% 3E0A09093C61727261793E0A0909093C646963743E0A090909093C6B65793E63 -% 6F6D2E6170706C652E7072696E742E50616765466F726D61742E504D486F7269 -% 7A6F6E74616C5265733C2F6B65793E0A090909093C7265616C3E37323C2F7265 -% 616C3E0A090909093C6B65793E636F6D2E6170706C652E7072696E742E746963 -% 6B65742E636C69656E743C2F6B65793E0A090909093C737472696E673E636F6D -% 2E6170706C652E7072696E74696E676D616E616765723C2F737472696E673E0A -% 090909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E -% 6D6F64446174653C2F6B65793E0A090909093C646174653E323030362D31302D -% 30395432303A31303A30355A3C2F646174653E0A090909093C6B65793E636F6D -% 2E6170706C652E7072696E742E7469636B65742E7374617465466C61673C2F6B -% 65793E0A090909093C696E74656765723E303C2F696E74656765723E0A090909 -% 3C2F646963743E0A09093C2F61727261793E0A093C2F646963743E0A093C6B65 -% 793E636F6D2E6170706C652E7072696E742E50616765466F726D61742E504D4F -% 7269656E746174696F6E3C2F6B65793E0A093C646963743E0A09093C6B65793E -% 636F6D2E6170706C652E7072696E742E7469636B65742E63726561746F723C2F -% 6B65793E0A09093C737472696E673E636F6D2E6170706C652E7072696E74696E -% 676D616E616765723C2F737472696E673E0A09093C6B65793E636F6D2E617070 -% 6C652E7072696E742E7469636B65742E6974656D41727261793C2F6B65793E0A -% 09093C61727261793E0A0909093C646963743E0A090909093C6B65793E636F6D -% 2E6170706C652E7072696E742E50616765466F726D61742E504D4F7269656E74 -% 6174696F6E3C2F6B65793E0A090909093C696E74656765723E313C2F696E7465 -% 6765723E0A090909093C6B65793E636F6D2E6170706C652E7072696E742E7469 -% 636B65742E636C69656E743C2F6B65793E0A090909093C737472696E673E636F -% 6D2E6170706C652E7072696E74696E676D616E616765723C2F737472696E673E -% 0A090909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B6574 -% 2E6D6F64446174653C2F6B65793E0A090909093C646174653E323030362D3130 -% 2D30395432303A31303A30355A3C2F646174653E0A090909093C6B65793E636F -% 6D2E6170706C652E7072696E742E7469636B65742E7374617465466C61673C2F -% 6B65793E0A090909093C696E74656765723E303C2F696E74656765723E0A0909 -% 093C2F646963743E0A09093C2F61727261793E0A093C2F646963743E0A093C6B -% 65793E636F6D2E6170706C652E7072696E742E50616765466F726D61742E504D -% 5363616C696E673C2F6B65793E0A093C646963743E0A09093C6B65793E636F6D -% 2E6170706C652E7072696E742E7469636B65742E63726561746F723C2F6B6579 -% 3E0A09093C737472696E673E636F6D2E6170706C652E7072696E74696E676D61 -% 6E616765723C2F737472696E673E0A09093C6B65793E636F6D2E6170706C652E -% 7072696E742E7469636B65742E6974656D41727261793C2F6B65793E0A09093C -% 61727261793E0A0909093C646963743E0A090909093C6B65793E636F6D2E6170 -% 706C652E7072696E742E50616765466F726D61742E504D5363616C696E673C2F -% 6B65793E0A090909093C7265616C3E313C2F7265616C3E0A090909093C6B6579 -% 3E636F6D2E6170706C652E7072696E742E7469636B65742E636C69656E743C2F -% 6B65793E0A090909093C737472696E673E636F6D2E6170706C652E7072696E74 -% 696E676D616E616765723C2F737472696E673E0A090909093C6B65793E636F6D -% 2E6170706C652E7072696E742E7469636B65742E6D6F64446174653C2F6B6579 -% 3E0A090909093C646174653E323030362D31302D30395432303A31303A30355A -% 3C2F646174653E0A090909093C6B65793E636F6D2E6170706C652E7072696E74 -% 2E7469636B65742E7374617465466C61673C2F6B65793E0A090909093C696E74 -% 656765723E303C2F696E74656765723E0A0909093C2F646963743E0A09093C2F -% 61727261793E0A093C2F646963743E0A093C6B65793E636F6D2E6170706C652E -% 7072696E742E50616765466F726D61742E504D566572746963616C5265733C2F -% 6B65793E0A093C646963743E0A09093C6B65793E636F6D2E6170706C652E7072 -% 696E742E7469636B65742E63726561746F723C2F6B65793E0A09093C73747269 -% 6E673E636F6D2E6170706C652E7072696E74696E676D616E616765723C2F7374 -% 72696E673E0A09093C6B65793E636F6D2E6170706C652E7072696E742E746963 -% 6B65742E6974656D41727261793C2F6B65793E0A09093C61727261793E0A0909 -% 093C646963743E0A090909093C6B65793E636F6D2E6170706C652E7072696E74 -% 2E50616765466F726D61742E504D566572746963616C5265733C2F6B65793E0A -% 090909093C7265616C3E37323C2F7265616C3E0A090909093C6B65793E636F6D -% 2E6170706C652E7072696E742E7469636B65742E636C69656E743C2F6B65793E -% 0A090909093C737472696E673E636F6D2E6170706C652E7072696E74696E676D -% 616E616765723C2F737472696E673E0A090909093C6B65793E636F6D2E617070 -% 6C652E7072696E742E7469636B65742E6D6F64446174653C2F6B65793E0A0909 -% 09093C646174653E323030362D31302D30395432303A31303A30355A3C2F6461 -% 74653E0A090909093C6B65793E636F6D2E6170706C652E7072696E742E746963 -% 6B65742E7374617465466C61673C2F6B65793E0A090909093C696E7465676572 -% 3E303C2F696E74656765723E0A0909093C2F646963743E0A09093C2F61727261 -% 793E0A093C2F646963743E0A093C6B65793E636F6D2E6170706C652E7072696E -% 742E50616765466F726D61742E504D566572746963616C5363616C696E673C2F -% 6B65793E0A093C646963743E0A09093C6B65793E636F6D2E6170706C652E7072 -% 696E742E7469636B65742E63726561746F723C2F6B65793E0A09093C73747269 -% 6E673E636F6D2E6170706C652E7072696E74696E676D616E616765723C2F7374 -% 72696E673E0A09093C6B65793E636F6D2E6170706C652E7072696E742E746963 -% 6B65742E6974656D41727261793C2F6B65793E0A09093C61727261793E0A0909 -% 093C646963743E0A090909093C6B65793E636F6D2E6170706C652E7072696E74 -% 2E50616765466F726D61742E504D566572746963616C5363616C696E673C2F6B -% 65793E0A090909093C7265616C3E313C2F7265616C3E0A090909093C6B65793E -% 636F6D2E6170706C652E7072696E742E7469636B65742E636C69656E743C2F6B -% 65793E0A090909093C737472696E673E636F6D2E6170706C652E7072696E7469 -% 6E676D616E616765723C2F737472696E673E0A090909093C6B65793E636F6D2E -% 6170706C652E7072696E742E7469636B65742E6D6F64446174653C2F6B65793E -% 0A090909093C646174653E323030362D31302D30395432303A31303A30355A3C -% 2F646174653E0A090909093C6B65793E636F6D2E6170706C652E7072696E742E -% 7469636B65742E7374617465466C61673C2F6B65793E0A090909093C696E7465 -% 6765723E303C2F696E74656765723E0A0909093C2F646963743E0A09093C2F61 -% 727261793E0A093C2F646963743E0A093C6B65793E636F6D2E6170706C652E70 -% 72696E742E7375625469636B65742E70617065725F696E666F5F7469636B6574 -% 3C2F6B65793E0A093C646963743E0A09093C6B65793E636F6D2E6170706C652E -% 7072696E742E50616765466F726D61742E504D41646A75737465645061676552 -% 6563743C2F6B65793E0A09093C646963743E0A0909093C6B65793E636F6D2E61 -% 70706C652E7072696E742E7469636B65742E63726561746F723C2F6B65793E0A -% 0909093C737472696E673E636F6D2E6170706C652E7072696E74696E676D616E -% 616765723C2F737472696E673E0A0909093C6B65793E636F6D2E6170706C652E -% 7072696E742E7469636B65742E6974656D41727261793C2F6B65793E0A090909 -% 3C61727261793E0A090909093C646963743E0A09090909093C6B65793E636F6D -% 2E6170706C652E7072696E742E50616765466F726D61742E504D41646A757374 -% 656450616765526563743C2F6B65793E0A09090909093C61727261793E0A0909 -% 090909093C7265616C3E302E303C2F7265616C3E0A0909090909093C7265616C -% 3E302E303C2F7265616C3E0A0909090909093C7265616C3E3738333C2F726561 -% 6C3E0A0909090909093C7265616C3E3535393C2F7265616C3E0A09090909093C -% 2F61727261793E0A09090909093C6B65793E636F6D2E6170706C652E7072696E -% 742E7469636B65742E636C69656E743C2F6B65793E0A09090909093C73747269 -% 6E673E636F6D2E6170706C652E7072696E74696E676D616E616765723C2F7374 -% 72696E673E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E -% 7469636B65742E6D6F64446174653C2F6B65793E0A09090909093C646174653E -% 323030362D31302D30395432303A31303A30355A3C2F646174653E0A09090909 -% 093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E737461 -% 7465466C61673C2F6B65793E0A09090909093C696E74656765723E303C2F696E -% 74656765723E0A090909093C2F646963743E0A0909093C2F61727261793E0A09 -% 093C2F646963743E0A09093C6B65793E636F6D2E6170706C652E7072696E742E -% 50616765466F726D61742E504D41646A75737465645061706572526563743C2F -% 6B65793E0A09093C646963743E0A0909093C6B65793E636F6D2E6170706C652E -% 7072696E742E7469636B65742E63726561746F723C2F6B65793E0A0909093C73 -% 7472696E673E636F6D2E6170706C652E7072696E74696E676D616E616765723C -% 2F737472696E673E0A0909093C6B65793E636F6D2E6170706C652E7072696E74 -% 2E7469636B65742E6974656D41727261793C2F6B65793E0A0909093C61727261 -% 793E0A090909093C646963743E0A09090909093C6B65793E636F6D2E6170706C -% 652E7072696E742E50616765466F726D61742E504D41646A7573746564506170 -% 6572526563743C2F6B65793E0A09090909093C61727261793E0A090909090909 -% 3C7265616C3E2D31383C2F7265616C3E0A0909090909093C7265616C3E2D3138 -% 3C2F7265616C3E0A0909090909093C7265616C3E3832343C2F7265616C3E0A09 -% 09090909093C7265616C3E3537373C2F7265616C3E0A09090909093C2F617272 -% 61793E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E7469 -% 636B65742E636C69656E743C2F6B65793E0A09090909093C737472696E673E63 -% 6F6D2E6170706C652E7072696E74696E676D616E616765723C2F737472696E67 -% 3E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B -% 65742E6D6F64446174653C2F6B65793E0A09090909093C646174653E32303036 -% 2D31302D30395432303A31303A30355A3C2F646174653E0A09090909093C6B65 -% 793E636F6D2E6170706C652E7072696E742E7469636B65742E7374617465466C -% 61673C2F6B65793E0A09090909093C696E74656765723E303C2F696E74656765 -% 723E0A090909093C2F646963743E0A0909093C2F61727261793E0A09093C2F64 -% 6963743E0A09093C6B65793E636F6D2E6170706C652E7072696E742E50617065 -% 72496E666F2E504D50617065724E616D653C2F6B65793E0A09093C646963743E -% 0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E -% 63726561746F723C2F6B65793E0A0909093C737472696E673E636F6D2E617070 -% 6C652E7072696E742E706D2E506F73745363726970743C2F737472696E673E0A -% 0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E69 -% 74656D41727261793C2F6B65793E0A0909093C61727261793E0A090909093C64 -% 6963743E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E50 -% 61706572496E666F2E504D50617065724E616D653C2F6B65793E0A0909090909 -% 3C737472696E673E69736F2D61343C2F737472696E673E0A09090909093C6B65 -% 793E636F6D2E6170706C652E7072696E742E7469636B65742E636C69656E743C -% 2F6B65793E0A09090909093C737472696E673E636F6D2E6170706C652E707269 -% 6E742E706D2E506F73745363726970743C2F737472696E673E0A09090909093C -% 6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E6D6F644461 -% 74653C2F6B65793E0A09090909093C646174653E323030332D30372D30315431 -% 373A34393A33365A3C2F646174653E0A09090909093C6B65793E636F6D2E6170 -% 706C652E7072696E742E7469636B65742E7374617465466C61673C2F6B65793E -% 0A09090909093C696E74656765723E313C2F696E74656765723E0A090909093C -% 2F646963743E0A0909093C2F61727261793E0A09093C2F646963743E0A09093C -% 6B65793E636F6D2E6170706C652E7072696E742E5061706572496E666F2E504D -% 556E61646A757374656450616765526563743C2F6B65793E0A09093C64696374 -% 3E0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B6574 -% 2E63726561746F723C2F6B65793E0A0909093C737472696E673E636F6D2E6170 -% 706C652E7072696E742E706D2E506F73745363726970743C2F737472696E673E -% 0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E -% 6974656D41727261793C2F6B65793E0A0909093C61727261793E0A090909093C -% 646963743E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E -% 5061706572496E666F2E504D556E61646A757374656450616765526563743C2F -% 6B65793E0A09090909093C61727261793E0A0909090909093C7265616C3E302E -% 303C2F7265616C3E0A0909090909093C7265616C3E302E303C2F7265616C3E0A -% 0909090909093C7265616C3E3738333C2F7265616C3E0A0909090909093C7265 -% 616C3E3535393C2F7265616C3E0A09090909093C2F61727261793E0A09090909 -% 093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E636C69 -% 656E743C2F6B65793E0A09090909093C737472696E673E636F6D2E6170706C65 -% 2E7072696E74696E676D616E616765723C2F737472696E673E0A09090909093C -% 6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E6D6F644461 -% 74653C2F6B65793E0A09090909093C646174653E323030362D31302D30395432 -% 303A31303A30355A3C2F646174653E0A09090909093C6B65793E636F6D2E6170 -% 706C652E7072696E742E7469636B65742E7374617465466C61673C2F6B65793E -% 0A09090909093C696E74656765723E303C2F696E74656765723E0A090909093C -% 2F646963743E0A0909093C2F61727261793E0A09093C2F646963743E0A09093C -% 6B65793E636F6D2E6170706C652E7072696E742E5061706572496E666F2E504D -% 556E61646A75737465645061706572526563743C2F6B65793E0A09093C646963 -% 743E0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65 -% 742E63726561746F723C2F6B65793E0A0909093C737472696E673E636F6D2E61 -% 70706C652E7072696E742E706D2E506F73745363726970743C2F737472696E67 -% 3E0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B6574 -% 2E6974656D41727261793C2F6B65793E0A0909093C61727261793E0A09090909 -% 3C646963743E0A09090909093C6B65793E636F6D2E6170706C652E7072696E74 -% 2E5061706572496E666F2E504D556E61646A7573746564506170657252656374 -% 3C2F6B65793E0A09090909093C61727261793E0A0909090909093C7265616C3E -% 2D31383C2F7265616C3E0A0909090909093C7265616C3E2D31383C2F7265616C -% 3E0A0909090909093C7265616C3E3832343C2F7265616C3E0A0909090909093C -% 7265616C3E3537373C2F7265616C3E0A09090909093C2F61727261793E0A0909 -% 0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E63 -% 6C69656E743C2F6B65793E0A09090909093C737472696E673E636F6D2E617070 -% 6C652E7072696E74696E676D616E616765723C2F737472696E673E0A09090909 -% 093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E6D6F64 -% 446174653C2F6B65793E0A09090909093C646174653E323030362D31302D3039 -% 5432303A31303A30355A3C2F646174653E0A09090909093C6B65793E636F6D2E -% 6170706C652E7072696E742E7469636B65742E7374617465466C61673C2F6B65 -% 793E0A09090909093C696E74656765723E303C2F696E74656765723E0A090909 -% 093C2F646963743E0A0909093C2F61727261793E0A09093C2F646963743E0A09 -% 093C6B65793E636F6D2E6170706C652E7072696E742E5061706572496E666F2E -% 7070642E504D50617065724E616D653C2F6B65793E0A09093C646963743E0A09 -% 09093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E6372 -% 6561746F723C2F6B65793E0A0909093C737472696E673E636F6D2E6170706C65 -% 2E7072696E742E706D2E506F73745363726970743C2F737472696E673E0A0909 -% 093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E697465 -% 6D41727261793C2F6B65793E0A0909093C61727261793E0A090909093C646963 -% 743E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E506170 -% 6572496E666F2E7070642E504D50617065724E616D653C2F6B65793E0A090909 -% 09093C737472696E673E41343C2F737472696E673E0A09090909093C6B65793E -% 636F6D2E6170706C652E7072696E742E7469636B65742E636C69656E743C2F6B -% 65793E0A09090909093C737472696E673E636F6D2E6170706C652E7072696E74 -% 2E706D2E506F73745363726970743C2F737472696E673E0A09090909093C6B65 -% 793E636F6D2E6170706C652E7072696E742E7469636B65742E6D6F6444617465 -% 3C2F6B65793E0A09090909093C646174653E323030332D30372D30315431373A -% 34393A33365A3C2F646174653E0A09090909093C6B65793E636F6D2E6170706C -% 652E7072696E742E7469636B65742E7374617465466C61673C2F6B65793E0A09 -% 090909093C696E74656765723E313C2F696E74656765723E0A090909093C2F64 -% 6963743E0A0909093C2F61727261793E0A09093C2F646963743E0A09093C6B65 -% 793E636F6D2E6170706C652E7072696E742E7469636B65742E41504956657273 -% 696F6E3C2F6B65793E0A09093C737472696E673E30302E32303C2F737472696E -% 673E0A09093C6B65793E636F6D2E6170706C652E7072696E742E7469636B6574 -% 2E707269766174654C6F636B3C2F6B65793E0A09093C66616C73652F3E0A0909 -% 3C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E74797065 -% 3C2F6B65793E0A09093C737472696E673E636F6D2E6170706C652E7072696E74 -% 2E5061706572496E666F5469636B65743C2F737472696E673E0A093C2F646963 -% 743E0A093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E -% 41504956657273696F6E3C2F6B65793E0A093C737472696E673E30302E32303C -% 2F737472696E673E0A093C6B65793E636F6D2E6170706C652E7072696E742E74 -% 69636B65742E707269766174654C6F636B3C2F6B65793E0A093C66616C73652F -% 3E0A093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E74 -% 7970653C2F6B65793E0A093C737472696E673E636F6D2E6170706C652E707269 -% 6E742E50616765466F726D61745469636B65743C2F737472696E673E0A3C2F64 -% 6963743E0A3C2F706C6973743E0A3842494D03E9000000000078000300000048 -% 004800000000030F022FFFEEFFEE033802410367057B03E00002000000480048 -% 0000000002D802280001000000640000000100030303000000017FFF00010001 -% 0000000000000000000000006808001901900000000000200000000000000000 -% 0000000000000000000000000000000000003842494D03ED0000000000100048 -% 00000001000200480000000100023842494D042600000000000E000000000000 -% 000000003F8000003842494D040D0000000000040000001E3842494D04190000 -% 000000040000001E3842494D03F3000000000009000000000000000001003842 -% 494D040A00000000000100003842494D271000000000000A0001000000000000 -% 00023842494D03F5000000000048002F66660001006C66660006000000000001 -% 002F6666000100A1999A0006000000000001003200000001005A000000060000 -% 00000001003500000001002D000000060000000000013842494D03F800000000 -% 00700000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800000000 -% FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800000000FFFFFFFF -% FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800000000FFFFFFFFFFFFFFFF -% FFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800003842494D04080000000000100000 -% 00010000024000000240000000003842494D041E000000000004000000003842 -% 494D041A00000000035D00000006000000000000000000000183000001560000 -% 001400620072006100760065002D0067006E0075002D0077006F0072006C0064 -% 002D006C006F0067006F00000001000000000000000000000000000000000000 -% 0001000000000000000000000156000001830000000000000000000000000000 -% 0000010000000000000000000000000000000000000010000000010000000000 -% 006E756C6C0000000200000006626F756E64734F626A63000000010000000000 -% 00526374310000000400000000546F70206C6F6E6700000000000000004C6566 -% 746C6F6E67000000000000000042746F6D6C6F6E670000018300000000526768 -% 746C6F6E670000015600000006736C69636573566C4C73000000014F626A6300 -% 000001000000000005736C6963650000001200000007736C69636549446C6F6E -% 67000000000000000767726F757049446C6F6E6700000000000000066F726967 -% 696E656E756D0000000C45536C6963654F726967696E0000000D6175746F4765 -% 6E6572617465640000000054797065656E756D0000000A45536C696365547970 -% 6500000000496D672000000006626F756E64734F626A63000000010000000000 -% 00526374310000000400000000546F70206C6F6E6700000000000000004C6566 -% 746C6F6E67000000000000000042746F6D6C6F6E670000018300000000526768 -% 746C6F6E67000001560000000375726C54455854000000010000000000006E75 -% 6C6C54455854000000010000000000004D736765544558540000000100000000 -% 0006616C74546167544558540000000100000000000E63656C6C546578744973 -% 48544D4C626F6F6C010000000863656C6C546578745445585400000001000000 -% 000009686F727A416C69676E656E756D0000000F45536C696365486F727A416C -% 69676E0000000764656661756C740000000976657274416C69676E656E756D00 -% 00000F45536C69636556657274416C69676E0000000764656661756C74000000 -% 0B6267436F6C6F7254797065656E756D0000001145536C6963654247436F6C6F -% 7254797065000000004E6F6E6500000009746F704F75747365746C6F6E670000 -% 00000000000A6C6566744F75747365746C6F6E67000000000000000C626F7474 -% 6F6D4F75747365746C6F6E67000000000000000B72696768744F75747365746C -% 6F6E6700000000003842494D041100000000000101003842494D041400000000 -% 0004000000013842494D040C000000001A350000000100000071000000800000 -% 01540000AA0000001A1900180001FFD8FFE000104A4649460001020100480048 -% 0000FFED000C41646F62655F434D0002FFEE000E41646F626500648000000001 -% FFDB0084000C08080809080C09090C110B0A0B11150F0C0C0F15181313151313 -% 18110C0C0C0C0C0C110C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C -% 0C0C0C0C0C010D0B0B0D0E0D100E0E10140E0E0E14140E0E0E0E14110C0C0C0C -% 0C11110C0C0C0C0C0C110C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C -% 0C0C0C0C0C0CFFC00011080080007103012200021101031101FFDD00040008FF -% C4013F0000010501010101010100000000000000030001020405060708090A0B -% 0100010501010101010100000000000000010002030405060708090A0B100001 -% 0401030204020507060805030C33010002110304211231054151611322718132 -% 061491A1B14223241552C16233347282D14307259253F0E1F163733516A2B283 -% 264493546445C2A3743617D255E265F2B384C3D375E3F3462794A485B495C4D4 -% E4F4A5B5C5D5E5F55666768696A6B6C6D6E6F637475767778797A7B7C7D7E7F7 -% 1100020201020404030405060707060535010002110321311204415161712213 -% 0532819114A1B14223C152D1F0332462E1728292435315637334F1250616A2B2 -% 83072635C2D2449354A317644555367465E2F2B384C3D375E3F34694A485B495 -% C4D4E4F4A5B5C5D5E5F55666768696A6B6C6D6E6F62737475767778797A7B7C7 -% FFDA000C03010002110311003F00F5549249252962FD63FADFD0BEADD3BFA95F -% FA67006BC4AA1D7BC1DC039B4EE6EDAFF46FFD35BE9D3FF09BD61FD7EFAFE3A1 -% 8FD91D22323AEDE000000E18E1C3DB658DFA2FC87B7DD451FF00A1191FA2F4AA -% C9E1FA4FD5DCEEA998EEA7D58BFA8751CC74D3597026D70038716BABAF1F1D8D -% DB65FF00CC52CF469AB67A94D8929EA2CFF1C4CB2D8E9FD132322AEEEB2C6D6E -% E63F9BAD993F9BFF0008B5A9FF0018D45AD31D1F3C585E6BA9B1400F7EA1B5D7 -% BF258EB2C76DFA14D76A9F4FFA834B58D7E7E4D8D773F66C6706D4D91F47D6B2 -% BFB4DCE6EEFE77F56FFC2F5ADDE9BD07A474B71B30B19B5DCE043AF717597104 -% 8739AFCABDD6E4399B9BBB67AA9292F4DBFA86452EB73B1460B8B88AA8F505AF -% 0C1F45F7BEAFD0B2C7FF00A1A5F7FA7FF721FF00E0ADA4924A79BEBBD47EB974 -% 9B1F7E06053D6B05DAB59597539356AEDCCB1937332D9B7D3F4ACC7632DFF494 -% 7F855CB752FF0019FF005971C7A7FB2A8E9F748939A320340D665B65185FF07F -% E13FF3E2F4D49253E59D37FC66FD64B323D4C9AF03269827ECF8FEA31CE8F67E -% 8B21CFC8D9EFFF004B4FFDB5FCF57E83D13AFF004EEB743ADC37383EBDBEB63D -% A36DB5EE1B99BD9AEE63FF00C1DF53ACC7BBFC0DB62C4FAD5FE2EFA4F5B6D995 -% 84D6F4EEABF49B91588AEC7025F199437D96FA9BDDFA7FE91FF1BE9FA2BCFABB -% FAD740EBC303A89FB1754C40E38990C135DA1FFE1F7B87EB38D76CF753FF005B -% FD0E4D1FA24A7DB9258DF56FEB0B3ACE31173063E75207AF44CB48FCDC9C677F -% 84C5B7F33FD1FF00336FE916CA4A524924929FFFD0F555CC7D7DFAE15FD58E96 -% 3D269B3A96687D7835812039BB77DF618DBB28F52BFD1FF86B3F47F43D5B6AE9 -% D782F56EA87EB37D6BCAEAAE71B315961A30441814D42CB3D50DB7DCDD98F5DB -% 97657B7FA45DFE0D2527FAADD06CCA7D9D433C3F2AFB9C2581FF00A5BEEB9DBD -% 98E2CB377BED7B7D5CABBFC151FA7C8B3D15EBDD07A1D7D2F1F7DA18FCFB9A06 -% 4DCC076C0FA18F8FBE5D5E263FD0A6BFFAF59FA7B6D58DF527A355481956FBED -% A2B635B31FA3B2D636FBDBB3DCE6DCDAACAFF49F4FF58BAA5D724A52499CE6B1 -% A5CE21AD689738E8001DCAE03AFF00F8DAC1C6C87E07D5FC63D57246E67AF3B6 -% 86BFE830B3682FCA67A9FB9E8D567F81C9494FA024BCBFA6FF008CDFAD0EC963 -% 73B0F06DAF5DF4D0E7D76684336B2CB2DC9ABD5F51DF42C6319FF0D5AE9FA87F -% 8CAFAAB81D3E9CCB6EB1F66434BABC163272416BBD1B59754E2C663BAAB37FF3 -% F6D7EAFA567D9FD6494F5292E1F0FF00C6C746C8B62DC0CDA292EDA2ED8D7800 -% 7D27DB5D563AE6EC6EDDDE9577AEB7A6756E9BD5F1465F4DC8665504ED2F61E1 -% D01DE9D8C3EFAACDAE6FE8EC6FA8929B6B9FFAEDF5529FACFD1DD8A36579F4FE -% 930725E0FB1FA6E61733DEDAB21ADF4EDFFADDFE958FA2B5D024929F11FAB3D7 -% 3A85393582F38BD4F049AB6580B75691F68C7CE66D7BFECB7ECD96B367AACCA6 -% 7E8EAFB4D78FE9FB2F4ECFA3A8E15799402D65920B1D1B98F6935DD4D9B4B9BE -% A536B1F559B5CBC5FEB8B2AE9FFE303AA8A229AEC6B2D796E9B5D6B28B6DB7FE -% DE7BAE7AEFBEA266165F6E00115DB59B76811B2DC77370AFF5777B9D6DF5FD99 -% DFF07E8BFF00B694F66924924A7FFFD1F50CA6DCFC5B9943B6DCEADC2B7710E2 -% 0EC77F9CBE7BFAB4E0031BB8377BECA4171F687DA296D46C0DF76C7EC77FDB5F -% CB5F44AF2FFAEFF50F37133EFEBBD0697E5D19AE2EEA3D3DB2FB03DC4BDD918C -% DFA56B2C7B9DBAAFE728B1FF00A1FD0FF454A75FEABFD6CE958551C5CFB7ECF5 -% 585A5B976FB6BF576B6ABB1EFB3E856FFD17A8CB5DB29FF03FA3B29FD274EFFA -% CBF5718DDCFEAB86D6F89C8A80FF00AB5E29565B32D95ED7EE021B66FF007169 -% 8D1CF6EEAFD4B58DFF00AEBFFAEAE51F567A78A1D939748A98D87B59639AC3EF -% FE65B90E26AAE86BBE97BFFF0003FCF4A6F7D6CFAD79DF5D731DD27A3EFABA15 -% 0EFD259043B21CD3B9AFB07E653B87EAD8EFFF008EBFF58FB3E3D15B1BEAF328 -% A994359B8D861B5D675B0804BFE916D96FE6FAAC67E67E8BFC27A0AE74EB72F2 -% 5870FEAFE28BE9A5C2B665D601C7A3633D4B6DB03D94D3EADAEB376FBEFF00A1 -% BFF43916FF00379FD33A66664752756E75BD42C69DAEAEB0C7EE206DDD6DB697 -% 6DDBFF0069BF4791F63FE91FA0BD3A1094FE51F5DB4592CB18EA5B67A664E3D2 -% 2CFB3D8CA7710D2D6398C0EDAF6B296B3D3AD9EAEBFB9EA7F3BF43F3F3727168 -% 19363AD65673C1FD333783732086ED756E2EB9F6FF00C5FDA2F7B3FE1175DD4D -% B57D9CBF368C367516FA78ADC2A326FBC8C6AEC7E4E463F517D77D1535FEA3BF -% 43BFF9CBFF0056FD27ABE9ACCE9F89899F636ACAE9F878990197598CCFB5B28B -% 2B25D35E2E6E1DF75F915DBB3D4C87BEBC6FF47EAD767E92C481C7C5C249F31C -% 3308E324D47865A5D7CAE05D7D74EFAAF0FA5EE716163DA46D734B37D3B086FA -% 16FD0F568FE77DFF00A657BA5F54C8C1CCAF370EFF00B2DAD86B5ED1B9AF6C7F -% 35918ECFE9547FC67E9B7FF45FB3FD35B35F41EAB876BF763B6DC4B6B873F633 -% 63B74FF3B4B5D7D9F67D5ED6E5595FBFFE2972AFC5AF2736EFD9CE6E157EA0AA -% 9DC1EDAED786FB9BE859BBD2FA5F9BFF006CFEE38E23FA244BF050C9FBC0C5F5 -% 7E8DF5F3A4655219D5AEA7A5E6B44B9B6D81B4BC69FA5C5C9B7D3ADFBB77F30E -% FD62AFF8BFD3595BAD7F8D3FAA9D36A78C6C8FDA59634AE8C604B4B88259BB28 -% B7D06D7BBD8FF4DD75ACFF004162F2BBED78B0E1753A832CD4327F9A7C7B5BB2 -% C1FE05AE6FBF6BFF00EDB46C6C460692D0CADDA83B581B13F9D5B9A2FC8B9BFB -% 9E933E87F39E8A8D911B9DD47AC754BFAAF5100E6E7BD8E3535BA064B7ECF486 -% 39DFE15F551450CDFF00D169CBB6FF00E6BD45E93F526870CC65A5C48B3ED16B -% 09DB2F639D57BDAD23D477B9DEA596FEFDB5D5FF0072172BD2FA68BEE630576F -% A4F0EDC04BF22E062A7574D67DEF7E47D0BBF49ECC3FE7B2A9C15E97F573A3BB -% A6E33ACBDA1995901BEA3038BF635BBBD2A5D6E9EB58CF52CF52EDBFF07FCC55 -% 424A7612492494FF00FFD2F5549249253CF7D68FABFF0055F268B3AA755C3DD7 -% D23DB918FB9992E7BB6D345553F1DD5D9917BECF4E9C5AADF53F49FA35C2E4F5 -% 3661D76B2DA3EDF994EFAB23A78AFED5563B590F7613C3856CCACBF6FA99BD4E -% EFF26E33FF0047D330723D3FD1749F5D7A9F52CCCFAFA27437554E6B008CAB1E -% 5B6B5D68B2BB5BD3298FD264D78CCB7D5CD67F43AAEBAA65B55CFB3D3E7F230C -% B2ACACAEB9946F65120D3539C7098F7FE8EBFB7E5BEFAF2BABE53D9E97EADEAF -% F83FD62CF4922247488DF792C9DE801AEB6931EFCEFDA15D7D53229C8C363C33 -% 0BA4E23EB661E457B3754FF4EDF4FD7C2AABB7F9CA3A6B2AC8B7F49FCD7A2B5B -% AE67E453D0FECD5B9CEA3D573336EC4A982B67B4BAAC5CAFB3D8FF00D5AFB1FF -% 00A4BD9E933F57F432FF004795F67B70BA2E4E3E3DB9165384324BFF00441C1A -% DC72F1F9D6DAEA5F4E2D357FC17ABB2BAFF4752DAEA3D4DDD4307131FA18A2DA -% 301CE7E6E2E23DB5B18F1FD15DBEE7D3859B4D0EDEFBB17ED6CFD73ECB91FA5A -% EAB2A5265C5C38AA20D91F6B1717171441D28D7EFF00F8CF0993539C5FBEF15B -% 291B9D5D55B8811F9D75B90E63BFEB752C8BBAAE3ED69A45B63AA3BCBDE1AD0E -% 27F36CDBBB756BAAB3A062D9EA37A9D79B65D66EB68A2C6B6963DAD875B73BA8 -% 5566563E5D0DF519FCCBF7D2A3D32CC365CCAFA7537E63041B29C67B1986C7FD -% 16B9F75ADDEFFF0084B37AA5A0BB04D74F958408C7420923A7F37170065DD7D4 -% 6AB5CD14002D632A77B6BD7F9B0D656FDAD64FE8B73FF43FE0D74EDEAACBBAB5 -% 54F54A2D38F750D37676D0368693B72AC7E3B1CC7D6EDDEFB3D0A2CC6FE777AC -% BEBF9D8B84D76331953F2EDDC6E6E35E6DA9A09FFB55B9BB773377E62CFC4B3A -% BDD857DB5DB8B8C368A4DD6BCD6F7899FD0BED3E9B94B8BDCF9A029920244588 -% 81127691F9BC5ECBAAF4BE92FE934F45AB25D9349B5D6E0DD5D6CBDB734B0B3E -% CD4E5FAB7E3FDA5AD637D47B3D3C9A3D2F655E865FA8AC7D4AFA96DCCE995DB6 -% 7516BEB63BD3C8AEBAE6EAEC60FD2E1DAEB9F6D0C7635DF47F57BBD7A7D2B3F9 -% 9F4960F4AE946EC62D17FDAAEC96B6BCA2D756CABD6AC3DF8D55198CB2BF4DBE -% EF7DDB3F4967AAB4FEAA75FCBE97D7AAB7A99ADADEA8598D7FA43F3E3D3664DF -% EED8EF4727F41F68FDCBAFF53D5FD0FA73F0C88E23BF567040A1B7F2EEFA574D -% E8FD3FA6348C5ACFA8F1166458E365CFFF008DC8B4BED7FF005377A75FF83575 -% 249317A92492494FFFD3F5540CDCBA7070EFCDBE7D1C6ADF759024EDADA6C7ED -% 1FD56A3AC6FADED73FEAEE5D4D0E70BFD3A5ED67D2732DB6AA2D637FAF558F6A -% 205903BA09A04F67CF7033735DD49EFCCBC56FB817E4B2A8B5F73277E5BED716 -% 8AFECD7DFF00AB50C6DB5E27A18FFA0F52BF52EB639FD5FA4F53EA95BDF7D74B -% F56E363068BACAC47BF3B2AF6B7ECD4E43F6ECA7171BF9AAD6565E065E7B6CCB -% EA00B6ECB3AD4C97319B0B6BA316B69FA0DA59ECD8D51ADDD3FA45B4D74B9A5C -% 4137BDCD0D0D703F45EF8F7395D8E2BE136234D2965AE214657FB1EB3A2FD5AC -% 1CE65561C3765C1871B1CD74FF00C3653ACFFA152E94748E9B896558B9D9D4D3 -% EAB837170DA2AA019D19556C76EB2E589F54BEB1DB957B28B2C2719C4CFBAAAD -% BFD7DC18CB9FB7F777AA37D79D5B5ECCEE9B7FA5937D97752CDC50C7E2DAF7B9 -% E5CE65949BADFB1B58D63297E5329F43FED5FE9941CD66CB8F4034FD8BB1C61C -% 3C422724AF500FC81EA3EB5D5F57A707F6BE0D9D42DAF78C4631AE2D13E9FAA2 -% FDAEAB1BD37EDABD97FF00DB6B88C5E875E063D9FB2F3701F1FCF65F546BEA35 -% C0F7BAA6FAD761DBFF0007B28A3FEBCB7BA3F59C3C8C3C5E9E3A7D995D1AA7B6 -% 8A6F6D6E6B68630399F68BB3BDBD3F32B63BDB63E9BBD7FF0083CAB568F55C1E -% 974D03A87567557E257B431CCADD90F74FD06D7454C737FB7B2C55E1EDE404CE -% C3626090008F144F4F95F27C9AB273DD90CA328DD8EF2DFB4E5340AABB4D5BFD -% 1F4F1696EF7B6BF51DFA4BBFF0244FB062605943F20B03EC6EDADA185EE04705 -% ACB0EE5DD1FACBF563A858DB3A6DD461BAB7FA577DB5CEAB68076B2C6D78D5D9 -% 89E959FE96DC9ABFE13629E67D54C4A1B9199BEA3601B9D977B0D74B43BFD1DB -% 7FB6EFE47A2AD619E28815F9316486422AA8741178FC2A1D8C0E5E53DE5F6383 -% 7F492DB1D3F4767A7BB62D7CEFD99574AC2A32697DADBF7FDA5CDB87A8CAD8E1 -% 8FE8E39B9B5D76DF6FDA5CFB3D4B6AA6AABFE16C5BBD12AE9991655563E3E466 -% 565C19F6A35B4540BBDAEB3DCFF57D26CFEE2E33EB4F561922B6FA5B1A379C0A -% BE8FA55FABFE135B7ED19190CAAAFB4BFD6B3D6B595D389FA2AFF4ADE672C741 -% 0DEC52DC6271167524D01FCBFAAFAEFD55EA87ABFD5DC0CF738D96DB486DEF23 -% 693757FA0C9F60FF00BB15DAB55711FE2872326DFAAF757907F98CCB5958F06B -% 9B4E4B9BFF006EE45ABB75036D4924924A7FFFD4F5558DF5BDF6D7F56F3ADA49 -% 6BEA636D2F01C4B5B5BD965B6B3D27D36FA9556C7D95FA76D6FDEB6557EA1875 -% 67E064E0DD22ACBA5F45846876D8D756E8FECB920A7C9EEA6ACA38EE3906D662 -% D4CB5F75EDF4FDD73836D77A34BBDAFF006EC7596FBFD8B9FBDAD63ADBECA9E6 -% BAEE7578F5B8B29AC1ECED9EEB2DDCBB1A73AA181D3F1AFE97567754CE0FC67D -% 15B8627A2CC670AF2AA7DF93BB7E6E265BF7FA0CF57F55F52FBBF43E9AC7B7A1 -% 0A3AADE3A9EF7673CB9D8E5CC1B5CD0760FB3501D67B9D5ED77D3FE5AB98720E -% 2E1EDDDA99B1CB8788F5EDFCA2D06750EAD7DADA2BDAC635BEE0E240D7F77D3D -% BB96DF4EB5F80D6E665DB2FA3FA3B48343371FF876BFD472BB8FD1FA87A6D751 -% 8CD6318D906DF7DA5C78F6FB58CFEA6E552EFAB5998E0E6752C865CEB6093686 -% B4B5AEF6B5B4D13F9AAC4CE396FA9FDE916B43DC8EDE91FBB10A1D6BAE751C81 -% 5636539A376E7D8DCB018C6F01B4D3634AE9B05BD4322E6E4BBA8E7166303EF6 -% 369B19FCADDEDF771FB8B98FB25188064DD6597D6E3B69A890DAE7FE118D1B95 -% DBE9C9C8A98DC9CDAB171DBEEB035E71E96B40ED57D3B1CA0963801A533C72CC -% CB5B010F59C56E3D95E2F4ECEA9D80E712CC5EA356512D2E3B8D2D6D1558FEA1 -% 539CE73EBB2EFD255FCDDD7DDFA351E9FD2F1307A6754CDEA783FB50E316E4D3 -% 82C16E26234B22A3E85777E8D8E731CFB3F494FAD91FCDD14BEC57F13AEF4AC2 -% C607A6D2FCDA1CE0D2E61735D69F065D99B1EDABFA8A97D64CEEB228FB65B7D6 -% DC5DE0D75BDBB6BC279DD6578D663D363AAC8B7F47EAE1755B3FED47A95FEA17 -% 7A75AA73C631DCA313E619C480B908EA770373E6D6EA9D5B2998EEC379AFA763 -% 3C7E93030B7B5CFD1D355F6B36E5DBB98FD8FF0052EC7FFC28B98C8B85A1F940 -% 9194EC8D9556D7EFA68A7D36D755BE87B76BFF0048FF0041BBBF45E97A5E9A06 -% 4D97D871AEF42F73322C2DC7810EBDE0ECDB5D7B9EE6B77FE6318AE61747B71B -% 09FD43A8BEBC375B3914D17822D35CBB1DD9505BE937D5BACF4B11B77E93F476 -% 5D4D1E9FE99478ACCAE66FCD18C4F52753AD7689FEAC5F48FF0014B5399F56F2 -% 2D8229BF32C763B9D12EAD95D18BBFFCFC7B176CB17EA6F4B7F49FAAFD3B06D0 -% E6DCDA459736CFA4DB2E2ECABEB3FF001575CFAD6D2909B24B30D8292492412F -% FFD5F5549249253E7FF59FA2BA8EB36D54322BEA85B97845D5B1F43336B0E666 -% 36E6E8EAA9C8A1FF006AB1FF00E9BED19DFF0068D71BD3BAFF0059E997BF1ABC -% DBFA6D588F7369C41B6EDAE2FDB94CBB0DFBE86FA567A9B6B6FD9FD25ECDD57A -% 5E3F54C3762DC5D59FA555F512CB6A7C1636EA2D6FBEBB36BDECFE5D6FB2AB3F -% 45658BC83AF62752C0CDFB0756B6F168975D9CFDF683496B68B3305EDFD25DED -% AF1EADF657FAAFF84FD37F3CD98BA901AEC4FF00D12C538906E3609D3FDF76F1 -% FEB7579F9197D3B2E8CAEA179B3ED347D8E9DAD732B6EEDB9955C5DE87BB657E -% BD3EA63FBEAB6DF47F49BF732EDE91D3F16EEA8CC68CE636B376156F66EA6B2E -% 6B2FC9B6CC6AAFB594E356FF005AFB3659FF004D79C63F4FCDF4DBD5F019916B -% 6A314D992E360158DD53AEAE9A19FA6F4B73FDDBBD3FF825D1F40FACAFE9186F -% C3A319F9E64D6E360FB33741EE6B31EB190CBB9FF0FE9A9E10C9C3E202B8A028 -% 4883D24D8CFC8C7AADAF26CCA63A9B9C7D0C5E9CDF5CD8D9735B7DD9DBF73B7E -% DFCC585D7F21DD41CE755EAE3328FE75D75D1BDDE544D97B96F7526331B0307A -% 93BA3E253EAD8EA48B6B326297E4D57D7F637E135DBFECF7FDA7FC1FF33F6654 -% 3A7750AF39AD03A636BA32ED34E26563D37D4031822FCADB6372B0B231FD7FD5 -% BFE50FB431FF00E0D18E500F0CAEC782D30B97A2B6E2FA3CD60559AF2E79B5CF -% B1876B0D9EF0D1FF00042C236FF9AB77173B330996578D8B45965B5BA9393635 -% CE7FE91A6BB5B8D5D1B37BFD377F38F7A2751A5D4877D9F19F4575CD6FA4B4B9 -% FBBFD23DCCB2AA68639DFE95DEA2A1665518321FB32B318C00D4C6B9DB77F6B2 -% DDEFAA9FEDFF00EC3298CA128D57F6B1819233BBEBA7F55B7D331B2BA7E47DA9 -% D96F7E4DB532B69F49AEB98D67E869A6BB1AF7ECF53F3B66CF5BFC3AB9D23A4D -% 3D73EB0E1F4BC661FD8D82FF00B5E550C0CFB392DF73BD59AF6E6BB3733F47F4 -% 28C5A71BEDB8DD3EAB31FF004EB0DB89D4FAC64D54301C8B321C594E2E382CAB -% DA36DAEB2C77E652D3B2D7B99FABB3F9CAFF004F532CF5DFAAFF0056707EAEF4 -% FF00B3E3B41C8BA1F9778E6CB23B6EF7368ABE863D5F98CFF497D975D6D69803 -% 402BC1B10DBC3F96CECA492498BD4924924A7FFFD6F5549249252952EA9D2713 -% AAE31A32439AE1269BEB3B6DA9C46DF571EDFF0006FF00FC0EDAFF00437B2DA6 -% CB2B5752494F997D6BE8DF5C7A66396E2DCEBBA73A03ECC16BAAF4F46FDA6FBF -% A762EC7DBEB3C7ADEA3B272E967A6FFD16262DDE9ACCE85D7BA735CCF4AAC7AE -% F757635D9F5D0E70F5D83FA6578D3E93EF636CAAEBB1BF9A7BFF0098F4D7B02C -% AEABF55BEAF75871B3A8605375CE2D27200F4EEF6FD0FD6A8F4F23DB1FE95189 -% A24EBAF62B4C7EBFDEF57FD27C67AA5DD5E8C99CBB5F55F631AE75D90F739EE6 -% 387A83D3B7F3E9B367F38FB3DFB3F9AFF06A855D63A97DA19958F66497B8906C -% A8BE96991B36D6FA9DEDFF0037DEBD6F23FC58740BEFF546466D4D6886542E16 -% 359F4B5ADF975E4DEDDAE7EEFE79059FE2A3A00205D9BD4322A9F7D365CC0C7C -% F6B7D1A29B5DC7FA451FB601D18FDAA363F3D5F361F597AC0AAAFB5E6D8EAEB6 -% 6D6E27AA58CB23F372F65953EDC777F85DBFA7C9FF00C11747D1BEABE5F5CD8F -% C4C72709E5B65B9F91BA8C7B090DDDF67C46B6ACDC8AAA63FF0045FA4A2AC8FC -% FCCA7FC27A074AFA97F557A4383F03A6D2CB1AFF005196D80DD635C349AAFC93 -% 75B57FD6DEB6D3E371BA3BB208F7F579B95D03EAEE0F43C7D94FE9B25E22ECA7 -% B5A1EE03E8D4C6D6D65746355FE031286B28ABFE37D5B2CD5492497292492494 -% A49249253FFFD9003842494D0421000000000079000000010100000018004100 -% 64006F00620065002000500068006F0074006F00730068006F00700020004500 -% 6C0065006D0065006E007400730000001C00410064006F006200650020005000 -% 68006F0074006F00730068006F007000200045006C0065006D0065006E007400 -% 7300200032002E003000000001003842494D042200000000012E4D4D002A0000 -% 00080007011200030000000100010000011A00050000000100000062011B0005 -% 000000010000006A012800030000000100020000013100020000001D00000072 -% 01320002000000140000008F8769000400000001000000A4000000D000000048 -% 00000001000000480000000141646F62652050686F746F73686F7020456C656D -% 656E747320322E3000323030363A31303A30392032323A31303A313900000003 -% A001000300000001FFFF0000A00200040000000100000156A003000400000001 -% 000001830000000000000006010300030000000100060000011A000500000001 -% 0000011E011B0005000000010000012601280003000000010002000002010004 -% 000000010000012E020200040000000100000000000000000000004800000001 -% 00000048000000013842494D03FD0000000000070000000000000000 -%EndPhotoshop -%begin_xml_code -/pdfmark where {pop true} {false} ifelse -/currentdistillerparams where {pop currentdistillerparams -/CoreDistVersion get 5000 ge } {false} ifelse -and not {userdict /pdfmark /cleartomark load put} if -[/NamespacePush pdfmark -[/_objdef {photoshop_metadata_stream} /type /stream /OBJ pdfmark -/MetadataString 5038 string def % exact length of metadata -/TempString 100 string def -/ConsumeMetadata { -currentfile TempString readline pop pop -currentfile MetadataString readstring pop pop -} bind def -ConsumeMetadata -%begin_xml_packet: 5038 -<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?> +%!PS-Adobe-3.0 EPSF-3.0
%%Title: brave-gnu-world-logo.eps
%%CreationDate: 09.10.2006 22:10 Uhr
%%BoundingBox: 0 0 342 387
%%HiResBoundingBox: 0 0 342 387
%%SuppressDotGainCompensation
%%EndComments
%%BeginProlog
%%EndProlog
%%BeginSetup
%%EndSetup
%ImageData: 342 387 8 3 0 1 3 "beginimage"
%BeginPhotoshop: 16252
% 3842494D0425000000000010000000000000000000000000000000003842494D
% 03EA000000001DA63C3F786D6C2076657273696F6E3D22312E302220656E636F
% 64696E673D225554462D38223F3E0A3C21444F435459504520706C6973742050
% 55424C494320222D2F2F4170706C6520436F6D70757465722F2F44544420504C
% 49535420312E302F2F454E222022687474703A2F2F7777772E6170706C652E63
% 6F6D2F445444732F50726F70657274794C6973742D312E302E647464223E0A3C
% 706C6973742076657273696F6E3D22312E30223E0A3C646963743E0A093C6B65
% 793E636F6D2E6170706C652E7072696E742E50616765466F726D61742E504D48
% 6F72697A6F6E74616C5265733C2F6B65793E0A093C646963743E0A09093C6B65
% 793E636F6D2E6170706C652E7072696E742E7469636B65742E63726561746F72
% 3C2F6B65793E0A09093C737472696E673E636F6D2E6170706C652E7072696E74
% 696E676D616E616765723C2F737472696E673E0A09093C6B65793E636F6D2E61
% 70706C652E7072696E742E7469636B65742E6974656D41727261793C2F6B6579
% 3E0A09093C61727261793E0A0909093C646963743E0A090909093C6B65793E63
% 6F6D2E6170706C652E7072696E742E50616765466F726D61742E504D486F7269
% 7A6F6E74616C5265733C2F6B65793E0A090909093C7265616C3E37323C2F7265
% 616C3E0A090909093C6B65793E636F6D2E6170706C652E7072696E742E746963
% 6B65742E636C69656E743C2F6B65793E0A090909093C737472696E673E636F6D
% 2E6170706C652E7072696E74696E676D616E616765723C2F737472696E673E0A
% 090909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E
% 6D6F64446174653C2F6B65793E0A090909093C646174653E323030362D31302D
% 30395432303A31303A30355A3C2F646174653E0A090909093C6B65793E636F6D
% 2E6170706C652E7072696E742E7469636B65742E7374617465466C61673C2F6B
% 65793E0A090909093C696E74656765723E303C2F696E74656765723E0A090909
% 3C2F646963743E0A09093C2F61727261793E0A093C2F646963743E0A093C6B65
% 793E636F6D2E6170706C652E7072696E742E50616765466F726D61742E504D4F
% 7269656E746174696F6E3C2F6B65793E0A093C646963743E0A09093C6B65793E
% 636F6D2E6170706C652E7072696E742E7469636B65742E63726561746F723C2F
% 6B65793E0A09093C737472696E673E636F6D2E6170706C652E7072696E74696E
% 676D616E616765723C2F737472696E673E0A09093C6B65793E636F6D2E617070
% 6C652E7072696E742E7469636B65742E6974656D41727261793C2F6B65793E0A
% 09093C61727261793E0A0909093C646963743E0A090909093C6B65793E636F6D
% 2E6170706C652E7072696E742E50616765466F726D61742E504D4F7269656E74
% 6174696F6E3C2F6B65793E0A090909093C696E74656765723E313C2F696E7465
% 6765723E0A090909093C6B65793E636F6D2E6170706C652E7072696E742E7469
% 636B65742E636C69656E743C2F6B65793E0A090909093C737472696E673E636F
% 6D2E6170706C652E7072696E74696E676D616E616765723C2F737472696E673E
% 0A090909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B6574
% 2E6D6F64446174653C2F6B65793E0A090909093C646174653E323030362D3130
% 2D30395432303A31303A30355A3C2F646174653E0A090909093C6B65793E636F
% 6D2E6170706C652E7072696E742E7469636B65742E7374617465466C61673C2F
% 6B65793E0A090909093C696E74656765723E303C2F696E74656765723E0A0909
% 093C2F646963743E0A09093C2F61727261793E0A093C2F646963743E0A093C6B
% 65793E636F6D2E6170706C652E7072696E742E50616765466F726D61742E504D
% 5363616C696E673C2F6B65793E0A093C646963743E0A09093C6B65793E636F6D
% 2E6170706C652E7072696E742E7469636B65742E63726561746F723C2F6B6579
% 3E0A09093C737472696E673E636F6D2E6170706C652E7072696E74696E676D61
% 6E616765723C2F737472696E673E0A09093C6B65793E636F6D2E6170706C652E
% 7072696E742E7469636B65742E6974656D41727261793C2F6B65793E0A09093C
% 61727261793E0A0909093C646963743E0A090909093C6B65793E636F6D2E6170
% 706C652E7072696E742E50616765466F726D61742E504D5363616C696E673C2F
% 6B65793E0A090909093C7265616C3E313C2F7265616C3E0A090909093C6B6579
% 3E636F6D2E6170706C652E7072696E742E7469636B65742E636C69656E743C2F
% 6B65793E0A090909093C737472696E673E636F6D2E6170706C652E7072696E74
% 696E676D616E616765723C2F737472696E673E0A090909093C6B65793E636F6D
% 2E6170706C652E7072696E742E7469636B65742E6D6F64446174653C2F6B6579
% 3E0A090909093C646174653E323030362D31302D30395432303A31303A30355A
% 3C2F646174653E0A090909093C6B65793E636F6D2E6170706C652E7072696E74
% 2E7469636B65742E7374617465466C61673C2F6B65793E0A090909093C696E74
% 656765723E303C2F696E74656765723E0A0909093C2F646963743E0A09093C2F
% 61727261793E0A093C2F646963743E0A093C6B65793E636F6D2E6170706C652E
% 7072696E742E50616765466F726D61742E504D566572746963616C5265733C2F
% 6B65793E0A093C646963743E0A09093C6B65793E636F6D2E6170706C652E7072
% 696E742E7469636B65742E63726561746F723C2F6B65793E0A09093C73747269
% 6E673E636F6D2E6170706C652E7072696E74696E676D616E616765723C2F7374
% 72696E673E0A09093C6B65793E636F6D2E6170706C652E7072696E742E746963
% 6B65742E6974656D41727261793C2F6B65793E0A09093C61727261793E0A0909
% 093C646963743E0A090909093C6B65793E636F6D2E6170706C652E7072696E74
% 2E50616765466F726D61742E504D566572746963616C5265733C2F6B65793E0A
% 090909093C7265616C3E37323C2F7265616C3E0A090909093C6B65793E636F6D
% 2E6170706C652E7072696E742E7469636B65742E636C69656E743C2F6B65793E
% 0A090909093C737472696E673E636F6D2E6170706C652E7072696E74696E676D
% 616E616765723C2F737472696E673E0A090909093C6B65793E636F6D2E617070
% 6C652E7072696E742E7469636B65742E6D6F64446174653C2F6B65793E0A0909
% 09093C646174653E323030362D31302D30395432303A31303A30355A3C2F6461
% 74653E0A090909093C6B65793E636F6D2E6170706C652E7072696E742E746963
% 6B65742E7374617465466C61673C2F6B65793E0A090909093C696E7465676572
% 3E303C2F696E74656765723E0A0909093C2F646963743E0A09093C2F61727261
% 793E0A093C2F646963743E0A093C6B65793E636F6D2E6170706C652E7072696E
% 742E50616765466F726D61742E504D566572746963616C5363616C696E673C2F
% 6B65793E0A093C646963743E0A09093C6B65793E636F6D2E6170706C652E7072
% 696E742E7469636B65742E63726561746F723C2F6B65793E0A09093C73747269
% 6E673E636F6D2E6170706C652E7072696E74696E676D616E616765723C2F7374
% 72696E673E0A09093C6B65793E636F6D2E6170706C652E7072696E742E746963
% 6B65742E6974656D41727261793C2F6B65793E0A09093C61727261793E0A0909
% 093C646963743E0A090909093C6B65793E636F6D2E6170706C652E7072696E74
% 2E50616765466F726D61742E504D566572746963616C5363616C696E673C2F6B
% 65793E0A090909093C7265616C3E313C2F7265616C3E0A090909093C6B65793E
% 636F6D2E6170706C652E7072696E742E7469636B65742E636C69656E743C2F6B
% 65793E0A090909093C737472696E673E636F6D2E6170706C652E7072696E7469
% 6E676D616E616765723C2F737472696E673E0A090909093C6B65793E636F6D2E
% 6170706C652E7072696E742E7469636B65742E6D6F64446174653C2F6B65793E
% 0A090909093C646174653E323030362D31302D30395432303A31303A30355A3C
% 2F646174653E0A090909093C6B65793E636F6D2E6170706C652E7072696E742E
% 7469636B65742E7374617465466C61673C2F6B65793E0A090909093C696E7465
% 6765723E303C2F696E74656765723E0A0909093C2F646963743E0A09093C2F61
% 727261793E0A093C2F646963743E0A093C6B65793E636F6D2E6170706C652E70
% 72696E742E7375625469636B65742E70617065725F696E666F5F7469636B6574
% 3C2F6B65793E0A093C646963743E0A09093C6B65793E636F6D2E6170706C652E
% 7072696E742E50616765466F726D61742E504D41646A75737465645061676552
% 6563743C2F6B65793E0A09093C646963743E0A0909093C6B65793E636F6D2E61
% 70706C652E7072696E742E7469636B65742E63726561746F723C2F6B65793E0A
% 0909093C737472696E673E636F6D2E6170706C652E7072696E74696E676D616E
% 616765723C2F737472696E673E0A0909093C6B65793E636F6D2E6170706C652E
% 7072696E742E7469636B65742E6974656D41727261793C2F6B65793E0A090909
% 3C61727261793E0A090909093C646963743E0A09090909093C6B65793E636F6D
% 2E6170706C652E7072696E742E50616765466F726D61742E504D41646A757374
% 656450616765526563743C2F6B65793E0A09090909093C61727261793E0A0909
% 090909093C7265616C3E302E303C2F7265616C3E0A0909090909093C7265616C
% 3E302E303C2F7265616C3E0A0909090909093C7265616C3E3738333C2F726561
% 6C3E0A0909090909093C7265616C3E3535393C2F7265616C3E0A09090909093C
% 2F61727261793E0A09090909093C6B65793E636F6D2E6170706C652E7072696E
% 742E7469636B65742E636C69656E743C2F6B65793E0A09090909093C73747269
% 6E673E636F6D2E6170706C652E7072696E74696E676D616E616765723C2F7374
% 72696E673E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E
% 7469636B65742E6D6F64446174653C2F6B65793E0A09090909093C646174653E
% 323030362D31302D30395432303A31303A30355A3C2F646174653E0A09090909
% 093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E737461
% 7465466C61673C2F6B65793E0A09090909093C696E74656765723E303C2F696E
% 74656765723E0A090909093C2F646963743E0A0909093C2F61727261793E0A09
% 093C2F646963743E0A09093C6B65793E636F6D2E6170706C652E7072696E742E
% 50616765466F726D61742E504D41646A75737465645061706572526563743C2F
% 6B65793E0A09093C646963743E0A0909093C6B65793E636F6D2E6170706C652E
% 7072696E742E7469636B65742E63726561746F723C2F6B65793E0A0909093C73
% 7472696E673E636F6D2E6170706C652E7072696E74696E676D616E616765723C
% 2F737472696E673E0A0909093C6B65793E636F6D2E6170706C652E7072696E74
% 2E7469636B65742E6974656D41727261793C2F6B65793E0A0909093C61727261
% 793E0A090909093C646963743E0A09090909093C6B65793E636F6D2E6170706C
% 652E7072696E742E50616765466F726D61742E504D41646A7573746564506170
% 6572526563743C2F6B65793E0A09090909093C61727261793E0A090909090909
% 3C7265616C3E2D31383C2F7265616C3E0A0909090909093C7265616C3E2D3138
% 3C2F7265616C3E0A0909090909093C7265616C3E3832343C2F7265616C3E0A09
% 09090909093C7265616C3E3537373C2F7265616C3E0A09090909093C2F617272
% 61793E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E7469
% 636B65742E636C69656E743C2F6B65793E0A09090909093C737472696E673E63
% 6F6D2E6170706C652E7072696E74696E676D616E616765723C2F737472696E67
% 3E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B
% 65742E6D6F64446174653C2F6B65793E0A09090909093C646174653E32303036
% 2D31302D30395432303A31303A30355A3C2F646174653E0A09090909093C6B65
% 793E636F6D2E6170706C652E7072696E742E7469636B65742E7374617465466C
% 61673C2F6B65793E0A09090909093C696E74656765723E303C2F696E74656765
% 723E0A090909093C2F646963743E0A0909093C2F61727261793E0A09093C2F64
% 6963743E0A09093C6B65793E636F6D2E6170706C652E7072696E742E50617065
% 72496E666F2E504D50617065724E616D653C2F6B65793E0A09093C646963743E
% 0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E
% 63726561746F723C2F6B65793E0A0909093C737472696E673E636F6D2E617070
% 6C652E7072696E742E706D2E506F73745363726970743C2F737472696E673E0A
% 0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E69
% 74656D41727261793C2F6B65793E0A0909093C61727261793E0A090909093C64
% 6963743E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E50
% 61706572496E666F2E504D50617065724E616D653C2F6B65793E0A0909090909
% 3C737472696E673E69736F2D61343C2F737472696E673E0A09090909093C6B65
% 793E636F6D2E6170706C652E7072696E742E7469636B65742E636C69656E743C
% 2F6B65793E0A09090909093C737472696E673E636F6D2E6170706C652E707269
% 6E742E706D2E506F73745363726970743C2F737472696E673E0A09090909093C
% 6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E6D6F644461
% 74653C2F6B65793E0A09090909093C646174653E323030332D30372D30315431
% 373A34393A33365A3C2F646174653E0A09090909093C6B65793E636F6D2E6170
% 706C652E7072696E742E7469636B65742E7374617465466C61673C2F6B65793E
% 0A09090909093C696E74656765723E313C2F696E74656765723E0A090909093C
% 2F646963743E0A0909093C2F61727261793E0A09093C2F646963743E0A09093C
% 6B65793E636F6D2E6170706C652E7072696E742E5061706572496E666F2E504D
% 556E61646A757374656450616765526563743C2F6B65793E0A09093C64696374
% 3E0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B6574
% 2E63726561746F723C2F6B65793E0A0909093C737472696E673E636F6D2E6170
% 706C652E7072696E742E706D2E506F73745363726970743C2F737472696E673E
% 0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E
% 6974656D41727261793C2F6B65793E0A0909093C61727261793E0A090909093C
% 646963743E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E
% 5061706572496E666F2E504D556E61646A757374656450616765526563743C2F
% 6B65793E0A09090909093C61727261793E0A0909090909093C7265616C3E302E
% 303C2F7265616C3E0A0909090909093C7265616C3E302E303C2F7265616C3E0A
% 0909090909093C7265616C3E3738333C2F7265616C3E0A0909090909093C7265
% 616C3E3535393C2F7265616C3E0A09090909093C2F61727261793E0A09090909
% 093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E636C69
% 656E743C2F6B65793E0A09090909093C737472696E673E636F6D2E6170706C65
% 2E7072696E74696E676D616E616765723C2F737472696E673E0A09090909093C
% 6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E6D6F644461
% 74653C2F6B65793E0A09090909093C646174653E323030362D31302D30395432
% 303A31303A30355A3C2F646174653E0A09090909093C6B65793E636F6D2E6170
% 706C652E7072696E742E7469636B65742E7374617465466C61673C2F6B65793E
% 0A09090909093C696E74656765723E303C2F696E74656765723E0A090909093C
% 2F646963743E0A0909093C2F61727261793E0A09093C2F646963743E0A09093C
% 6B65793E636F6D2E6170706C652E7072696E742E5061706572496E666F2E504D
% 556E61646A75737465645061706572526563743C2F6B65793E0A09093C646963
% 743E0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65
% 742E63726561746F723C2F6B65793E0A0909093C737472696E673E636F6D2E61
% 70706C652E7072696E742E706D2E506F73745363726970743C2F737472696E67
% 3E0A0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B6574
% 2E6974656D41727261793C2F6B65793E0A0909093C61727261793E0A09090909
% 3C646963743E0A09090909093C6B65793E636F6D2E6170706C652E7072696E74
% 2E5061706572496E666F2E504D556E61646A7573746564506170657252656374
% 3C2F6B65793E0A09090909093C61727261793E0A0909090909093C7265616C3E
% 2D31383C2F7265616C3E0A0909090909093C7265616C3E2D31383C2F7265616C
% 3E0A0909090909093C7265616C3E3832343C2F7265616C3E0A0909090909093C
% 7265616C3E3537373C2F7265616C3E0A09090909093C2F61727261793E0A0909
% 0909093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E63
% 6C69656E743C2F6B65793E0A09090909093C737472696E673E636F6D2E617070
% 6C652E7072696E74696E676D616E616765723C2F737472696E673E0A09090909
% 093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E6D6F64
% 446174653C2F6B65793E0A09090909093C646174653E323030362D31302D3039
% 5432303A31303A30355A3C2F646174653E0A09090909093C6B65793E636F6D2E
% 6170706C652E7072696E742E7469636B65742E7374617465466C61673C2F6B65
% 793E0A09090909093C696E74656765723E303C2F696E74656765723E0A090909
% 093C2F646963743E0A0909093C2F61727261793E0A09093C2F646963743E0A09
% 093C6B65793E636F6D2E6170706C652E7072696E742E5061706572496E666F2E
% 7070642E504D50617065724E616D653C2F6B65793E0A09093C646963743E0A09
% 09093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E6372
% 6561746F723C2F6B65793E0A0909093C737472696E673E636F6D2E6170706C65
% 2E7072696E742E706D2E506F73745363726970743C2F737472696E673E0A0909
% 093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E697465
% 6D41727261793C2F6B65793E0A0909093C61727261793E0A090909093C646963
% 743E0A09090909093C6B65793E636F6D2E6170706C652E7072696E742E506170
% 6572496E666F2E7070642E504D50617065724E616D653C2F6B65793E0A090909
% 09093C737472696E673E41343C2F737472696E673E0A09090909093C6B65793E
% 636F6D2E6170706C652E7072696E742E7469636B65742E636C69656E743C2F6B
% 65793E0A09090909093C737472696E673E636F6D2E6170706C652E7072696E74
% 2E706D2E506F73745363726970743C2F737472696E673E0A09090909093C6B65
% 793E636F6D2E6170706C652E7072696E742E7469636B65742E6D6F6444617465
% 3C2F6B65793E0A09090909093C646174653E323030332D30372D30315431373A
% 34393A33365A3C2F646174653E0A09090909093C6B65793E636F6D2E6170706C
% 652E7072696E742E7469636B65742E7374617465466C61673C2F6B65793E0A09
% 090909093C696E74656765723E313C2F696E74656765723E0A090909093C2F64
% 6963743E0A0909093C2F61727261793E0A09093C2F646963743E0A09093C6B65
% 793E636F6D2E6170706C652E7072696E742E7469636B65742E41504956657273
% 696F6E3C2F6B65793E0A09093C737472696E673E30302E32303C2F737472696E
% 673E0A09093C6B65793E636F6D2E6170706C652E7072696E742E7469636B6574
% 2E707269766174654C6F636B3C2F6B65793E0A09093C66616C73652F3E0A0909
% 3C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E74797065
% 3C2F6B65793E0A09093C737472696E673E636F6D2E6170706C652E7072696E74
% 2E5061706572496E666F5469636B65743C2F737472696E673E0A093C2F646963
% 743E0A093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E
% 41504956657273696F6E3C2F6B65793E0A093C737472696E673E30302E32303C
% 2F737472696E673E0A093C6B65793E636F6D2E6170706C652E7072696E742E74
% 69636B65742E707269766174654C6F636B3C2F6B65793E0A093C66616C73652F
% 3E0A093C6B65793E636F6D2E6170706C652E7072696E742E7469636B65742E74
% 7970653C2F6B65793E0A093C737472696E673E636F6D2E6170706C652E707269
% 6E742E50616765466F726D61745469636B65743C2F737472696E673E0A3C2F64
% 6963743E0A3C2F706C6973743E0A3842494D03E9000000000078000300000048
% 004800000000030F022FFFEEFFEE033802410367057B03E00002000000480048
% 0000000002D802280001000000640000000100030303000000017FFF00010001
% 0000000000000000000000006808001901900000000000200000000000000000
% 0000000000000000000000000000000000003842494D03ED0000000000100048
% 00000001000200480000000100023842494D042600000000000E000000000000
% 000000003F8000003842494D040D0000000000040000001E3842494D04190000
% 000000040000001E3842494D03F3000000000009000000000000000001003842
% 494D040A00000000000100003842494D271000000000000A0001000000000000
% 00023842494D03F5000000000048002F66660001006C66660006000000000001
% 002F6666000100A1999A0006000000000001003200000001005A000000060000
% 00000001003500000001002D000000060000000000013842494D03F800000000
% 00700000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800000000
% FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800000000FFFFFFFF
% FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800000000FFFFFFFFFFFFFFFF
% FFFFFFFFFFFFFFFFFFFFFFFFFFFF03E800003842494D04080000000000100000
% 00010000024000000240000000003842494D041E000000000004000000003842
% 494D041A00000000035D00000006000000000000000000000183000001560000
% 001400620072006100760065002D0067006E0075002D0077006F0072006C0064
% 002D006C006F0067006F00000001000000000000000000000000000000000000
% 0001000000000000000000000156000001830000000000000000000000000000
% 0000010000000000000000000000000000000000000010000000010000000000
% 006E756C6C0000000200000006626F756E64734F626A63000000010000000000
% 00526374310000000400000000546F70206C6F6E6700000000000000004C6566
% 746C6F6E67000000000000000042746F6D6C6F6E670000018300000000526768
% 746C6F6E670000015600000006736C69636573566C4C73000000014F626A6300
% 000001000000000005736C6963650000001200000007736C69636549446C6F6E
% 67000000000000000767726F757049446C6F6E6700000000000000066F726967
% 696E656E756D0000000C45536C6963654F726967696E0000000D6175746F4765
% 6E6572617465640000000054797065656E756D0000000A45536C696365547970
% 6500000000496D672000000006626F756E64734F626A63000000010000000000
% 00526374310000000400000000546F70206C6F6E6700000000000000004C6566
% 746C6F6E67000000000000000042746F6D6C6F6E670000018300000000526768
% 746C6F6E67000001560000000375726C54455854000000010000000000006E75
% 6C6C54455854000000010000000000004D736765544558540000000100000000
% 0006616C74546167544558540000000100000000000E63656C6C546578744973
% 48544D4C626F6F6C010000000863656C6C546578745445585400000001000000
% 000009686F727A416C69676E656E756D0000000F45536C696365486F727A416C
% 69676E0000000764656661756C740000000976657274416C69676E656E756D00
% 00000F45536C69636556657274416C69676E0000000764656661756C74000000
% 0B6267436F6C6F7254797065656E756D0000001145536C6963654247436F6C6F
% 7254797065000000004E6F6E6500000009746F704F75747365746C6F6E670000
% 00000000000A6C6566744F75747365746C6F6E67000000000000000C626F7474
% 6F6D4F75747365746C6F6E67000000000000000B72696768744F75747365746C
% 6F6E6700000000003842494D041100000000000101003842494D041400000000
% 0004000000013842494D040C000000001A350000000100000071000000800000
% 01540000AA0000001A1900180001FFD8FFE000104A4649460001020100480048
% 0000FFED000C41646F62655F434D0002FFEE000E41646F626500648000000001
% FFDB0084000C08080809080C09090C110B0A0B11150F0C0C0F15181313151313
% 18110C0C0C0C0C0C110C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C
% 0C0C0C0C0C010D0B0B0D0E0D100E0E10140E0E0E14140E0E0E0E14110C0C0C0C
% 0C11110C0C0C0C0C0C110C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C
% 0C0C0C0C0C0CFFC00011080080007103012200021101031101FFDD00040008FF
% C4013F0000010501010101010100000000000000030001020405060708090A0B
% 0100010501010101010100000000000000010002030405060708090A0B100001
% 0401030204020507060805030C33010002110304211231054151611322718132
% 061491A1B14223241552C16233347282D14307259253F0E1F163733516A2B283
% 264493546445C2A3743617D255E265F2B384C3D375E3F3462794A485B495C4D4
% E4F4A5B5C5D5E5F55666768696A6B6C6D6E6F637475767778797A7B7C7D7E7F7
% 1100020201020404030405060707060535010002110321311204415161712213
% 0532819114A1B14223C152D1F0332462E1728292435315637334F1250616A2B2
% 83072635C2D2449354A317644555367465E2F2B384C3D375E3F34694A485B495
% C4D4E4F4A5B5C5D5E5F55666768696A6B6C6D6E6F62737475767778797A7B7C7
% FFDA000C03010002110311003F00F5549249252962FD63FADFD0BEADD3BFA95F
% FA67006BC4AA1D7BC1DC039B4EE6EDAFF46FFD35BE9D3FF09BD61FD7EFAFE3A1
% 8FD91D22323AEDE000000E18E1C3DB658DFA2FC87B7DD451FF00A1191FA2F4AA
% C9E1FA4FD5DCEEA998EEA7D58BFA8751CC74D3597026D70038716BABAF1F1D8D
% DB65FF00CC52CF469AB67A94D8929EA2CFF1C4CB2D8E9FD132322AEEEB2C6D6E
% E63F9BAD993F9BFF0008B5A9FF0018D45AD31D1F3C585E6BA9B1400F7EA1B5D7
% BF258EB2C76DFA14D76A9F4FFA834B58D7E7E4D8D773F66C6706D4D91F47D6B2
% BFB4DCE6EEFE77F56FFC2F5ADDE9BD07A474B71B30B19B5DCE043AF717597104
% 8739AFCABDD6E4399B9BBB67AA9292F4DBFA86452EB73B1460B8B88AA8F505AF
% 0C1F45F7BEAFD0B2C7FF00A1A5F7FA7FF721FF00E0ADA4924A79BEBBD47EB974
% 9B1F7E06053D6B05DAB59597539356AEDCCB1937332D9B7D3F4ACC7632DFF494
% 7F855CB752FF0019FF005971C7A7FB2A8E9F748939A320340D665B65185FF07F
% E13FF3E2F4D49253E59D37FC66FD64B323D4C9AF03269827ECF8FEA31CE8F67E
% 8B21CFC8D9EFFF004B4FFDB5FCF57E83D13AFF004EEB743ADC37383EBDBEB63D
% A36DB5EE1B99BD9AEE63FF00C1DF53ACC7BBFC0DB62C4FAD5FE2EFA4F5B6D995
% 84D6F4EEABF49B91588AEC7025F199437D96FA9BDDFA7FE91FF1BE9FA2BCFABB
% FAD740EBC303A89FB1754C40E38990C135DA1FFE1F7B87EB38D76CF753FF005B
% FD0E4D1FA24A7DB9258DF56FEB0B3ACE31173063E75207AF44CB48FCDC9C677F
% 84C5B7F33FD1FF00336FE916CA4A524924929FFFD0F555CC7D7DFAE15FD58E96
% 3D269B3A96687D7835812039BB77DF618DBB28F52BFD1FF86B3F47F43D5B6AE9
% D782F56EA87EB37D6BCAEAAE71B315961A30441814D42CB3D50DB7DCDD98F5DB
% 97657B7FA45DFE0D2527FAADD06CCA7D9D433C3F2AFB9C2581FF00A5BEEB9DBD
% 98E2CB377BED7B7D5CABBFC151FA7C8B3D15EBDD07A1D7D2F1F7DA18FCFB9A06
% 4DCC076C0FA18F8FBE5D5E263FD0A6BFFAF59FA7B6D58DF527A355481956FBED
% A2B635B31FA3B2D636FBDBB3DCE6DCDAACAFF49F4FF58BAA5D724A52499CE6B1
% A5CE21AD689738E8001DCAE03AFF00F8DAC1C6C87E07D5FC63D57246E67AF3B6
% 86BFE830B3682FCA67A9FB9E8D567F81C9494FA024BCBFA6FF008CDFAD0EC963
% 73B0F06DAF5DF4D0E7D76684336B2CB2DC9ABD5F51DF42C6319FF0D5AE9FA87F
% 8CAFAAB81D3E9CCB6EB1F66434BABC163272416BBD1B59754E2C663BAAB37FF3
% F6D7EAFA567D9FD6494F5292E1F0FF00C6C746C8B62DC0CDA292EDA2ED8D7800
% 7D27DB5D563AE6EC6EDDDE9577AEB7A6756E9BD5F1465F4DC8665504ED2F61E1
% D01DE9D8C3EFAACDAE6FE8EC6FA8929B6B9FFAEDF5529FACFD1DD8A36579F4FE
% 930725E0FB1FA6E61733DEDAB21ADF4EDFFADDFE958FA2B5D024929F11FAB3D7
% 3A85393582F38BD4F049AB6580B75691F68C7CE66D7BFECB7ECD96B367AACCA6
% 7E8EAFB4D78FE9FB2F4ECFA3A8E15799402D65920B1D1B98F6935DD4D9B4B9BE
% A536B1F559B5CBC5FEB8B2AE9FFE303AA8A229AEC6B2D796E9B5D6B28B6DB7FE
% DE7BAE7AEFBEA266165F6E00115DB59B76811B2DC77370AFF5777B9D6DF5FD99
% DFF07E8BFF00B694F66924924A7FFFD1F50CA6DCFC5B9943B6DCEADC2B7710E2
% 0EC77F9CBE7BFAB4E0031BB8377BECA4171F687DA296D46C0DF76C7EC77FDB5F
% CB5F44AF2FFAEFF50F37133EFEBBD0697E5D19AE2EEA3D3DB2FB03DC4BDD918C
% DFA56B2C7B9DBAAFE728B1FF00A1FD0FF454A75FEABFD6CE958551C5CFB7ECF5
% 585A5B976FB6BF576B6ABB1EFB3E856FFD17A8CB5DB29FF03FA3B29FD274EFFA
% CBF5718DDCFEAB86D6F89C8A80FF00AB5E29565B32D95ED7EE021B66FF007169
% 8D1CF6EEAFD4B58DFF00AEBFFAEAE51F567A78A1D939748A98D87B59639AC3EF
% FE65B90E26AAE86BBE97BFFF0003FCF4A6F7D6CFAD79DF5D731DD27A3EFABA15
% 0EFD259043B21CD3B9AFB07E653B87EAD8EFFF008EBFF58FB3E3D15B1BEAF328
% A994359B8D861B5D675B0804BFE916D96FE6FAAC67E67E8BFC27A0AE74EB72F2
% 5870FEAFE28BE9A5C2B665D601C7A3633D4B6DB03D94D3EADAEB376FBEFF00A1
% BFF43916FF00379FD33A66664752756E75BD42C69DAEAEB0C7EE206DDD6DB697
% 6DDBFF0069BF4791F63FE91FA0BD3A1094FE51F5DB4592CB18EA5B67A664E3D2
% 2CFB3D8CA7710D2D6398C0EDAF6B296B3D3AD9EAEBFB9EA7F3BF43F3F3727168
% 19363AD65673C1FD333783732086ED756E2EB9F6FF00C5FDA2F7B3FE1175DD4D
% B57D9CBF368C367516FA78ADC2A326FBC8C6AEC7E4E463F517D77D1535FEA3BF
% 43BFF9CBFF0056FD27ABE9ACCE9F89899F636ACAE9F878990197598CCFB5B28B
% 2B25D35E2E6E1DF75F915DBB3D4C87BEBC6FF47EAD767E92C481C7C5C249F31C
% 3308E324D47865A5D7CAE05D7D74EFAAF0FA5EE716163DA46D734B37D3B086FA
% 16FD0F568FE77DFF00A657BA5F54C8C1CCAF370EFF00B2DAD86B5ED1B9AF6C7F
% 35918ECFE9547FC67E9B7FF45FB3FD35B35F41EAB876BF763B6DC4B6B873F633
% 63B74FF3B4B5D7D9F67D5ED6E5595FBFFE2972AFC5AF2736EFD9CE6E157EA0AA
% 9DC1EDAED786FB9BE859BBD2FA5F9BFF006CFEE38E23FA244BF050C9FBC0C5F5
% 7E8DF5F3A4655219D5AEA7A5E6B44B9B6D81B4BC69FA5C5C9B7D3ADFBB77F30E
% FD62AFF8BFD3595BAD7F8D3FAA9D36A78C6C8FDA59634AE8C604B4B88259BB28
% B7D06D7BBD8FF4DD75ACFF004162F2BBED78B0E1753A832CD4327F9A7C7B5BB2
% C1FE05AE6FBF6BFF00EDB46C6C460692D0CADDA83B581B13F9D5B9A2FC8B9BFB
% 9E933E87F39E8A8D911B9DD47AC754BFAAF5100E6E7BD8E3535BA064B7ECF486
% 39DFE15F551450CDFF00D169CBB6FF00E6BD45E93F526870CC65A5C48B3ED16B
% 09DB2F639D57BDAD23D477B9DEA596FEFDB5D5FF0072172BD2FA68BEE630576F
% A4F0EDC04BF22E062A7574D67DEF7E47D0BBF49ECC3FE7B2A9C15E97F573A3BB
% A6E33ACBDA1995901BEA3038BF635BBBD2A5D6E9EB58CF52CF52EDBFF07FCC55
% 424A7612492494FF00FFD2F5549249253CF7D68FABFF0055F268B3AA755C3DD7
% D23DB918FB9992E7BB6D345553F1DD5D9917BECF4E9C5AADF53F49FA35C2E4F5
% 3661D76B2DA3EDF994EFAB23A78AFED5563B590F7613C3856CCACBF6FA99BD4E
% EFF26E33FF0047D330723D3FD1749F5D7A9F52CCCFAFA27437554E6B008CAB1E
% 5B6B5D68B2BB5BD3298FD264D78CCB7D5CD67F43AAEBAA65B55CFB3D3E7F230C
% B2ACACAEB9946F65120D3539C7098F7FE8EBFB7E5BEFAF2BABE53D9E97EADEAF
% F83FD62CF4922247488DF792C9DE801AEB6931EFCEFDA15D7D53229C8C363C33
% 0BA4E23EB661E457B3754FF4EDF4FD7C2AABB7F9CA3A6B2AC8B7F49FCD7A2B5B
% AE67E453D0FECD5B9CEA3D573336EC4A982B67B4BAAC5CAFB3D8FF00D5AFB1FF
% 00A4BD9E933F57F432FF004795F67B70BA2E4E3E3DB9165384324BFF00441C1A
% DC72F1F9D6DAEA5F4E2D357FC17ABB2BAFF4752DAEA3D4DDD4307131FA18A2DA
% 301CE7E6E2E23DB5B18F1FD15DBEE7D3859B4D0EDEFBB17ED6CFD73ECB91FA5A
% EAB2A5265C5C38AA20D91F6B1717171441D28D7EFF00F8CF0993539C5FBEF15B
% 291B9D5D55B8811F9D75B90E63BFEB752C8BBAAE3ED69A45B63AA3BCBDE1AD0E
% 27F36CDBBB756BAAB3A062D9EA37A9D79B65D66EB68A2C6B6963DAD875B73BA8
% 5566563E5D0DF519FCCBF7D2A3D32CC365CCAFA7537E63041B29C67B1986C7FD
% 16B9F75ADDEFFF0084B37AA5A0BB04D74F958408C7420923A7F37170065DD7D4
% 6AB5CD14002D632A77B6BD7F9B0D656FDAD64FE8B73FF43FE0D74EDEAACBBAB5
% 54F54A2D38F750D37676D0368693B72AC7E3B1CC7D6EDDEFB3D0A2CC6FE777AC
% BEBF9D8B84D76331953F2EDDC6E6E35E6DA9A09FFB55B9BB773377E62CFC4B3A
% BDD857DB5DB8B8C368A4DD6BCD6F7899FD0BED3E9B94B8BDCF9A029920244588
% 81127691F9BC5ECBAAF4BE92FE934F45AB25D9349B5D6E0DD5D6CBDB734B0B3E
% CD4E5FAB7E3FDA5AD637D47B3D3C9A3D2F655E865FA8AC7D4AFA96DCCE995DB6
% 7516BEB63BD3C8AEBAE6EAEC60FD2E1DAEB9F6D0C7635DF47F57BBD7A7D2B3F9
% 9F4960F4AE946EC62D17FDAAEC96B6BCA2D756CABD6AC3DF8D55198CB2BF4DBE
% EF7DDB3F4967AAB4FEAA75FCBE97D7AAB7A99ADADEA8598D7FA43F3E3D3664DF
% EED8EF4727F41F68FDCBAFF53D5FD0FA73F0C88E23BF567040A1B7F2EEFA574D
% E8FD3FA6348C5ACFA8F1166458E365CFFF008DC8B4BED7FF005377A75FF83575
% 249317A92492494FFFD3F5540CDCBA7070EFCDBE7D1C6ADF759024EDADA6C7ED
% 1FD56A3AC6FADED73FEAEE5D4D0E70BFD3A5ED67D2732DB6AA2D637FAF558F6A
% 205903BA09A04F67CF7033735DD49EFCCBC56FB817E4B2A8B5F73277E5BED716
% 8AFECD7DFF00AB50C6DB5E27A18FFA0F52BF52EB639FD5FA4F53EA95BDF7D74B
% F56E363068BACAC47BF3B2AF6B7ECD4E43F6ECA7171BF9AAD6565E065E7B6CCB
% EA00B6ECB3AD4C97319B0B6BA316B69FA0DA59ECD8D51ADDD3FA45B4D74B9A5C
% 4137BDCD0D0D703F45EF8F7395D8E2BE136234D2965AE214657FB1EB3A2FD5AC
% 1CE65561C3765C1871B1CD74FF00C3653ACFFA152E94748E9B896558B9D9D4D3
% EAB837170DA2AA019D19556C76EB2E589F54BEB1DB957B28B2C2719C4CFBAAAD
% BFD7DC18CB9FB7F777AA37D79D5B5ECCEE9B7FA5937D97752CDC50C7E2DAF7B9
% E5CE65949BADFB1B58D63297E5329F43FED5FE9941CD66CB8F4034FD8BB1C61C
% 3C422724AF500FC81EA3EB5D5F57A707F6BE0D9D42DAF78C4631AE2D13E9FAA2
% FDAEAB1BD37EDABD97FF00DB6B88C5E875E063D9FB2F3701F1FCF65F546BEA35
% C0F7BAA6FAD761DBFF0007B28A3FEBCB7BA3F59C3C8C3C5E9E3A7D995D1AA7B6
% 8A6F6D6E6B68630399F68BB3BDBD3F32B63BDB63E9BBD7FF0083CAB568F55C1E
% 974D03A87567557E257B431CCADD90F74FD06D7454C737FB7B2C55E1EDE404CE
% C3626090008F144F4F95F27C9AB273DD90CA328DD8EF2DFB4E5340AABB4D5BFD
% 1F4F1696EF7B6BF51DFA4BBFF0244FB062605943F20B03EC6EDADA185EE04705
% ACB0EE5DD1FACBF563A858DB3A6DD461BAB7FA577DB5CEAB68076B2C6D78D5D9
% 89E959FE96DC9ABFE13629E67D54C4A1B9199BEA3601B9D977B0D74B43BFD1DB
% 7FB6EFE47A2AD619E28815F9316486422AA8741178FC2A1D8C0E5E53DE5F6383
% 7F492DB1D3F4767A7BB62D7CEFD99574AC2A32697DADBF7FDA5CDB87A8CAD8E1
% 8FE8E39B9B5D76DF6FDA5CFB3D4B6AA6AABFE16C5BBD12AE9991655563E3E466
% 565C19F6A35B4540BBDAEB3DCFF57D26CFEE2E33EB4F561922B6FA5B1A379C0A
% BE8FA55FABFE135B7ED19190CAAAFB4BFD6B3D6B595D389FA2AFF4ADE672C741
% 0DEC52DC6271167524D01FCBFAAFAEFD55EA87ABFD5DC0CF738D96DB486DEF23
% 693757FA0C9F60FF00BB15DAB55711FE2872326DFAAF757907F98CCB5958F06B
% 9B4E4B9BFF006EE45ABB75036D4924924A7FFFD4F5558DF5BDF6D7F56F3ADA49
% 6BEA636D2F01C4B5B5BD965B6B3D27D36FA9556C7D95FA76D6FDEB6557EA1875
% 67E064E0DD22ACBA5F45846876D8D756E8FECB920A7C9EEA6ACA38EE3906D662
% D4CB5F75EDF4FDD73836D77A34BBDAFF006EC7596FBFD8B9FBDAD63ADBECA9E6
% BAEE7578F5B8B29AC1ECED9EEB2DDCBB1A73AA181D3F1AFE97567754CE0FC67D
% 15B8627A2CC670AF2AA7DF93BB7E6E265BF7FA0CF57F55F52FBBF43E9AC7B7A1
% 0A3AADE3A9EF7673CB9D8E5CC1B5CD0760FB3501D67B9D5ED77D3FE5AB98720E
% 2E1EDDDA99B1CB8788F5EDFCA2D06750EAD7DADA2BDAC635BEE0E240D7F77D3D
% BB96DF4EB5F80D6E665DB2FA3FA3B48343371FF876BFD472BB8FD1FA87A6D751
% 8CD6318D906DF7DA5C78F6FB58CFEA6E552EFAB5998E0E6752C865CEB6093686
% B4B5AEF6B5B4D13F9AAC4CE396FA9FDE916B43DC8EDE91FBB10A1D6BAE751C81
% 5636539A376E7D8DCB018C6F01B4D3634AE9B05BD4322E6E4BBA8E7166303EF6
% 369B19FCADDEDF771FB8B98FB25188064DD6597D6E3B69A890DAE7FE118D1B95
% DBE9C9C8A98DC9CDAB171DBEEB035E71E96B40ED57D3B1CA0963801A533C72CC
% CB5B010F59C56E3D95E2F4ECEA9D80E712CC5EA356512D2E3B8D2D6D1558FEA1
% 539CE73EBB2EFD255FCDDD7DDFA351E9FD2F1307A6754CDEA783FB50E316E4D3
% 82C16E26234B22A3E85777E8D8E731CFB3F494FAD91FCDD14BEC57F13AEF4AC2
% C607A6D2FCDA1CE0D2E61735D69F065D99B1EDABFA8A97D64CEEB228FB65B7D6
% DC5DE0D75BDBB6BC279DD6578D663D363AAC8B7F47EAE1755B3FED47A95FEA17
% 7A75AA73C631DCA313E619C480B908EA770373E6D6EA9D5B2998EEC379AFA763
% 3C7E93030B7B5CFD1D355F6B36E5DBB98FD8FF0052EC7FFC28B98C8B85A1F940
% 9194EC8D9556D7EFA68A7D36D755BE87B76BFF0048FF0041BBBF45E97A5E9A06
% 4D97D871AEF42F73322C2DC7810EBDE0ECDB5D7B9EE6B77FE6318AE61747B71B
% 09FD43A8BEBC375B3914D17822D35CBB1DD9505BE937D5BACF4B11B77E93F476
% 5D4D1E9FE99478ACCAE66FCD18C4F52753AD7689FEAC5F48FF0014B5399F56F2
% 2D8229BF32C763B9D12EAD95D18BBFFCFC7B176CB17EA6F4B7F49FAAFD3B06D0
% E6DCDA459736CFA4DB2E2ECABEB3FF001575CFAD6D2909B24B30D8292492412F
% FFD5F5549249253E7FF59FA2BA8EB36D54322BEA85B97845D5B1F43336B0E666
% 36E6E8EAA9C8A1FF006AB1FF00E9BED19DFF0068D71BD3BAFF0059E997BF1ABC
% DBFA6D588F7369C41B6EDAE2FDB94CBB0DFBE86FA567A9B6B6FD9FD25ECDD57A
% 5E3F54C3762DC5D59FA555F512CB6A7C1636EA2D6FBEBB36BDECFE5D6FB2AB3F
% 45658BC83AF62752C0CDFB0756B6F168975D9CFDF683496B68B3305EDFD25DED
% AF1EADF657FAAFF84FD37F3CD98BA901AEC4FF00D12C538906E3609D3FDF76F1
% FEB7579F9197D3B2E8CAEA179B3ED347D8E9DAD732B6EEDB9955C5DE87BB657E
% BD3EA63FBEAB6DF47F49BF732EDE91D3F16EEA8CC68CE636B376156F66EA6B2E
% 6B2FC9B6CC6AAFB594E356FF005AFB3659FF004D79C63F4FCDF4DBD5F019916B
% 6A314D992E360158DD53AEAE9A19FA6F4B73FDDBBD3FF825D1F40FACAFE9186F
% C3A319F9E64D6E360FB33741EE6B31EB190CBB9FF0FE9A9E10C9C3E202B8A028
% 4883D24D8CFC8C7AADAF26CCA63A9B9C7D0C5E9CDF5CD8D9735B7DD9DBF73B7E
% DFCC585D7F21DD41CE755EAE3328FE75D75D1BDDE544D97B96F7526331B0307A
% 93BA3E253EAD8EA48B6B326297E4D57D7F637E135DBFECF7FDA7FC1FF33F6654
% 3A7750AF39AD03A636BA32ED34E26563D37D4031822FCADB6372B0B231FD7FD5
% BFE50FB431FF00E0D18E500F0CAEC782D30B97A2B6E2FA3CD60559AF2E79B5CF
% B1876B0D9EF0D1FF00042C236FF9AB77173B330996578D8B45965B5BA9393635
% CE7FE91A6BB5B8D5D1B37BFD377F38F7A2751A5D4877D9F19F4575CD6FA4B4B9
% FBBFD23DCCB2AA68639DFE95DEA2A1665518321FB32B318C00D4C6B9DB77F6B2
% DDEFAA9FEDFF00EC3298CA128D57F6B1819233BBEBA7F55B7D331B2BA7E47DA9
% D96F7E4DB532B69F49AEB98D67E869A6BB1AF7ECF53F3B66CF5BFC3AB9D23A4D
% 3D73EB0E1F4BC661FD8D82FF00B5E550C0CFB392DF73BD59AF6E6BB3733F47F4
% 28C5A71BEDB8DD3EAB31FF004EB0DB89D4FAC64D54301C8B321C594E2E382CAB
% DA36DAEB2C77E652D3B2D7B99FABB3F9CAFF004F532CF5DFAAFF0056707EAEF4
% FF00B3E3B41C8BA1F9778E6CB23B6EF7368ABE863D5F98CFF497D975D6D69803
% 402BC1B10DBC3F96CECA492498BD4924924A7FFFD6F5549249252952EA9D2713
% AAE31A32439AE1269BEB3B6DA9C46DF571EDFF0006FF00FC0EDAFF00437B2DA6
% CB2B5752494F997D6BE8DF5C7A66396E2DCEBBA73A03ECC16BAAF4F46FDA6FBF
% A762EC7DBEB3C7ADEA3B272E967A6FFD16262DDE9ACCE85D7BA735CCF4AAC7AE
% F757635D9F5D0E70F5D83FA6578D3E93EF636CAAEBB1BF9A7BFF0098F4D7B02C
% AEABF55BEAF75871B3A8605375CE2D27200F4EEF6FD0FD6A8F4F23DB1FE95189
% A24EBAF62B4C7EBFDEF57FD27C67AA5DD5E8C99CBB5F55F631AE75D90F739EE6
% 387A83D3B7F3E9B367F38FB3DFB3F9AFF06A855D63A97DA19958F66497B8906C
% A8BE96991B36D6FA9DEDFF0037DEBD6F23FC58740BEFF546466D4D6886542E16
% 359F4B5ADF975E4DEDDAE7EEFE79059FE2A3A00205D9BD4322A9F7D365CC0C7C
% F6B7D1A29B5DC7FA451FB601D18FDAA363F3D5F361F597AC0AAAFB5E6D8EAEB6
% 6D6E27AA58CB23F372F65953EDC777F85DBFA7C9FF00C11747D1BEABE5F5CD8F
% C4C72709E5B65B9F91BA8C7B090DDDF67C46B6ACDC8AAA63FF0045FA4A2AC8FC
% FCCA7FC27A074AFA97F557A4383F03A6D2CB1AFF005196D80DD635C349AAFC93
% 75B57FD6DEB6D3E371BA3BB208F7F579B95D03EAEE0F43C7D94FE9B25E22ECA7
% B5A1EE03E8D4C6D6D65746355FE031286B28ABFE37D5B2CD5492497292492494
% A49249253FFFD9003842494D0421000000000079000000010100000018004100
% 64006F00620065002000500068006F0074006F00730068006F00700020004500
% 6C0065006D0065006E007400730000001C00410064006F006200650020005000
% 68006F0074006F00730068006F007000200045006C0065006D0065006E007400
% 7300200032002E003000000001003842494D042200000000012E4D4D002A0000
% 00080007011200030000000100010000011A00050000000100000062011B0005
% 000000010000006A012800030000000100020000013100020000001D00000072
% 01320002000000140000008F8769000400000001000000A4000000D000000048
% 00000001000000480000000141646F62652050686F746F73686F7020456C656D
% 656E747320322E3000323030363A31303A30392032323A31303A313900000003
% A001000300000001FFFF0000A00200040000000100000156A003000400000001
% 000001830000000000000006010300030000000100060000011A000500000001
% 0000011E011B0005000000010000012601280003000000010002000002010004
% 000000010000012E020200040000000100000000000000000000004800000001
% 00000048000000013842494D03FD0000000000070000000000000000
%EndPhotoshop
%begin_xml_code
/pdfmark where {pop true} {false} ifelse
/currentdistillerparams where {pop currentdistillerparams
/CoreDistVersion get 5000 ge } {false} ifelse
and not {userdict /pdfmark /cleartomark load put} if
[/NamespacePush pdfmark
[/_objdef {photoshop_metadata_stream} /type /stream /OBJ pdfmark
/MetadataString 5038 string def % exact length of metadata
/TempString 100 string def
/ConsumeMetadata {
currentfile TempString readline pop pop
currentfile MetadataString readstring pop pop
} bind def
ConsumeMetadata
%begin_xml_packet: 5038
<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?> <?adobe-xap-filters esc="CR"?> <x:xapmeta xmlns:x='adobe:ns:meta/' x:xaptk='XMP toolkit 2.8.2-33, framework 1.5'> <rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:iX='http://ns.adobe.com/iX/1.0/'> @@ -598,77 +61,7 @@ ConsumeMetadata -<?xpacket end='w'?> -%end_xml_packet -[{photoshop_metadata_stream} 2 dict begin /Type /Metadata def /Subtype /XML def currentdict end /PUT pdfmark -[{photoshop_metadata_stream} MetadataString /PUT pdfmark -[/_objdef {nextImage} /NI pdfmark -%end_xml_code -gsave % EPS gsave -/hascolor -/deviceinfo where -{pop deviceinfo /Colors known -{deviceinfo /Colors get exec 1 gt} -{false} ifelse} -{/statusdict where -{pop statusdict /processcolors known -{statusdict /processcolors get exec 1 gt} -{false} ifelse} -{false} ifelse} -ifelse -def -40 dict begin -/_image systemdict /image get def -/_setgray systemdict /setgray get def -/_currentgray systemdict /currentgray get def -/_settransfer systemdict /settransfer get def -/_currenttransfer systemdict /currenttransfer get def -/blank 0 _currenttransfer exec -1 _currenttransfer exec eq def -/negative blank -{0 _currenttransfer exec 0.5 lt} -{0 _currenttransfer exec 1 _currenttransfer exec gt} -ifelse def -/inverted? negative def -/level2 systemdict /languagelevel known -{languagelevel 2 ge} {false} ifelse def -/level3 systemdict /languagelevel known -{languagelevel 3 ge} {false} ifelse def -level2 {/band 0 def} {/band 5 def} ifelse -gsave % Image Header gsave -/rows 387 def -/cols 342 def -342 387 scale -level2 { -/DeviceRGB -setcolorspace currentdict /PhotoshopDuotoneColorSpace undef currentdict /PhotoshopDuotoneAltColorSpace undef } if -/beginimage level2 -{/image load def} -{{pop .9 setgray 0 0 moveto 0 1 lineto -1 1 lineto 1 0 lineto fill 0 setgray -0 1 translate 1 cols div 1 rows div scale -/ratio {cols 400 div mul} def -/Helvetica findfont 15 ratio scalefont setfont -5 ratio -20 ratio moveto -(Mit JPEG komprimierte Bilder ben\232tigen PostScript Level 2) show -/x 128 string def -{currentfile x readline {} {pop exit} ifelse -(~>) search {pop pop pop exit} {pop} ifelse -} loop } def} -ifelse -12 dict begin -/ImageType 1 def -/Width cols def -/Height rows def -/ImageMatrix [cols 0 0 rows neg 0 rows] def -/BitsPerComponent 8 def -/Decode [0 1 0 1 0 1] def -/DataSource currentfile /ASCII85Decode filter -/DCTDecode filter def -currentdict end -%%BeginBinary: 21006 -beginimage -s4IA0!"_al8O`[\!W`9l!([(is6]js6"FnCAH67k!!!!"s4[O,!"obO%M0*b&.fQt +<?xpacket end='w'?>
%end_xml_packet
[{photoshop_metadata_stream} 2 dict begin /Type /Metadata def /Subtype /XML def currentdict end /PUT pdfmark
[{photoshop_metadata_stream} MetadataString /PUT pdfmark
[/_objdef {nextImage} /NI pdfmark
%end_xml_code
gsave % EPS gsave
/hascolor
/deviceinfo where
{pop deviceinfo /Colors known
{deviceinfo /Colors get exec 1 gt}
{false} ifelse}
{/statusdict where
{pop statusdict /processcolors known
{statusdict /processcolors get exec 1 gt}
{false} ifelse}
{false} ifelse}
ifelse
def
40 dict begin
/_image systemdict /image get def
/_setgray systemdict /setgray get def
/_currentgray systemdict /currentgray get def
/_settransfer systemdict /settransfer get def
/_currenttransfer systemdict /currenttransfer get def
/blank 0 _currenttransfer exec
1 _currenttransfer exec eq def
/negative blank
{0 _currenttransfer exec 0.5 lt}
{0 _currenttransfer exec 1 _currenttransfer exec gt}
ifelse def
/inverted? negative def
/level2 systemdict /languagelevel known
{languagelevel 2 ge} {false} ifelse def
/level3 systemdict /languagelevel known
{languagelevel 3 ge} {false} ifelse def
level2 {/band 0 def} {/band 5 def} ifelse
gsave % Image Header gsave
/rows 387 def
/cols 342 def
342 387 scale
level2 {
/DeviceRGB
setcolorspace currentdict /PhotoshopDuotoneColorSpace undef currentdict /PhotoshopDuotoneAltColorSpace undef } if
/beginimage level2
{/image load def}
{{pop .9 setgray 0 0 moveto 0 1 lineto
1 1 lineto 1 0 lineto fill 0 setgray
0 1 translate 1 cols div 1 rows div scale
/ratio {cols 400 div mul} def
/Helvetica findfont 15 ratio scalefont setfont
5 ratio -20 ratio moveto
(Mit JPEG komprimierte Bilder ben\232tigen PostScript Level 2) show
/x 128 string def
{currentfile x readline {} {pop exit} ifelse
(~>) search {pop pop pop exit} {pop} ifelse
} loop } def}
ifelse
12 dict begin
/ImageType 1 def
/Width cols def
/Height rows def
/ImageMatrix [cols 0 0 rows neg 0 rows] def
/BitsPerComponent 8 def
/Decode [0 1 0 1 0 1] def
/DataSource currentfile /ASCII85Decode filter
/DCTDecode filter def
currentdict end
%%BeginBinary: 21006
beginimage
s4IA0!"_al8O`[\!W`9l!([(is6]js6"FnCAH67k!!!!"s4[O,!"obO%M0*b&.fQt '+km!,8q:3)C$FB(Ddl(+qY4l$k*OQ&I]'V$k*OQ$k*OQ$k*OQ$k*OQ$k*OQ$k*OQ $iq%U',DH$)]';0'FkT_'GM#e%Ls0b$k*OQ$kX'[$k*OQ$kWmV$k*OQ$k*OQ$k*OQ $k*OQ$k*OQ$k*OQ$k30O!"fJ;K)o!T!?qLF&HMtG!WUsU"995;_uW(&!!*6(!<E3% @@ -985,9 +378,4 @@ P"KeukZoD(0?%Inm@+%To>d`-]BZ:eT4b-1P?\XtIBLQ#Ou?0'_*:r(p6IVgL7U\d e<718C=1KkIR!E`os"4GNSjHmdoMW',cN&P8P2Q"P#@H7,a>*f8L5f2P"A8;,a)&g 8L0OrP"?rK,a(_ps4?ZO?6#,#IDmMkaX!e>;I1?+8q"Z)iQ3@CgeqGuP"L/A-/lrk Vqb0V*0NpB`?jKb,cBEq?6#,#IDmMkaX!e>;I1?+8q"Z)iQ3@CgeqGuP"L/A-/lrk -Vqb0V*0NpB`?jKb,cBEq?6#,#IDmMkaX!e>;I1?+8q"Z)iQ3@CgeqGuP"L/A-/lrkVuPE~> -%%EndBinary -grestore end % Image Trailer grestore -grestore % EPS grestore -[{nextImage} 1 dict begin /Metadata {photoshop_metadata_stream} def currentdict end /PUT pdfmark -[/NamespacePop pdfmark +Vqb0V*0NpB`?jKb,cBEq?6#,#IDmMkaX!e>;I1?+8q"Z)iQ3@CgeqGuP"L/A-/lrkVuPE~>
%%EndBinary
grestore end % Image Trailer grestore
grestore % EPS grestore
[{nextImage} 1 dict begin /Metadata {photoshop_metadata_stream} def currentdict end /PUT pdfmark
[/NamespacePop pdfmark
\ No newline at end of file diff --git a/Master/texmf-dist/doc/generic/pgf/images/brave-gnu-world-logo.xbb b/Master/texmf-dist/doc/generic/pgf/images/brave-gnu-world-logo.xbb new file mode 100644 index 00000000000..8a4669dd911 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/images/brave-gnu-world-logo.xbb @@ -0,0 +1,6 @@ +%%Title: /Users/tantau/Library/texmf/tex/generic/pgf/doc/generic/pgf/images/brave-gnu-world-logo.jpg +%%Creator: extractbb 20130405 +%%BoundingBox: 0 0 342 387 +%%HiResBoundingBox: 0.000000 0.000000 342.000000 387.000000 +%%CreationDate: Tue Aug 27 10:50:29 2013 + diff --git a/Master/texmf-dist/doc/generic/pgf/macros/pgfmanual-en-macros.tex b/Master/texmf-dist/doc/generic/pgf/macros/pgfmanual-en-macros.tex index 116cde6d9bf..e687ae3c426 100644 --- a/Master/texmf-dist/doc/generic/pgf/macros/pgfmanual-en-macros.tex +++ b/Master/texmf-dist/doc/generic/pgf/macros/pgfmanual-en-macros.tex @@ -7,8 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -% $Header: /cvsroot/pgf/pgf/doc/generic/pgf/macros/pgfmanual-en-macros.tex,v 1.45 2009/11/15 13:13:24 ludewich Exp $ - +% $Header: /cvsroot/pgf/pgf/doc/generic/pgf/macros/pgfmanual-en-macros.tex,v 1.79 2013/12/20 15:22:35 tantau Exp $ \providecommand\href[2]{\texttt{#1}} @@ -18,20 +17,34 @@ \colorlet{examplefill}{yellow!80!black} \definecolor{graphicbackground}{rgb}{0.96,0.96,0.8} -\definecolor{codebackground}{rgb}{0.8,0.8,1} +\definecolor{codebackground}{rgb}{0.9,0.9,1} \newenvironment{pgfmanualentry}{\list{}{\leftmargin=2em\itemindent-\leftmargin\def\makelabel##1{\hss##1}}}{\endlist} -\newcommand\pgfmanualentryheadline[1]{\itemsep=0pt\parskip=0pt\item\strut{#1}\par\topsep=0pt} +\newcommand\pgfmanualentryheadline[1]{\itemsep=0pt\parskip=0pt{\raggedright\item\strut{#1}\par}\topsep=0pt} \newcommand\pgfmanualbody{\parskip3pt} +\let\origtexttt=\texttt +\def\texttt#1{{\def\textunderscore{\char`\_}\def\textbraceleft{\char`\{}\def\textbraceright{\char`\}}\origtexttt{#1}}} +\def\exclamationmarktext{!} +\def\atmarktext{@} + +{ + \catcode`\|=12 + \gdef\pgfmanualnormalbar{|} + \catcode`\|=13 + \AtBeginDocument{\gdef|{\ifmmode\pgfmanualnormalbar\else\expandafter\verb\expandafter|\fi}} +} + \newenvironment{pgflayout}[1]{ \begin{pgfmanualentry} - \pgfmanualentryheadline{\texttt{\string\pgfpagesuselayout\char`\{\declare{#1}\char`\}}\oarg{options}} + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + \texttt{\string\pgfpagesuselayout\char`\{\declare{#1}\char`\}}\oarg{options}% + } \index{#1@\protect\texttt{#1} layout}% \index{Page layouts!#1@\protect\texttt{#1}}% - \pgfmanualpdflabel{#1}{}% \pgfmanualbody } { @@ -48,12 +61,149 @@ \end{pgfmanualentry} } +\makeatletter + +\def\includeluadocumentationof#1{ + \directlua{require 'pgf.manual.DocumentParser'} + \directlua{pgf.manual.DocumentParser.include '#1'} +} + +\newenvironment{luageneric}[4]{ + \pgfmanualentry + \pgfmanualentryheadline{#4 \texttt{#1\declare{#2}}#3} + \index{#2@\protect\texttt{#2} (Lua)}% + \def\temp{#1} + \ifx\temp\pgfutil@empty\else + \index{#1@\protect\texttt{#1}!#2@\protect\texttt{#2} (Lua)}% + \fi + \pgfmanualbody +}{\endpgfmanualentry} + +\newenvironment{luatable}[3]{ + \medskip + \luageneric{#1}{#2}{ (declared in \texttt{#3})}{\textbf{Lua table}} +}{\endluageneric} + +\newenvironment{luafield}[1]{ + \pgfmanualentry + \pgfmanualentryheadline{Field \texttt{\declare{#1}}} + \pgfmanualbody +}{\endpgfmanualentry} + + +\newenvironment{lualibrary}[1]{ + \pgfmanualentry + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + \textbf{Graph Drawing Library} \texttt{\declare{#1}}% + } + \index{#1@\protect\texttt{#1} graph drawing library}% + \index{Libraries!#1@\protect\texttt{#1}}% + \index{Graph drawing libraries!#1@\protect\texttt{#1}}% + \vskip.25em + {\ttfamily\char`\\usegdlibrary\char`\{\declare{#1}\char`\}\space\space \char`\%\space\space \LaTeX\space and plain \TeX}\\ + {\ttfamily\char`\\usegdlibrary[\declare{#1}]\space \char`\%\space\space Con\TeX t}\smallskip\par + \pgfmanualbody +}{\endpgfmanualentry} + +\newenvironment{luadeclare}[4]{ + \pgfmanualentry + \def\manual@temp@default{#3}% + \def\manual@temp@initial{#4}% + \def\manual@temp@{#3#4}% + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + {\ttfamily/graph + drawing/\declare{#1}\opt{=}}\opt{#2}\hfill% + \ifx\manual@temp@\pgfutil@empty\else% + (\ifx\manual@temp@default\pgfutil@empty\else% + default {\ttfamily #3}\ifx\manual@temp@initial\pgfutil@empty\else, \fi% + \fi% + \ifx\manual@temp@initial\pgfutil@empty\else% + initially {\ttfamily #4}% + \fi% + )\fi% + }% + \index{#1@\protect\texttt{#1} key}% + \pgfmanualbody + \gdef\myname{#1}% +% \keyalias{tikz} +% \keyalias{tikz/graphs} +}{\endpgfmanualentry} + +\newenvironment{luadeclarestyle}[4]{ + \pgfmanualentry + \def\manual@temp@para{#2}% + \def\manual@temp@default{#3}% + \def\manual@temp@initial{#4}% + \def\manual@temp@{#3#4}% + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + {\ttfamily/graph drawing/\declare{#1}}\ifx\manual@temp@para\pgfutil@empty\else\opt{\texttt=}\opt{#2}\fi\hfill% + (style\ifx\manual@temp@\pgfutil@empty\else, % + \ifx\manual@temp@default\pgfutil@empty\else% + default {\ttfamily #3}\ifx\manual@temp@initial\pgfutil@empty\else, \fi% + \fi% + \ifx\manual@temp@initial\pgfutil@empty\else% + initially {\ttfamily #4}% + \fi% + \fi)% + }% + \index{#1@\protect\texttt{#1} key}% + \pgfmanualbody% + \gdef\myname{#1}% +% \keyalias{tikz} +% \keyalias{tikz/graphs} +}{\endpgfmanualentry} + +\newenvironment{luanamespace}[2]{ + \luageneric{#1}{#2}{}{\textbf{Lua namespace}} +}{\endluageneric} + +\newenvironment{luafiledescription}[1]{}{} + +\newenvironment{luacommand}[4]{ + \hypertarget{pgf/lua/#1}{\luageneric{#2}{#3}{\texttt{(#4)}}{\texttt{function}}} +}{\endluageneric} + +\newenvironment{luaparameters}{\par\emph{Parameters:}% + \parametercount=0\relax% + \let\item=\parameteritem% + \let\list=\restorelist% +} +{\par +} + +\newenvironment{luareturns}{\par\emph{Returns:}% + \parametercount=0\relax% + \let\item=\parameteritem% + \let\list=\restorelist% +} +{\par +} + +\newcount\parametercount + +\newenvironment{parameterdescription}{\unskip% + \parametercount=0\relax% + \let\item=\parameteritem% + \let\list=\restorelist% +} +{\par +} +\let\saveditemcommand=\item +\let\savedlistcommand=\list +\def\denselist#1#2{\savedlistcommand{#1}{#2}\parskip0pt\itemsep0pt} +\def\restorelist{\let\item=\saveditemcommand\denselist} +\def\parameteritem{\pgfutil@ifnextchar[\parameteritem@{}}%} +\def\parameteritem@[#1]{\advance\parametercount by1\relax\hskip0.15em plus 1em\emph{\the\parametercount.}\kern1ex\def\test{#1}\ifx\test\pgfutil@empty\else#1\kern.5em\fi} + \newenvironment{commandlist}[1]{% - \begin{pgfmanualentry} - \foreach \xx in {#1} {% - \expandafter\extractcommand\xx\@@ - }% - \pgfmanualbody + \begin{pgfmanualentry} + \foreach \xx in {#1} {% + \expandafter\extractcommand\xx\@@ + }% + \pgfmanualbody }{% \end{pgfmanualentry} }% @@ -64,20 +214,21 @@ % \begin{internallist}[register]{\pgf@xa,\pgf@xb} % \end{internallist} \newenvironment{internallist}[2][register]{% - \begin{pgfmanualentry} - \foreach \xx in {#2} {% - \expandafter\extractinternalcommand\expandafter{\xx}{#1}% - }% - \pgfmanualbody + \begin{pgfmanualentry} + \foreach \xx in {#2} {% + \expandafter\extractinternalcommand\expandafter{\xx}{#1}% + }% + \pgfmanualbody }{% \end{pgfmanualentry} }% \def\extractinternalcommand#1#2{% - \pgfmanualentryheadline{Internal #2 \declare{\texttt{\string#1}}}% \removeats{#1}% + \pgfmanualentryheadline{% + \pgfmanualpdflabel{\textbackslash\strippedat}{}% + Internal #2 \declare{\texttt{\string#1}}}% \index{Internals!\strippedat @\protect\myprintocmmand{\strippedat}}% \index{\strippedat @\protect\myprintocmmand{\strippedat}}% - \pgfmanualpdflabel{\textbackslash\strippedat}{}% } %% MW: START MATH MACROS @@ -89,120 +240,147 @@ \def\extractmathfunctionname@#1(#2)#3\tmpb{\def\mathname{#1}} \makeatother - + \newenvironment{math-function}[1]{ - \def\mathdefaultname{#1} - \extractmathfunctionname{#1} - \edef\mathurl{{math:\mathname}}\expandafter\hypertarget\expandafter{\mathurl}{}% - \begin{pgfmanualentry} - \pgfmanualentryheadline{\texttt{#1}}% - \index{\mathname @\protect\texttt{\mathname} math function}% - \index{Math functions!\mathname @\protect\texttt{\mathname}}% - \pgfmanualbody + \def\mathdefaultname{#1} + \extractmathfunctionname{#1} + \edef\mathurl{{math:\mathname}}\expandafter\hypertarget\expandafter{\mathurl}{}% + \begin{pgfmanualentry} + \pgfmanualentryheadline{\texttt{#1}}% + \index{\mathname @\protect\texttt{\mathname} math function}% + \index{Math functions!\mathname @\protect\texttt{\mathname}}% + \pgfmanualbody } { - \end{pgfmanualentry} + \end{pgfmanualentry} } \def\pgfmanualemptytext{} \def\pgfmanualvbarvbar{\char`\|\char`\|} \newenvironment{math-operator}[4][]{% - \begin{pgfmanualentry} - \csname math#3operator\endcsname{#2}{#4} - \def\mathtest{#4}% - \ifx\mathtest\pgfmanualemptytext% - \def\mathtype{(#3 operator)} - \else% - \def\mathtype{(#3 operator; uses the \texttt{#4} function)} - \fi% - \pgfmanualentryheadline{\mathexample\hfill\mathtype}% - \def\mathtest{#1}% - \ifx\mathtest\pgfmanualemptytext% - \index{#2@\protect\texttt{#2} #3 math operator}% - \index{Math operators!#2@\protect\texttt{#2}}% - \fi% - \pgfmanualbody + \begin{pgfmanualentry} + \csname math#3operator\endcsname{#2}{#4} + \def\mathtest{#4}% + \ifx\mathtest\pgfmanualemptytext% + \def\mathtype{(#3 operator)} + \else% + \def\mathtype{(#3 operator; uses the \texttt{#4} function)} + \fi% + \pgfmanualentryheadline{\mathexample\hfill\mathtype}% + \def\mathtest{#1}% + \ifx\mathtest\pgfmanualemptytext% + \index{#2@\protect\texttt{#2} #3 math operator}% + \index{Math operators!#2@\protect\texttt{#2}}% + \fi% + \pgfmanualbody } {\end{pgfmanualentry}} \newenvironment{math-operators}[5][]{% - \begin{pgfmanualentry} - \csname math#4operator\endcsname{#2}{#3} - \def\mathtest{#5}% - \ifx\mathtest\pgfmanualemptytext% - \def\mathtype{(#4 operators)} - \else% - \def\mathtype{(#4 operators; use the \texttt{#5} function)} - \fi% - \pgfmanualentryheadline{\mathexample\hfill\mathtype}% - \def\mathtest{#1}% - \ifx\mathtest\pgfmanualemptytext% - \index{#2#3@\protect\texttt{#2\protect\ #3} #4 math operators}% - \index{Math operators!#2#3@\protect\texttt{#2\protect\ #3}}% - \fi% - \pgfmanualbody + \begin{pgfmanualentry} + \csname math#4operator\endcsname{#2}{#3} + \def\mathtest{#5}% + \ifx\mathtest\pgfmanualemptytext% + \def\mathtype{(#4 operators)} + \else% + \def\mathtype{(#4 operators; use the \texttt{#5} function)} + \fi% + \pgfmanualentryheadline{\mathexample\hfill\mathtype}% + \def\mathtest{#1}% + \ifx\mathtest\pgfmanualemptytext% + \index{#2#3@\protect\texttt{#2\protect\ #3} #4 math operators}% + \index{Math operators!#2#3@\protect\texttt{#2\protect\ #3}}% + \fi% + \pgfmanualbody } {\end{pgfmanualentry}} \def\mathinfixoperator#1#2{% - \def\mathoperator{\texttt{#1}}% - \def\mathexample{\mvar{x}\space\texttt{#1}\space\mvar{y}}% + \def\mathoperator{\texttt{#1}}% + \def\mathexample{\mvar{x}\space\texttt{#1}\space\mvar{y}}% } \def\mathprefixoperator#1#2{% - \def\mathoperator{\texttt{#1}}% - \def\mathexample{\texttt{#1}\mvar{x}}% + \def\mathoperator{\texttt{#1}}% + \def\mathexample{\texttt{#1}\mvar{x}}% } \def\mathpostfixoperator#1#2{% - \def\mathoperator{\texttt{#1}} - \def\mathexample{\mvar{x}\texttt{#1}}% + \def\mathoperator{\texttt{#1}} + \def\mathexample{\mvar{x}\texttt{#1}}% } \def\mathgroupoperator#1#2{% - \def\mathoperator{\texttt{#1\ #2}}% - \def\mathexample{\texttt{#1}\mvar{x}\texttt{#2}}% + \def\mathoperator{\texttt{#1\ #2}}% + \def\mathexample{\texttt{#1}\mvar{x}\texttt{#2}}% } \expandafter\let\csname matharray accessoperator\endcsname=\mathgroupoperator \expandafter\let\csname matharrayoperator\endcsname=\mathgroupoperator \def\mathconditionaloperator#1#2{% - \def\mathoperator{#1\space#2} - \def\mathexample{\mvar{x}\ \texttt{#1}\ \mvar{y}\ {\texttt{#2}}\ \mvar{z}} + \def\mathoperator{#1\space#2} + \def\mathexample{\mvar{x}\ \texttt{#1}\ \mvar{y}\ {\texttt{#2}}\ \mvar{z}} } \newcommand\mathcommand[1][\mathdefaultname]{% - \expandafter\makemathcommand#1(\empty)\stop% - \expandafter\extractcommand\mathcommandname\@@% - \medskip + \expandafter\makemathcommand#1(\empty)\stop% + \expandafter\extractcommand\mathcommandname\@@% + \medskip } \makeatletter \def\makemathcommand#1(#2)#3\stop{% - \expandafter\def\expandafter\mathcommandname\expandafter{\csname pgfmath#1\endcsname}% - \ifx#2\empty% - \else% - \@makemathcommand#2,\stop, - \fi} + \expandafter\def\expandafter\mathcommandname\expandafter{\csname pgfmath#1\endcsname}% + \ifx#2\empty% + \else% + \@makemathcommand#2,\stop, + \fi} \def\@makemathcommand#1,{% - \ifx#1\stop% - \else% - \expandafter\def\expandafter\mathcommandname\expandafter{\mathcommandname{\ttfamily\char`\{#1\char`\}}}% - \expandafter\@makemathcommand% - \fi} + \ifx#1\stop% + \else% + \expandafter\def\expandafter\mathcommandname\expandafter{\mathcommandname{\ttfamily\char`\{#1\char`\}}}% + \expandafter\@makemathcommand% + \fi} \makeatother \def\calcname{\textsc{calc}} + +\newenvironment{math-keyword}[1]{ + \extracttikzmathkeyword#1@ + \begin{pgfmanualentry} + \pgfmanualentryheadline{\texttt{\color{red}\mathname}\mathrest}% + \index{\mathname @\protect\texttt{\mathname} tikz math function}% + \index{TikZ math functions!\mathname @\protect\texttt{\mathname}}% + \pgfmanualbody +} +{ + \end{pgfmanualentry} +} + +\def\extracttikzmathkeyword#1#2@{% + \def\mathname{#1}% + \def\mathrest{#2}% +} + %% MW: END MATH MACROS \def\extractcommand#1#2\@@{% - \pgfmanualentryheadline{\declare{\texttt{\string#1}}#2}% \removeats{#1}% + \pgfmanualentryheadline{% + \pgfmanualpdflabel{\textbackslash\strippedat}{}% + \declare{\texttt{\string#1}}#2% + }% \index{\strippedat @\protect\myprintocmmand{\strippedat}} - \pgfmanualpdflabel{\textbackslash\strippedat}{}% +} + +\def\luaextractcommand#1#2\relax{% + \declare{\texttt{\string#1}}#2\par% +% \removeats{#1}% + % \index{\strippedat @\protect\myprintocmmand{\strippedat}} + % \pgfmanualpdflabel{\textbackslash\strippedat}{}% } @@ -217,12 +395,14 @@ } \def\extractenvironement#1#2\@@{% - \pgfmanualentryheadline{{\ttfamily\char`\\begin\char`\{\declare{#1}\char`\}}#2}% + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + {\ttfamily\char`\\begin\char`\{\declare{#1}\char`\}}#2% + }% \pgfmanualentryheadline{{\ttfamily\ \ }\meta{environment contents}}% \pgfmanualentryheadline{{\ttfamily\char`\\end\char`\{\declare{#1}\char`\}}}% \index{#1@\protect\texttt{#1} environment}% \index{Environments!#1@\protect\texttt{#1}} - \pgfmanualpdflabel{#1}{}% } @@ -263,10 +443,26 @@ \newenvironment{shape}[1]{ \begin{pgfmanualentry} - \pgfmanualentryheadline{Shape {\ttfamily\declare{#1}}}% + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + \textbf{Shape} {\ttfamily\declare{#1}}% + }% \index{#1@\protect\texttt{#1} shape}% \index{Shapes!#1@\protect\texttt{#1}} - \pgfmanualpdflabel{#1}{}% + \pgfmanualbody +} +{ + \end{pgfmanualentry} +} + +\newenvironment{pictype}[2]{ + \begin{pgfmanualentry} + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + \textbf{Pic type} {\ttfamily\declare{#1}#2}% + }% + \index{#1@\protect\texttt{#1} pic type}% + \index{Pic Types!#1@\protect\texttt{#1}} \pgfmanualbody } { @@ -275,10 +471,11 @@ \newenvironment{shading}[1]{ \begin{pgfmanualentry} - \pgfmanualentryheadline{Shading {\ttfamily\declare{#1}}}% + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + \textbf{Shading} {\ttfamily\declare{#1}}}% \index{#1@\protect\texttt{#1} shading}% \index{Shadings!#1@\protect\texttt{#1}} - \pgfmanualpdflabel{#1}{}% \pgfmanualbody } { @@ -286,12 +483,58 @@ } +\newenvironment{graph}[1]{ + \begin{pgfmanualentry} + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + \textbf{Graph} {\ttfamily\declare{#1}}}% + \index{#1@\protect\texttt{#1} graph}% + \index{Graphs!#1@\protect\texttt{#1}} + \pgfmanualbody +} +{ + \end{pgfmanualentry} +} + +\newenvironment{gdalgorithm}[2]{ + \begin{pgfmanualentry} + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + \textbf{Layout} {\ttfamily/graph drawing/\declare{#1}\opt{=}}\opt{\meta{options}}}% + \index{#1@\protect\texttt{#1} layout}% + \index{Layouts!#1@\protect\texttt{#1}}% + \foreach \algo in {#2} + {\edef\marshal{\noexpand\index{#2@\noexpand\protect\noexpand\texttt{#2} algorithm}}\marshal}% + \index{Graph drawing layouts!#1@\protect\texttt{#1}} + \item{\small alias {\ttfamily/tikz/#1}}\par + \item{\small alias {\ttfamily/tikz/graphs/#1}}\par + \item{\small Employs {\ttfamily algorithm=#2}}\par + \pgfmanualbody +} +{ + \end{pgfmanualentry} +} + \newenvironment{dataformat}[1]{ \begin{pgfmanualentry} - \pgfmanualentryheadline{Format {\ttfamily\declare{#1}}}% + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + \textbf{Format} {\ttfamily\declare{#1}}}% \index{#1@\protect\texttt{#1} format}% \index{Formats!#1@\protect\texttt{#1}} - \pgfmanualpdflabel{#1}{}% + \pgfmanualbody +} +{ + \end{pgfmanualentry} +} + +\newenvironment{stylesheet}[1]{ + \begin{pgfmanualentry} + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + \textbf{Style sheet} {\ttfamily\declare{#1}}}% + \index{#1@\protect\texttt{#1} style sheet}% + \index{Style sheets!#1@\protect\texttt{#1}} \pgfmanualbody } { @@ -309,10 +552,11 @@ \def\gobble#1{} \def\extracthandler#1#2\@nil{% - \pgfmanualentryheadline{Key handler \meta{key}{\ttfamily/\declare{#1}}#2}% + \pgfmanualentryheadline{% + \pgfmanualpdflabel{/handlers/#1}{}% + \textbf{Key handler} \meta{key}{\ttfamily/\declare{#1}}#2}% \index{\gobble#1@\protect\texttt{#1} handler}% \index{Key handlers!#1@\protect\texttt{#1}} - \pgfmanualpdflabel{/handlers/#1}% } @@ -336,17 +580,17 @@ % \mchoice{choice1,choice2,choice3} \newcommand\mchoice[1]{% - \begingroup - \firstchoicetrue - \foreach \mchoice@ in {#1} {% - \iffirstchoice - \global\firstchoicefalse - \else - \choicesep - \fi - \choicearg{\mchoice@}% - }% - \endgroup + \begingroup + \firstchoicetrue + \foreach \mchoice@ in {#1} {% + \iffirstchoice + \global\firstchoicefalse + \else + \choicesep + \fi + \choicearg{\mchoice@}% + }% + \endgroup }% % \begin{key}{/path/x=value} @@ -369,39 +613,39 @@ % #1: the key % #2: a default path (or empty) \def\insertpathifneeded#1#2{% - \def\insertpathifneeded@@{#2}% - \ifx\insertpathifneeded@@\empty - \def\mykey{#1}% - \else - \insertpathifneeded@#2\@nil - \ifpgfutil@in@ - \def\mykey{#2/#1}% - \else - \def\mykey{#1}% - \fi - \fi + \def\insertpathifneeded@@{#2}% + \ifx\insertpathifneeded@@\empty + \def\mykey{#1}% + \else + \insertpathifneeded@#2\@nil + \ifpgfutil@in@ + \def\mykey{#2/#1}% + \else + \def\mykey{#1}% + \fi + \fi }% \def\insertpathifneeded@#1#2\@nil{% - \def\insertpathifneeded@@{#1}% - \def\insertpathifneeded@@@{/}% - \ifx\insertpathifneeded@@\insertpathifneeded@@@ - \pgfutil@in@true - \else - \pgfutil@in@false - \fi + \def\insertpathifneeded@@{#1}% + \def\insertpathifneeded@@@{/}% + \ifx\insertpathifneeded@@\insertpathifneeded@@@ + \pgfutil@in@true + \else + \pgfutil@in@false + \fi }% % \begin{keylist}[default path] -% {/path/option 1=value,/path/option 2=value2} +% {/path/option 1=value,/path/option 2=value2} % \end{keylist} \newenvironment{keylist}[2][]{% - \begin{pgfmanualentry} + \begin{pgfmanualentry} \def\extrakeytext{}% - \foreach \xx in {#2} {% - \expandafter\insertpathifneeded\expandafter{\xx}{#1}% - \expandafter\extractkey\mykey\@nil% - }% - \pgfmanualbody + \foreach \xx in {#2} {% + \expandafter\insertpathifneeded\expandafter{\xx}{#1}% + \expandafter\extractkey\mykey\@nil% + }% + \pgfmanualbody }{% \end{pgfmanualentry} }% @@ -415,12 +659,14 @@ \ifpgfutil@in@% \extractequalinitial#1\@nil% \else - \pgfmanualentryheadline{{\ttfamily\declare{#1}}\hfill(\extrakeytext no value)}% + \pgfmanualentryheadline{% \def\mykey{#1}% \def\mypath{}% - \def\myname{}% + \gdef\myname{}% \firsttimetrue% + \pgfmanualdecomposecount=0\relax% \decompose#1/\nil% + {\ttfamily\declare{#1}}\hfill(\extrakeytext no value)}% \fi \fi% } @@ -434,31 +680,49 @@ \ifpgfutil@in@% \extractinitial{#1}#2\@nil% \else - \pgfmanualentryheadline{{\ttfamily\declare{#1}=}#2\hfill(\extrakeytext no default)}% + \pgfmanualentryheadline{% + \def\mykey{#1}% + \def\mypath{}% + \gdef\myname{}% + \firsttimetrue% + \pgfmanualdecomposecount=0\relax% + \decompose#1/\nil% + {\ttfamily\declare{#1}=}#2\hfill(\extrakeytext no default)}% \fi% \fi% - \def\mykey{#1}% - \def\mypath{}% - \def\myname{}% - \firsttimetrue% - \decompose#1/\nil% } \def\extractdefault#1#2(default #3)\@nil{% - \pgfmanualentryheadline{{\ttfamily\declare{#1}\opt{=}}\opt{#2}\hfill (\extrakeytext default {\ttfamily#3})}% + \pgfmanualentryheadline{% + \def\mykey{#1}% + \def\mypath{}% + \gdef\myname{}% + \firsttimetrue% + \pgfmanualdecomposecount=0\relax% + \decompose#1/\nil% + {\ttfamily\declare{#1}\opt{=}}\opt{#2}\hfill (\extrakeytext default {\ttfamily#3})}% } \def\extractinitial#1#2(initially #3)\@nil{% - \pgfmanualentryheadline{{\ttfamily\declare{#1}=}#2\hfill (\extrakeytext no default, initially {\ttfamily#3})}% + \pgfmanualentryheadline{% + \def\mykey{#1}% + \def\mypath{}% + \gdef\myname{}% + \firsttimetrue% + \pgfmanualdecomposecount=0\relax% + \decompose#1/\nil% + {\ttfamily\declare{#1}=}#2\hfill (\extrakeytext no default, initially {\ttfamily#3})}% } \def\extractequalinitial#1 (initially #2)\@nil{% - \pgfmanualentryheadline{{\ttfamily\declare{#1}}\hfill (\extrakeytext initially {\ttfamily#2})}% - \def\mykey{#1}% - \def\mypath{}% - \def\myname{}% - \firsttimetrue% - \decompose#1/\nil% + \pgfmanualentryheadline{% + \def\mykey{#1}% + \def\mypath{}% + \gdef\myname{}% + \firsttimetrue% + \pgfmanualdecomposecount=0\relax% + \decompose#1/\nil% + {\ttfamily\declare{#1}}\hfill (\extrakeytext initially {\ttfamily#2})}% } % Introduces a key alias '/#1/<name of current key>' @@ -468,6 +732,7 @@ } \newif\iffirsttime +\newcount\pgfmanualdecomposecount \makeatother @@ -477,26 +742,48 @@ % aha. \index{#1@\protect\texttt{#1} key}% \index{\mypath#1@\protect\texttt{#1}}% - \def\myname{#1}% + \gdef\myname{#1}% + \pgfmanualpdflabel{#1}{} \else% - \iffirsttime - \begingroup - % also make a pdf link anchor with full key path. - \def\hyperlabelwithoutslash##1/\nil{% - \pgfmanualpdflabel{##1}{}% - }% - \hyperlabelwithoutslash/#1/#2\nil - \endgroup - \def\mypath{#1@\protect\texttt{/#1/}!}% - \firsttimefalse - \else - \expandafter\def\expandafter\mypath\expandafter{\mypath#1@\protect\texttt{#1/}!}% - \fi - \def\firsttime{} - \decompose/#2\nil% + \advance\pgfmanualdecomposecount by1\relax% + \ifnum\pgfmanualdecomposecount>2\relax% + \decomposetoodeep#1/#2\nil% + \else% + \iffirsttime% + \begingroup% + % also make a pdf link anchor with full key path. + \def\hyperlabelwithoutslash##1/\nil{% + \pgfmanualpdflabel{##1}{}% + }% + \hyperlabelwithoutslash/#1/#2\nil% + \endgroup% + \def\mypath{#1@\protect\texttt{/#1/}!}% + \firsttimefalse% + \else% + \expandafter\def\expandafter\mypath\expandafter{\mypath#1@\protect\texttt{#1/}!}% + \fi% + \def\firsttime{}% + \decompose/#2\nil% + \fi% \fi% } +\def\decomposetoodeep#1/#2/\nil{% + % avoid too-deep nesting in index + \index{#1/#2@\protect\texttt{#1/#2} key}% + \index{\mypath#1/#2@\protect\texttt{#1/#2}}% + \decomposefindlast/#1/#2/\nil% +} +\makeatletter +\def\decomposefindlast/#1/#2\nil{% + \def\test{#2}% + \ifx\test\pgfutil@empty% + \gdef\myname{#1}% + \else% + \decomposefindlast/#2\nil% + \fi% +} +\makeatother \def\indexkey#1{% \def\mypath{}% \decompose#1/\nil% @@ -511,21 +798,23 @@ \end{pgfmanualentry} } \def\extractpredefinedmethod#1(#2)\@nil{% - \pgfmanualentryheadline{Method \declare{\ttfamily #1}\texttt(#2\texttt) \hfill(predefined for all classes)} + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + Method \declare{\ttfamily #1}\texttt(#2\texttt) \hfill(predefined for all classes)} \index{#1@\protect\texttt{#1} method}% \index{Methods!#1@\protect\texttt{#1}} - \pgfmanualpdflabel{#1}{}% } \newenvironment{ooclass}[1]{ \begin{pgfmanualentry} \def\currentclass{#1} - \pgfmanualentryheadline{Class \declare{\texttt{#1}}} + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + \textbf{Class} \declare{\texttt{#1}}} \index{#1@\protect\texttt{#1} class}% \index{Class #1@Class \protect\texttt{#1}}% \index{Classes!#1@\protect\texttt{#1}} - \pgfmanualpdflabel{#1}{}% \pgfmanualbody } { @@ -543,14 +832,17 @@ \def\extractmethod#1(#2)\@nil{% \def\test{#1} \ifx\test\currentclass - \pgfmanualentryheadline{Constructor \declare{\ttfamily #1}\texttt(#2\texttt)} + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + Constructor \declare{\ttfamily #1}\texttt(#2\texttt)} \else - \pgfmanualentryheadline{Method \declare{\ttfamily #1}\texttt(#2\texttt)} + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + Method \declare{\ttfamily #1}\texttt(#2\texttt)} \fi \index{#1@\protect\texttt{#1} method}% \index{Methods!#1@\protect\texttt{#1}} \index{Class \currentclass!#1@\protect\texttt{#1}}% - \pgfmanualpdflabel{#1}{}% } \newenvironment{attribute}[1]{ @@ -564,24 +856,28 @@ \def\extractattribute#1=#2;\@nil{% \def\test{#2}% \ifx\test\@empty - \pgfmanualentryheadline{Private attribute \declare{\ttfamily #1} \hfill (initially empty)} + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + Private attribute \declare{\ttfamily #1} \hfill (initially empty)} \else - \pgfmanualentryheadline{Private attribute \declare{\ttfamily #1} \hfill (initially {\ttfamily #2})} + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + Private attribute \declare{\ttfamily #1} \hfill (initially {\ttfamily #2})} \fi \index{#1@\protect\texttt{#1} attribute}% \index{Attributes!#1@\protect\texttt{#1}} \index{Class \currentclass!#1@\protect\texttt{#1}}% - \pgfmanualpdflabel{#1}{}% } \newenvironment{predefinednode}[1]{ \begin{pgfmanualentry} - \pgfmanualentryheadline{Predefined node {\ttfamily\declare{#1}}}% + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + \textbf{Predefined node} {\ttfamily\declare{#1}}}% \index{#1@\protect\texttt{#1} node}% \index{Predefined node!#1@\protect\texttt{#1}} - \pgfmanualpdflabel{#1}{}% \pgfmanualbody } { @@ -590,10 +886,11 @@ \newenvironment{coordinatesystem}[1]{ \begin{pgfmanualentry} - \pgfmanualentryheadline{Coordinate system {\ttfamily\declare{#1}}}% + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + \textbf{Coordinate system} {\ttfamily\declare{#1}}}% \index{#1@\protect\texttt{#1} coordinate system}% \index{Coordinate systems!#1@\protect\texttt{#1}} - \pgfmanualpdflabel{#1}{}% \pgfmanualbody } { @@ -602,7 +899,7 @@ \newenvironment{snake}[1]{ \begin{pgfmanualentry} - \pgfmanualentryheadline{Snake {\ttfamily\declare{#1}}}% + \pgfmanualentryheadline{\textbf{Snake} {\ttfamily\declare{#1}}}% \index{#1@\protect\texttt{#1} snake}% \index{Snakes!#1@\protect\texttt{#1}} \pgfmanualbody @@ -613,7 +910,7 @@ \newenvironment{decoration}[1]{ \begin{pgfmanualentry} - \pgfmanualentryheadline{Decoration {\ttfamily\declare{#1}}}% + \pgfmanualentryheadline{\textbf{Decoration} {\ttfamily\declare{#1}}}% \index{#1@\protect\texttt{#1} decoration}% \index{Decorations!#1@\protect\texttt{#1}} \pgfmanualbody @@ -627,14 +924,17 @@ \makeatletter \newenvironment{pathoperation}[3][]{ \begin{pgfmanualentry} - \pgfmanualentryheadline{\textcolor{gray}{{\ttfamily\char`\\path}\ + \def\pgfmanualtest{#1}% + \pgfmanualentryheadline{% + \ifx\pgfmanualtest\@empty% + \pgfmanualpdflabel{#2}{}% + \fi% + \textcolor{gray}{{\ttfamily\char`\\path}\ \ \dots} \declare{\texttt{#2}}#3\ \textcolor{gray}{\dots\texttt{;}}}% - \def\pgfmanualtest{#1}% \ifx\pgfmanualtest\@empty% \index{#2@\protect\texttt{#2} path operation}% \index{Path operations!#2@\protect\texttt{#2}}% - \pgfmanualpdflabel{#2}{}% \fi% \pgfmanualbody } @@ -643,14 +943,17 @@ } \newenvironment{datavisualizationoperation}[3][]{ \begin{pgfmanualentry} - \pgfmanualentryheadline{\textcolor{gray}{{\ttfamily\char`\\datavisualization}\ + \def\pgfmanualtest{#1}% + \pgfmanualentryheadline{% + \ifx\pgfmanualtest\@empty% + \pgfmanualpdflabel{#2}{}% + \fi% + \textcolor{gray}{{\ttfamily\char`\\datavisualization}\ \ \dots} \declare{\texttt{#2}}#3\ \textcolor{gray}{\dots\texttt{;}}}% - \def\pgfmanualtest{#1}% \ifx\pgfmanualtest\@empty% \index{#2@\protect\texttt{#2} (data visualization)}% \index{Data visualization!#2@\protect\texttt{#2}}% - \pgfmanualpdflabel{#2}{}% \fi% \pgfmanualbody } @@ -659,19 +962,14 @@ } \makeatother -\def\extractcommand#1#2\@@{% - \pgfmanualentryheadline{\declare{\texttt{\string#1}}#2}% - \removeats{#1}% - \index{\strippedat @\protect\myprintocmmand{\strippedat}} - \pgfmanualpdflabel{\textbackslash\strippedat}{}% -} - \def\doublebs{\texttt{\char`\\\char`\\}} \newenvironment{package}[1]{ \begin{pgfmanualentry} - \pgfmanualentryheadline{{\ttfamily\char`\\usepackage\char`\{\declare{#1}\char`\}\space\space \char`\%\space\space \LaTeX}} + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + {\ttfamily\char`\\usepackage\char`\{\declare{#1}\char`\}\space\space \char`\%\space\space \LaTeX}} \index{#1@\protect\texttt{#1} package}% \index{Packages and files!#1@\protect\texttt{#1}}% \pgfmanualentryheadline{{\ttfamily\char`\\input \declare{#1}.tex\space\space\space \char`\%\space\space plain \TeX}} @@ -685,13 +983,14 @@ \newenvironment{pgfmodule}[1]{ \begin{pgfmanualentry} - \pgfmanualentryheadline{{\ttfamily\char`\\usepgfmodule\char`\{\declare{#1}\char`\}\space\space\space + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + {\ttfamily\char`\\usepgfmodule\char`\{\declare{#1}\char`\}\space\space\space \char`\%\space\space \LaTeX\space and plain \TeX\space and pure pgf}} \index{#1@\protect\texttt{#1} module}% \index{Modules!#1@\protect\texttt{#1}}% \pgfmanualentryheadline{{\ttfamily\char`\\usepgfmodule[\declare{#1}]\space\space \char`\%\space\space Con\TeX t\space and pure pgf}} \pgfmanualbody - \pgfmanualpdflabel{#1}{}% } { \end{pgfmanualentry} @@ -699,17 +998,37 @@ \newenvironment{pgflibrary}[1]{ \begin{pgfmanualentry} - \pgfmanualentryheadline{{\ttfamily\char`\\usepgflibrary\char`\{\declare{#1}\char`\}\space\space\space - \char`\%\space\space \LaTeX\space and plain \TeX\space and pure pgf}} + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + \textbf{\tikzname\ Library} \texttt{\declare{#1}}} \index{#1@\protect\texttt{#1} library}% \index{Libraries!#1@\protect\texttt{#1}}% - \pgfmanualentryheadline{{\ttfamily\char`\\usepgflibrary[\declare{#1}]\space\space \char`\%\space\space Con\TeX t\space and pure pgf}} - \pgfmanualentryheadline{{\ttfamily\char`\\usetikzlibrary\char`\{\declare{#1}\char`\}\space\space - \char`\%\space\space \LaTeX\space and plain \TeX\space when using \tikzname}} - \pgfmanualentryheadline{{\ttfamily\char`\\usetikzlibrary[\declare{#1}]\space - \char`\%\space\space Con\TeX t\space when using \tikzname}} + \vskip.25em% + {{\ttfamily\char`\\usepgflibrary\char`\{\declare{#1}\char`\}\space\space\space + \char`\%\space\space \LaTeX\space and plain \TeX\space and pure pgf}}\\ + {{\ttfamily\char`\\usepgflibrary[\declare{#1}]\space\space \char`\%\space\space Con\TeX t\space and pure pgf}}\\ + {{\ttfamily\char`\\usetikzlibrary\char`\{\declare{#1}\char`\}\space\space + \char`\%\space\space \LaTeX\space and plain \TeX\space when using \tikzname}}\\ + {{\ttfamily\char`\\usetikzlibrary[\declare{#1}]\space + \char`\%\space\space Con\TeX t\space when using \tikzname}}\\[.5em] + \pgfmanualbody +} +{ + \end{pgfmanualentry} +} + +\newenvironment{purepgflibrary}[1]{ + \begin{pgfmanualentry} + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + \textbf{{\small PGF} Library} \texttt{\declare{#1}}} + \index{#1@\protect\texttt{#1} library}% + \index{Libraries!#1@\protect\texttt{#1}}% + \vskip.25em% + {{\ttfamily\char`\\usepgflibrary\char`\{\declare{#1}\char`\}\space\space\space + \char`\%\space\space \LaTeX\space and plain \TeX}}\\ + {{\ttfamily\char`\\usepgflibrary[\declare{#1}]\space\space \char`\%\space\space Con\TeX t}}\\[.5em] \pgfmanualbody - \pgfmanualpdflabel{#1}{}% } { \end{pgfmanualentry} @@ -717,12 +1036,15 @@ \newenvironment{tikzlibrary}[1]{ \begin{pgfmanualentry} - \pgfmanualentryheadline{{\ttfamily\char`\\usetikzlibrary\char`\{\declare{#1}\char`\}\space\space \char`\%\space\space \LaTeX\space and plain \TeX}} + \pgfmanualentryheadline{% + \pgfmanualpdflabel{#1}{}% + \textbf{\tikzname\ Library} \texttt{\declare{#1}}} \index{#1@\protect\texttt{#1} library}% \index{Libraries!#1@\protect\texttt{#1}}% - \pgfmanualentryheadline{{\ttfamily\char`\\usetikzlibrary[\declare{#1}]\space \char`\%\space\space Con\TeX t}} + \vskip.25em% + {{\ttfamily\char`\\usetikzlibrary\char`\{\declare{#1}\char`\}\space\space \char`\%\space\space \LaTeX\space and plain \TeX}}\\ + {{\ttfamily\char`\\usetikzlibrary[\declare{#1}]\space \char`\%\space\space Con\TeX t}}\\[.5em] \pgfmanualbody - \pgfmanualpdflabel{#1}{}% } { \end{pgfmanualentry} @@ -858,89 +1180,225 @@ \def\noindexing{\let\index=\@gobble} +\newenvironment{arrowtipsimple}[1]{ + \begin{pgfmanualentry} + \pgfmanualentryheadline{\textbf{Arrow Tip Kind} {\ttfamily#1}} + \index{#1@\protect\texttt{#1} arrow tip}% + \index{Arrow tips!#1@\protect\texttt{#1}}% + \def\currentarrowtype{#1} + \pgfmanualbody} +{ + \end{pgfmanualentry} +} -\newcommand\symarrow[1]{ +\newenvironment{arrowtip}[4]{ + \begin{pgfmanualentry} + \pgfmanualentryheadline{\textbf{Arrow Tip Kind} {\ttfamily#1}} + \index{#1@\protect\texttt{#1} arrow tip}% + \index{Arrow tips!#1@\protect\texttt{#1}}% + \pgfmanualbody + \def\currentarrowtype{#1} + \begin{minipage}[t]{10.25cm} + #2 + \end{minipage}\hskip5mm\begin{minipage}[t]{4.75cm} + \leavevmode\vskip-2em + \tikz{ + \draw [black!50,line width=5mm,-{#1[#3,color=black]}] (-4,0) -- (0,0); + \foreach \action in {#4} + { \expandafter\processaction\action\relax } + } + \end{minipage}\par\smallskip + } +{ + \end{pgfmanualentry} +} + +\newenvironment{arrowcap}[5]{ + \begin{pgfmanualentry} + \pgfmanualentryheadline{\textbf{Arrow Tip Kind} {\ttfamily#1}} + \index{#1@\protect\texttt{#1} arrow tip}% + \index{Arrow tips!#1@\protect\texttt{#1}}% + \pgfmanualbody + \def\currentarrowtype{#1} + \begin{minipage}[t]{10.25cm} + #2 + \end{minipage}\hskip5mm\begin{minipage}[t]{4.75cm} + \leavevmode\vskip-2em + \tikz{ + \path [tips, line width=10mm,-{#1[#3,color=black]}] (-4,0) -- (0,0); + \draw [line width=10mm,black!50] (-3,0) -- (#5,0); + \foreach \action in {#4} + { \expandafter\processaction\action\relax } + } + \end{minipage}\par\smallskip + } +{ + \end{pgfmanualentry} +} + +\def\processaction#1=#2\relax{ + \expandafter\let\expandafter\pgf@temp\csname manual@action@#1\endcsname + \ifx\pgf@temp\relax\else + \pgf@temp#2/0/\relax + \fi +} +\def\manual@action@length#1/#2/#3\relax{% + \draw [red,|<->|,semithick,xshift=#2] ([yshift=4pt]current bounding + box.north -| -#1,0) coordinate (last length) -- node + [above=-2pt] {|length|} ++(#1,0); +} +\def\manual@action@width#1/#2/#3\relax{% + \draw [overlay, red,|<->|,semithick] (.5,-#1/2) -- node [below,sloped] {|width|} (.5,#1/2); +} +\def\manual@action@inset#1/#2/#3\relax{% + \draw [red,|<->|,semithick,xshift=#2] ([yshift=-4pt]current bounding + box.south -| last length) -- node [below] {|inset|} ++(#1,0); +} + +\newenvironment{arrowexamples} +{\begin{tabbing} + \hbox to \dimexpr\linewidth-5.5cm\relax{\emph{Appearance of the below at line width} \hfil} \= + \hbox to 1.9cm{\emph{0.4pt}\hfil} \= \hbox to 2cm{\emph{0.8pt}\hfil} \= \emph{1.6pt} \\ + } +{\end{tabbing}\vskip-1em} + +\newenvironment{arrowcapexamples} +{\begin{tabbing} + \hbox to \dimexpr\linewidth-5.5cm\relax{\emph{Appearance of the below at line width} \hfil} \= + \hbox to 1.9cm{\emph{1ex}\hfil} \= \hbox to 2cm{\emph{1em}\hfil} \\ + } +{\end{tabbing}\vskip-1em} + +\def\arrowcapexample#1[#2]{\def\temp{#1}\ifx\temp\pgfutil@empty\arrowcapexample@\currentarrowtype[{#2}]\else\arrowcapexample@#1[{#2}]\fi} +\def\arrowcapexample@#1[#2]{% + {\sfcode`\.1000\small\texttt{#1[#2]}} \> + \kern-.5ex\tikz [baseline,>={#1[#2]}] \draw [line + width=1ex,->] (0,.5ex) -- (2em,.5ex); \> + \kern-.5em\tikz [baseline,>={#1[#2]}] \draw [line + width=1em,->] (0,.5ex) -- (2em,.5ex); \\ +} + +\def\arrowexample#1[#2]{\def\temp{#1}\ifx\temp\pgfutil@empty\arrowexample@\currentarrowtype[{#2}]\else\arrowexample@#1[{#2}]\fi} +\def\arrowexample@#1[#2]{% + {\sfcode`\.1000\small\texttt{#1[#2]}} \> + \tikz [baseline,>={#1[#2]}] \draw [line + width=0.4pt,->] (0,.5ex) -- (2em,.5ex); thin \> + \tikz [baseline,>={#1[#2]}] \draw [line + width=0.8pt,->] (0,.5ex) -- (2em,.5ex); \textbf{thick} \> + \tikz [baseline,>={#1[#2]}] \draw [line + width=1.6pt,->] (0,.5ex) -- (3em,.5ex); \\ +} +\def\arrowexampledup[#1]{\arrowexample[{#1] \currentarrowtype[}]} +\def\arrowexampledupdot[#1]{\arrowexample[{#1] . \currentarrowtype[}]} + +\def\arrowexampledouble#1[#2]{\def\temp{#1}\ifx\temp\pgfutil@empty\arrowexampledouble@\currentarrowtype[{#2}]\else\arrowexampledouble@#1[{#2}]\fi} +\def\arrowexampledouble@#1[#2]{% + {\sfcode`\.1000\small\texttt{#1[#2]} on double line} \> + \tikz [baseline,>={#1[#2]}] + \draw [double equal sign distance,line width=0.4pt,->] (0,.5ex) -- (2em,.5ex); thin \> + \tikz [baseline,>={#1[#2]}] + \draw [double equal sign distance,line width=0.8pt,->] (0,.5ex) -- (2em,.5ex); \textbf{thick} \> + \tikz [baseline,>={#1[#2]}] + \draw [double equal sign distance, line width=1.6pt,->] (0,.5ex) -- (3em,.5ex); \\ +} + + + +\newcommand\symarrow[1]{% \index{#1@\protect\texttt{#1} arrow tip}% - \index{Arrow tips!#1@\protect\texttt{#1}} + \index{Arrow tips!#1@\protect\texttt{#1}}% \texttt{#1}& yields thick \begin{tikzpicture}[arrows={#1-#1},thick,baseline] - \useasboundingbox (0pt,-0.5ex) rectangle (1cm,2ex); + \useasboundingbox (-1mm,-0.5ex) rectangle (1.1cm,2ex); + \fill [black!15] (1cm,-.5ex) rectangle (1.1cm,1.5ex) (-1mm,-.5ex) rectangle (0mm,1.5ex) ; \draw (0pt,.5ex) -- (1cm,.5ex); \end{tikzpicture} and thin \begin{tikzpicture}[arrows={#1-#1},thin,baseline] - \useasboundingbox (0pt,-0.5ex) rectangle (1cm,2ex); + \useasboundingbox (-1mm,-0.5ex) rectangle (1.1cm,2ex); + \fill [black!15] (1cm,-.5ex) rectangle (1.1cm,1.5ex) (-1mm,-.5ex) rectangle (0mm,1.5ex) ; \draw (0pt,.5ex) -- (1cm,.5ex); \end{tikzpicture} } -\newcommand\symarrowdouble[1]{ +\newcommand\symarrowdouble[1]{% \index{#1@\protect\texttt{#1} arrow tip}% - \index{Arrow tips!#1@\protect\texttt{#1}} + \index{Arrow tips!#1@\protect\texttt{#1}}% \texttt{#1}& yields thick \begin{tikzpicture}[arrows={#1-#1},thick,baseline] - \useasboundingbox (0pt,-0.5ex) rectangle (1cm,2ex); + \useasboundingbox (-1mm,-0.5ex) rectangle (1.1cm,2ex); + \fill [black!15] (1cm,-.5ex) rectangle (1.1cm,1.5ex) (-1mm,-.5ex) rectangle (0mm,1.5ex) ; \draw (0pt,.5ex) -- (1cm,.5ex); \end{tikzpicture} and thin \begin{tikzpicture}[arrows={#1-#1},thin,baseline] - \useasboundingbox (0pt,-0.5ex) rectangle (1cm,2ex); + \useasboundingbox (-1mm,-0.5ex) rectangle (1.1cm,2ex); + \fill [black!15] (1cm,-.5ex) rectangle (1.1cm,1.5ex) (-1mm,-.5ex) rectangle (0mm,1.5ex) ; \draw (0pt,.5ex) -- (1cm,.5ex); \end{tikzpicture}, double \begin{tikzpicture}[arrows={#1-#1},thick,baseline] - \useasboundingbox (0pt,-0.5ex) rectangle (1cm,2ex); + \useasboundingbox (-1mm,-0.5ex) rectangle (1.1cm,2ex); + \fill [black!15] (1cm,-.5ex) rectangle (1.1cm,1.5ex) (-1mm,-.5ex) rectangle (0mm,1.5ex) ; \draw[double,double equal sign distance] (0pt,.5ex) -- (1cm,.5ex); \end{tikzpicture} and \begin{tikzpicture}[arrows={#1-#1},thin,baseline] - \useasboundingbox (0pt,-0.5ex) rectangle (1cm,2ex); + \useasboundingbox (-1mm,-0.5ex) rectangle (1.1cm,2ex); + \fill [black!15] (1cm,-.5ex) rectangle (1.1cm,1.5ex) (-1mm,-.5ex) rectangle (0mm,1.5ex) ; \draw[double,double equal sign distance] (0pt,.5ex) -- (1cm,.5ex); \end{tikzpicture} } -\newcommand\sarrow[2]{ +\newcommand\sarrow[2]{% \index{#1@\protect\texttt{#1} arrow tip}% - \index{Arrow tips!#1@\protect\texttt{#1}} + \index{Arrow tips!#1@\protect\texttt{#1}}% \index{#2@\protect\texttt{#2} arrow tip}% - \index{Arrow tips!#2@\protect\texttt{#2}} + \index{Arrow tips!#2@\protect\texttt{#2}}% \texttt{#1-#2}& yields thick \begin{tikzpicture}[arrows={#1-#2},thick,baseline] - \useasboundingbox (0pt,-0.5ex) rectangle (1cm,2ex); + \useasboundingbox (-1mm,-0.5ex) rectangle (1.1cm,2ex); + \fill [black!15] (1cm,-.5ex) rectangle (1.1cm,1.5ex) (-1mm,-.5ex) rectangle (0mm,1.5ex) ; \draw (0pt,.5ex) -- (1cm,.5ex); \end{tikzpicture} and thin \begin{tikzpicture}[arrows={#1-#2},thin,baseline] - \useasboundingbox (0pt,-0.5ex) rectangle (1cm,2ex); + \useasboundingbox (-1mm,-0.5ex) rectangle (1.1cm,2ex); + \fill [black!15] (1cm,-.5ex) rectangle (1.1cm,1.5ex) (-1mm,-.5ex) rectangle (0mm,1.5ex) ; \draw (0pt,.5ex) -- (1cm,.5ex); \end{tikzpicture} } -\newcommand\sarrowdouble[2]{ +\newcommand\sarrowdouble[2]{% \index{#1@\protect\texttt{#1} arrow tip}% - \index{Arrow tips!#1@\protect\texttt{#1}} + \index{Arrow tips!#1@\protect\texttt{#1}}% \index{#2@\protect\texttt{#2} arrow tip}% - \index{Arrow tips!#2@\protect\texttt{#2}} + \index{Arrow tips!#2@\protect\texttt{#2}}% \texttt{#1-#2}& yields thick \begin{tikzpicture}[arrows={#1-#2},thick,baseline] - \useasboundingbox (0pt,-0.5ex) rectangle (1cm,2ex); + \useasboundingbox (-1mm,-0.5ex) rectangle (1.1cm,2ex); + \fill [black!15] (1cm,-.5ex) rectangle (1.1cm,1.5ex) (-1mm,-.5ex) rectangle (0mm,1.5ex) ; \draw (0pt,.5ex) -- (1cm,.5ex); \end{tikzpicture} and thin \begin{tikzpicture}[arrows={#1-#2},thin,baseline] - \useasboundingbox (0pt,-0.5ex) rectangle (1cm,2ex); + \useasboundingbox (-1mm,-0.5ex) rectangle (1.1cm,2ex); + \fill [black!15] (1cm,-.5ex) rectangle (1.1cm,1.5ex) (-1mm,-.5ex) rectangle (0mm,1.5ex) ; \draw (0pt,.5ex) -- (1cm,.5ex); \end{tikzpicture}, double \begin{tikzpicture}[arrows={#1-#2},thick,baseline] - \useasboundingbox (0pt,-0.5ex) rectangle (1cm,2ex); + \useasboundingbox (-1mm,-0.5ex) rectangle (1.1cm,2ex); + \fill [black!15] (1cm,-.5ex) rectangle (1.1cm,1.5ex) (-1mm,-.5ex) rectangle (0mm,1.5ex) ; \draw[double,double equal sign distance] (0pt,.5ex) -- (1cm,.5ex); \end{tikzpicture} and \begin{tikzpicture}[arrows={#1-#2},thin,baseline] - \useasboundingbox (0pt,-0.5ex) rectangle (1cm,2ex); + \useasboundingbox (-1mm,-0.5ex) rectangle (1.1cm,2ex); + \fill [black!15] (1cm,-.5ex) rectangle (1.1cm,1.5ex) (-1mm,-.5ex) rectangle (0mm,1.5ex) ; \draw[double,double equal sign distance] (0pt,.5ex) -- (1cm,.5ex); \end{tikzpicture} } -\newcommand\carrow[1]{ +\newcommand\carrow[1]{% \index{#1@\protect\texttt{#1} arrow tip}% - \index{Arrow tips!#1@\protect\texttt{#1}} + \index{Arrow tips!#1@\protect\texttt{#1}}% \texttt{#1}& yields for line width 1ex \begin{tikzpicture}[arrows={#1-#1},line width=1ex,baseline] - \useasboundingbox (0pt,-0.5ex) rectangle (1.5cm,2ex); + \useasboundingbox (-1mm,-0.5ex) rectangle (1.6cm,2ex); + \fill [black!15] (1.5cm,-.5ex) rectangle (1.6cm,1.5ex) (-1mm,-.5ex) rectangle (0mm,1.5ex) ; \draw (0pt,.5ex) -- (1.5cm,.5ex); \end{tikzpicture} } @@ -1046,32 +1504,62 @@ % a proper replacement sequence for tabs (as many spaces as % configured) \def\codeexample@tabinit{% - \ifnum\pgfkeysvalueof{/codeexample/tabsize}=0\relax - \let\codeexample@tabinit@replacementchars=\relax - \let\codeexample@tabinit@catcode=\relax - \else - \let\codeexample@tabinit@catcode=\codeexample@tabinit@catcode@ - \let\codeexample@tabinit@replacementchars=\codeexample@tabinit@replacementchars@ - \fi + \ifnum\pgfkeysvalueof{/codeexample/tabsize}=0\relax + \let\codeexample@tabinit@replacementchars=\relax + \let\codeexample@tabinit@catcode=\relax + \else + \let\codeexample@tabinit@catcode=\codeexample@tabinit@catcode@ + \let\codeexample@tabinit@replacementchars=\codeexample@tabinit@replacementchars@ + \fi } +\newif\ifpgfmanualtikzsyntaxhilighting + \pgfqkeys{/codeexample}{% - width/.code= {\setlength\codeexamplewidth{#1}}, - graphic/.code= {\colorlet{graphicbackground}{#1}}, - code/.code= {\colorlet{codebackground}{#1}}, - execute code/.is if=code@execute, - code only/.code= {\code@executefalse}, - pre/.store in=\code@pre, - post/.store in=\code@post, + width/.code= {\setlength\codeexamplewidth{#1}}, + graphic/.code= {\colorlet{graphicbackground}{#1}}, + code/.code= {\colorlet{codebackground}{#1}}, + execute code/.is if=code@execute, + code only/.code= {\code@executefalse}, + pre/.store in=\code@pre, + post/.store in=\code@post, % #1 is the *complete* environment contents as it shall be % typeset. In particular, the catcodes are NOT the normal ones. - typeset listing/.code= {#1}, - render instead/.store in=\code@render, - vbox/.code= {\def\code@pre{\vbox\bgroup\setlength{\hsize}{\linewidth-6pt}}\def\code@post{\egroup}}, - ignorespaces/.code= {\let\@gobble@till@return=\@gobble@till@return@ignore}, - leave comments/.code= {\def\code@catcode@hook{\catcode`\%=12}\let\commenthandler=\relax\let\typesetcomment=\relax}, - tabsize/.initial=0,% FIXME : this here is merely used for indentation. It is just a TAB REPLACEMENT. - every codeexample/.style={width=4cm+7pt}, + typeset listing/.code= {#1}, + render instead/.store in=\code@render, + vbox/.code= {\def\code@pre{\vbox\bgroup\setlength{\hsize}{\linewidth-6pt}}\def\code@post{\egroup}}, + ignorespaces/.code= {\let\@gobble@till@return=\@gobble@till@return@ignore}, + leave comments/.code= {\def\code@catcode@hook{\catcode`\%=12}\let\commenthandler=\relax\let\typesetcomment=\relax}, + tabsize/.initial=0,% FIXME : this here is merely used for indentation. It is just a TAB REPLACEMENT. + every codeexample/.style={width=4cm+7pt, tikz syntax=true}, + from file/.code={\codeexamplefromfiletrue\def\codeexamplesource{#1}}, + tikz syntax/.is if=pgfmanualtikzsyntaxhilighting, +} + + +\newread\examplesource + + +% Opening, reading and closing the results file + +\def\opensource#1{ + \immediate\openin\examplesource=#1 +} +\def\do@codeexamplefromfile{% + \immediate\openin\examplesource\expandafter{\codeexamplesource}% + \def\examplelines{}% + \readexamplelines + \closein\examplesource + \expandafter\endofcodeexample\expandafter{\examplelines}% +} + +\def\readexamplelines{ + \ifeof\examplesource% + \else + \immediate\read\examplesource to \exampleline + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\examplelines\expandafter\expandafter\expandafter{\expandafter\examplelines\exampleline} + \expandafter\readexamplelines% + \fi } \let\code@pre\pgfutil@empty @@ -1079,6 +1567,7 @@ \let\code@render\pgfutil@empty \def\code@catcode@hook{} +\newif\ifcodeexamplefromfile \newdimen\codeexamplewidth \newif\ifcode@execute \newbox\codeexamplebox @@ -1086,6 +1575,10 @@ \begingroup% \code@executetrue \pgfqkeys{/codeexample}{every codeexample,#1}% + \ifpgfmanualtikzsyntaxhilighting% + \pgfkeys{/codeexample/syntax hilighting}% + \fi% + \ifcodeexamplefromfile\begingroup\fi \codeexample@tabinit% assigns \codeexample@tabinit@[catcode,replacementchars] \parindent0pt \begingroup% @@ -1100,7 +1593,11 @@ \code@catcode@hook% \codeexample@tabinit@catcode \relax% - \find@example} + \ifcodeexamplefromfile% + \expandafter\do@codeexamplefromfile% + \else% + \expandafter\find@example% + \fi} \def\endofcodeexample#1{% \endgroup% \ifcode@execute% @@ -1155,6 +1652,7 @@ \fi% \code@mid% \colorbox{codebackground}{% + \pgfkeysvalueof{/codeexample/prettyprint/base color}% \begin{minipage}[t]{\code@width}% {% \let\do\@makeother @@ -1179,7 +1677,7 @@ \code@end% \par% \medskip - \end{codeexample} + \endcodeexample\endgroup } \def\endcodeexample{\endgroup} @@ -1189,16 +1687,52 @@ \usepackage{pgfmanual} -\makeatletter -% \pgfautoxrefs will be defined by 'make dist' -\pgfutil@ifundefined{pgfautoxrefs}{% - \def\pgfmanualpdflabel#1#2{#2}% NO-OP - \def\pgfmanualpdfref#1#2{#2}% - \pgfkeys{ - /pdflinks/codeexample links=false,% DISABLED. - }% -}{} -\makeatother + +% autoxref is now always on + +% \makeatletter +% % \pgfautoxrefs will be defined by 'make dist' +% \pgfutil@ifundefined{pgfautoxrefs}{% +% \renewcommand\pgfmanualpdflabel[3][]{#3}% NO-OP +% \def\pgfmanualpdfref#1#2{#2}% +% \pgfkeys{ +% /pdflinks/codeexample links=false,% DISABLED. +% }% +% }{} +% \makeatother + +\newdimen\pgfmanualcslinkpreskip + +% Styling of the pretty printer +\pgfkeys{ + /codeexample/syntax hilighting/.style={ + /codeexample/prettyprint/key name/.code={\textcolor{green!50!black}{\pgfmanualpdfref{##1}{##1}}}, + /codeexample/prettyprint/key name with handler/.code 2 args={\textcolor{green!50!black}{\pgfmanualpdfref{##1}{##1}}/\textcolor{blue!70!black}{\pgfmanualpdfref{/handlers/##2}{##2}}}, + /codeexample/prettyprint/key value display only/.code={\textcolor{green!50!black}{{\itshape{\let\pgfmanualwordstartup\relax\pgfmanualprettyprintcode{##1}}}}}, + /codeexample/prettyprint/cs/.code={\textcolor{blue!70!black}{\pgfmanualcslinkpreskip4.25pt\pgfmanualpdfref{##1}{##1}}}, + /codeexample/prettyprint/cs with args/.code 2 args={\textcolor{black}{\pgfmanualcslinkpreskip4.25pt\pgfmanualpdfref{##1}{##1}}\{\textcolor{black}{\pgfmanualprettyprintcode{##2}}\pgfmanualclosebrace}, + /codeexample/prettyprint/cs arguments/pgfkeys/.initial=1, + /codeexample/prettyprint/cs/pgfkeys/.code 2 args={\textcolor{black}{\pgfmanualcslinkpreskip4.25pt\pgfmanualpdfref{##1}{##1}}\{\textcolor{black}{\pgfmanualprettyprintpgfkeys{##2}}\pgfmanualclosebrace}, + /codeexample/prettyprint/cs arguments/begin/.initial=1, + /codeexample/prettyprint/cs/begin/.code 2 args={\textcolor{black}{##1}\{\textcolor{blue!70!black}{\pgfmanualpdfref{##2}{##2}}\pgfmanualclosebrace}, + /codeexample/prettyprint/cs arguments/end/.initial=1, + /codeexample/prettyprint/cs/end/.code 2 args={\textcolor{black}{##1}\{\textcolor{blue!70!black}{\pgfmanualpdfref{##2}{##2}}\pgfmanualclosebrace}, + /codeexample/prettyprint/word/.code={\pgfmanualwordstartup{\begingroup\pgfkeyssetvalue{/pdflinks/search key prefixes in}{}\pgfmanualpdfref{##1}{##1}\endgroup}}, + /codeexample/prettyprint/point/.code={\textcolor{violet}{##1}},% + /codeexample/prettyprint/point with cs/.code 2 args={\textcolor{violet}{(\pgfmanualpdfref{##1}{##1}:##2}},% + /codeexample/prettyprint/comment font=\itshape, + /codeexample/prettyprint/base color/.initial=\color{black!55}, + /pdflinks/render hyperlink/.code={% + {\setbox0=\hbox{##1}% + \rlap{{\color{white}\dimen0\wd0\advance\dimen0by-\pgfmanualcslinkpreskip\hskip\pgfmanualcslinkpreskip\vrule width\dimen0 height-1pt depth1.6pt}}% + \box0% + }% + } + } +} + +\def\pgfmanualwordstartup{\textcolor{black}} + %%% Local Variables: %%% mode: latex diff --git a/Master/texmf-dist/doc/generic/pgf/pgfmanual.pdf b/Master/texmf-dist/doc/generic/pgf/pgfmanual.pdf Binary files differindex 68d7e593a38..24ba754a77e 100644 --- a/Master/texmf-dist/doc/generic/pgf/pgfmanual.pdf +++ b/Master/texmf-dist/doc/generic/pgf/pgfmanual.pdf diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-actions.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-actions.tex index 77172602df0..81d12c2c6e9 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-actions.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-actions.tex @@ -31,6 +31,8 @@ In detail, paths can be used in the following ways: \item You can \emph{stroke} (also known as \emph{draw}) a path. \item + You can add \emph{arrow tips} to a path. +\item You can \emph{fill} a path with a uniform color. \item You can \emph{clip} subsequent renderings against the path. @@ -42,7 +44,7 @@ In detail, paths can be used in the following ways: You can also perform any combination of the above, though it makes no sense to fill and shade a path at the same time. -To perform (a combination of) the first three actions, you can use the +To perform (a combination of) the first four actions, you can use the following command: \begin{command}{\pgfusepath\marg{actions}} Applies the given \meta{actions} to the current path. Afterwards, @@ -59,8 +61,8 @@ following command: \pgfusepath{fill} \end{pgfpicture} \end{codeexample} - \item \declare{|stroke|} - strokes the path. See Section~\ref{section-stroke} for further details. + \item \declare{|stroke|} strokes the path. See + Section~\ref{section-stroke} for further details. \begin{codeexample}[] \begin{pgfpicture} \pgfpathmoveto{\pgfpointorigin} @@ -69,9 +71,10 @@ following command: \pgfusepath{stroke} \end{pgfpicture} \end{codeexample} + \item \declare{|draw|} has the same effect as |stroke|. \item \declare{|clip|} - clips all subsequent drawings against the path. See - Section~\ref{section-clip} for further details. + clips all subsequent drawings against the path. Always supresses + arrow tips. See Section~\ref{section-clip} for further details. \begin{codeexample}[] \begin{pgfpicture} \pgfpathmoveto{\pgfpointorigin} @@ -251,91 +254,6 @@ this may change in the future, so do not count on this. You can set the stroke opacity using |\pgfsetstrokeopacity|. This command is described in Section~\ref{section-transparency}. -\subsubsection{Graphic Parameter: Arrows} - -After a path has been drawn, \pgfname\ can add arrow tips at the -ends. It will only add arrows at the beginning of the first subpath -and at the end of the last subpath. For closed paths the result is not -defined, that is, it may change without notice in the future. - -\begin{command}{\pgfsetarrowsstart\marg{arrow kind}} - Sets the arrow tip kind used at the start of a (possibly curved) - path. When this option is used, the line will often be slightly - shortened to ensure that the tip of the arrow will exactly ``touch'' - the ``real'' start of the line. - - To ``clear'' the start arrow, say |\pgfsetarrowsstart{}|. -\begin{codeexample}[] -\begin{pgfpicture} - \pgfsetarrowsstart{latex} - \pgfpathmoveto{\pgfpointorigin} - \pgfpathlineto{\pgfpoint{1cm}{0cm}} - \pgfusepath{stroke} - \pgfsetarrowsstart{to} - \pgfpathmoveto{\pgfpoint{0cm}{2mm}} - \pgfpathlineto{\pgfpoint{1cm}{2mm}} - \pgfusepath{stroke} -\end{pgfpicture} -\end{codeexample} - - The effect of this command persists only till the end of the current - \TeX\ scope. - - The different possible arrow kinds are explained in - Section~\ref{section-arrows}. -\end{command} - -\begin{command}{\pgfsetarrowsend\marg{arrow kind}} - Sets the arrow tip kind used at the end of a path. -\begin{codeexample}[] -\begin{pgfpicture} - \pgfsetarrowsstart{latex} - \pgfsetarrowsend{to} - \pgfpathmoveto{\pgfpointorigin} - \pgfpathlineto{\pgfpoint{1cm}{0cm}} - \pgfusepath{stroke} -\end{pgfpicture} -\end{codeexample} -\end{command} - -\begin{command}{\pgfsetarrows{\texttt{\char`\{}}\meta{start kind}|-|\meta{end kind}{\texttt{\char`\}}}} - Sets the start arrow kind to \meta{start kind} and the end kind to - \meta{end kind}. -\begin{codeexample}[] -\begin{pgfpicture} - \pgfsetarrows{latex-to} - \pgfpathmoveto{\pgfpointorigin} - \pgfpathlineto{\pgfpoint{1cm}{0cm}} - \pgfusepath{stroke} -\end{pgfpicture} -\end{codeexample} -\end{command} - -\begin{command}{\pgfsetshortenstart\marg{dimension}} - This command will shortened the start of every stroked path by the - given dimension. This shortening is done in addition to automatic - shortening done by a start arrow, but it can be used even if no - start arrow is given. - - This command is useful if you wish arrows or lines to ``stop shortly - before'' a given point. -\begin{codeexample}[] -\begin{pgfpicture} - \pgfpathcircle{\pgfpointorigin}{5mm} - \pgfusepath{stroke} - \pgfsetarrows{latex-} - \pgfsetshortenstart{4pt} - \pgfpathmoveto{\pgfpoint{5mm}{0cm}} % would be on the circle - \pgfpathlineto{\pgfpoint{2cm}{0cm}} - \pgfusepath{stroke} -\end{pgfpicture} -\end{codeexample} -\end{command} - -\begin{command}{\pgfsetshortenend\marg{dimension}} - Works like |\pgfsetshortenstart|. -\end{command} - \subsubsection{Inner Lines} @@ -345,7 +263,7 @@ color. This is a useful effect for creating ``double'' lines, for instance by setting the line width to 2pt and stroking a black line and then setting the inner line width to 1pt and stroking a white line on the same path as the original path. This results in what looks -like two lines, each of thickness 0.5pt, spaces 1pt apart. +like two lines, each of thickness 0.5pt, spaced 1pt apart. You may wonder why there is direct support for this ``double stroking'' in the basic layer. After all, this effect is easy to @@ -416,6 +334,98 @@ Two commands are used to set the inner line width and color. \end{command} +\subsection{Arrow Tips on a Path} +\label{section-tips} + +After a path has been drawn, \pgfname\ can add arrow tips at the +ends, depending on how the |tips| key is set, on whether |stroke| or +|clip| arw used and on whether the path contains closed subpaths. The +exact rules when arrow tips are added are explained in +Section~\ref{section-arrow-tips-where}. + +\begin{command}{\pgfsetarrowsstart\marg{start arrow tip specification}} + Sets the arrow tip kind used at the start of a (possibly curved) + path. The syntax of the \meta{start arrow specification} is detailed + in Section~\ref{section-arrow-spec}. + + To ``clear'' the start arrow, say |\pgfsetarrowsstart{}|. +\begin{codeexample}[] +\begin{pgfpicture} + \pgfsetarrowsstart{Latex[length=10pt]} + \pgfpathmoveto{\pgfpointorigin} + \pgfpathlineto{\pgfpoint{1cm}{0cm}} + \pgfusepath{stroke} + \pgfsetarrowsstart{Computer Modern Rightarrow} + \pgfpathmoveto{\pgfpoint{0cm}{2mm}} + \pgfpathlineto{\pgfpoint{1cm}{2mm}} + \pgfusepath{stroke} +\end{pgfpicture} +\end{codeexample} + + The effect of this command persists only till the end of the current + \TeX\ scope. +\end{command} + +\begin{command}{\pgfsetarrowsend\marg{end arrow tip specification}} + Sets the arrow tip kind used at the end of a path. +\begin{codeexample}[] +\begin{pgfpicture} + \pgfsetarrowsstart{Latex[length=10pt]} + \pgfsetarrowsend{Computer Modern Rightarrow} + \pgfpathmoveto{\pgfpointorigin} + \pgfpathlineto{\pgfpoint{1cm}{0cm}} + \pgfusepath{stroke} +\end{pgfpicture} +\end{codeexample} +\end{command} + +\begin{command}{\pgfsetarrows\marg{argument}} + The \meta{argument} can be of the form \meta{start arrow tip + specifciation}|-|\meta{end arrow tip specification}. In this + case, both the start and the end arrow specification are set: +\begin{codeexample}[] +\begin{pgfpicture} + \pgfsetarrows{Latex[length=10pt]->>} + \pgfpathmoveto{\pgfpointorigin} + \pgfpathlineto{\pgfpoint{1cm}{0cm}} + \pgfusepath{stroke} +\end{pgfpicture} +\end{codeexample} + Alternatively, \meta{argument} can be of the form |[|\meta{arrow + keys}|]|. In this case, the \meta{arrow keys} will be set for all + arrow tips in the current scope, see Section~\ref{section-arrow-scopes}. +\end{command} + + +\begin{command}{\pgfsetshortenstart\marg{dimension}} + This command will shortened the start of every stroked path by the + given dimension. This shortening is done in addition to automatic + shortening done by a start arrow, but it can be used even if no + start arrow is given. + + It is usually better to use the |sep| key with arrow tips. + + This command is useful if you wish arrows or lines to ``stop shortly + before'' a given point. +\begin{codeexample}[] +\begin{pgfpicture} + \pgfpathcircle{\pgfpointorigin}{5mm} + \pgfusepath{stroke} + \pgfsetarrows{Latex-} + \pgfsetshortenstart{4pt} + \pgfpathmoveto{\pgfpoint{5mm}{0cm}} % would be on the circle + \pgfpathlineto{\pgfpoint{2cm}{0cm}} + \pgfusepath{stroke} +\end{pgfpicture} +\end{codeexample} +\end{command} + +\begin{command}{\pgfsetshortenend\marg{dimension}} + Works like |\pgfsetshortenstart|. +\end{command} + + + \subsection{Filling a Path} \label{section-fill} @@ -423,7 +433,7 @@ Filling a path means coloring every interior point of the path with the current fill color. It is not always obvious whether a point is ``inside'' a path when the path is self-intersecting and/or consists or multiple parts. In this case either the nonzero winding number rule -or the even-odd crossing number rule is used to decide, which points +or the even-odd crossing number rule is used to decide which points lie ``inside.'' These rules are explained in Section~\ref{section-rules}. diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-arrows.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-arrows.tex index aac739b9d1f..15926efe567 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-arrows.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-arrows.tex @@ -1,4 +1,4 @@ -% Copyright 2006 by Till Tantau +% Copyright 2013 by Till Tantau % % This file may be distributed and/or modified % @@ -8,54 +8,30 @@ % See the file doc/generic/pgf/licenses/LICENSE for more details. -\section{Arrow Tips} +\section{Defining New Arrow Tip Kinds} \label{section-arrows} \subsection{Overview} -\subsubsection{When Does PGF Draw Arrow Tips?} - -\pgfname\ offers an interface for placing \emph{arrow tips} at the end -of lines. The interface works as follows: - -\begin{enumerate} -\item - You (or someone else) assigns a name to a certain kind of arrow - tips. For example, the - arrow tip |latex| is the arrow tip used by the standard \LaTeX\ - picture environment; the arrow tip |to| looks like the tip of the - arrow in \TeX's |\to| command; and so on. - - This is done once at the beginning of the document. -\item - Inside some picture, at some point you specify that in the current - scope from now on you would like tips of, say, kind |to| to be added - at the end and/or beginning of all paths. - - When an arrow kind has been installed and when \pgfname\ is about to - stroke a path, the following things happen: - \begin{enumerate} - \item - The beginning and/or end of the path is shortened appropriately. - \item - The path is stroked. - \item - The arrow tip is drawn at the beginning and/or end of the path, - appropriately rotated and appropriately resized. - \end{enumerate} -\end{enumerate} - -In the above description, there are a number of ``appropriately.'' -The exact details are not quite trivial and described later on. - - -\subsubsection{Meta-Arrow Tips} - -In \pgfname, arrows are ``meta-arrows'' in the same way that fonts in -\TeX\ are ``meta-fonts.'' When a meta-arrow is resized, it is not -simply scaled, but a possibly complicated transformation is applied to -the size. +In present section we have a look at how you can define new arrow tips +for use in \pgfname. The low-level commands for selecting which arrow +tips are to be used have already been described in +Section~\ref{section-tips}, the general syntax rules for using arrows +are detailed in Section~\ref{section-tikz-arrows}. Although +Section~\ref{section-tikz-arrows} describes the use of arrows in +\tikzname, in reality, \tikzname\ itself does not actually do anything +about arrow tips; all of the functionality is implemented on the +\pgfname\ level in the commands described in +Section~\ref{section-tikz-arrows}. Indeed, even the |/.tip| key +handler described in Section~\ref{section-tikz-arrows} is actually +implemented on the \pgfname\ layer. + +What has \emph{not} yet been covered is how you can actually define a +complete new arrow tip. In \pgfname, arrows are ``meta-arrows'' in the +same way that fonts in \TeX\ are ``meta-fonts.'' When a meta-arrow is +resized, it is not simply scaled, but a possibly complicated +transformation is applied to the size. A meta-font is not one particular font at a specific size with a specific stroke width (and with a large number of other parameters @@ -73,84 +49,42 @@ text was scaled down, while the second text is a ``normal'' tiny text. The second text is easier to read. \pgfname's meta-arrows work in a similar fashion: The shape of an -arrow tip can vary according to the line width of the arrow tip is -used. Thus, an arrow tip drawn at a line width of 5pt will typically -\emph{not} be five times as large as an arrow tip of line width -1pt. Instead, the size of the arrow will get bigger only slowly as the -line width increases. +arrow tip can vary according to a great number of parameters, the line +width of the arrow tip being one of them. Thus, an arrow tip drawn at +a line width of 5pt will typically \emph{not} be five times as large +as an arrow tip of line width 1pt. Instead, the size of the arrow will +get bigger only slowly as the line width increases. -To appreciate the difference, here are the |latex| and |to| arrows, as -drawn by \pgfname\ at four different sizes: +To appreciate the difference, here are the |Latex| and +|Classical TikZ Rightarrow| arrows, as drawn by \pgfname\ at four different sizes: \medskip -\begin{tikzpicture} - \draw[-latex,line width=0.1pt] (0pt,0ex) -- +(3,0) node[thin,right] {line width is 0.1pt}; - \draw[-latex,line width=0.4pt] (0pt,-2em) -- +(3,0) node[thin,right] {line width is 0.4pt}; - \draw[-latex,line width=1.2pt] (0pt,-4em) -- +(3,0) node[thin,right] {line width is 1.2pt}; - \draw[-latex,line width=5pt] (0pt,-6em) -- +(3,0) node[thin,right] {line width is 5pt}; - - \draw[-to,line width=0.1pt] (6cm,0ex) -- +(3,0) node[thin,right] {line width is 0.1pt}; - \draw[-to,line width=0.4pt] (6cm,-2em) -- +(3,0) node[thin,right] {line width is 0.4pt}; - \draw[-to,line width=1.2pt] (6cm,-4em) -- +(3,0) node[thin,right] {line width is 1.2pt}; - \draw[-to,line width=5pt] (6cm,-6em) -- +(3,0) node[thin,right] {line width is 5pt}; +\begin{tikzpicture}[1/.tip=Latex, 2/.tip=Classical TikZ Rightarrow] + \draw[-1, line width=0.1pt] (0pt,0ex) -- +(3,0) node[thin,right] {line width is 0.1pt}; + \draw[-1, line width=0.4pt] (0pt,-2em) -- +(3,0) node[thin,right] {line width is 0.4pt}; + \draw[-1, line width=1.2pt] (0pt,-4em) -- +(3,0) node[thin,right] {line width is 1.2pt}; + \draw[-1, line width=5pt] (0pt,-6em) -- +(3,0) node[thin,right] {line width is 5pt}; + + \draw[-2, line width=0.1pt] (6cm,0ex) -- +(3,0) node[thin,right] {line width is 0.1pt}; + \draw[-2, line width=0.4pt] (6cm,-2em) -- +(3,0) node[thin,right] {line width is 0.4pt}; + \draw[-2, line width=1.2pt] (6cm,-4em) -- +(3,0) node[thin,right] {line width is 1.2pt}; + \draw[-2, line width=5pt] (6cm,-6em) -- +(3,0) node[thin,right] {line width is 5pt}; \end{tikzpicture} \medskip -Here, by comparison, is the same arrow when it is simply ``resized'' -(as done by some programs): - -\pgfarrowsdeclare{bad latex}{bad latex} -{ - \pgfarrowsleftextend{-1\pgflinewidth} - \pgfarrowsrightextend{9\pgflinewidth} -} -{ - \pgfpathmoveto{\pgfpoint{9\pgflinewidth}{0pt}} - \pgfpathcurveto - {\pgfpoint{6.3333\pgflinewidth}{.5\pgflinewidth}} - {\pgfpoint{2\pgflinewidth}{2\pgflinewidth}} - {\pgfpoint{-1\pgflinewidth}{3.75\pgflinewidth}} - \pgfpathlineto{\pgfpoint{-1\pgflinewidth}{-3.75\pgflinewidth}} - \pgfpathcurveto - {\pgfpoint{2\pgflinewidth}{-2\pgflinewidth}} - {\pgfpoint{6.3333\pgflinewidth}{-.5\pgflinewidth}} - {\pgfpoint{9\pgflinewidth}{0pt}} - \pgfusepathqfill -} - -\pgfarrowsdeclare{bad to}{bad to} -{ - \pgfarrowsleftextend{-2\pgflinewidth} - \pgfarrowsrightextend{\pgflinewidth} -} -{ - \pgfsetlinewidth{0.8\pgflinewidth} - \pgfsetdash{}{0pt} - \pgfsetroundcap - \pgfsetroundjoin - \pgfpathmoveto{\pgfpoint{-3\pgflinewidth}{4\pgflinewidth}} - \pgfpathcurveto - {\pgfpoint{-2.75\pgflinewidth}{2.5\pgflinewidth}} - {\pgfpoint{0pt}{0.25\pgflinewidth}} - {\pgfpoint{0.75\pgflinewidth}{0pt}} - \pgfpathcurveto - {\pgfpoint{0pt}{-0.25\pgflinewidth}} - {\pgfpoint{-2.75\pgflinewidth}{-2.5\pgflinewidth}} - {\pgfpoint{-3\pgflinewidth}{-4\pgflinewidth}} - \pgfusepathqstroke -} +Here, by comparison, are the same arrows when they are simply ``resized'': \medskip -\begin{tikzpicture} - \draw[-bad latex,line width=0.1pt] (0pt,0ex) -- +(3,0) node[thin,right] {line width is 0.1pt}; - \draw[-bad latex,line width=0.4pt] (0pt,-2em) -- +(3,0) node[thin,right] {line width is 0.4pt}; - \draw[-bad latex,line width=1.2pt] (0pt,-4em) -- +(3,0) node[thin,right] {line width is 1.2pt}; - \draw[-bad latex,line width=5pt] (0pt,-6em) -- +(3,0) node[thin,right] {line width is 5pt}; - - \draw[-bad to,line width=0.1pt] (6cm,0ex) -- +(3,0) node[thin,right] {line width is 0.1pt}; - \draw[-bad to,line width=0.4pt] (6cm,-2em) -- +(3,0) node[thin,right] {line width is 0.4pt}; - \draw[-bad to,line width=1.2pt] (6cm,-4em) -- +(3,0) node[thin,right] {line width is 1.2pt}; - \draw[-bad to,line width=5pt] (6cm,-6em) -- +(3,0) node[thin,right] {line width is 5pt}; +\begin{tikzpicture}[1/.tip=Latex, 2/.tip=Classical TikZ Rightarrow] + \draw[-{1[length=1pt]}, line width=0.1pt] (0pt,0ex) -- +(3,0) node[thin,right] {line width is 0.1pt}; + \draw[-{1[length=4pt]}, line width=0.4pt] (0pt,-2em) -- +(3,0) node[thin,right] {line width is 0.4pt}; + \draw[-{1[length=12pt]}, line width=1.2pt] (0pt,-4em) -- +(3,0) node[thin,right] {line width is 1.2pt}; + \draw[-{1[length=32pt]}, line width=5pt] (0pt,-6em) -- +(3,0) node[thin,right] {line width is 5pt}; + + \draw[-{2[length=0.455pt]}, line width=0.1pt] (6cm,0ex) -- +(3,0) node[thin,right] {line width is 0.1pt}; + \draw[-{2[length=1.82pt]}, line width=0.4pt] (6cm,-2em) -- +(3,0) node[thin,right] {line width is 0.4pt}; + \draw[-{2[length=5.46pt]}, line width=1.2pt] (6cm,-4em) -- +(3,0) node[thin,right] {line width is 1.2pt}; + \draw[-{2[length=14.56pt]}, line width=5pt] (6cm,-6em) -- +(3,0) node[thin,right] {line width is 5pt}; \end{tikzpicture} \bigskip @@ -163,632 +97,807 @@ appearance of an arrow tip. In particular, the width of the inner line tips as well as other options that are specific to the arrow tip. +\subsection{Terminology} +\label{section-arrow-terminology} -\subsection{Declaring an Arrow Tip Kind} - -To declare an arrow kind ``from scratch,'' the following command is -used: +Before we have a look at the exact commands used for defining arrow +tips, we need to fix some terminology. Consider the following drawing +of an arrow tip where the arrow tip is drawn transparently so that we +can see what is ``happening behind it'': -\begin{command}{\pgfarrowsdeclare\marg{start name}\marg{end - name}\marg{extend code}\marg{arrow tip code}} - This command declares a new arrow kind. An arrow kind has two names, - which will typically be the same. When the arrow tip needs to be - drawn, the \meta{arrow tip code} will be invoked, but the canvas - transformation is setup beforehand to a rotation such that when an - arrow tip pointing right is specified, the arrow tip that is - actually drawn points in the direction of the line. +\begin{tikzpicture} + \draw [red!50, ,line width=1cm] (0,0) -- (4,0); + \path [tips, opacity=.25,line width=1cm, -{Stealth[black,line width=0pt,length=4cm, width=4cm, inset=1cm]}] (0,0) -- (6,0); + + \draw [->,thick] (1,0) -- (8,0) node [right] {$x$-axis}; + \draw [->,thick] (5,-2.25) -- (5,2.25) node [above] {$y$-axis}; + + \foreach \i in {-3,-2,-1,1,2} \draw (\i+5,-1mm) -- (\i+5,1mm) node [above] {\small$\i$}; + \foreach \i in {-2,-1,1,2} \draw (49mm,\i) -- (51mm,\i) node [right] {\small$\i$};; +\end{tikzpicture} - \medskip - \textbf{Naming the arrow kind.} - The \meta{start name} is the name - used for the arrow tip when it is at the start of a path, the \meta{end - name} is the name used at the end of a path. For example, the - arrow kind that looks like a parenthesis has the \meta{start - name} |(| and the \meta{end name} |)| so that you can say - |\pgfsetarrows{(-)}| to specify that you want parenthesis arrows and - both ends. - - The \meta{end name} and \meta{start name} can be quite arbitrary and - may contain spaces. +I have also added a coordinate system. The code for drawing an arrow +tip always draws it in the way shown above: Pointing right along the +$x$-axis. + +We will use the following terminology: +\begin{itemize} +\item The point where tip of the arrow ends is called the + \emph{tip end}. It is at $(1,0)$ in our example and we always + assume it to lie on the $x$-axis, so we just treat it as a distance, + 1 in this case. This is the position where the original path was + supposed to end (so if the arrow tip had not been added to the red + path, it would have ended here). +\item The \emph{back end} of the arrow is where a vertical line just + to the left of the arrow intersects the $x$-axis. In our case, this + is the point $(-3,0)$ and again we treat it as a distance, $-3$ in + this case. +\item The \emph{line end} is the position where the path now + ends. This should be a position inside the arrow head that gets + ``covered'' by the path. Note that a path may have a round or a rect + head and should still be covered. Clearly, necessary shortening of + the path will be the difference between the tip end and the line + end. +\item The \emph{visual back end} is the position where the path and + the the arrow head ``meet last'' on the path. In our case, because + of the inset, the visual back end is not the same as the back end: + The arrow ends ``visually'' at $(-2,0)$. The difference between the + back end and the visual back end is important when the arrow tip is + flexed, see Section~\ref{section-arrow-flex} for an explanation of + flexing. +\item There is also a \emph{visual tip end}, the counterpart of the + visual back end for the front. In our case, the visual tip end and + the tip end obviously coincide, but if we were to reverse the arrow + tip, the visual tip end would be different form the tip end (while + the visual back end would then coincide with the new back end). +\item There are four points that make up the \emph{convex hull} of the + arrow tip: $(1,0)$, $(-3,2)$, and $(-3,-2)$. + + Normally, \pgfname\ automatically keeps track of a bounding box of + everything you draw. However, since arrow tips are drawn so often, + \pgfname\ caches the code needing for drawing arrow tips internally + and because of this cache it cannot determine the size of the arrow + tip just based on the drawing commands used for drawing the + tip. Instead, a convex hull of the arrow tip must be explicitly + provided in the definition. +\end{itemize} + +When you design a new arrow tip, all of the above parameters must be +defined. + +\subsection{Caching and Rendering of Arrows} + +As a last preparation for the description of the commands for +declaring arrows, it is important to understand the exact process by +which \pgfname\ draws arrows. - \medskip - \textbf{Basics of the arrow tip code.} - Let us next have a look at the \meta{arrow tip code}. This code will - be used to draw the arrow tip when \pgfname\ thinks this is - necessary. The code should draw an arrow that ``points right,'' - which means that is should draw an arrow at the end of a line coming - from the left and ending at the origin. - - As an example, suppose we wanted to declare an arrow tip consisting - of two arcs, that is, we want the arrow tip to look more or less - like the red part of the following picture: -\begin{codeexample}[] -\begin{tikzpicture}[line width=3pt] - \draw (-2,0) -- (0,0); - \draw[red,line join=round,line cap=round] - (-10pt,10pt) arc (180:270:10pt) arc (90:180:10pt); -\end{tikzpicture} -\end{codeexample} +\begin{enumerate} +\item First, you have to define an arrow tip kind using + |\pgfdeclarearrow{name=foo,...|. This will tell \pgfname\ that %} + |foo| is now the name of an arrow tip. In particular, the + parser for arrow tip specifications will now treat |foo| as the name + of an arrow tip and will not try to consider |f|, |o|, and |o| as + the names of single-char shorthands. + + Other than storing the definitions in the declaration internally, + this command has little other effect. In particular, no drawing or + other processing takes place. +\item Now assume that at some point the arrow tip |foo| is actually + used. In this case, certain options may have been set, for instance + the user may have requested the arrow tip + |foo[length=5pt,open]|. What happens next depends on whether it is + the first time the arrow tip |foo| is used with \emph{these exact + options} ornot. +\item Assume that is the first time |foo| is requested at a length of + 5pt and in an ``open'' version. \pgfname\ now retrieves the + definition of the arrow tip kind that it stored in the first step + and executes the so-called \emph{setup} code. When this code is + executed, all the options will be in force (for + instance, |\pgfarrowlength| will equal |5pt| in our case). The job + of the setup code is two-fold: First, it needs to compute all of the + parameters listed in Section~\ref{section-arrow-terminology}, that + is, it has to compute where the tip end will lie in the arrow tip's + coordinate system \emph{at the particular size of 5pt}, where the + back end will be, where the convex hull points lie, and so + on. Second, the setup code should precompute values that will be + important for constructing the path of the arrow. In our example, + there is little to do in this regard, but for more complicated + arrows, all time-consuming preparations are done now. + + It is \emph{not} the job of the setup to actually draw the arrow + tip, only to ``prepare'' this as much as possible. + + The setup code will always be executed only once for each arrow tip + kind for a given set of options. Thus, when a user uses + |foo[length=5pt,open]| once more later anywhere in the document, the + setup code will not be executed again. +\item The next thing that happens is that we have a look at the + \emph{drawin code} stored in the |code| field of the arrow. In our + example, the drawing code would consist of creating a filled path + with four straight segments. + + In most cases, what happens now is that the drawing code is executed in a + special sandbox in which the low-level driver commands that do the + actual drawing are intercepted and stored away in a so-called + \emph{cache}. Once such a cache has been created, its contents will + be reused whenever |foo[length=5pt,open]| is requested by a user and + just like the setup code, the drawing code will not be executed + again. + + There are, however, two cases in which the drawing code gets executed + each time the arrow is used: First, an arrow tip kind can specify + that this should always happen by saying |cachable=false| in its + definition. This is necessary if the drawing code contains + low-level drawing commands that cannot be intercepted such as a use + of |\pgftext| for arrow tips that ``contain text.'' Second, when the + |bend| option is used, the same arrow tip will look different each + time it is used, namely in dependence on the exact curvature of the + path to which it is added. + + Because the drawing code may be executed several times, while the + setup code may not, we must find a way to ``communicate'' the + values computed by the setup code to the drawing code. This is done + by explicitly calling |\pgfarrowssave| inside the setup + code. Whatever is ``saved'' in this way is restored each time before + the drawing code is executed. +\end{enumerate} - We could use the following as \meta{arrow tip code} for this: -\begin{codeexample}[code only] -\pgfarrowsdeclare{arcs}{arcs}{...} -{ - \pgfsetdash{}{0pt} % do not dash - \pgfsetroundjoin % fix join - \pgfsetroundcap % fix cap - \pgfpathmoveto{\pgfpoint{-10pt}{10pt}} - \pgfpatharc{180}{270}{10pt} - \pgfpatharc{90}{180}{10pt} - \pgfusepathqstroke -} -\end{codeexample} +As can be seen, the process is a bit involved, but it leads to +a reasonably fast arrow tip management. - Indeed, when the |...| is set appropriately (in a moment), we can - write the following: -\pgfarrowsdeclare{arcs}{arcs}{\pgfarrowsleftextend{0pt}\pgfarrowsrightextend{0pt}} -{ - \pgfsetdash{}{0pt} % do not dash - \pgfsetroundjoin % fix join - \pgfsetroundcap % fix cap - \pgfpathmoveto{\pgfpoint{-10pt}{10pt}} - \pgfpatharc{180}{270}{10pt} - \pgfpatharc{90}{180}{10pt} - \pgfusepathqstroke -} -\begin{codeexample}[] -\begin{tikzpicture} - \draw[-arcs,line width=3pt] (-2,0) -- (0,0); - \draw[arcs-arcs,line width=1pt] (-2,-1.5) -- (0,-1); - \useasboundingbox (-2,-2) rectangle (0,0.75); -\end{tikzpicture} -\end{codeexample} - As can be seen in the second example, the arrow tip is automatically - rotated as needed when the arrow is drawn. This is achieved by a - canvas rotation. +\subsection{Declaring an Arrow Tip Kind} +\begin{command}{\pgfdeclarearrow\marg{config}} + This command is both used to define a new arrow tip kind and to to + declare a so-called shorthand. We have a look at the case that a + complete new arrow tip kind is created and then have a look how the + command can be used to create shorthands. + \medskip - \textbf{Special considerations about the arrow tip code.} - There are several things you need to be aware of when designing - arrow tip code: - \begin{itemize} - \item - Inside the code, you may not use the |\pgfusepath| - command. The reason is that this command internally calls arrow - construction commands, which is something you obviously do not want - to happen. - - Instead of |\pgfusepath|, use the quick versions. Typically, you - will use |\pgfusepathqstroke|, |\pgfusepathqfill|, or - |\pgfusepathqfillstroke|. - \item - The code will be executed only once, namely the first time the - arrow tip needs to be drawn. The resulting low-level driver - commands are protocolled and stored away. In all subsequent - uses of the arrow tip, the protocolled code is directly inserted. - \item - However, the code will be executed anew for each line width. Thus, - an arrow of line width 2pt may result in a different protocol than - the same arrow for a line width of 0.4pt. - \item - If you stroke the path that you construct, you should first set - the dashing to solid and setup fixed joins and caps, as - needed. This will ensure that the arrow tip will always look the - same. - \item - When the arrow tip code is executed, it is automatically put - inside a low-level scope, so nothing will ``leak out'' from the - scope. - \item - The high-level coordinate transformation matrix will be set to the - identity matrix when the code is executed for the first time. - \end{itemize} + \noindent\textbf{Defining a Complete New Arrow Tip Kind.} + The \meta{config} is a key--value list in which different keys are + used to setup the to-be defined arrow. The following keys can be given: - \medskip - \textbf{Designing meta-arrows.} - The \meta{arrow tip code} should adjust the size of the arrow in - accordance with the line width. For a small line width, the arrow - tip should be small, for a large line width, it should be - larger. However, the size of the arrow typically \emph{should not} - grow in direct proportion to the line width. On the other hand, the - size of the arrow head typically \emph{should} grow ``a bit'' with - the line width. - - For these reasons, \pgfname\ will not simply executed your arrow - code within a scaled scope, where the scaling depends on the line - width. Instead, your \meta{arrow tip code} is reexecuted again for - each different line width. - - In our example, we could use the following code for the new arrow - tip kind |arc'| (note the prime): + \begin{itemize} + \item \declare{|name|}|=|\meta{name} or |name=|\meta{start name}|-|\meta{end + name} + + This defines the name of the arrow tip. It is legal to define an + arrow tip a second time, in this case the previous definition will + be overwritten in the current \TeX\ scope. It is customary to use + a name with an uppercase fist letter for a ``complete'' arrow tip + kind. Short names and lower case names should be used for + shorthands that change their meaning inside a document, while + arrow tips with uppercase first letters should not be redefined. + + If the name contains a hyphen, the second syntax is assumed and + everything before the hyphen will be the name used in start arrow + specifications, while the text after the hyphen is the name used + in end specifications. + \item \declare{|parameters|}|=|\marg{list of macros} + + As explained earlier, an arrow tip typically needs to be redrawn + each time an option like |length| or |inset| is changed. However, + for some arrow tips, the |inset| has no influence, while for other + it is important whether the arrow is reversed or not. (How keys + like |length| actually set \TeX\ dimensions like |\pgfarrowlength| + is explained in Section~\ref{section-arrow-options}.) + + The job of the |parameters| key is to specify which dependencies + the arrow tip has. Everything that will influence any of the + parameters computed in the setup code or used in the drawing code + should be listed here. + + The \meta{list of macros} will be used inside a + |\csname|-|\endcsname| pair and should expand to the current + values of the relevant parameters have. For example, if the arrow + tip depends on the current value of |\pgfarrowlength| and + |\pgfarrowwidth| only, then \meta{list of macros} should be set to + |\the\pgfarrowlength,\the\pgfarrowwidth|. (Actually, the comma is + optional, the \meta{list of macros} does not really have to be a + list, just something that can be expanded unambiuously.) + + Note that the line width (|\pgflinewidth|) and the inner line + width (|\pgfinnerlinewidth|) are always parameters and need not be + specified in the |parameters|. + + It is important to get this parameter right. Otherwise, arrow tips + may look wrong because \pgfname\ thinks that it can reuse some + code when, in reality, this code actually depends on a parameter + not listed here. + + \item \declare{|setup code|}|=|\marg{code} + + When an arrow tip is used, the value stored in |parameters| is + expanded and it is tested whether the result was encountered + before. If not, the \meta{code} gets executed (only this + once). The code can now do aribtrarily complicated computations + the prepare the later drawing of the arrow tip. Also the + \meta{code} must specify the different tip and back ends and the + convex hull points. This is done by calling the following macros + inside the \meta{code}: + + \begin{command}{\pgfarrowssettipend\marg{dimension}} + When this command is called inside the setup code of an arrow + tip, it specifies that the tip of the drawn arrow will end + exactly at \meta{dimension}. For example, for our earlier + example of the large arrow tip, where the tip end was at 1cm, we + would call \begin{codeexample}[code only] -\newdimen\arrowsize -\pgfarrowsdeclare{arcs'}{arcs'}{...} -{ - \arrowsize=0.2pt - \advance\arrowsize by .5\pgflinewidth - \pgfsetdash{}{0pt} % do not dash - \pgfsetroundjoin % fix join - \pgfsetroundcap % fix cap - \pgfpathmoveto{\pgfpoint{-4\arrowsize}{4\arrowsize}} - \pgfpatharc{180}{270}{4\arrowsize} - \pgfpatharc{90}{180}{4\arrowsize} - \pgfusepathqstroke -} +\pgfarrowssettipend{1cm} \end{codeexample} -\newdimen\arrowsize -\pgfarrowsdeclare{arcs'}{arcs'}{\pgfarrowsleftextend{0pt}\pgfarrowsrightextend{0pt}} -{ - \arrowsize=0.2pt - \advance\arrowsize by .5\pgflinewidth - \pgfsetdash{}{0pt} % do not dash - \pgfsetroundjoin % fix join - \pgfsetroundcap % fix cap - \pgfpathmoveto{\pgfpoint{-4\arrowsize}{4\arrowsize}} - \pgfpatharc{180}{270}{4\arrowsize} - \pgfusepathqstroke - \pgfpathmoveto{\pgfpointorigin} - \pgfpatharc{90}{180}{4\arrowsize} - \pgfusepathqstroke -} -\begin{codeexample}[] -\begin{tikzpicture} - \draw[-arcs',line width=3pt] (-2,0) -- (0,0); - \draw[arcs'-arcs',line width=1pt] (-2,-1.5) -- (0,-1); - \useasboundingbox (-2,-1.75) rectangle (0,0.5); -\end{tikzpicture} + Note that for efficience reasons, the \meta{dimension} is not + passed through |\pgfmathsetlength|; rather what happens is that + |\pgf@x=|\meta{dimension} gets executed. In particular, you can + pack further computations into the \meta{dimension} by simply + starting it with a number and then appending some code that + modifies |\pgf@x|. Here is an example where instead of 1cm we + use $1\mathrm{cm} - \frac12\mathrm{linewidth}$ as the tip end: +\begin{codeexample}[code only] +\pgfarrowssettipend{1cm\advance\pgf@x by-.5\pgflinewidth} \end{codeexample} + If the command is not called at all inside the setup code, the + tip end is set to |0pt|. + \end{command} - However, sometimes, it can also be useful to have arrows that do not - resize at all when the line width changes. This can be achieved by - giving absolute size coordinates in the code, as done for |arc|. On - the other hand, you can also have the arrow resize linearly with the - line width by specifying all coordinates as multiples of - |\pgflinewidth|. - - \medskip - \textbf{The left and right extend.} - Let us have another look at the exact left and right ``ends'' of our - arrow tip. Let us draw the arrow tip |arc'| at a very large size: - -\begin{codeexample}[] -\begin{tikzpicture} - \draw[help lines] (-2,-1) grid (1,1); - \draw[line width=10pt,-arcs'] (-2,0) -- (0,0); - \draw[line width=2pt,white] (-2,0) -- (0,0); -\end{tikzpicture} + \begin{command}{\pgfarrowssetbackend\marg{dimension}} + Works like the command for the tip end, only it sets the back + end. In our example we would call +\begin{codeexample}[code only] +\pgfarrowssettipend{-3cm} \end{codeexample} + Defaults to |0pt|. + \end{command} + + \begin{command}{\pgfarrowssetlineend\marg{dimension}} + Sets the line end, so in the example we have + |\pgfarrowssettipend{-1cm}|. Default to |0pt|. + \end{command} + + \begin{command}{\pgfarrowssetvisualbackend\marg{dimension}} + Sets the visual back end, |\pgfarrowssetvisualbackend{-2cm}| in + our example. Default to the value of the normal back end. + \end{command} + + \begin{command}{\pgfarrowssetvisualtipend\marg{dimension}} + Sets the visual tip end. Default to the value of the normal tip + end and, thus, we need not set it in our example. + \end{command} + + \begin{command}{\pgfarrowshullpoint\marg{x dimension}\marg{y dimension}} + Adds a point to the convex hull of the arrow tip. As for the + previous commands, no math parsing is done; instead \pgfname\ + says |\pgf@x=|\meta{x dimension} and then |\pgf@y=|\meta{y + dimension}. Thus, both ``dimensions'' can contain code for + advancing and thus modifying |\pgf@x| and |\pgf@y|. + + In our example we would write +\begin{codeexample}[code only] +\pgfarrowshullpoint{1cm}{0pt} +\pgfarrowshullpoint{-3cm}{2cm} +\pgfarrowshullpoint{-3cm}{-2cm} +\end{codeexample} + \end{command} - As one can see, the arrow tip does not ``touch'' the origin as it - should, but protrudes a little over the origin. One remedy to this - undesirable effect is to change the code of the arrow tip such that - everything is shifted half an |\arrowsize| to the left. While this - will cause the arrow tip to touch the origin, the line itself will - then interfere with the arrow: The arrow tip will be partly - ``hidden'' by the line itself. - - \pgfname\ uses a different approach to solving the problem: The - \meta{extend code} argument can be used to ``tell'' \pgfname\ how - much the arrow protrudes over the origin. The argument is also used - to tell \pgfname\ where the ``left'' end of the arrow is. However, - this number is important only when the arrow is being reversed or - composed with other arrow tips. - - Once \pgfname\ knows the right extend of an arrow kind, it can - \emph{shorten} lines by this amount when drawing arrows. - Here is a picture that shows what the visualizes the extends. The - arrow tip itself is shown in red once more: + \begin{command}{\pgfarrowsupperhullpoint\marg{x dimension}\marg{y dimension}} + This command works like the previous command, only it normally + adds \emph{two} points to the convex hull: First, the point $(\meta{x + dimension},\meta{y dimension})$ and, secondly, the point $(\meta{x + dimension},-\meta{y dimension})$. However, the second point is + only added if the arrow is not a harpoon. - \medskip - \begin{tikzpicture} - \draw[line width=1cm,-arcs',red] (-6,0) -- (0,0); - \draw[line width=1cm,black] (-6,0) -- (0,0); - \draw[help lines] (-6,0) -- (2,0) (0,-3) -- (0,3) coordinate (a); - \draw[help lines,xshift=0.5cm] (0,-3) -- (0,3) coordinate (b); - \draw[help lines,xshift=-2.5cm-0.8pt] (0,-3) -- (0,3) coordinate (c); - - \coordinate (xline 1) at (0,1.5); - \coordinate (xline 2) at (0,2.8); - - \draw[|->|] (xline 1 -| a) -- node[above=2pt] {right extend} (xline 1 -| b); - \draw[|<-|] (xline 2 -| c) -- node[above=2pt] {left extend} (xline 2 -| a); - - \draw (0,0) -- (1,-1) node[below right] {origin}; - \end{tikzpicture} - - - The \meta{extend code} is normal \TeX\ code that is executed - whenever \pgfname\ wants to know how far the arrow tip will protrude - to the right and left. The code should call the following two - commands: \declare{|\pgfarrowsrightextend|} and - \declare{|\pgfarrowsleftextend|}. Both arguments take one argument - that specifies the size. Here is the final code for the |arc''| arrow - tip: -\begin{codeexample}[] -\pgfarrowsdeclare{arcs''}{arcs''} -{ - \arrowsize=0.2pt - \advance\arrowsize by .5\pgflinewidth - \pgfarrowsleftextend{-4\arrowsize-.5\pgflinewidth} - \pgfarrowsrightextend{.5\pgflinewidth} -} -{ - \arrowsize=0.2pt - \advance\arrowsize by .5\pgflinewidth - \pgfsetdash{}{0pt} % do not dash - \pgfsetroundjoin % fix join - \pgfsetroundcap % fix cap - \pgfpathmoveto{\pgfpoint{-4\arrowsize}{4\arrowsize}} - \pgfpatharc{180}{270}{4\arrowsize} - \pgfusepathqstroke - \pgfpathmoveto{\pgfpointorigin} - \pgfpatharc{90}{180}{4\arrowsize} - \pgfusepathqstroke -} -\begin{tikzpicture} - \draw[help lines] (-2,-1) grid (1,1); - \draw[line width=10pt,-arcs''] (-2,0) -- (0,0); - \draw[line width=2pt,white] (-2,0) -- (0,0); -\end{tikzpicture} + Thus, in our example we could simplify the convex hull to +\begin{codeexample}[code only] +\pgfarrowshullpoint{1cm}{0pt} +\pgfarrowsupperhullpoint{-3cm}{2cm} \end{codeexample} + If the \meta{y dimension} is zero or less, only one point, + namely $(\meta{x dimension},\meta{y dimension})$, is added to + the hull. Thus, we could also have used the upper convex hull + command in the first of the two of the above commands. + \end{command} + + \begin{command}{\pgfarrowssave\marg{macro}} + As explained earlier, the setup code needs to ``communicate'' + with the drawing code via ``saved values.'' This command get the + name of a macro and will store the value this macro had + internally. Then, each time drawing code is executed, the value + of this macro will be restored. + \end{command} + + \begin{command}{\pgfarrowssavethe\marg{register}} + Works like |\pgfarrowssave|, only the parameter must be a + register and |\the|\meta{register} will be saved. + Typically, you will write something like +\begin{codeexample}[code only] +\pgfarrowssavethe{\pgfarrowlength} +\pgfarrowssavethe{\pgfarrowwidth} +\end{codeexample} + To ensure that inside the drawing code the the dimension + registers |\pgfarrowlength| and |\pgfarrowwidth| are setup with + the values they had during the setup. + \end{command} + + \item \declare{|drawing code|}|=|\marg{code} + + This code will be executed at least once for each setting of the + parameters when the time arrow tip is actually drawn. Usually, + this one execution will be all and the + low-level commands generated inside the \meta{code} will we stored + in a special cache; but in some cases the \meta{code} gets + executed each time the arrow tip is used, so do not assume + anything about it. Inside the \meta{code}, you have access to all + values that were saved in the setup code as well as to the line + width. + + The \meta{code} should draw the arrow tip ``going right along the + $x$-axis.'' \pgfname\ will take care of setting up a canvas + transformation beforehand to a rotation such that when the + drawing is rendered, the arrow tip that is actually drawn points + in the direction of the line. Alternatively, when bending is + switched on, even more complicated low-level transformations will + be done automatically. + + The are some special considerations concerning the \meta{code}: + \begin{itemize} + \item + In the \meta{code} you may \emph{not} use |\pgfusepath| + since this would try to add arrow tips to the arrow tip and lead + to a recursion. Use the ``quick'' versions |\pgfusepathqstroke| + and so on instead, which never try to add arrow tips. + \item + If you stroke the path that you construct, you should first set + the dashing to solid and set up fixed joins and caps, as + needed. This will ensure that the arrow tip will always look the + same. + \item + When the arrow tip code is executed, it is automatically put + inside a low-level scope, so nothing will ``leak out'' from the + scope. + \item + The high-level coordinate transformation matrix will be set to the + identity matrix when the code is executed for the first time. + \end{itemize} + + \item \declare{|cache|}|=|\meta{true or false} + + When set to |true|, which is the default, the \meta{code} will be + executed only once for a partiular value of parameters and the + low-level commands created by the drawing code (using the system + layer protocol subsystem, see Section~\ref{section-protocols}) + will be cached and reused later on. However, when the drawing code + contains ``uncachable'' code like a call to |\pgftext|, caching + must be switched off by saying |cache=false|. + + \item \declare{|bending mode|}|=|\meta{mode} + + This key is important only when the |bend| option is used with an + arrow, see Section~\ref{section-arrow-flex} for an introduction to + this option. The |bend| option asks us to, well, bend the arrow + head. For some arrow head this is not possible or leads to very + strange drawings (for instance, when the |\pgftext| command is + used) and then it is better to switch bending off for the arrow + head (|flex| will then be used instead). To achieve this, set + \meta{mode} to |none|. + + For most arrow tips it does, however, make sense to bend + them. There are (at least) two different mathematical ways of + doing so, see Section~\ref{section-library-curvilinear} for details. Which of + these ways is use can be configured by setting \meta{mode} to + either |orthogonal| or to |polar|. It is best to try simply try + out both when designing an arrow tip to see which works + better. Since |orthogonal| is quicker and often gives good oder + even better results, it is the default. Some arrow tips, however, + profit from saying |bending mode=polar|. + + \item \declare{|defaults|}|=|\meta{arrow keys} + + The \meta{arrow keys} allow you to configure the default values + for the parameters on which an arrow tip depends. The \meta{arrow + keys} will be executed first before any other arrow tip options + are executed, see Section~\ref{section-arrow-scopes} for the exact + sequence. Also see Section~\ref{section-arrow-options} below for + more details on arrow options. + \end{itemize} - \medskip - \textbf{Taking inner lines into account.} - In addition to the line width, there is another parameter that (may) - influence the way an arrow looks: The inner line width, which is the - line width of the second line that is stroked on top of a normal - line in order to create the effect of a ``double'' line. When this - line width changes, the arrow tip code is also reexecuted (and - cached), so your code may depend on the current value of the inner - line width. - - The following example shows how this works. The |implies| arrow - defined below has to setup the line width not for the ``main'' line - width, but for the main line width minus the inner line width, - divided by~2. + This concludes the description of the keys you provide for the + declaration of an arrow. Let us now have a look at a simple example + that uses these features: We want to define an arrow tip kind |foo| + that produces the arrow tip we used as our running examlpe. However, + to make things a bit more interesting, let us make it + ``configurable'' insofar as the length of the arrow tip can be + configured using the |length| option, which sets the + |\pgfarrowlength|. By default, this length should be the gigantic + 4cm we say in the example, but uses should be able to set it to + anything they like. We will not worry about the arrow width or + insets, of arrow line width, or harpoons, or anything else in this + example to keep it simple. + + Here is the code: \begin{codeexample}[code only] -\pgfarrowsdeclare{implies}{implies}{...} -{ - \pgfmathsetlength{\pgfutil@tempdimb}{.5\pgflinewidth-.5*\pgfinnerlinewidth}% - \pgfsetlinewidth{\pgfutil@tempdimb} - \pgfsetdash{}{0pt} - \pgfsetroundcap - \pgfsetroundjoin - \pgfmathsetlength{\pgfutil@tempdima}{.25\pgflinewidth+.25*\pgfinnerlinewidth}% - \pgfpathmoveto {\pgfpoint{-1.4\pgfutil@tempdima}{2.65\pgfutil@tempdima}} - \pgfpathcurveto{\pgfpoint{-0.75\pgfutil@tempdima}{1.25\pgfutil@tempdima}} - {\pgfpoint{1\pgfutil@tempdima}{0.05\pgfutil@tempdima}} - {\pgfpoint{2\pgfutil@tempdima}{0pt}} - \pgfpathcurveto{\pgfpoint{1\pgfutil@tempdima}{-0.05\pgfutil@tempdima}} - {\pgfpoint{-.75\pgfutil@tempdima}{-1.25\pgfutil@tempdima}} - {\pgfpoint{-1.4\pgfutil@tempdima}{-2.65\pgfutil@tempdima}} - \pgfusepathqstroke -} +\pgfdeclarearrow{ + name = foo, + parameters = { \the\pgfarrowlength }, + setup code = { + % The different end values: + \pgfarrowssettipend{.25\pgfarrowlength} + \pgfarrowssetlineend{-.25\pgfarrowlength} + \pgfarrowssetvisualbackend{-.5\pgfarrowlength} + \pgfarrowssetbackend{-.75\pgfarrowlength} + % The hull + \pgfarrowshullpoint{.25\pgfarrowlength}{0pt} + \pgfarrowshullpoint{-.75\pgfarrowlength}{.5\pgfarrowlength} + \pgfarrowshullpoint{-.75\pgfarrowlength}{-.5\pgfarrowlength} + % Saves: Only the length: + \pgfarrowssavethe\pgfarrowlength + }, + drawing code = { + \pgfpathmoveto{.25\pgfarrowlength}{0pt} + \pgfpathlineto{-.75\pgfarrowlength}{.5\pgfarrowlength} + \pgfpathlineto{-.5\pgfarrowlength}{0pt} + \pgfpathlineto{-.75\pgfarrowlength}{-.5\pgfarrowlength} + \pgfpathclose + \pgfusepathqfill + }, + defaults = { length = 4cm } +} \end{codeexample} - Here is the effect for different combinations of line width and - inner line width: + We can now use it: +\pgfdeclarearrow{ + name = foo, + parameters = { \the\pgfarrowlength }, + setup code = { + % The different end values: + \pgfarrowssettipend{.25\pgfarrowlength} + \pgfarrowssetlineend{-.25\pgfarrowlength} + \pgfarrowssetvisualbackend{-.5\pgfarrowlength} + \pgfarrowssetbackend{-.75\pgfarrowlength} + % The hull + \pgfarrowshullpoint{.25\pgfarrowlength}{0pt} + \pgfarrowshullpoint{-.75\pgfarrowlength}{.5\pgfarrowlength} + \pgfarrowshullpoint{-.75\pgfarrowlength}{-.5\pgfarrowlength} + % Saves: Only the length: + \pgfarrowssavethe\pgfarrowlength + }, + drawing code = { + \pgfpathmoveto{\pgfqpoint{.25\pgfarrowlength}{0pt}} + \pgfpathlineto{\pgfqpoint{-.75\pgfarrowlength}{.5\pgfarrowlength}} + \pgfpathlineto{\pgfqpoint{-.5\pgfarrowlength}{0pt}} + \pgfpathlineto{\pgfqpoint{-.75\pgfarrowlength}{-.5\pgfarrowlength}} + \pgfpathclose + \pgfusepathqfill + }, + defaults = { length = 4cm } +} \begin{codeexample}[] -\begin{tikzpicture} - \foreach \linewidth in {2,2.4,...,4.4} - \foreach \innerlinewidth in {0.4,0.8,...,1.8} - { - \pgfsetlinewidth{\linewidth pt} - \pgfsetinnerlinewidth{\innerlinewidth pt} - \draw [-implies] (\innerlinewidth*50pt,\linewidth*40pt) -- ++(4mm,0); - } -\end{tikzpicture} +\tikz \draw [-foo] (0,0) -- (8,0); +\end{codeexample} +\begin{codeexample}[] +\tikz \draw [-{foo[length=2cm,bend]}] (0,0) to [bend left] (3,0); \end{codeexample} \medskip - \textbf{Arrow options.} - You may wish to have further option influence the appearance of an - arrow tip. For instance, for a ``pointed'' arrow you may wish to set - the opening angle of the tip. Then, whenever this option changes - that arrow tip code also needs to be reexecuted, even though the - line width has stayed the same. - - You can use the commands |\pgfsetarrowoptions| and - |\pgfgetarrowoptions| to set such options for an arrow tip. Whenever - an arrow tip needs to be rendered, it is checked whether the arrow - tip code has already been executed for the current (expanded) value of the - options. If so, the cached code is used; otherwise the code is - executed once more. Naturally, inside the code the current value of - the arrow options should be taken into account. - - Arrow options can and must be specified individually for each arrow - type. - - In the following example, we make the arc angle an option. -\begin{codeexample}[] -\pgfarrowsdeclare{var arc}{var arc} % options is an angle -{ - \arrowsize=0.2pt - \advance\arrowsize by .5\pgflinewidth - \pgfarrowsleftextend{-4\arrowsize-.5\pgflinewidth} - \pgfarrowsrightextend{.5\pgflinewidth} -} -{ - \arrowsize=0.2pt - \advance\arrowsize by .5\pgflinewidth - \pgfsetdash{}{0pt} % do not dash - \pgfsetroundjoin % fix join - \pgfsetroundcap % fix cap - \pgfpathmoveto{\pgfpointorigin} - \pgfpatharc{-90}{-180+\pgfgetarrowoptions{var arc}}{4\arrowsize} - \pgfusepathqstroke - \pgfpathmoveto{\pgfpointorigin} - \pgfpatharc{90}{180-\pgfgetarrowoptions{var arc}}{4\arrowsize} - \pgfusepathqstroke -} -\begin{tikzpicture} - \draw[help lines] (-2,-4) grid (1,4); - \foreach \option in {-60,-50,...,60} - { - \pgfsetarrowoptions{var arc}{\option} - \draw[ultra thick,-var arc] (-2,\option/15) -- (0,\option/15); - } -\end{tikzpicture} + \noindent\textbf{Defining a Shorthand.} + The |\pgfdeclarearrow| command can also used to define + \emph{shorthands}. This works as follows: + \begin{itemize} + \item First, you must provide a |name| just in the same way as when + you define a full-flung new arrow tip kind. + \item Second, instead of all of the other options listed above, you + just use one more option: + + \smallskip + \declare{|means|}|=|\meta{end arrow specification} + + This sets up things so that whenever \meta{name} is now used in an + arrow specification, it will be replaced by the \meta{end arrow + specification} (the problems resulting form the \meta{name} + begin used in a start arrow specification are taken care of + automatically). See also Section~\ref{section-arrow-tip-macro} for + details on the order in which options get executed in such cases. + + Note that the \meta{end arrow specification} will be executed + immediately to build the so-called arrow option caches, a concept + explored in more detail in + Section~\ref{section-arrow-option-cache}. In practice, this has + mainly two effects: First, all arrow tips referred to in the + specification must already exist (at least as ``dummy'' + versions). Second, all dimensions mentioned in options of the + \meta{end arrow specification} will be evaluated immediately. For + instance, when you write +\begin{codeexample}[code only] +\pgfdeclarearrow{ name=foo, means = bar[length=2cm+\mydimen] } \end{codeexample} + The value |2cm+\mydimen| is evaluated immediately. When |foo| is + used later on and |\mydimen| has changed, this has no effect. + \end{itemize} \end{command} -\pgfarrowsdeclare{arcs''}{arcs''} -{ - \arrowsize=0.2pt - \advance\arrowsize by .5\pgflinewidth - \pgfarrowsleftextend{-4\arrowsize-.5\pgflinewidth} - \pgfarrowsrightextend{.5\pgflinewidth} -} -{ - \arrowsize=0.2pt - \advance\arrowsize by .5\pgflinewidth - \pgfsetdash{}{0pt} % do not dash - \pgfsetroundjoin % fix join - \pgfsetroundcap % fix cap - \pgfpathmoveto{\pgfpoint{-4\arrowsize}{4\arrowsize}} - \pgfpatharc{180}{270}{4\arrowsize} - \pgfusepathqstroke - \pgfpathmoveto{\pgfpointorigin} - \pgfpatharc{90}{180}{4\arrowsize} - \pgfusepathqstroke -} - -\begin{command}{\pgfsetarrowoptions\marg{arrow tip}\marg{text}} - Sets the options for the \meta{arrow tip} to \meta{text}. The - default, before any call to this macro is made, is 0. -\end{command} -\begin{command}{\pgfgetarrowoptions\marg{arrow tip}} - This will expand to the current value of the options for the - \meta{arrow tip}. -\end{command} +\subsection{Handling Arrow Options} +\label{section-arrow-options} -\subsection{Declaring a Derived Arrow Tip Kind} +When you declare an arrow tip, your drawing code should take into +account the different arrow keys set for it (like the arrow tip length, +width, or harpooning). The different arrow keys that are available +have been described in detail in Section~\ref{section-arrow-config}; but +how do we access the values set by an option like |length| or +|harpoon| or |bend| in the drawing code? In the present section we +have a look at how this works. -It is possible to declare arrow kinds in terms of existing ones. For -these command to work correctly, the left and right extends must be -set correctly. -\begin{command}{\pgfarrowsdeclarealias\marg{start name}\marg{end - name}\marg{old start name}\marg{old end name}} - This command can be used to create an alias (another name) for an - existing arrow kind. +\subsubsection{Dimension Options} -\begin{codeexample}[] -\pgfarrowsdeclarealias{<}{>}{arcs''}{arcs''}% -\begin{tikzpicture} - \pgfsetarrows{<->} - \pgfsetlinewidth{1ex} - \pgfpathmoveto{\pgfpointorigin} - \pgfpathlineto{\pgfpoint{3.5cm}{2cm}} - \pgfusepath{stroke} - \useasboundingbox (-0.25,-0.25) rectangle (3.75,2.25); -\end{tikzpicture} -\end{codeexample} -\end{command} +Most arrow keys, like |length| or |width'|, simple set a \TeX\ +dimension register to a certain value. For example, |length| sets the +value of the \TeX\ dimension register |\pgfarrowlength|. Note that +|length| takes several values as input with a complicated semantics as +explained for the |length| key on +page~\pageref{length-arrow-key}. All of these settings are not +important for the setup code: When it gets executed, the code behind +the |length| key will have computed a simple number that is stored +in |\pgfarrowlength|. Indeed, inside the setup code you do not have +access to the exact value given to the |length| key; just to the +final computed value. +The following \TeX\ dimensions are available to the setup code: -\begin{command}{\pgfarrowsdeclarereversed\marg{start name}\marg{end - name}\marg{old start name}\marg{old end name}} - This command creates a new arrow kind that is the ``reverse'' of an - existing arrow kind. The (automatically cerated) code of the new - arrow kind will contain a flip of the canvas and the meanings of the - left and right extend will be reversed. +\begin{itemize} +\item |\pgfarrowslength|. It gets set by the arrow keys |length| and |angle|. +\item |\pgfarrowswidth|. It gets set by |width|, |width'|, and |angle|. +\item |\pgfarrowsinset|. It gets set by |inset| and |inset'|. +\item |\pgfarrowslinewidth|. It gets set by |line width| and |line width'|. +\end{itemize} -\begin{codeexample}[] -\pgfarrowsdeclarereversed{arcs reversed}{arcs reversed}{arcs''}{arcs''}% -\begin{tikzpicture} - \pgfsetarrows{arcs reversed-arcs reversed} - \pgfsetlinewidth{1ex} - \pgfpathmoveto{\pgfpointorigin} - \pgfpathlineto{\pgfpoint{3.5cm}{2cm}} - \pgfusepath{stroke} - \useasboundingbox (-0.25,-0.25) rectangle (3.75,2.25); -\end{tikzpicture} -\end{codeexample} -\end{command} +If your setup code depends on any of them, add them to the +|parameters| key of the arrow tip. +\subsubsection{True--False Options} -\begin{command}{\pgfarrowsdeclarecombine\opt{|*|}\opt{\oarg{offset}}\marg{start - name}\marg{end name}\marg{first start name}\marg{first end - name}\penalty0\marg{second start name}\marg{second end name}} - This command creates a new arrow kind that combines two existing - arrow kinds. The first arrow kind is the ``innermost'' arrow kind, - the second arrow kind is the ``outermost.'' +A number of arrow keys just do a yes/no switch, like |reversed|. All +of them setup a \TeX-if that you can access in the setup code: - The code for the combined arrow kind will install a canvas - translation before the innermost arrow kind in drawn. This - translation is calculated such that the right tip of the innermost - arrow touches the right end of the outermost arrow. The optional - \meta{offset} can be used to increase (or decrease) the distance - between the inner and outermost arrow. +\begin{itemize} +\item |\ifpgfarrowreversed| is setup by |reversed|. +\item |\ifpgfarrowswap| is setup by |swap| and also |right|. +\item |\ifpgfarrowharpoon| is setup by |harpoon| and also |left| and |right|. +\item |\ifpgfarrowroundcap| is set to true by |line cap=round| and set + to false by |line cap=butt|. It also gets (re)set by |round| and |sharp|. +\item |\ifpgfarrowroundjoin| is set to true by |line join=round| and set + to false by |line join=miter|. It also gets (re)set by |round| and |sharp|. +\item |\ifpgfarrowopen| is set to true by |fill=none| and by |open| + (which is a shorthand for |fill=none|) and set to false by |color| + and all other |fill=|\meta{color}. +\end{itemize} -\begin{codeexample}[] -\pgfarrowsdeclarecombine[\pgflinewidth] - {combined}{combined}{arcs''}{arcs''}{latex}{latex}% -\begin{tikzpicture} - \pgfsetarrows{combined-combined} - \pgfsetlinewidth{1ex} - \pgfpathmoveto{\pgfpointorigin} - \pgfpathlineto{\pgfpoint{3.5cm}{2cm}} - \pgfusepath{stroke} - \useasboundingbox (-0.25,-0.25) rectangle (3.75,2.25); -\end{tikzpicture} +If you code depends on any of these, you must add them to +the |parameters| in such a way that the parameters are different when +the \TeX-if is set from when it is not set. An easy way to achieve +this is to write something like +\begin{codeexample}[code only] + parameters = { \the\pgfarrowlength,..., + \ifpgfarrowharpoon h\fi\ + \ifpgfarrowroundjoin j\fi} \end{codeexample} +In other words, for each set parameter on which the arrow tip depends, +a specific letter is added to the parameters, making them unique. + +The first two of the above keys are a bit special: Reversing and swapping an +arrow tip can be done just by fiddling with the +transformation matrix: a reverse is a ``flip'' along the $y$-axis and +a swap is a flip along the $x$-axis. This is done automatically by +\pgfname. + +Nevertheless, you may wish to modify you code in dependence +especially of the |reverse| key: When |\ifpgfarrowreverse| is true, +\pgfname\ will flip the coordinate system along the $y$-axis, will +negate all end values (like line end, tip end, and so on) and will +exchange the meaning of back end and tip end as well as of visual back +end and visual back end. Usually, this is exactly what one need; +\emph{except} that the line end may no longer be appropriate. After +all, the line end should be chosen so that it is completely covered by +the arrow. Now, when the arrow tip is open, a reversed arrow should no +longer have the line end near the old visual back end, but near to the +old visual tip end. + +For these reasons, you may need to make the computation of the line +end dependent on whether the arrow is reversed or not. Note that when +you specify a different line end for a reversed arrow tip, the +transformation and inverting of the coordinate system will still be +done, meaning that if |reverse| is true, you need to specify a line +end in the ``old'' coordinate system that is at the position where, +after everything is inverted, it will be at the correct +position. Usually that means that if the |reverse| option is set, you +need to \emph{increase} the line end. + + +\subsubsection{Inaccessible Options} + +There are some options that influence the way an arrow tip looks, but +that you cannot access inside the setup code. Handling these options +lies entirely with \pgfname. If you wish your setup code to handle +these options, you have to setup your own ``parallel'' options. + +\begin{itemize} +\item |quick|, |flex|, |flex'|, and |bend| are all handled + automatically. You can, however, set the |bending mode| to avoid + bending of your arrow tip. +\item The colors set by |color| and |fill|. You can, however, access + them indirectly, namely through the current stroke and fill colors. +\item |sep| +\end{itemize} + + +\subsubsection{Defining New Arrow Keys} +\label{section-arrow-option-cache} + +The set of predefined options is already quite long and most arrow +tips will not need more than the predefined options. However, +sometimes an arrow tip may need to introduce a new special-purpose +option. For instance, suppose we wish to introcue a new fictive arrow +key |depth|. In such cases, you must do two things: - In the star variant, the end of the line is not in the outermost - arrow, but inside the innermost arrow. - -\begin{codeexample}[] -\pgfarrowsdeclarecombine*[\pgflinewidth] - {combined'}{combined'}{arcs''}{arcs''}{latex}{latex}% -\begin{tikzpicture} - \pgfsetarrows{combined'-combined'} - \pgfsetlinewidth{1ex} - \pgfpathmoveto{\pgfpointorigin} - \pgfpathlineto{\pgfpoint{3.5cm}{2cm}} - \pgfusepath{stroke} - \useasboundingbox (-0.25,-0.25) rectangle (3.75,2.25); -\end{tikzpicture} +\begin{enumerate} +\item + Introduce a new dimension register or macro that will hold the + configuration value and which will be accessed by the setup + code. The could be achieved by saying +\begin{codeexample}[code only] +\newdimen\pgfarrowdepth \end{codeexample} -\end{command} - - -\begin{command}{\pgfarrowsdeclaredouble\opt{\oarg{offset}}\marg{start - name}\marg{end name}\marg{old start name}\marg{old end - name}} - This command is a shortcut for combining an arrow kind with itself. +\item + Introduce a new arrow key option |/pgf/arrow keys/depth| that allows + users to configure the new macro or register. +\end{enumerate} -\begin{codeexample}[] -\pgfarrowsdeclaredouble{<<}{>>}{arcs''}{arcs''}% -\begin{tikzpicture} - \pgfsetarrows{<<->>} - \pgfsetlinewidth{1ex} - \pgfpathmoveto{\pgfpointorigin} - \pgfpathlineto{\pgfpoint{3.5cm}{2cm}} - \pgfusepath{stroke} - \useasboundingbox (-0.25,-0.25) rectangle (3.75,2.25); -\end{tikzpicture} +When an arrow is selected via for instance |foo[depth=5pt]|, the +key--value pairs between the square brackets are executed with the +path prefix |/pgf/arrow keys|. Thus, in the example, our depth key +would get executed. Thus, it is temping to write something like +\begin{codeexample}[code only] +\pgfkeys{/pgf/arrow keys/depth/.code = \pgfmathsetlength{\pgfarrowdepth}{#1}} \end{codeexample} -\end{command} - - -\begin{command}{\pgfarrowsdeclaretriple\opt{\oarg{offset}}\marg{start - name}\marg{end name}\marg{old start name}\marg{old end - name}} - This command is a shortcut for combining an arrow kind with itself - and then again. -\begin{codeexample}[] -\pgfarrowsdeclaretriple{<<<}{>>>}{arcs''}{arcs''}% -\begin{tikzpicture} - \pgfsetarrows{<<<->>>} - \pgfsetlinewidth{1ex} - \pgfpathmoveto{\pgfpointorigin} - \pgfpathlineto{\pgfpoint{3.5cm}{2cm}} - \pgfusepath{stroke} - \useasboundingbox (-0.25,-0.25) rectangle (3.75,2.25); -\end{tikzpicture} +Sadly, this will not work. The reason is that the is yet another level +of caching involved when \pgfname\ processes arrow tips: The option +cache! The problem is each time an arrow tip is used, even when the +drawing code of the arrow tip is nicely cached, we still need to +process the options in |foo[length=5pt]| to find out which version in +the cache we would like to access. To make matters worse, |foo| might +be a shorthand that calls other arrow tips, which add more options, +and so on. Unfortunately, executing keys is quite an expensive +operation (\pgfname's key--value parser is powerful, but that power +comes at a price). So, whenever possible, we do \emph{not} want the +key--value parser to be started. + +For these reasons, when something like |foo[|\meta{options}|]| is +encountered inside a shorthand, the \meta{options} are executed only +once. They should now setup the \emph{arrow option cache}, which is +some code that, when executed, should setup the values that the +\meta{options} configure. In our example, the |depth| key should add +something to the arrow option cache that sets |\pgfarrowdepth| to the +given value. + +Adding something to the arrow option cache is done using the following +command: + +\begin{command}{\pgfarrowsaddtooptions\marg{code}} + This command should be called by keys with the prefix + |/pgf/arrow keys| to add code to the arrow option cache. For our + |depth| key example, we could use this key as follows: +\begin{codeexample}[code only] +\pgfkeys{/pgf/arrow keys/depth/.code= + \pgfarrowsaddtooptions{\pgfmathsetlength{\pgfarrowdepth}{#1}} +\end{codeexample} + Actually, this is still not optimal since the expensive + |\pgfmathsetlength| command is now called each time an arrow tip is + used with the |depth| option set. The trick is to do the expensive + operation only once and then store only very quick code in the arrow + option cache: +\begin{codeexample}[code only] +\pgfkeys{/pgf/arrow keys/depth/.code= + \pgfmathsetlength{\somedimen}{#1} + \pgfarrowsaddtooptions{\pgfarrowdepth=\somedimen} % buggy +\end{codeexample} + The above code will not (yet) work since |\somedimen| will surely + have a different value when the cache is executed. The trick is to + use some |\expandafter|s: +\begin{codeexample}[code only] +\pgfkeys{/pgf/arrow keys/depth/.code= + \pgfmathsetlength{\somedimen}{#1} + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\pgfarrowdepth\expandafter=\the\somedimen} \end{codeexample} \end{command} +\begin{command}{\pgfarrowsaddtolateoptions\marg{code}} + This command works like |\pgfarrowsaddtooptions|, only the + \meta{code} will be executed ``later'' than the code added by the + normal version of the command. This is useful for keys that depend + on the length of an arrow: Keys like |width'| want to define the + arrow width as a multiple of the arrow length, but when the |width'| + key is given, the length may not yet have been specified. By making + the computation of the width a ``late'' option, we ensure that + |\pgfarrowlength| will have been setup correctly. +\end{command} +If you define a new option that sets a dimensions and if that +dimension should change in accordance to the setting of either +|scale length| or |scale width|, you need to make \pgfname\ ``aware'' +of this using the following key: +\begin{command}{\pgfarrowsaddtolengthscalelist\marg{dimension register}} + Each time an arrow tip is used, the given \meta{dimension register} + will be multiplied by the |scale length| factor prior to the actual + drawing. You call this command only once in the preamble somewhere. +\end{command} - -\subsection{Using an Arrow Tip Kind} - -The following commands install the arrow kind that will be used when -stroking is done. - -\begin{command}{\pgfsetarrowsstart\marg{start arrow kind}} - Installs the given \meta{start arrow kind} for all subsequent - strokes in the in the current \TeX-group. If \meta{start arrow kind} - is empty, no arrow tips will be drawn at the start of the last - segment of paths. -\begin{codeexample}[] -\begin{tikzpicture} - \pgfsetarrowsstart{latex} - \pgfsetlinewidth{1ex} - \pgfpathmoveto{\pgfpointorigin} - \pgfpathlineto{\pgfpoint{3.5cm}{2cm}} - \pgfusepath{stroke} - \useasboundingbox (-0.25,-0.25) rectangle (3.75,2.25); -\end{tikzpicture} -\end{codeexample} +\begin{command}{\pgfarrowsaddtowidthscalelist\marg{dimension register}} + Works like |\pgfarrowsaddtolengthscalelist|, only for width parameters. \end{command} -\begin{command}{\pgfsetarrowsend\marg{start arrow kind}} - Like |\pgfsetarrowsstart|, only for the end of the arrow. + +\begin{command}{\pgfarrowsthreeparameters\marg{line-width dependent + size specification}} + This command is useful for parsing the values given to keys like + |length| or |width| the expect a dimension followed optionally for + some numbers. This command converts the \meta{line-width dependent + size specification}, which may consist of one, two, or three + numbers, into a triple of three numbers in curly braces, which gets + stored in the macro |\pgfarrowstheparameters|. Here is an example, + where |\showvalueofmacro| is used in this example to show the value + stored in a macro: + \makeatletter + \def\showvalueofmacro#1{% + \texttt{\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\pgfutil@gobble\expandafter\expandafter\expandafter\string\expandafter\csname#1\endcsname} + } \begin{codeexample}[] -\begin{tikzpicture} - \pgfsetarrowsend{latex} - \pgfsetlinewidth{1ex} - \pgfpathmoveto{\pgfpointorigin} - \pgfpathlineto{\pgfpoint{3.5cm}{2cm}} - \pgfusepath{stroke} - \useasboundingbox (-0.25,-0.25) rectangle (3.75,2.25); -\end{tikzpicture} +\pgfarrowsthreeparameters{2pt 1} +\showvalueofmacro\pgfarrowstheparameters \end{codeexample} \end{command} -\emph{Warning:} If the compatibility mode is active (which is the -default), there also exist old commands called |\pgfsetstartarrow| and -|\pgfsetendarrow|, which are incompatible with the meta-arrow -management. +\begin{command}{\pgfarrowslinewidthdependent\marg{dimension}\marg{line + width factor}\marg{outer factor}} + This command take three parameters and does the ``line width + dependent computation'' described on page~\pageref{length-arrow-key} + for the |length| key. The result is returned in |\pgf@x|. -\begin{command}{\pgfsetarrows\texttt{\char`\{}\meta{start kind}|-|\meta{end kind}\texttt{\char`\}}} - Calls |\pgfsetarrowsstart| for \meta{start kind} and - |\pgfsetarrowsend| for \meta{end kind}. -\begin{codeexample}[] -\begin{tikzpicture} - \pgfsetarrows{latex-to} - \pgfsetlinewidth{1ex} - \pgfpathmoveto{\pgfpointorigin} - \pgfpathlineto{\pgfpoint{3.5cm}{2cm}} - \pgfusepath{stroke} - \useasboundingbox (-0.25,-0.25) rectangle (3.75,2.25); -\end{tikzpicture} + The idea is that you can setup line-width dependent keys like + |length| or |width| using code like the following: +\begin{codeexample}[code only] +\pgfkeys{/pgf/arrow keys/depth/.code={% + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtolateoptions\expandafter{% + \expandafter\pgfarrowslinewidthdependent\pgfarrowstheparameters% compute... + \pgfarrowdepth\pgf@x% ... and store. + }% +} \end{codeexample} \end{command} +\begin{command}{\pgfarrowslengthdependent\marg{dimension}\marg{length factor}\marg{dummy}} + This command take three parameters, of which the last one is + ignored, and does the ``length dependent computation'' described for + the |width'| and |inset'| keys. The result is returned in |\pgf@x|. -\subsection{Predefined Arrow Tip Kinds} - -\label{standard-arrows} - -The following arrow tip kinds are always defined: + You can setup length dependent keys using code like the following: +\begin{codeexample}[code only] +\pgfkeys{/pgf/arrow keys/depth'/.code={% + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtolateoptions\expandafter{% + \expandafter\pgfarrowslengthdependent\pgfarrowstheparameters% compute... + \pgfarrowdepth\pgf@x% ... and store. + }% +} +\end{codeexample} +\end{command} -{ -\bigskip -\catcode`\|=12 -\begin{tabular}{ll} - \sarrow{stealth}{stealth} \\ - \sarrow{stealth reversed}{stealth reversed} \\ - \sarrow{to}{to} \\ - \sarrow{to reversed}{to reversed} \\ - \sarrow{latex}{latex} \\ - \sarrow{latex reversed}{latex reversed} \\ - \index{*vbar@\protect\texttt{\protect\myvbar} arrow tip}% - \index{Arrow tips!*vbar@\protect\texttt{\protect\myvbar}} - \texttt{|-|}& yields thick - \begin{tikzpicture}[arrows={|-|},thick] - \useasboundingbox (0pt,-0.5ex) rectangle (1cm,2ex); - \draw (0,0) -- (1,0); - \end{tikzpicture} and thin - \begin{tikzpicture}[arrows={|-|},thin] - \useasboundingbox (0pt,-0.5ex) rectangle (1cm,2ex); - \draw (0,0) -- (1,0); - \end{tikzpicture} -\end{tabular} -} - -For further arrow tips, see page~\pageref{section-library-arrows}. %%% Local Variables: %%% mode: latex diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-decorations.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-decorations.tex index ea145e8fb06..92da9d37342 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-decorations.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-decorations.tex @@ -48,10 +48,9 @@ The workflow for using decorations is the following: \emph{to-be-decorated} path. \item You place the path construction commands inside the environment |{pgfdecoration}|. This environment takes the name of a previously - declared decoration as a parameter. It will then starting ``walking + declared decoration as a parameter. It will then start ``walking along'' the to-be-decorated path. As it does this, a special finite - automaton called a \emph{decoration automaton} produces as its - output new path construction commands (or even other outputs). These + automaton called a \emph{decoration automaton} produces new path commands as its output (or even other outputs). These outputs replace the to-be-decorated path; indeed, after the to-be-decorated path has been fully walked along it is thrown away, only the output of the automaton persists. @@ -80,7 +79,7 @@ automata are presented. \subsubsection{The Different Paths} -In order to prevent confusion with different types of path, such +In order to prevent confusion with different types of paths, such as those that are extended, those that are decorated and those that are created, the following conventions will be used: @@ -118,14 +117,14 @@ It is permissible that a decoration issues a |\pgfusepath| command. As usual, this causes the current path to be filled or stroked or some other action to be taken and the current path is set to the empty path. As described above, when the decoration -automaton starts the current path is the preexisting path and as the -automaton progresses, the current path is constantly being extend by -the output path. This means that first time e |\pgfusepath| command is +automaton starts, the current path is the preexisting path and as the +automaton progresses, the current path is constantly being extended by +the output path. This means that first time a |\pgfusepath| command is used on a decoration, the preexisting path is part of the path this command operates on; in subsequent calls only the part of the output path constructed since the last |\pgfusepath| command will be used. -You can use this mechanism to stroke or fill different part of the +You can use this mechanism to stroke or fill different parts of the output path in different colors, line widths, fills and shades; all within the same decoration. Alternatively, a decoration can choose to produce no output path at all: the |text| decoration simply typesets @@ -134,17 +133,17 @@ text along a path. \subsubsection{Segments and States} -The most common use a decoration is to ``repeat something along a +The most common use of a decoration is to ``repeat something along a path'' (for example, the |zigzag| decoration repeats \tikz\draw decorate[decoration=zigzag] {(0,0)--(\pgfdecorationsegmentlength,0)}; along a path). However, it -not necessarily the case that only one thing be repeated: a decoration +not necessarily the case that only one thing is repeated: a decoration can consist of different parts, or \emph{segments}, repeated in a particular order. When you declare a decoration, you provide a description of how their different segments will be rendered. The description of -each segment should be given in a way as if the ``x-axis'' of the +each segment should be given in a way as if the ``$x$-axis'' of the segment is the tangent to the path at a particular point, and that point is the origin of the segment. Thus, for example, the segment of the |zigzag| decoration might be @@ -157,10 +156,10 @@ defined using the following code: \pgfname\ will ensure that an appropriate coordinate transformation is in place when the segment is rendered such that -the segment actually points in the right direction. Also +the segment actually points in the right direction. Also, subsequent segments will be transformed such that they are ``further along the path'' toward the end of the path. -All transformations are setup automatically. +All transformations are set up automatically. Note that we did not use a |\pgfpathmoveto{\pgfpointorigin}| at the beginning of the segment code. Doing so would subdivide the path into @@ -182,7 +181,7 @@ Decorations use a mechanism known in theoretical in computer science as \emph{finite state automata} to describe which segment is used at a particular point. The idea is the following: For the first segment we start in a special \emph{state} called the \emph{initial state}. In -this state, and also in all other state later, \pgfname\ first +this state, and also in all other states later, \pgfname\ first computes how much space is left on the input path. That is, \pgfname\ keeps track of the distance to the end of the input path. Attached to each state there is a set of rules of the following form: ``If the remaining @@ -193,7 +192,7 @@ so, immediately switches to state~$q$. Only if none of the rules tell us to switch to another state, \pgfname\ will execute the state's code. This code will (typically) add a segment to the output path. In addition to the rules -there is also width parameter attached to each state. \pgfname\ then +there is also a width parameter attached to each state. \pgfname\ then translates the coordinate system by this width and reduces the remaining distance on the input path. Then, \pgfname\ either stays in the current state or switches to another state, depending on yet @@ -225,16 +224,16 @@ this command describes the decoration automaton. certain distance. This will also work if the path is not a straight line. That is, it is permissible that the path curves are veers at a sharp angle. It is also permissible that while traveling along the - input path the current input segment ends and a new input segment starts. In this + input path, the current input segment ends and a new input segment starts. In this case, the remaining distance on the first input segment is subtracted - from the \meta{dimension} and then we traveled along the second + from the \meta{dimension} and then we travel along the second input segment for the remaining distance. This input segment may also end early, in which case we travel along the next input segment, and so on. Note that it cannot happen that we travel past the end of the input path since this would have caused an immediate switch to the |final| state. - Note note that the computation of the path lengths has only a low + Note that the computation of the path lengths has only a low accuracy because of \TeX's small math capabilities. Do not expect high accuracy alignments when using decorations (unless the input path consists only of horizontal and vertical lines). @@ -251,15 +250,15 @@ this command describes the decoration automaton. happen: \begin{enumerate} \item - The \meta{options} are parsed. This may lead, see below, to a - state switch. When this happens, the following steps are not + The \meta{options} are parsed. This may lead to a + state switch, see below. When this happens, the following steps are not executed. The \meta{options} are executed one after the other in the given order. If an option causes a state switch, the switch is immediate, even if later options might cause a different state switch. \item The \meta{code} is executed in a \TeX-group with the current - transformation matrix setup in such a way that the origin is on + transformation matrix set up in such a way that the origin is on the input path at the current point (the point at the distance traveled up to now) and the coordinate system is rotated in such a way that the positive $x$-axis points in the direction of @@ -268,7 +267,7 @@ this command describes the decoration automaton. As described earlier, the \meta{code} can have two different effects: If it just contains path construction commands, the - decoration will produce an output path, which is extends the + decoration will produce an output path, that is, it extends the preexisting path. Here is an example: \begin{codeexample}[] @@ -295,7 +294,7 @@ this command describes the decoration automaton. \end{codeexample} Alternatively, the \meta{code} can also contain the - |\pgfusepath| command. This will use the path in usual manner, + |\pgfusepath| command. This will use the path in the usual manner, where ``the path'' is the preexisting path plus a part of the output path for the first invocation and the different parts of the rest of the output path for the following invocation. Here is @@ -332,13 +331,13 @@ this command describes the decoration automaton. The \meta{options} are executed with the key path set to |/pgf/decoration automaton|. The following keys are defined: - \begin{key}{/pgf/decoration automaton/switch if less than=\meta{dimension}| to |\meta{new state}} + \begin{key}{/pgf/decoration automaton/switch if less than=\meta{dimension}\texttt{ to }\meta{new state}} When this key is encountered, \pgfname\ checks whether the remaining distance to the end of the input path is less than \meta{dimension}. If so, an immediate state switch to \meta{new state} occurs. \end{key} - \begin{key}{/pgf/decoration automaton/switch if input segment less than=\\\meta{dimension}| to |\meta{new state}} + \begin{key}{/pgf/decoration automaton/switch if input segment less than=\\\meta{dimension}\texttt{ to }\meta{new state}} When this key is encountered, \pgfname\ checks whether the remaining distance to the end of the current input segment of the input path is less than \meta{dimension}. If so, an immediate @@ -395,7 +394,7 @@ this command describes the decoration automaton. operation. Otherwise, it is checked whether the current input segment is a closepath segment and whether the remaining distance on the current input segment is at most - \meta{distance}. If so, the a closepath operation is used to + \meta{distance}. If so, then a closepath operation is used to close the decorated path and the automaton continues with the next subpath, remaining in the current state. @@ -403,11 +402,11 @@ this command describes the decoration automaton. \end{key} \begin{key}{/pgf/decoration automaton/auto corner on length=\meta{dimension}} - This key has the following effect: Firstly, the \TeX-if + This key has the following effect: Firstly, in case the \TeX-if |\ifpgfdecoratepathhascorners| is false, nothing happens. Otherwise, it is tested whether the remaining distance on the current input segment is at most \meta{dimension}. If so, - a lineto operation is used to reach the end of this input + a |lineto| operation is used to reach the end of this input segment and the automaton continues with the next input segment, but remains in the current state. @@ -421,10 +420,10 @@ this command describes the decoration automaton. next state. For this, the following two options are useful: \begin{key}{/pgf/decoration automaton/persistent precomputation=\meta{precode}} - If the \meta{code} of state is executed, the \meta{precode} is - executed first and it executed outside the \TeX-group of the + If the \meta{code} of the state is executed, the \meta{precode} is + executed first and it is executed outside the \TeX-group of the \meta{code}. Note that when the \meta{precode} is executed, the - transformation matrix is not setup. + transformation matrix is not set up. \end{key} \begin{key}{/pgf/decoration automaton/persistent postcomputation=\meta{postcode}} @@ -588,7 +587,7 @@ Once a decoration has been declared, it can be used. \item The decoration automata move along the input paths, thus creating (and possibly using) the output paths. These output paths extend - (unless they are used) the current path. + the current path (unless they are used). \end{enumerate} Some important points should be noted regarding the use of this @@ -597,18 +596,18 @@ Once a decoration has been declared, it can be used. \begin{itemize} \item If \meta{environment contents} does not begin with - |\pgfpathmoveto|, he last known point on the preexisting path is + |\pgfpathmoveto|, the last known point on the preexisting path is assumed as the starting point. \item All except the last of any sequence of consecutive move-to commands in \meta{environment contents} are discarded. \item - Any move-to commands at end of \meta{environment contents} are + Any move-to commands at the end of \meta{environment contents} are ignored. \item Any close-path commands on the input path are interpreted as straight lines. - Internally something a little more complicated is going on, + Internally, something a little more complicated is going on, however, a closed path on the input path has no effect on the output path, other than causing the automaton to travel in a straight line towards the location of the last move-to command on @@ -617,16 +616,16 @@ Once a decoration has been declared, it can be used. Although tangent computations for the input path work with the last point on the preexisting path, no automatic move-to operations are issued for the output path. - If an output path commences with a line-to or curve-to when the + If an output path starts with a line-to or curve-to when the existing path is empty, an appropriate move-to command should be - inserted before the decoration commences. + inserted before the decoration starts. \item If a decoration uses its own path, the first time this happens the preexisting path is part of the path that is used at this point. \end{itemize} - When the decoration automata ``work on'' their respective input - paths, before the automaton starts, \meta{before code} is +Before the automata start to "work on" their respective inputs paths, + \meta{before code} is executed. After the decoration automaton has finished, \meta{after code} is executed. @@ -733,7 +732,7 @@ Once a decoration has been declared, it can be used. \end{command} The following style is executed each time a decoration is used. You - may use it to setup default options for decorations. + may use it to set up default options for decorations. \begin{stylekey}{/pgf/every decoration (initially \normalfont empty)} This style is executed for every decoration. \end{stylekey} @@ -822,8 +821,7 @@ multiple decorations. It is, in essence, an automaton that decorates an input path with decoration automatons. In general, however, the end effect is still that a path is decorated with other paths, and the input path should be thought of as being divided into sub-input-paths, each with -their own decoration. Like ordinary decorations, before a -meta-decoration can be used it must be declared. +their own decoration. Like ordinary decorations, a meta-decoration must be declared before it can be used. \subsubsection{Declaring Meta-Decorations} @@ -886,7 +884,7 @@ meta-decoration can be used it must be declared. \end{command} \begin{command}{\beforedecoration\marg{before code}} - Defines \marg{before code} as (typically) \pgfname{} commands to be + Defines \meta{before code} as (typically) \pgfname{} commands to be executed before the decoration is applied to the current segment. This command can be omitted. If you wish to set up some decoration specific parameters @@ -895,7 +893,7 @@ meta-decoration can be used it must be declared. \end{command} \begin{command}{\afterdecoration\marg{after code}} - Defines \marg{after code} as commands to be executed after the + Defines \meta{after code} as commands to be executed after the decoration has been applied to the current segment. This command can be omitted. \end{command} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-design.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-design.tex index cb36ae4442a..63d6ebeacf7 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-design.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-design.tex @@ -11,7 +11,7 @@ \section{Design Principles} This section describes the basic layer of \pgfname. This layer is -build on top of the system layer. Whereas the system layer just +built on top of the system layer. Whereas the system layer just provides the absolute minimum for drawing graphics, the basic layer provides numerous commands that make it possible to create sophisticated graphics easily and also quickly. diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-external.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-external.tex index fc4606b0848..33792dd1a2f 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-external.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-external.tex @@ -107,7 +107,7 @@ As we see in Figure~\ref{fig1}, the world is flat. \end{figure} \end{codeexample} - Each graphic that is be externalized should have a unique name. Note + Each graphic to be externalized should have a unique name. Note that this name will be used as the name of a file in the file system, so it should not contain any funny characters. @@ -136,7 +136,7 @@ As we see in Figure~\ref{fig1}, the world is flat. the graphic file is included. \item The most complex behaviour arises when current the |\jobname| equals the \meta{file name prefix} and, furthermore, the - a \emph{real job name} has been declared. The behaviour for this + \emph{real job name} has been declared. The behaviour for this case is explained later. \end{enumerate} @@ -178,7 +178,7 @@ modify the |\jobname| appropriately. This is done in two steps: the graphic for which you need an external graphic to be generated. To set the |\jobname|, you use the |--jobname=| option of \TeX: -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] bash> latex --jobname=survey-graphic1 survey.tex \end{codeexample} \end{enumerate} @@ -199,19 +199,19 @@ The following things will now happen: Note that, typically, \meta{everything} will contain just a single |{tikzpicture}| or |{pgfpicture}| environment. However, this need - not be the case, you use, say, a |{pspicture}| environment as + not be the case, you can use, say, a |{pspicture}| environment as \meta{everything} or even just some normal \TeX-text. \item At the |\endpgfgraphicnamed|, the box \emph{is} shipped out using the original |\shipout| command. Thus, unlike everything else, the contents of the graphic is made part of the output. \item When the box containing the graphic is shipped out, the paper - size is modified such that it exactly equal to the height and width + size is modified such that it is exactly equal to the height and width of the box. \end{enumerate} The net effect of everything described above is that the two commands -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] bash> latex --jobname=survey-graphic1 survey.tex bash> dvips survey-graphic1 \end{codeexample} @@ -222,7 +222,7 @@ page that contains exactly the graphic produced by the code between exactly the size of the graphic. If you use pdf\TeX, producing the graphic is even simpler: -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] bash> pdflatex --jobname=survey-graphic1 survey.tex \end{codeexample} \noindent produces the single-page |pdf|-file |survey-graphic1.pdf|. @@ -360,7 +360,7 @@ external graphics. To create the external graphics, we run |pdflatex| twice, once for each graphic: -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] bash> pdflatex --jobname=survey-f1 survey.tex This is pdfTeX, Version 3.141592-1.40.3 (Web2C 7.5.6) entering extended mode @@ -372,7 +372,7 @@ Output written on survey-f1.pdf (1 page, 1016 bytes). Transcript written on survey-f1.log. \end{codeexample} -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] bash> pdflatex --jobname=survey-f2 survey.tex This is pdfTeX, Version 3.141592-1.40.3 (Web2C 7.5.6) entering extended mode @@ -416,7 +416,9 @@ By comparison, in this figure we see a rectangle: \end{document} \end{codeexample} If we now run pdf\LaTeX, then, indeed, \pgfname\ is no longer needed: -\begin{codeexample}[code only] +% In the following, we switch off typesetting of listings because the +% parentheses confuse the pretty printer +\begin{codeexample}[code only,typeset listing/.code=#1] bash> pdflatex survey.tex This is pdfTeX, Version 3.141592-1.40.3 (Web2C 7.5.6) entering extended mode diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-images.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-images.tex index 2267999f3df..79ff832a88d 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-images.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-images.tex @@ -100,7 +100,7 @@ option: inserted and a warning is printed. \item \declare{|interpolate=|\meta{true or false}} selects whether the - image should ``smoothed'' when zoomed. False by default. + image should be ``smoothed'' when zoomed. False by default. \item \declare{|mask=|\meta{mask name}} selects a transparency mask. The mask must previously be declared using |\pgfdeclaremask| (see @@ -118,7 +118,7 @@ option: \begin{command}{\pgfaliasimage\marg{new image name}\marg{existing image name}} The \marg{existing image name} is ``cloned'' and the \marg{new image - name} can now be used whenever original image is used. This + name} can now be used whenever the original image is used. This command is useful for creating aliases for alternate extensions and for accessing the last image inserted using |\pgfimage|. @@ -135,7 +135,7 @@ option: If the macro |\pgfalternateextension| expands to some nonempty \meta{alternate extension}, \pgfname\ will first try to use the image - names \meta{image name}|.|\meta{alternate extension}. If this + named \meta{image name}|.|\meta{alternate extension}. If this image is not defined, \pgfname\ will next check whether \meta{alternate extension} contains a |!| character. If so, everything up to this exclamation mark and including it is deleted from \meta{alternate diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-internalregisters.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-internalregisters.tex index ec5d715f168..035e10b1edd 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-internalregisters.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-internalregisters.tex @@ -71,7 +71,7 @@ looking into the source code of |\pgfpointadd| to see which registers are used. \end{internallist} \begin{internallist}[openin handle]{\r@pgf@reada} - An |\openin| handle which is used to read files within locally scoped parts of \pgfname, for example to check if a file exists or to read data files. You should always use |\immediate| in front of output operations involving |\w@pgf@writea| and you should always close the file before returning from your code. + An |\openin| handle which is used to read files within locally scoped parts of \pgfname, for example to check if a file exists or to read data files. You should always use |\immediate| in front of output operations involving |\r@pgf@writea| and you should always close the file before returning from your code. \begin{codeexample}[code only] \immediate\openin\r@pgf@reada=myfile.dat % do something with \macro diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-layers.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-layers.tex index 3563d91db33..0f1c9e1eb02 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-layers.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-layers.tex @@ -15,7 +15,7 @@ \subsection{Overview} \pgfname\ provides a layering mechanism for composing graphics from -multiple layers. (This mechanism is not be confused with the +multiple layers. (This mechanism is not to be confused with the conceptual ``software layers'' the \pgfname\ system is composed of.) Layers are often used in graphic programs. The idea is that you can draw on the different layers in any order. So you might start drawing @@ -53,7 +53,7 @@ layer. You can declare a new layer using the following command: \begin{command}{\pgfdeclarelayer\marg{name}} This command declares a layer named \meta{name} for later - use. Mainly, this will setup some internal bookkeeping. + use. Mainly, this will set up some internal bookkeeping. \end{command} The next step toward using a layer is to tell \pgfname\ which layers @@ -62,8 +62,7 @@ ordering. Thus, it is possible to have more layers declared than are actually used. \begin{command}{\pgfsetlayers\marg{layer list}} - This command, which should be used \emph{outside} a |{pgfpicture}| - environment, tells \pgfname\ which layers will be used in + This command tells \pgfname\ which layers will be used in pictures. They are stacked on top of each other in the order given. The layer |main| should always be part of the list. Here is an example: @@ -72,6 +71,9 @@ actually used. \pgfdeclarelayer{foreground} \pgfsetlayers{background,main,foreground} \end{codeexample} + + This command should be given either outside of any picture or ``directly inside'' of a picture. + Here, the ``directly inside'' means that there should be no further level of \TeX\ grouping between |\pgfsetlayers| and the matching |\end{pgfpicture}| (no closing braces, no |\end{...}|). It will also work if |\pgfsetlayers| is provided before |\end{tikzpicture}| (with similar restrictions). \end{command} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-matrices.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-matrices.tex index d77f1312123..ca17510a797 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-matrices.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-matrices.tex @@ -25,15 +25,15 @@ options very similar to the |\pgfnode| command. In the following, the basic idea behind the alignment mechanism is explained first. Then the command |\pgfmatrix| is explained. At the -end of the section additional ways of modifying the width of columns -and rows is discussed. +end of the section, additional ways of modifying the width of columns +and rows are discussed. \subsection{Cell Pictures and Their Alignment} A matrix consists of rows of \emph{cells}. Cells are separated using the special command |\pgfmatrixnextcell|, rows are ended using the -command |\pgfmatrixendrow| (the command |\\| is setup to mean the same +command |\pgfmatrixendrow| (the command |\\| is set up to mean the same as |\pgfmatrixendrow| by default). Each cell contains a \emph{cell picture}, although cell pictures are not complete pictures as they lack layers. However, each cell picture has its own bounding box like a @@ -41,7 +41,7 @@ normal picture does. These bounding boxes are important for the alignment as explained in the following. Each cell picture will have an origin somewhere in the picture (or -even outside the picture). The position of these origins is important +even outside the picture). The position of these origins are important for the alignment: On each row the origins will be on the same horizontal line and for each column the origins will also be on the same vertical line. These two requirements mean that the cell pictures @@ -93,7 +93,7 @@ All matrices are typeset using the following command: The resulting matrix is used as the |text| box of the node. As for a normal node, the \meta{usage} commands are applied, so that the - path(s) of the resulting node are stroked or filled or whatever. + path(s) of the resulting node is (are) stroked or filled or whatever. \medskip \textbf{Specifying the cells and rows.\ } @@ -108,7 +108,7 @@ All matrices are typeset using the following command: to |\pgfmatrixnextcell|. This way, it will ``look'' as if |&| is used. \item Rows are ended using the command |\pgfmatrixendrow|, but |\\| - is setup to mean the same by default. However, some environments + is set up to mean the same by default. However, some environments like |{minipage}| redefine |\\|, so it is good to have |\pgfmatrixendrow| as a ``fallback.'' \item Every row \emph{including the last row} must be ended using @@ -232,10 +232,10 @@ commands for the column spacing. been started, subsequent uses of this optional argument for the column have no effect. - To determine the space between the two columns the are separated by + To determine the space between the two columns that are separated by |\pgfmatrixnextcell|, the following algorithm is executed: \begin{enumerate} - \item Both the default separation list (as setup by + \item Both the default separation list (as set up by |\pgfsetmatrixcolumnsep|) and the \meta{additional sep list} are processed, in this order. If the \meta{additional sep list} argument is missing, only the default separation list is @@ -244,7 +244,7 @@ commands for the column spacing. well as occurrences of the keywords |between origins| and |between borders|. \item All dimensions occurring in either list are added together to - arrive at an dimension $d$. + arrive at a dimension $d$. \item The last occurrence of either of the keywords is located. If neither keyword is present, we proceed as if |between borders| were present. @@ -260,7 +260,7 @@ commands for the column spacing. \item For the |between origins| mode, the spacing between the two columns is computed differently: Recall that the origins of the cell pictures in both pictures lie on two vertical lines. The - spacing between the two columns is setup such that the horizontal + spacing between the two columns is set up such that the horizontal distance between these two lines is exactly $d$. This mode may only be used between columns \emph{already @@ -268,9 +268,9 @@ commands for the column spacing. \end{itemize} All of the above rules boil down to the following effects: \begin{itemize} - \item A default spacing between columns should be setup using + \item A default spacing between columns should be set up using |\pgfsetmatrixcolumnsep|. For example, you might say - |\pgfsetmatrixcolumnsep{5pt}| to have columns be spaced apart by + |\pgfsetmatrixcolumnsep{5pt}| to have columns spaced apart by |5pt|. You could say \begin{verbatim} \pgfsetmatrixcolumnsep{1cm,between origins} @@ -355,7 +355,7 @@ commands are called differently. way as for columns. For the last row the optional argument has no effect. - Inside matrices (and only there) the command |\\| is setup to mean + Inside matrices (and only there) the command |\\| is set up to mean the same as this command. \end{command} @@ -422,7 +422,7 @@ current column in a callback: \begin{command}{\pgfmatrixcurrentrow} This counter stores the current row of the current cell of the - matrix. Do not even think of changing this counter. + matrix. Do not even think about changing this counter. \end{command} \begin{command}{\pgfmatrixcurrentcolumn} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-nodes.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-nodes.tex index 5df4c13b6bb..c40d308b3f4 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-nodes.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-nodes.tex @@ -38,7 +38,7 @@ path is stroked or filled. \subsubsection{Creating and Referencing Nodes} You create a node by calling the macro |\pgfnode| or the more general -|\pgfmultipartnode|. These macro takes several parameters and draws +|\pgfmultipartnode|. This macro takes several parameters and draws the requested shape at a certain position. In addition, it will ``remember'' the node's position within the current |{pgfpicture}|. You can then, later on, refer to the @@ -46,7 +46,7 @@ node's position. Coordinate transformations are ``fully supported,'' which means that if you used coordinate transformations to shift or rotate the shape of a node, the node's position will still be correctly determined by \pgfname. This is \emph{not} the case if you use canvas -transformations, instead. +transformations instead. \subsubsection{Anchors} @@ -81,7 +81,7 @@ The simplest shape, the |coordinate|, has just one anchor, namely the shapes like the |rectangle| shape also have a \emph{background path}. This is a \pgfname-path that is defined by the shape. The shape does not prescribe what should happen with the path: When a node -is created this path may be stroked (resulting in a frame around the +is created, this path may be stroked (resulting in a frame around the label), filled (resulting in a background color for the text), or just discarded. @@ -91,12 +91,12 @@ text, when a shape is drawn, up to seven different layers are drawn: \begin{enumerate} \item The ``behind the background layer.'' Unlike the background path, - which be used in different ways by different nodes, the graphic + which can be used in different ways by different nodes, the graphic commands given for this layer will always stroke or always fill the path they construct. They might also insert some text that is ``behind everything.'' \item - The background path layer. How this path is used depends on how the + The background path layer. How this path is used depends on the arguments of the |\pgfnode| command. \item The ``before the background path layer.'' This layer works like the @@ -111,7 +111,7 @@ text, when a shape is drawn, up to seven different layers are drawn: executed.'' \item The foreground path layer. This path is treated in the same way as the - background path, only it is drawn only after the label text has been + background path, only it is drawn after the label text has been drawn. \item The ``before the foreground layer.'' @@ -142,8 +142,8 @@ multipart nodes: They only have one part named |text|. When a shape is declared, you must specify the node parts. There is a simple command called |\nodeparts| that takes a list of the part names as input. When you create a node of a multipart shape, for each part -of the node you must have setup a \TeX-box containing the text of the -part. For a part named |XYZ| you must setup the box +of the node you must have set up a \TeX-box containing the text of the +part. For a part named |XYZ| you must set up the box |\pgfnodepartXYZbox|. The box will be placed at the anchor |XYZ|. See the description of |\pgfmultipartnode| for more details. @@ -225,9 +225,9 @@ the description of |\pgfmultipartnode| for more details. shapes), this command can also be used with multi-part nodes. When this command is called, for each node part of the node you must - have setup one \TeX-box. Suppose the shape has two parts: The |text| + have set up one \TeX-box. Suppose the shape has two parts: The |text| part and the |lower| part. Then, prior to calling - |\pgfmultipartnode|, you must have setup the boxes + |\pgfmultipartnode|, you must have set up the boxes |\pgfnodeparttextbox| and |\pgfnodepartlowerbox|. These boxes may contain any \TeX-text. The shape code will then compute the positions of the shape's anchors based on the sizes of the these @@ -253,7 +253,7 @@ the description of |\pgfmultipartnode| for more details. part name. Although you need a different box for each part of a single shape, two different shapes may very well use the same box even when the names of the parts are different. Suppose you have a - |circle split| shape that has an |lower| part and you have a + |circle split| shape that has a |lower| part and you have a |uml class| shape that has a |methods| part. Then, in order to avoid exhausting \TeX's limited number of box registers, you can say \begin{codeexample}[code only] @@ -389,11 +389,12 @@ node. These values are stored in the following keys. \subsubsection{Deferred Node Positioning} +\label{section-shapes-deferred-node-positioning} Normally, when a node is created using a command like |\pgfnode|, the node is immediately inserted into the current picture. In particular, you have no chance to change the position of a created node after it -has been create. Using |\pgfpositionnodelater| in concert with +has been created. Using |\pgfpositionnodelater| in concert with |\pgfpositionnodenow|, you can create a node whose position is determined only at some later time. @@ -406,7 +407,7 @@ determined only at some later time. node is not relevant for the picture's bounding box, but a bounding box for the node is computed and stored in the macros |\pgfpositionnodelaterminx| to |\pgfpositionnodelatermaxy|. Then, - the \meta{macro name} is called with the following macros setup: + the \meta{macro name} is called with the following macros set up: \begin{command}{\pgfpositionnodelaterbox} A box register number (|0| currently) that stores the node's paths @@ -416,9 +417,9 @@ determined only at some later time. \begin{command}{\pgfpositionnodelatername} The name of the just-created-node. This name will be the - originally "desired" name of the box plus the fixed prefix - |not yet positioned@|. The idea is to ensure that the original - name is not inadvertently used before the node is actually + originally ``desired'' name of the box plus the fixed prefix + |not yet positionedPGFINTERNAL|. The idea is to ensure that the + original name is not inadvertently used before the node is actually positioned. When |\pgfpositionnodenow| is called, it will change the name to the original name. \end{command} @@ -426,7 +427,8 @@ determined only at some later time. \begin{command}{\pgfpositionnodelaterminx} The minimal $x$-position of a bounding box of the node. This bounding box refers to the node when it is positioned with the - anchor at the origin. + anchor at the origin. It is guaranteed, that this macro will + contain a dimension in the format \meta{number}|pt|. \end{command} \begin{command}{\pgfpositionnodelaterminy} \end{command} @@ -443,6 +445,17 @@ determined only at some later time. above macros are local to a scope that ends right after the call to \meta{macro name}, so it is your job to copy the values to safety inside \meta{macro name}. + + The following two macros will also be set inside the call to + \meta{macro name}, but they are only ``informative'' in the sense + that you need \emph{not} restore these macros when + |\pgfpositionnodenow| is called. + + \begin{command}{\pgfpositionnodelaterpath} + This macro stores the path of the background of the node. See + Section~\ref{section-soft-paths} for an overview of how these + paths are encode. + \end{command} By setting \meta{macro name} to |\relax| (which is the default), you can switch off the whole mechanism. When a picture is interrupted, @@ -452,12 +465,13 @@ determined only at some later time. \begin{command}{\pgfpositionnodenow\marg{coordinate}} This command is used to position a node that has previously been - created with |\pgfpositionnodelater|. When |\pgfpositionnodenow| is + created using the command |\pgfpositionnodelater|. When |\pgfpositionnodenow| is called, the macros and boxes mentioned in the description of |\pgfpositionnodenow| must be set to the value they had when the \meta{macro name} was called. Provided this is the case, this command will insert the box into the current picture, shifted by - \meta{coordinate}. Subsequently, you can refer to the node with its + \meta{coordinate}. Then, the late code (see below) + is called. Subsequently, you can refer to the node with its original name as if it had just been created. \begin{codeexample}[] @@ -493,6 +507,22 @@ determined only at some later time. \end{command} +\begin{command}{\pgfnodepostsetupcode\marg{node name}\marg{code}} + When you call this macro inside a scope for which the + |\pgfpositionnodelater| has been called, the \meta{code} will be + stored internally. Later, when the node named \meta{node name} is + actually positioned using |\pgfpositionnodenow|, the \meta{code} + will be executed. When this macro is called multiple times with the + same \meta{node name}, the \meta{code} accumulates. However, When + |\pgfpositionnodenow| is called, the code stored for the node is + cleared. + + The main purpose of this mechanism is to allow \tikzname\ to store + so-called ``late options'' with a node that will be positioned only + later. +\end{command} + + \subsection{Using Anchors} Each shape defines a set of anchors. We saw already that the anchors @@ -568,9 +598,9 @@ following commands: A special situation arises when the \meta{node} lies in a picture different from the current picture. In this case, if you have not told \pgfname\ that the picture should be ``remembered,'' the - \meta{node} will be treated as if it lied in the current + \meta{node} will be treated as if it lay in the current picture. For example, if the \meta{node} was at position $(3,2)$ in - the original picture, it is treated as if it lied at position + the original picture, it is treated as if it lay at position $(3,2)$ in the current picture. However, if you have told \pgfname\ to remember the picture position of the node's picture and also of the current picture, @@ -625,7 +655,7 @@ not-so-easy. Because of this, \pgfname\ does not do so automatically. Rather, you have to proceed as follows: \begin{enumerate} \item You have to use a backend driver that supports position - tracking. pdf\TeX\ is one such drivers, |dvips| currently is not. + tracking. pdf\TeX\ is one such driver, |dvips| currently is not. \item You have to say |\pgfrememberpicturepositiononpagetrue| somewhere before or inside every picture \begin{itemize} @@ -670,6 +700,12 @@ should not attempt to redefine. bounding box of the current path. \end{predefinednode} +\begin{predefinednode}{current subpath start} + This node is of shape |coordinate| and is at the beginning of the + current subpath. This is the position of the last move-to + operation. +\end{predefinednode} + \begin{predefinednode}{current page} This node is inside a virtual remembered picture. The size of this node is the size of the current page. This means that if you create @@ -769,7 +805,7 @@ In order to define a new shape, you must provide: \subsubsection{Normal Anchors Versus Saved Anchors} -Anchors are special places in shape. For example, the |north east| +Anchors are special places in a shape. For example, the |north east| anchor, which is a normal anchor, lies at the upper right corner of the |rectangle| shape, as does |\northeast|, which is a saved anchor. The difference is the following: \emph{saved anchors are @@ -782,7 +818,7 @@ The idea behind all this is that a shape can declare a very large number of normal anchors, but when a node of this shape is created, these anchors are not actually computed. However, this causes a problem: When we wish to reference an anchor of a node at some later -time, we must still able to compute the position of the anchor. For +time, we must still be able to compute the position of the anchor. For this, we may need a lot of information: What was the transformation matrix that was in force when the node was created? What was the size of the text box? What were the values of the different separation @@ -791,7 +827,7 @@ dimensions? And so on. To solve this problem, \pgfname\ will always compute the locations of all \emph{saved anchors} and store these positions. Then, when an normal anchor position is requested later on, the anchor position can -be given just from knowing where the locations of the saved anchors. +be given just from knowing where the locations of the saved anchors are. As an example, consider the |rectangle| shape. For this shape two anchors are saved: The |\northeast| corner and the |\southwest| @@ -856,13 +892,13 @@ The following command declares a new shape: By default, a shape has just one node part called |text|. However, there can be several node parts. For example, the |circle split| shape has two parts: the |text| part, which - shows that upper text, and a |lower| part, which shows the + shows that the upper text, and a |lower| part, which shows the lower text. For the |circle split| shape the |\nodeparts| command was called with the argument |{text,lower}|. When a multipart node is created, the text labels are drawn in the sequences listed in the \meta{list of node parts}. For each node - part there you must have declared one anchor and the \TeX-box of + part, you must have declared one anchor and the \TeX-box of the part is placed at this anchor. For a node part called |XYZ| the \TeX-box |\pgfnodepartXYZbox| is placed at anchor |XYZ|. \end{command} @@ -877,7 +913,7 @@ The following command declares a new shape: is executed, the \TeX-boxes of the node parts will contain the text labels of the node. Possibly, these box are void. For example, if there is just a |text| part, the node - |\pgfnodeparttextbox| will be setup when the \meta{code} is + |\pgfnodeparttextbox| will be set up when the \meta{code} is executed. The \meta{code} can use the width, height, and depth of the @@ -1029,9 +1065,9 @@ The following command declares a new shape: creation is applied automatically to the coordinates returned by the anchor's \meta{code}. - Out |simple rectangle| only has one text label (node - part) called |text|. This is the default situation, so we need not - do anything. For the |text| node part we must setup a |text| + Our |simple rectangle| only has one text label (node + part) called |text|. This is the default situation, so we do not need to + do anything. For the |text| node part we must set up a |text| anchor. This anchor is used upon creation of a node to determine the lower left corner of the text label (within the private coordinate system of the shape). By default, the |text| anchor is @@ -1095,12 +1131,12 @@ The following command declares a new shape: shape. What exactly is considered as the ``border'' of the shape depends on the shape. - When the user request a point on the border of the shape using the + When the user requests a point on the border of the shape using the |\pgfpointshapeborder| command, the \meta{code} will be executed to discern this point. When the execution of the \meta{code} starts, the dimensions |\pgf@x| and |\pgf@y| will have been set to a location $p$ in the shape's coordinate system. It is now the job of - the \meta{code} to setup |\pgf@x| and |\pgf@y| such that they + the \meta{code} to set up |\pgf@x| and |\pgf@y| such that they specify the point on the shape's border that lies on a straight line from the shape's center to the point $p$. Usually, this is a somewhat complicated computation, involving many case distinctions @@ -1255,7 +1291,7 @@ The following command declares a new shape: }\hskip-1.2cm \begin{tikzpicture} \node[shade,draw,shape=document,inner sep=2ex] (x) {Remark}; - \node[fill=examplefill,draw,ellipse,double] + \node[fill=yellow!80!black,draw,ellipse,double] at ([shift=(-80:3cm)]x) (y) {Use Case}; \draw[dashed] (x) -- (y); diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-paths.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-paths.tex index 5284f22bb36..eacaa4b84e8 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-paths.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-paths.tex @@ -16,7 +16,7 @@ The ``basic entity of drawing'' in \pgfname\ is the \emph{path}. A path consists of several parts, each of which is either a closed or open curve. An open curve has a starting point and an end point and, in between, consists of several \emph{segments}, each of which is -either a straight line or a Bézier curve. Here is an example of a +either a straight line or a B\'ezier curve. Here is an example of a path (in red) consisting of two parts, one open, one closed: \begin{codeexample}[] @@ -58,7 +58,7 @@ Section~\ref{section-bb} for more details. Each path construction command extends the current path in some way. The ``current path'' is a global entity that persists across \TeX\ groups. Thus, between calls to the path construction commands -you can perform arbitrary computations and even open and closed \TeX\ +you can perform arbitrary computations and even open and close \TeX\ groups. The current path only gets ``flushed'' when the |\pgfusepath| command is called (or when the soft-path subsystem is used directly, see Section~\ref{section-soft-paths}). @@ -83,7 +83,7 @@ can also be used to start a new part of a path. \pgfpathlineto{\pgfpoint{2cm}{1cm}} \pgfpathlineto{\pgfpoint{3cm}{0.5cm}} \pgfpathlineto{\pgfpoint{3cm}{0cm}} - \pgfsetfillcolor{examplefill} + \pgfsetfillcolor{yellow!80!black} \pgfusepath{fill,stroke} \end{pgfpicture} \end{codeexample} @@ -95,14 +95,14 @@ can also be used to start a new part of a path. \pgfpathmoveto{\pgfpoint{2cm}{1cm}} % New part \pgfpathlineto{\pgfpoint{3cm}{0.5cm}} \pgfpathlineto{\pgfpoint{3cm}{0cm}} - \pgfsetfillcolor{examplefill} + \pgfsetfillcolor{yellow!80!black} \pgfusepath{fill,stroke} \end{pgfpicture} \end{codeexample} The command will apply the current coordinate transformation matrix to \meta{coordinate} before using it. - The command will update the bounding box of the current path and + It will update the bounding box of the current path and picture, if necessary. \end{command} @@ -121,14 +121,14 @@ can also be used to start a new part of a path. \pgfpathmoveto{\pgfpointorigin} \pgfpathlineto{\pgfpoint{1cm}{1cm}} \pgfpathlineto{\pgfpoint{2cm}{1cm}} - \pgfsetfillcolor{examplefill} + \pgfsetfillcolor{yellow!80!black} \pgfusepath{fill,stroke} \end{pgfpicture} \end{codeexample} The command will apply the current coordinate transformation matrix to \meta{coordinate} before using it. - The command will update the bounding box of the current path and + It will update the bounding box of the current path and picture, if necessary. \end{command} @@ -136,10 +136,10 @@ can also be used to start a new part of a path. \subsection{The Curve-To Path Operations} \begin{command}{\pgfpathcurveto\marg{support 1}\marg{support 2}\marg{coordinate}} - This command extends the current path with a Bézier curve from the + This command extends the current path with a B\'ezier curve from the last point of the path to \meta{coordinate}. The \meta{support 1} and \meta{support 2} are the first and second support point of the - Bézier curve. For more information on Bézier curve, please consult a + B\'ezier curve. For more information on B\'ezier curves, please consult a standard textbook on computer graphics. Like the line-to command, this command may not be the first path @@ -149,14 +149,14 @@ can also be used to start a new part of a path. \pgfpathmoveto{\pgfpointorigin} \pgfpathcurveto {\pgfpoint{1cm}{1cm}}{\pgfpoint{2cm}{1cm}}{\pgfpoint{3cm}{0cm}} - \pgfsetfillcolor{examplefill} + \pgfsetfillcolor{yellow!80!black} \pgfusepath{fill,stroke} \end{pgfpicture} \end{codeexample} The command will apply the current coordinate transformation matrix to \meta{coordinate} before using it. - The command will update the bounding box of the current path and + It will update the bounding box of the current path and picture, if necessary. However, the bounding box is simply made large enough such that it encompasses all of the support points and the \meta{coordinate}. This will guarantee that the curve is @@ -168,14 +168,14 @@ can also be used to start a new part of a path. \begin{command}{\pgfpathquadraticcurveto\marg{support}\marg{coordinate}} This command works like |\pgfpathcurveto|, only it uses a quadratic - Bézier curve rather than a cubic one. This means that only one + B\'ezier curve rather than a cubic one. This means that only one support point is needed. \begin{codeexample}[] \begin{pgfpicture} \pgfpathmoveto{\pgfpointorigin} \pgfpathquadraticcurveto {\pgfpoint{1cm}{1cm}}{\pgfpoint{2cm}{0cm}} - \pgfsetfillcolor{examplefill} + \pgfsetfillcolor{yellow!80!black} \pgfusepath{fill,stroke} \end{pgfpicture} \end{codeexample} @@ -189,7 +189,7 @@ can also be used to start a new part of a path. \end{command} -There exist two commands to draw only part of a cubic Bézier curve: +There exist two commands to draw only part of a cubic B\'ezier curve: \begin{command}{\pgfpathcurvebetweentime\marg{time $t_1$}\marg{time $t_2$}\marg{point p}\marg{point $s_1$}\marg{point $s_2$}\marg{point q}} @@ -257,7 +257,7 @@ circles to a path are described. \begin{command}{\pgfpatharc\marg{start angle}\marg{end angle}{\ttfamily\char`\{}\meta{radius}\opt{| and |\meta{y-radius}}{\ttfamily\char`\}}} This command appends a part of a circle (or an ellipse) to the current - path. Imaging the curve between \meta{start angle} and \meta{end + path. Imagine the curve between \meta{start angle} and \meta{end angle} on a circle of radius \meta{radius} (if $\meta{start angle} < \meta{end angle}$, the curve goes around the circle counterclockwise, otherwise clockwise). This curve is now moved such @@ -398,7 +398,7 @@ circles to a path are described. are numerically very unstable. In particular, the arc will not always really end at the \meta{target coordinate}, but may be off by up to several points. A more precise positioning is currently - infeasible due to \TeX's numerical weaknesses. The only case that + infeasible due to \TeX's numerical weaknesses. The only case it works quite nicely is when the resulting angle is a multiple of~$90^\circ$. \end{command} @@ -406,7 +406,7 @@ circles to a path are described. \begin{command}{\pgfpatharctoprecomputed\marg{center point}\marg{start angle}\marg{end angle}\marg{end point}\\\marg{x-radius}\marg{y-radius}\marg{ratio x-radius/y-radius}\marg{ratio y-radius/x-radius}} A specialized arc operation which is fast and numerically stable, provided a lot of information is given in advance. - In contrast to |\pgfpatharc|, it explicitly interpolates start- and end points. + In contrast to |\pgfpatharc|, it explicitly interpolates start and end points. In contrast to |\pgfpatharcto|, this routine is numerically stable and quite fast since it relies on a lot of available information. \begin{codeexample}[] @@ -438,8 +438,9 @@ circles to a path are described. \end{codeexample} \begin{command}{\pgfpatharctomaxstepsize} - The quality of arc approximation taken by |\pgfpatharctoprecomputed| by means of Bezier splines is % TODOsp: Bezier --> Bézier? - controlled by a mesh width, which is initially + The quality of arc approximation taken by + |\pgfpatharctoprecomputed| by means of B\'ezier splines is + controlled by a mesh width, which is initially |\def\pgfpatharctoprecomputed{45}|. @@ -539,15 +540,15 @@ start a new part of the path. \subsection{The Grid Path Operation} -\begin{command}{\pgfpathgrid\oarg{options}\marg{lower left}\marg{upper right}} +\begin{command}{\pgfpathgrid\oarg{options}\marg{first corner}\marg{second corner}} Appends a grid to the current path. That is, a (possibly large) number of parts are added to the path, each part consisting of a single horizontal or vertical straight line segment. Conceptually, the origin is part of the grid and the grid is clipped - to the rectangle specified by the \meta{lower left} and - the \meta{upper right} corner. However, no clipping occurs (this - command just adds parts to the current path). Rather, the points + to the rectangle specified by the \meta{first corner} and + the \meta{second corner}. However, no clipping occurs (this + command just adds parts to the current path) and the points where the lines enter and leave the ``clipping area'' are computed and used to add simple lines to the current path. @@ -575,7 +576,7 @@ start a new part of the path. \end{pgfpicture} \end{codeexample} The command will apply coordinate transformations and update the - bounding boxes tightly. As for ellipses, the transformations are + bounding boxes. As for ellipses, the transformations are applied to the ``conceptually finished'' grid. \begin{codeexample}[] \begin{pgfpicture} @@ -592,14 +593,14 @@ start a new part of the path. \begin{command}{\pgfpathparabola\marg{bend vector}\marg{end vector}} This command appends two half-parabolas to the current path. The first starts at the current point and ends at the current point plus - \meta{bend vector}. At his point, it has its bend. The second half - parabola starts at that bend point and end at point that is given by + \meta{bend vector}. At this point, it has its bend. The second half + parabola starts at that bend point and ends at point that is given by the bend plus \meta{end vector}. If you set \meta{end vector} to the null vector, you append only a half parabola that goes from the current point to the bend; by setting \meta{bend vector} to the null vector, you append only a - half parabola that goes to current point plus \meta{end vector} and + half parabola that goes through the current point and \meta{end vector} and has its bend at the current point. It is not possible to use this command to draw a part of a parabola @@ -672,7 +673,7 @@ cosine curves in intervals that are multiples of $\pi/2$. \pgfpathcosine{\pgfpoint{1cm}{-1cm}} \pgfpathsine{\pgfpoint{1cm}{-1cm}} \pgfpathcosine{\pgfpoint{1cm}{1cm}} - \pgfsetfillcolor{examplefill} + \pgfsetfillcolor{yellow!80!black} \pgfusepath{fill,stroke} \end{pgfpicture} \end{codeexample} @@ -693,7 +694,7 @@ documented in Section~\ref{section-plots}. \subsection{Rounded Corners} Normally, when you connect two straight line segments or when you -connect two curves that end and start ``at different angles'' you get +connect two curves that end and start ``at different angles,'' you get ``sharp corners'' between the lines or curves. In some cases it is desirable to produce ``rounded corners'' instead. Thus, the lines or curves should be shortened a bit and then connected by arcs. @@ -841,7 +842,7 @@ are (globally) updated. To facilitate this, you can use the following command: \begin{command}{\pgf@protocolsizes\marg{x-dimension}\marg{y-dimension}} - Updates all of the above dimension in such a way that the point + Updates all of the above dimensions in such a way that the point specified by the two arguments is inside both bounding boxes. For the picture's bounding box this updating occurs only if |\ifpgf@relevantforpicturesize| is true, see below. diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-patterns.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-patterns.tex index cfb74f5b51b..6837464fccd 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-patterns.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-patterns.tex @@ -15,7 +15,7 @@ \subsection{Overview} There are many ways of filling a path. First, you can fill it using a -solid color and this is also the fasted method. Second, you can also +solid color and this is also the fastest method. Second, you can also fill it using a shading, which means that the color changes smoothly between two (or more) different colors. Third, you can fill it using a tiling pattern and it is explained in the following how this is done. @@ -58,13 +58,12 @@ internally, a new (fixed) instance of a pattern is declared when the parameters of a pattern change. Second, the phase of patterns is not well-defined, that is, it is not -clear where origin of the ``first'' tile is. To be more precise, +clear where the origin of the ``first'' tile is. To be more precise, PostScript and \textsc{pdf} on the one hand and \textsc{svg} on the other hand define the origin differently. PostScript and \textsc{pdf} define a fixed origin that is independent of where the path lies. This has the highly desirable effect that if you use the same pattern to -fill multiple paths, this has the same effect as if you used the -pattern to will a single path that is the union of all the paths. By +fill multiple paths, the outcome is the same as if you had filled a single path consisting of the union of all these paths. By comparison, \textsc{svg} uses the upper-left (?) corner of the path to be filled as the origin. However, the \textsc{svg} specification is a bit vague on this question. @@ -83,9 +82,9 @@ command is used for this: \marg{tile size}% \marg{code}} - This command declares a new form-only pattern. The \marg{name} is a - name for later reference. The two parameters \marg{lower left} and - \marg{upper right} must describe a bounding box that is large enough + This command declares a new form-only pattern. The \meta{name} is a + name for later reference. The two parameters \meta{lower left} and + \meta{upper right} must describe a bounding box that is large enough to encompass the complete tile. The size of a tile is given by \meta{tile size}, that is, a tile is @@ -134,11 +133,11 @@ command is used for this: Normally, when this argument is empty, once a pattern has been declared, it becomes ``frozen''. This means that it is not possible to enlarge the pattern or change the line width later on. - By specifying \meta{variables} no pattern is actually created. + By specifying \meta{variables}, no pattern is actually created. Instead, the arguments are stored away (so the macros, registers or keys do not have to be defined in advance). - When the fill patten is set, \pgfname{} checks if the pattern has + When the fill pattern is set, \pgfname{} checks if the pattern has already been created with the \meta{variables} set to their current values (\pgfname{} is usually ``smart enough'' to distinguish between macros, registers and keys). If so, this already-declared-pattern @@ -223,7 +222,7 @@ Once a pattern has been declared, it can be used. This command specifies that paths that are filled should be filled with the ``color'' by the pattern \meta{name}. For an inherently colored pattern, the \meta{color} parameter is ignored. For - form-only patterns, the \meta{color} parameter specified the color + form-only patterns, the \meta{color} parameter specifies the color to be used for the pattern. \begin{codeexample}[] \begin{tikzpicture} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-plots.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-plots.tex index 89b51dffbad..61e627f8304 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-plots.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-plots.tex @@ -51,13 +51,22 @@ sets of commands exist. The commands for creating streams start with \subsection{Generating Plot Streams} \subsubsection{Basic Building Blocks of Plot Streams} -A \emph{plot stream} is a (long) sequence of the following three + +A \emph{plot stream} is a (long) sequence of the following commands: \begin{enumerate} \item |\pgfplotstreamstart|, \item - |\pgfplotstreampoint|, and + |\pgfplotstreampoint|, +\item + |\pgfplotstreampointoutlier|, +\item + |\pgfplotstreampointundefined|, +\item + |\pgfplotstreamnewdataset|, +\item + |\pgfplotstreamspecial|, and \item |\pgfplotstreamend|. \end{enumerate} @@ -75,11 +84,17 @@ end with the last command. Here is an example of a plot stream: \pgfplotstreamend \end{codeexample} +Streams are \emph{global}, meaning that they are not influenced by +\TeX\ groups. + \begin{command}{\pgfplotstreamstart} This command signals that a plot stream starts. The effect of this command is to call the internal command |\pgf@plotstreamstart|, which is set by the current plot handler to do whatever needs to be - done at the beginning of the plot. + done at the beginning of the plot. It will also reset the + meaning of the internal commands like |\pgf@plotstreampoint| to the + initial setting for the plot handler (what this means will be + explained in a moment). \end{command} \begin{command}{\pgfplotstreampoint\marg{point}} @@ -88,18 +103,110 @@ end with the last command. Here is an example of a plot stream: which is also set by the current plot handler. This command should now ``handle'' the point in some sensible way. For example, a line-to command might be issued for the point. + + When a plot handler is installed, it will setup the internal command + |\pgf@plotstreampoint| in some way. It is permissible to change the + meaning of this internal command during a stream. For instance, a + handler might setup |\pgf@plotstreampoint| in some sensible way for + the first point and then redefine it so that subsequent points are + handled in some other way. + + As mentioned earlier, the |\pgfplotstreamstart| will always reset + the definition of the internal command to the initial meaning it had + when the handler was installed. This is true for the other commands + mentioned in the following. +\end{command} + +\begin{command}{\pgfplotstreampointoutlier\marg{point}} + An \emph{outlier} is a point that is ``out of bounds'' in some + way. For instance, it might have very large coordinates or the + coordinates might just be outside some specified + range. Nevertheless, an outlier is still a well-defined point. This + command is issued, for instance, by \textsc{gnuplot} when a value is + outside the specified range. + + You can configure how outliers are treated using the following key: + \begin{key}{/pgf/handle outlier points in plots=\meta{how} + (initially jump)} + \keyalias{tikz} + You can set \meta{how} to one of the following values: + \begin{itemize} + \item |plot| This will cause the outlier to be drawn normally, + just as if |\pgfplotstreampoint| had been used rather than this + command. + \item |ignore| The outlier will be completely ignored, just as if + the command had not been used at all. + \item |jump| This causes the internal macro |\pgf@plotstreamjump| + to be called. A ``jump'' in a stream is a position where a + ``gap'' is introduced. For instance, a simple line-to plot + handler will stop the current subpath at a jump position and + begin with a move-to operation at the next normal point of the + stream. + + The net effect of this setting is that at outlier points plots + get interrupted and ``restarted'' when the points are no longer + outliers. This is usually the behaviour you will be looking for. + \end{itemize} + \end{key} +\end{command} + +\begin{command}{\pgfplotstreampointundefined} + This command indicated that the stream contains an ``undefined'' + point like a point where some coordinate results for a division by + zero. Such a point cannot be plotted, which is why it is not given + as a parameter. However, such a point \emph{can} result in a jump in + the plot, depending on the setting of the following key: + \begin{key}{/pgf/handle undefined points in plots=\meta{how} + (initially jump)} + \keyalias{tikz} + You can set \meta{how} to one of the following values: + \begin{itemize} + \item |ignore| The undefined point will be completely ignored, just as if + the command had not been used at all. + \item |jump| This causes the internal macro |\pgf@plotstreamjump| + to be called. + \end{itemize} + \end{key} +\end{command} + +\begin{command}{\pgfplotstreamnewdataset} + This command indicated that in the stream a ``new data set'' starts. + So, the stream does not end, but there is a logical break in the + data. For example, when a table is read from a file, empty lines are + interpreted as indicating new data sets. What happens when a new + data set is encountered is governed by the following key: + \begin{key}{/pgf/handle new data sets in plots=\meta{how} + (initially jump)} + \keyalias{tikz} + You can set \meta{how} to one of the following values: + \begin{itemize} + \item |ignore| The command will be completely ignored, just as if + the command had not been used at all. + \item |jump| This causes the internal macro |\pgf@plotstreamjump| + to be called. + \end{itemize} + \end{key} +\end{command} + +\begin{command}{\pgfplotstreamspecial\marg{text}} + This command causes |\pgf@plotstreamspecial| to be called with + \meta{text} as its parameter. This allows handler-specific + information to be passed to the handler. All normal handlers ignore + this command. \end{command} \begin{command}{\pgfplotstreamend} This command signals that a plot stream ends. It calls - |\pgf@plotstreamend|, which should now do any necessary ``cleanup.'' + |\pgf@plotstreamend|, which should now do any necessary ``cleanup.'' \end{command} Note that plot streams are not buffered, that is, the different points are handled immediately. However, using the recording handler, it is possible to record a stream. + \subsubsection{Commands That Generate Plot Streams} +\label{section-plot-jumps} Plot streams can be created ``by hand'' as in the earlier example. However, most of the time the coordinates will be produced @@ -109,23 +216,44 @@ file and converts it into a plot stream. \begin{command}{\pgfplotxyfile\marg{filename}} This command will try to open the file \meta{filename}. If this succeeds, it will convert the file contents into a plot stream as - follows: A |\pgfplotstreamstart| is issued. Then, each nonempty line - of the file should start with two numbers separated by a space, such - as |0.1 1| or |100 -.3|. Anything following the numbers is ignored. - - Each pair \meta{x} and \meta{y} of numbers is converted into one - plot stream point in the xy-coordinate system. Thus, a line like -\begin{codeexample}[code only] -2 -5 some text + follows: A |\pgfplotstreamstart| is issued. Then, for each nonempty + line a |\pgfplotstreamnewdataset| is produced. Other lines in the + file should start with two numbers separated by a space, such as + |0.1 1| or |100 -.3|. The numbers may be followed by some text, + which will be ignore \emph{except} if it is exactly ``|u|'' or + ``|o|''. For ``|u|'', the point is considered to be undefined and + |\pgfplotstreampointundefined| is called. For ``|o|'', the point is + considered to be an outlier and |\pgfplotstreampointoutlier| is + called. Otherwise, each pair \meta{x} and \meta{y} of numbers is + converted into one plot stream point in the xy-coordinate + system. Thus, a line like +\begin{codeexample}[code only, tikz syntax=false] +0 Nan u +1 1 some text +2 4 +3 9 + +4 16 o +5 25 oo \end{codeexample} is turned into \begin{codeexample}[code only] -\pgfplotstreampoint{\pgfpointxy{2}{-5}} +\pgfplotstreamstart +\pgfplotstreampointundefined +\pgfplotstreampoint{\pgfpointxy{1}{1}} +\pgfplotstreampoint{\pgfpointxy{2}{4}} +\pgfplotstreampoint{\pgfpointxy{3}{9}} +\pgfplotstreamnewdataset +\pgfplotstreampointoutlier{\pgfpointxy{4}{16}} +\pgfplotstreampoint{\pgfpointxy{5}{25}} +\pgfplotstreamend \end{codeexample} + (Note that the last line is not an outlier because |oo| is not the + same as |o|). The two characters |%| and |#| are also allowed in a file and they are both treated as comment characters. Thus, a line starting with - either of them is empty and, hence, ignored. + either of them is treated as empty. When the file has been read completely, |\pgfplotstreamend| is called. @@ -136,24 +264,25 @@ file and converts it into a plot stream. This command works like |\pgfplotxyfile|, only \emph{three} numbers are expected on each non-empty line. They are converted into points in the xyz-coordinate system. Consider, the following file: -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] % Some comments # more comments 2 -5 1 first entry -2 -.2 2 second entry +2 -.2 2 o 2 -5 2 third entry \end{codeexample} It is turned into the following stream: \begin{codeexample}[code only] \pgfplotstreamstart +\pgfplotstreamnewdataset +\pgfplotstreamnewdataset \pgfplotstreampoint{\pgfpointxyz{2}{-5}{1}} -\pgfplotstreampoint{\pgfpointxyz{2}{-.2}{2}} +\pgfplotstreampointoutlier{\pgfpointxyz{2}{-.2}{2}} \pgfplotstreampoint{\pgfpointxyz{2}{-5}{2}} \pgfplotstreamend \end{codeexample} \end{command} - Currently, there is no command that can decide automatically whether the xy-coordinate system should be used or whether the xyz-system should be used. However, it would not be terribly difficult to write a @@ -202,7 +331,7 @@ intelligently. Let us start with the situation where none of these files exists. Then \pgfname\ will first generate the file \meta{prefix}|.gnuplot|. In this file it writes -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] set terminal table; set output "#1.table"; set format "%.5f" \end{codeexample} where |#1| is replaced by \meta{prefix}. Then, in a second line, it @@ -239,11 +368,23 @@ set terminal table; set output "#1.table"; set format "%.5f" read. As explained in Section~\ref{section-tikz-gnuplot}, the net effect - of the above mechanism is that |gnuplot| is called as little as + of the above mechanism is that |gnuplot| is called as seldom as possible and that when you pass along the |.gnuplot| and |.table| files with your |.tex| file to someone else, that person can \TeX\ the |.tex| file without having |gnuplot| installed and without having the |\write18| mechanism switched on. + + \begin{key}{/pgf/plot/gnuplot call=\meta{gnuplot invocation} (initially gnuplot)} + This key can be used to change the way gnuplot is called. + + Some portable Mik\TeX{} distribution needs something like the + following. + +\begin{codeexample}[code only] + \pgfkeys{/pgf/plot/gnuplot call="/Programs/gnuplot/binary/gnuplot"} +\end{codeexample} + + \end{key} \end{command} @@ -252,13 +393,13 @@ set terminal table; set output "#1.table"; set format "%.5f" \label{section-plot-handlers} -A \emph{plot handler} prescribes what ``should be done'' with a +A \emph{plot handler} determines what ``should be done'' with a plot stream. You must set the plot handler before the stream starts. The following commands install the most basic plot handlers; more plot handlers are defined in the file |pgflibraryplothandlers|, which is documented in Section~\ref{section-library-plothandlers}. -All plot handlers work by setting redefining the following three +All plot handlers work by setting or redefining the following three macros: |\pgf@plotstreamstart|, |\pgf@plotstreampoint|, and |\pgf@plotstreamend|. @@ -322,7 +463,7 @@ macros: |\pgf@plotstreamstart|, |\pgf@plotstreampoint|, and \begin{command}{\pgfplothandlerrecord\marg{macro}} When this handler is installed, each time a plot stream command is - called, this command will be appended to \meta{macros}. Thus, at + called, this command will be appended to \meta{macro}. Thus, at the end of the stream, \meta{macro} will contain all the commands that were issued on the stream. You can then install another handler and invoke \meta{macro} to ``replay'' the stream @@ -346,6 +487,112 @@ macros: |\pgf@plotstreamstart|, |\pgf@plotstreampoint|, and \end{codeexample} \end{command} + + +\subsection{Defining New Plot Handlers} + +You can define new plot handlers using the following command: + +\begin{command}{\pgfdeclareplothandler\marg{macro}\marg{arguments}\marg{configuration}} + This command creates a new plot handler that can subsequently be + called using the macro \meta{macro}. This macro take the arguments + given in \meta{arguments}, which can be a list like |#1#2| if + \meta{macro} should be invoked with two arguments. Here is a typical example: +\begin{codeexample}[code only] +\pgfdeclareplothandler{\myhandler}{#1}{...} +... +\myhandler{foo} +\pgfplotstreamstart +... +\pgfplotstreamend +\end{codeexample} + + The \meta{configuration} is used to define the behaviour of the + handler. It is a list of key--value pairs, where the following keys + are allowed: + \begin{itemize} + \item |start=|\meta{code}. The \meta{code} will be executed whenever + |\pgfplotstreamstart| is used while the handler \meta{macro} is + selected. Inside the \meta{code}, you can use |#1|, |#2|, and so + on to refer to the parameters that were given to \meta{macro}: +\begin{codeexample}[width=6cm] +\pgfdeclareplothandler{\myhandler}{#1}{ + start = Hi #1., + end = Bye #1., +} +\myhandler{foo} +\pgfplotstreamstart +\pgfplotstreamend +\myhandler{bar} +\pgfplotstreamstart +\pgfplotstreamend +\end{codeexample} + \item |end=|\meta{code} Works just like |start|. + \item |point=|\meta{code}. The \meta{code} will be executed whenever + |\pgfplotstreampoint| is used while the handler \meta{macro} is in + force. Inside the \meta{code}, you can use |#1|, |#2|, and so on + to refer to the arguments give to \meta{macro}, while you can use + |##1| to refer to the argument given to |\pgfplotstreampoint| + itself (this will be the coordinate). +\begin{codeexample}[] +\pgfdeclareplothandler{\myhandler}{#1}{ + point=\pgfpathcircle{##1}{#1} % ##1 is the coordinate, + % #1 the parameter for \myhandler +} +\begin{pgfpicture} + \myhandler{1pt} + \pgfplotstreamstart + \pgfplotstreampoint{\pgfpoint{0pt}{0pt}} + \pgfplotstreampoint{\pgfpoint{3pt}{3pt}} + \pgfplotstreampoint{\pgfpoint{6pt}{3pt}} + \pgfplotstreampoint{\pgfpoint{9pt}{0pt}} + \pgfplotstreamend + \pgfusepath{stroke} + \myhandler{3pt} + \pgfplotstreamstart + \pgfplotstreampoint{\pgfpoint{0pt}{0pt}} + \pgfplotstreampoint{\pgfpoint{9pt}{0pt}} + \pgfplotstreamend + \pgfusepath{stroke} +\end{pgfpicture} +\end{codeexample} + The \meta{code} will also be called for + |\pgfplotstreampointoutlier| when this command has been configured + to |plot| the outliers. + \item |jump=|\meta{code} The \meta{code} will be called whenever a + jump has been requested indirectly via an outlier point, and + undefined point, or a new data set (for each of which the command + needs to be configured to |jump|). As always, inside the + \meta{code} you can access |#1| and so on. + \item |special=|\meta{code} Causes \meta{code} to be executed + whenever |\pgfplotstreamspecial|\marg{something} is used. Inside + the \meta{code}, you can access \meta{something} via |##1| and the + parameters of \meta{macro} as |#1|, |#2|, and so on. + \end{itemize} + + In addition to the above keys, there exist also ``code macro + versions'' of them: + \begin{itemize} + \item |point macro=|\meta{some macro}. Causes |\pgfplotstreampoint| + to call \meta{some macro} directly (actually, + |\pgf@plotstreampoint| is set to be equal to \meta{some + macro}). Inside the \meta{some macro} you can use |#1| to access + the coordinate passed to |\pgfplotstreampoint| and you can no + longer access the parameters passed to the original call to + \meta{macro} that installed the handler. So, \meta{some macro} + must take exactly one argument, namely |#1|. + \item |special macro=|\meta{some macro}. As |point macro|, only for + specials. + \item |start macro=|\meta{some macro}. Causes \meta{some macro} to + be executed at the start. This macro, like the below ones, may not + take any parameters and will not have access to the parameters + passed to the original \meta{macro}. + \item |end macro=|\meta{some macro}. As above. + \item |jump macro=|\meta{some macro}. As above. + \end{itemize} +\end{command} + + %%% Local Variables: %%% mode: latex %%% TeX-master: "pgfmanual" diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-points.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-points.tex index 931a6a7bcf9..833118bdf57 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-points.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-points.tex @@ -121,7 +121,7 @@ $y$-vector do not necessarily point ``horizontally'' and \end{command} \begin{command}{\pgfsetyvec\marg{point}} - Works like |\pgfsetyvec|. + Works like |\pgfsetxvec|. \end{command} @@ -178,7 +178,7 @@ three dimensional graphics. \end{command} \begin{command}{\pgfsetzvec\marg{point}} - Works like |\pgfsetzvec|. + Works like |\pgfsetxvec|. \end{command} Inside the $xyz$-coordinate system, you can also specify points @@ -206,7 +206,7 @@ using spherical and cylindrical coordinates. \begin{command}{\pgfpointspherical\marg{longitude}\marg{latitude}\marg{radius}} This command yields a point ``on the surface of the earth'' - specified by the \meta{longitude} and the \marg{latitude}. The + specified by the \meta{longitude} and the \meta{latitude}. The radius of the earth is given by \meta{radius}. The equator lies in the $xy$-plane. \begin{codeexample}[] @@ -274,7 +274,7 @@ coordinates. \begin{command}{\pgfpointnormalised\marg{point}} - This command returns a normalized version of \meta{point}, that is, + This command returns a normalised version of \meta{point}, that is, a vector of length 1pt pointing in the direction of \meta{point}. If \meta{point} is the $0$-vector or extremely short, a vector of length 1pt pointing upwards is returned. @@ -304,7 +304,7 @@ coordinates. \label{section-pointsattime} The commands in this section allow you to specify points on a line or -a curve. Imaging a point ``traveling'' along a curve from some point +a curve. Imagine a point ``traveling'' along a curve from some point $p$ to another point $q$. At time $t=0$ the point is at $p$ and at time $t=1$ it is at $q$ and at time, say, $t=1/2$ it is ``somewhere in the middle.'' The exact location at time $t=1/2$ will not necessarily @@ -313,7 +313,7 @@ curve from $p$ and $q$ is equal. Rather, the exact location will depend on the ``speed'' at which the point is traveling, which in turn depends on the lengths of the support vectors in a complicated manner. If you are interested in the details, please see a good book -on Bézier curves. +on B\'ezier curves. @@ -336,7 +336,7 @@ on Bézier curves. \end{command} \begin{command}{\pgfpointlineatdistance\marg{distance}\marg{start point}\marg{end point}} - Yields a point that is located \meta{distance} many units removed + Yields a point that is located \meta{distance} many units away from the start point in the direction of the end point. In other words, this is the point that results if we travel \meta{distance} steps from \meta{start point} towards \meta{end point}. @@ -354,9 +354,31 @@ on Bézier curves. \end{codeexample} \end{command} +\begin{command}{\pgfpointarcaxesattime\marg{time + $t$}\marg{center}\marg{0-degree axis}\marg{90-degree + axis}\marg{start angle}\\\marg{end angle}} + Yields a point on the arc between \meta{start angle} and \meta{end + angle} on an ellipse whose center is at \meta{center} and whose + two principal axes are \meta{0-degree axis} and \meta{90-degree + axis}. For $t=0$ the point at the \meta{start angle} is returned + and for $t=1$ the point at the \meta{end angle}. + +\begin{codeexample}[] +\begin{tikzpicture} + \draw[help lines] (0,0) grid (3,2); + \pgfpathmoveto{\pgfpoint{2cm}{1cm}} + \pgfpatharcaxes{0}{60}{\pgfpoint{2cm}{0cm}}{\pgfpoint{0cm}{1cm}} + \pgfusepath{stroke} + \foreach \t in {0,0.25,0.5,0.75,1} + {\pgftext[at=\pgfpointarcaxesattime{\t}{\pgfpoint{0cm}{1cm}} + {\pgfpoint{2cm}{0cm}}{\pgfpoint{0cm}{1cm}}{0}{60}]{\t}} +\end{tikzpicture} +\end{codeexample} +\end{command} + \begin{command}{\pgfpointcurveattime\marg{time $t$}\marg{point $p$}\marg{point $s_1$}\marg{point $s_2$}\marg{point $q$}} - Yields a point that is on the Bézier curve from $p$ to $q$ with the + Yields a point that is on the B\'ezier curve from $p$ to $q$ with the support points $s_1$ and $s_2$. The time $t$ is used to determine the location, where $t=0$ yields $p$ and $t=1$ yields $q$. @@ -492,7 +514,7 @@ mechanism to determine border points of shapes. This library defines the below command and allows you to calculate the intersections of two arbitrary paths. However, due to the low accuracy of \TeX, the paths should not be ``too complicated''. - In particular, you should not try to intersect paths consisting + In particular, you should not try to intersect paths consisting of lots of very small segments such as plots or decorated paths. \end{pgflibrary} @@ -611,7 +633,7 @@ takes a coordinate as parameter will just execute this parameter and then use the values of |\pgf@x| and |\pgf@y| as the coordinates to which it will move the pen on the current path. -since commands like |\pgfpointnormalised| modify other variables +Since commands like |\pgfpointnormalised| modify other variables besides |\pgf@x| and |\pgf@y| during the computation of the final values of |\pgf@x| and |\pgf@y|, it is a good idea to enclose a call of a command like |\pgfpoint| in a \TeX-scope and then make the changes of diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-quick.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-quick.tex index f43e9d29de8..c7f762bef6c 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-quick.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-quick.tex @@ -27,7 +27,7 @@ be processed or if you expect your commands to be executed very often. \begin{command}{\pgfqpointxy\marg{$s_x$}\marg{$s_y$}} This command does the same as |\pgfpointxy|, but \meta{$s_x$} and \meta{$s_y$} - must be simple numbers without unit, like |1.234| or |5.0|. Mathematical expressions or units are not allows. + must be simple numbers without unit, like |1.234| or |5.0|. Mathematical expressions or units are not allowed. \end{command} \begin{command}{\pgfqpointxyz\marg{$s_x$}\marg{$s_y$}\marg{$s_z$}} @@ -177,7 +177,7 @@ not want arrows to be drawn. ``translational part'' of the coordinate transformation matrix, instead of adding the translational part to the current canvas transformation matrix directly. Both methods have the same - effect (box \meta{box number} is translated where it should), but + effect (box \meta{box number} is translated to where it should be), but the method used by |\pgfqboxsynced| ensures that hyperlinks are placed correctly. Note that scaling and rotation will not (cannot, even) apply to hyperlinks. diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-scopes.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-scopes.tex index ceb90cb8adf..9d8e999a863 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-scopes.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-scopes.tex @@ -41,7 +41,7 @@ The \pgfname\ system consists of several layers: The basic layer is documented in the present part. \item[Frontend layer.] - The frontend layer is not loaded by a single packages. Rather, + The frontend layer is not loaded by a single package. Rather, different packages, like \tikzname\ or \textsc{pgfpict2e}, are different frontends to the basic layer. @@ -101,7 +101,7 @@ apply. In essence, the following scoping mechanisms are available: keep changes of the graphic state local to that environment. The effect of commands that change the graphic state are local to - the current |{pgfscope}| but not always to the current \TeX\ + the current |{pgfscope}|, but not always to the current \TeX\ group. Thus, if you open a \TeX\ group (some text in curly braces) inside a |{pgfscope}|, and if you change, for example, the dash pattern, the effect of this changed dash pattern will persist till @@ -133,7 +133,7 @@ apply. In essence, the following scoping mechanisms are available: The |\pgftext| command can be used to create a scope in which \TeX\ ``escapes back'' to normal \TeX\ mode. The text passed to the |\pgftext| is ``heavily guarded'' against having any effect on the - scope in which it is used. For example, it is possibly to use + scope in which it is used. For example, it is possible to use another |{pgfpicture}| environment inside the argument of |\pgftext|. \end{enumerate} @@ -154,6 +154,7 @@ rules: + \subsection{The Hierarchical Structure of the Package} Before we come to the structuring commands provided by \pgfname\ to @@ -212,9 +213,9 @@ The following package is just a convenience. What this command does is to load the file |pgfmodule|\meta{module}|.code.tex| for each \meta{module} in - the \meta{module names}. Thus, to write your own module, + the list of \meta{module names}. Thus, to write your own module, all you need to do is to place a file of the appropriate name - somewhere where \TeX\ can find it. \LaTeX, plain \TeX, and Con\TeX t + somewhere \TeX\ can find it. \LaTeX, plain \TeX, and Con\TeX t users can then use your library. \end{command} @@ -294,7 +295,7 @@ environment. ``mentioned'' despite the fact that you will not ``see'' them in your code. - Once the \meta{environment contents} has been parsed completely, a + Once the \meta{environment contents} have been parsed completely, a \TeX\ box is created whose size is the size of the computed bounding box and this box is inserted at the current position. @@ -366,7 +367,7 @@ Rectangles \begin{pgfpicture} In order to make \pgfname\ ``remember'' a picture, the \TeX-if |\||ifpgfrememberpicturepositiononpage| should be set to |true|. It is only important that this \TeX-if is |true| at the end of the - |{pgfpicture}|-environment, so you can switch it on inside the + |{pgfpicture}|-en\-vi\-ron\-ment, so you can switch it on inside the environment. However, you can also just switch it on globally, then the positions of all pictures are remembered. @@ -401,7 +402,7 @@ Rectangles \begin{pgfpicture} If this option is set to true of a picture, \pgfname\ will attempt to record the position of the picture on the page. (This attempt - will fail with most drivers and when it works it typically requires + will fail with most drivers and when it works, it typically requires two runs of \TeX.) The position is not directly accessible. Rather, the nodes mechanism will use this position if you access a node from another picture. See Sections~\ref{section-cross-pictures-pgf} @@ -417,16 +418,25 @@ Rectangles \begin{pgfpicture} picture has been typeset completely, \pgfname\ must decide at which height the baseline of the picture should lie. Normally, the baseline is set to the $y$-coordinate of the bottom of the picture, - but it is often desirable to use another height. + but it is often desirable to use a different height. \begin{codeexample}[] -Text \tikz{\pgfpathcircle{\pgfpointorigin}{1ex}\pgfusepath{stroke}}, - \tikz{\pgfsetbaseline{0pt} - \pgfpathcircle{\pgfpointorigin}{1ex}\pgfusepath{stroke}}, - \tikz{\pgfsetbaseline{.5ex} - \pgfpathcircle{\pgfpointorigin}{1ex}\pgfusepath{stroke}}, - \tikz{\pgfsetbaseline{-1ex} - \pgfpathcircle{\pgfpointorigin}{1ex}\pgfusepath{stroke}}. +Text +\begin{pgfpicture} + \pgfpathcircle{\pgfpointorigin}{1ex}\pgfusepath{stroke} +\end{pgfpicture}, +\begin{pgfpicture} + \pgfsetbaseline{0pt} + \pgfpathcircle{\pgfpointorigin}{1ex}\pgfusepath{stroke} +\end{pgfpicture}, +\begin{pgfpicture} + \pgfsetbaseline{.5ex} + \pgfpathcircle{\pgfpointorigin}{1ex}\pgfusepath{stroke} +\end{pgfpicture}, +\begin{pgfpicture} + \pgfsetbaseline{-1ex} + \pgfpathcircle{\pgfpointorigin}{1ex}\pgfusepath{stroke} +\end{pgfpicture}. \end{codeexample} \end{command} @@ -443,11 +453,11 @@ Text \tikz{\pgfpathcircle{\pgfpointorigin}{1ex}\pgfusepath{stroke}}, \begin{codeexample}[] Hello -\tikz{ +\begin{pgfpicture} \pgfsetbaselinepointlater{\pgfpointanchor{X}{base}} % Note: no shape X, yet - \node [cross out,draw] (X) {world.}; -} + \pgfnode{cross out}{center}{world.}{X}{\pgfusepath{stroke}} +\end{pgfpicture} \end{codeexample} \end{command} @@ -637,7 +647,7 @@ a shading into a |{pgfpicture}|. This command will typeset \meta{text} in normal \TeX\ mode and insert the resulting box into the |{pgfpicture}|. The bounding box of the graphic will be updated so that all of the text box is - inside. Be default, the text box is centered at the origin, but this + inside. By default, the text box is centered at the origin, but this can be changed either by giving appropriate \meta{options} or by applying an appropriate coordinate transformation beforehand. @@ -737,3 +747,21 @@ a shading into a |{pgfpicture}|. \end{key} \end{command} + + +\subsection{Error Messages and Warnings} + +Sometimes, a command inside \pgfname\ may fail. In this case, two +commands are useful to communicate with the author: + +\begin{command}{\pgferror\marg{message}} + Stops the processing of the current document and prints out the + \meta{message}. In \LaTeX, this will be done using |\PackageError|, + otherwise |\errmessage| is used directly. +\end{command} + +\begin{command}{\pgfwarning\marg{message}} + Prints the \meta{message} on the output, but does not interrupt the + processing. In \LaTeX, this will be done using |\PackageWarning|, + otherwise a write to stream $17$ is used. +\end{command} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-shadings.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-shadings.tex index d38f6bf3759..16d4dd04d99 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-shadings.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-shadings.tex @@ -27,7 +27,7 @@ complicated shadings. Horizontal shadings could be created by rotating a vertical shading by 90 degrees, but explicit commands for creating both horizontal and vertical shadings are included for convenience. -Once you have declared a shading, you can insert it into text using +Once you have declared a shading, you can insert it into the text using the command |\pgfuseshading|. This command cannot be used directly in a |{pgfpicture}|, you have to put a |\pgftext| around it. The second command for using shadings, |\pgfshadepath|, on the other hand, can @@ -38,8 +38,8 @@ A horizontal shading is a horizontal bar of a certain height whose color changes smoothly. You must at least specify the colors at the left and at the right end of the bar, but you can also add color specifications for points in between. For example, suppose you -which to create a bar that is red at the left end, green in the -middle, and blue at the end. Suppose you would like the bar to be 4cm +wish to create a bar that is red at the left end, green in the +middle, and blue at the end, and you would like the bar to be 4cm long. This could be specified as follows: \begin{codeexample}[code only] rgb(0cm)=(1,0,0); rgb(2cm)=(0,1,0); rgb(4cm)=(0,0,1) @@ -63,7 +63,7 @@ in increasing order. \begin{command}{\pgfdeclarehorizontalshading\oarg{color list}\marg{shading name}\marg{shading height}\marg{color specification}} Declares a horizontal shading named \meta{shading name} of the specified - \meta{height} with the specified colors. The length of the bar is + \meta{height} with the specified colors. The width of the bar is deduced automatically from the maximum dimension in the specification. \begin{codeexample}[] @@ -127,7 +127,7 @@ in increasing order. \begin{command}{\pgfdeclareradialshading\oarg{color list}\marg{shading name}\marg{center point}\marg{color specification}} - Declares an radial shading. A radial shading is a circle whose inner + Declares a radial shading. A radial shading is a circle whose inner color changes as specified by the color specification. Assuming that the center of the shading is at the origin, the color of the center will be the color specified for 0cm and the color of the border of @@ -161,9 +161,9 @@ in increasing order. This command creates a \emph{functional shading}. For such a shading, the color of each point is calculated by calling a function - that gets the coordinates of the point as input and yields the + that takes the coordinates of the point as input and yields the color as an output. Note that the function is evaluated by the - \emph{renderer}, not by \pgfname\ or \TeX or someone else at + \emph{renderer}, not by \pgfname\ or \TeX\ or someone else at compile-time. This means that the evaluation of this function has to be done \emph{extremely quickly} and the function should be \emph{very simple}. For this reason, only a very restricted set of @@ -200,7 +200,7 @@ in increasing order. empty (or should be treated as if it were empty). The function should then replace these two values by three values, representing the red, green, and blue color of the point. The numbers should be - real values, not integers since Apple's PDF renderer is broken in + real values, not integers since, Apple's PDF renderer is broken in this regard (use cvr at the end if necessary). Conceptually, the function will be evaluated once for each point of @@ -212,7 +212,7 @@ in increasing order. Because of the rather difficult PostScript syntax, use this macro only \emph{if you know what you are doing} (or if you are - advantageous, of course). + adventurous, of course). As for other shadings, the optional \meta{color list} is used to determine whether a shading needs to be recalculated when a color @@ -232,7 +232,7 @@ in increasing order. 40 sub dup mul 0.5 mul add sqrt % exponential decay dup mul neg 1.0005 exch exp 1.0 exch sub - % Compute distance form (70bp,70bp) from stored coordinate, scaled + % Compute distance from (70bp,70bp) from stored coordinate, scaled 3 1 roll 70 sub dup mul .5 mul exch 70 sub dup mul add sqrt @@ -246,7 +246,7 @@ in increasing order. Inside the PostScript function \meta{type 4 function} you cannot use colors directly. Rather, you must push the color components on the - stack. For this, it is useful to call |\pgfshadecolorrgb| in the + stack. For this, it is useful to call |\pgfshadecolortorgb| in the \meta{init code}: \begin{command}{\pgfshadecolortorgb\marg{color name}\marg{macro}} @@ -358,7 +358,7 @@ be used in the \meta{type 4 function} argument. This command must be used inside a |{pgfpicture}| environment. The effect is a bit complex, so let us go over it step by step. - First, \pgfname\ will setup a local scope. + First, \pgfname\ will set up a local scope. Second, it uses the current path to clip everything inside this scope. However, the current path is once more available after the @@ -374,7 +374,7 @@ be used in the \meta{type 4 function} argument. Inside the scope, the low-level transformation matrix is modified. The center of the shading is translated (moved) such that it lies on the center of the bounding box of the path. The low-level coordinate - system is also scaled such that the shading ``covers'' the shading (the + system is also scaled such that the shading ``covers'' the path (the details are a bit more complex, see below). Then, the coordinate system is rotated by \meta{angle}. Finally, if the macro |\pgfsetadditionalshadetransform| has been used, an additional @@ -385,7 +385,7 @@ be used in the \meta{type 4 function} argument. shading seems to ``fill'' the path. If both the path and the shadings were always rectangles and if - rotation were never involved, it would be easy to scale shadings + rotations were never involved, it would be easy to scale shadings such they always cover the path. However, when a vertical shading is rotated, it must obviously be ``magnified'' so that it still covers the path. Things get worse when the path is not a @@ -512,7 +512,7 @@ be used in the \meta{type 4 function} argument. \end{tikzpicture} \end{codeexample} - Note that rainbow shadings are \emph{way} to colorful in almost all + Note that rainbow shadings are \emph{way} too colorful in almost all applications. \end{command} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-transformations.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-transformations.tex index 44774b573b3..145463b7ffb 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-transformations.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-transformations.tex @@ -7,19 +7,20 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\section{Coordinate and Canvas Transformations} +\section{Coordinate, Canvas, and Nonlinear Transformations} \subsection{Overview} -\pgfname\ offers two different ways of scaling, shifting, and rotating +\pgfname\ offers different ways of scaling, shifting, and rotating (these operations are generally known as \emph{transformations}) graphics: You can apply \emph{coordinate transformations} to all -coordinates and you can apply \emph{canvas transformations} to the -canvas on which you draw. (The names ``coordinate'' and ``canvas'' +coordinates, you can apply \emph{canvas transformations} to the +canvas on which you draw, and you can apply \emph{additional nonlinear + transformations.} (The names ``coordinate'' and ``canvas'' transformations are not standard, I introduce them only for the purposes of this manual.) -The difference is the following: +The differences are the following: \begin{itemize} \item @@ -44,6 +45,17 @@ The difference is the following: canvas is transformed, in this case stretched by a factor of two. In the resulting image \emph{everything} will be larger: Text, lines, coordinates, and shadings. +\item + Nonlinear transformations are a special form of coordinate + transformations that are, as the name suggests, not linear. The + support for nonlinear transformations is quite different from the + support for linear coordinate transformations, the main reason being + speed: While linear coordinate transformations can be applied very + quickly (\pgfname\ does so almost constantly), nonlinear + transformations are much harder to apply and also to use. For this + reason, nonlinear transformations are implemented in a special + module |nonlineartransformations| that has to be loaded + explicitly. By default, they are not available. \end{itemize} In many cases, it is preferable that you use coordinate @@ -52,13 +64,16 @@ transformations are used, \pgfname\ looses track of the coordinates of nodes and shapes. Also, canvas transformations often cause undesirable effects like changing text size. For these reasons, \pgfname\ makes it easy to setup the coordinate transformation, but a bit harder to -change the canvas transformation. +change the canvas transformation. Because of the speed penalties +caused by nonlinear transformations, they are even harder to set up. \subsection{Coordinate Transformations} +\label{section-linear-coordinate-transformations} \subsubsection{How PGF Keeps Track of the Coordinate Transformation Matrix} +\label{section-transform-cm} \pgfname\ has an internal coordinate transformation matrix. This matrix is applied to coordinates ``in certain situations.'' This means @@ -70,7 +85,7 @@ matrix to their inputs. The coordinate transformation matrix consists of four numbers $a$, $b$, $c$, and $d$, and two dimensions $s$ and $t$. When the coordinate -transformation matrix is applied to a coordinate $(x,y)$ the new +transformation matrix is applied to a coordinate $(x,y)$, the new coordinate $(ax+by+s,cx+dy+t)$ results. For more details on how transformation matrices work in general, please see, for example, the \textsc{pdf} or PostScript reference or a textbook on computer @@ -187,8 +202,8 @@ coordinate transformations. -\begin{command}{\pgftransformrotate\marg{degrees}} - Rotates coordinates counterclockwise by \meta{degrees}. +\begin{command}{\pgftransformrotate\marg{angles}} + Rotates coordinates counterclockwise by \meta{angles} given in degrees. \begin{codeexample}[] \begin{tikzpicture} \draw[help lines] (0,0) grid (3,2); @@ -236,7 +251,7 @@ coordinate transformations. \begin{command}{\pgftransformarrow\marg{start}\marg{end}} - Shift coordinates to the end of the line going from \meta{start} + Shifts coordinates to the end of the line going from \meta{start} to \meta{end} with the correct rotation. \begin{codeexample}[] \begin{tikzpicture} @@ -280,7 +295,7 @@ coordinate transformations. ensure that the rotation is done in such a way that text is never ``upside down.'' - There is another \TeX\ if that influences this command. If you set + There is another \TeX\ |\if| that influences this command. If you set |\ifpgfresetnontranslationattime| to true, then, between shifting the coordinate and (possibly) rotating/sloping the coordinate, the command |\pgftransformresetnontranslations| is @@ -341,6 +356,33 @@ coordinate transformations. \end{command} +\begin{command}{\pgftransformarcaxesattime\marg{time + $t$}\marg{center}\marg{0-degree axis}\marg{90-degree + axis}\marg{start angle}\marg{end angle}} + Shifts coordinates by a specific point on an arc at a specific + time, see Section~\ref{section-pointsattime} once more. + + As for the previous commands, |\ifpgfslopedattime| + decides whether an additional rotation should be applied and + |\ifpgfallowupsidedowattime| is also considered. +\begin{codeexample}[] +\begin{tikzpicture} + \draw[help lines] (0,0) grid (3,2); + \pgfpathmoveto{\pgfpoint{2cm}{1cm}} + \pgfpatharcaxes{0}{60}{\pgfpoint{2cm}{0cm}}{\pgfpoint{0cm}{1cm}} + \pgfusepath{stroke} + \pgfslopedattimetrue + \pgftransformarcaxesattime{.25} + {\pgfpoint{0cm}{1cm}} + {\pgfpoint{2cm}{0cm}}{\pgfpoint{0cm}{1cm}} + {0}{60} + \pgftext{Hi!} +\end{tikzpicture} +\end{codeexample} + The value of |\ifpgfresetnontranslationsattime| is also taken into account. +\end{command} + + { \let\ifpgfslopedattime=\relax \begin{textoken}{\ifpgfslopedattime} @@ -352,7 +394,7 @@ coordinate transformations. \let\ifpgfallowupsidedowattime=\relax \begin{textoken}{\ifpgfallowupsidedowattime} Decides whether the ``at time'' transformation commands should - allow the rotation be down in such a way that ``upside-down text'' + allow the rotation be done in such a way that ``upside-down text'' can result. \end{textoken} } @@ -370,7 +412,7 @@ coordinate transformations. The coordinate transformation commands introduced up to now are always applied in addition to any previous transformations. In contrast, the commands presented in the following can be used to change the -transformation matrix ``absolutely.'' Note that this is, in general, +transformation matrix ``in absolute terms.'' Note that this is, in general, dangerous and will often produce unexpected effects. You should use these commands only if you really know what you are doing. @@ -467,7 +509,7 @@ transformation matrices. \subsection{Canvas Transformations} The canvas transformation matrix is not managed by \pgfname, but by -the output format like \pdf\ or PostScript. All the \pgfname\ does is +the output format like \pdf\ or PostScript. All that \pgfname\ does is to call appropriate low-level |\pgfsys@| commands to change the canvas transformation matrix. @@ -582,9 +624,463 @@ a coordinate transformation, see the previous section). \end{contextenvironment} +\subsection{Nonlinear Transformations} +\label{section-nonlinear-transformations} +In order to use nonlinear transformations, you first have to load the +following \pgfname\ module: + +\begin{pgfmodule}{nonlineartransformations} + Loads the necessary functionality for nonlinear transformations. +\end{pgfmodule} + + +\subsubsection{Introduction} + +The difference between the coordinate transformations introduced in +Section~\ref{section-linear-coordinate-transformations} above to +nonlinear transformations is, of course, that the transformations can +be nonlinear. An example of a nonlinear transformation is the +transformation underlying polar coordinates: A polar coordinate +$(r,d)$ gets transformed to the canvas position $(d\cos r,d\sin r)$, +which is clearly not a linear transformation. + +Nonlinear transformations work somewhat like the normal linear +coordinate transformations in the sense that they apply to coordinate +and thereby to the construction of paths, but not to things like text +or line width or shadings. (Indeed, it is not possible to apply +nonlinear transformations to, say, text.) + +This means that there is a fundamental +difference between, on the one hand, calling a function like +|\pgfpointpolar| or specifying a coordinate as |(45:2)| in \tikzname\ +and, on the other hand, installing the nonlinear transformation +``polar coordinates'' using the command |\pgftransformnonlinear|: In a +coordinate like |(45:2)| the user explicitly says ``please evaluate +this one coordinate in polar coordinate and then continue in the +normal coordinate system with the result.'' Otherwise nothing changes +and a line between two points specified in this way is still a +straight line. + +Things are quite different when we install a polar +\emph{transformation} using |\pgftransformnonlinear|. Now, even a +seemingly low-level Cartesian coordinate |\pgfqpoint{1pt}{1pt}| will +get transformed. Even more drastically, what is specified as a +straight line like +\begin{codeexample}[code only] +\draw (0,1) -- (1,1); +\end{codeexample} +can become curved since \emph{everything} gets transformed. + + +\subsubsection{Installing Nonlinear Transformation} + +\makeatletter +\def\polartransformation{ + % \pgf@x will contain the radius + % \pgf@y will contain the distance + \pgfmathsincos@{\pgf@x}% + % pgfmathresultx is now the cosine of radius and + % pgfmathresulty is the sine of radius + \pgf@x=\pgfmathresultx\pgf@y% + \pgf@y=\pgfmathresulty\pgf@y% +} +\makeatother + +\begin{command}{\pgftransformnonlinear\marg{transformation code}} + This command adds the \meta{transformation code} to the list of non-linear + transformations currently in force. Thus, similar to linear + coordinate transformations, each additional call to this function + adds another transformation to the current \TeX\ scope and the + effect ends at the end of the current scope. In practice, however, + you typically will not have more than one active nonlinear + transformation. + + The job of the \meta{transformation code} is to map a point~$p$ + given in the registers |\pgf@x| and |\pgf@y| to a new + coordinate~$f(p)$, which should be returned in |\pgf@x| and |\pgf@y| + as well. As an example, suppose we wish to install polar coordinates + as the nonlinear transformation. For this, we need a bit of code: +\begin{codeexample}[code only] +\def\polartransformation{% + % \pgf@x will contain the radius + % \pgf@y will contain the distance + \pgfmathsincos@{\pgf@x}% + % pgfmathresultx is now the cosine of radius and + % pgfmathresulty is the sine of radius + \pgf@x=\pgfmathresultx\pgf@y% + \pgf@y=\pgfmathresulty\pgf@y% +} +\end{codeexample} + (In case you wonder why you cannot just call |\pgfpointpolar| at + this point: You can, but this function internally uses |\pgf@x| + and |\pgf@y| in complicated ways, so you would first have to safe + them so some other registers. Also, the above is faster.) + + If we were to call this function again, we would get something funny + like ``polar-polar coordinates,'' so let's not do this. Let us + instead have a look at the effect this call has: Once a nonlinear + transformation is installed, all subsequent path constructions are + affected by this transformation. In particular, a normal grid now + becomes the typical ``polar grid.'' + +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + % Start nonlinear transformation + \pgftransformnonlinear{\polartransformation}% see above + + % Draw something with this transformation in force + \draw (0pt,0mm) grid [xstep=10pt, ystep=5mm] (90pt, 20mm); +\end{tikzpicture} +\end{codeexample} +\end{command} + + +\subsubsection{Applying Nonlinear Transformations to Points} + +\begin{command}{\pgfpointtransformednonlinear\marg{point}} + Works like |\pgfpointtransformed|, but also applies the current + nonlinear transformation; that is, it first applies the current + linear transformation and then the current nonlinear + transformations. Note that, just like |\pgfpointtransformed|, you + normally do not call this function directly since it is called + internally by the path drawing commands. +\end{command} + + +\subsubsection{Applying Nonlinear Transformations to Paths} + +When a nonlinear transformation is installed, the normal path +construction commands like |\pgfpathmoveto| get adjusted so that the +``honour'' the nonlinear transformations currently in force. For +|\pgfpathmoveto| this is pretty simple: Instead of just applying the +linear transformation matrix to the point to which the path should +``jump'' next, we also apply the nonlinear transformation. However, +for a command like |\pgfpathlineto|, things are much more difficult: +A straight line will no longer be a straight line! + +In order to make straight lines ``bend'', the following changes are in +force while a nonlinear transformation is installed: + +\begin{enumerate} +\item Whenever a straight line between two points $p$ and $q$ should + be added to the path, either through |\pgfpathlineto| or through + |\pgfpathclose|, we replace this straight line by a ``degenerated + curve'' from $p$ to $q$ whose control points are at one third and + two third of the distance between $p$ and $q$ on the line between + $p$ and $q$. In this way, while nonlinear transformations are in + force, we only need to transform curves. +\item Next, suppose we wish to transform a curve from $p$ to $q$ with + supports $s$ and $t$. For this, we simply apply the nonlinear + transformation $f$ to all four points and draw a line with the + results. Note that this mapping is actually not quite satisfactory + for long lines that are strongly curved: +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + { + \pgftransformnonlinear{\polartransformation} + % The curve with the controls computed by pgf: a nice quarter arc + \draw [red] (0,20mm) -- (90pt,20mm); + } + % Here is the curve with controls just transformed: + \draw (0:20mm) .. controls (30pt:20mm) and (60pt:20mm) .. (90pt:20mm); +\end{tikzpicture} +\end{codeexample} + As the example shows, the control points now lie on the arc; but in + reality they should point along the tangents at the start and the + end. This is exactly when \pgfname\ does through the computation + described above. +\item + To overcome the effect of the control points being ``off,'' it is + necessary to split up longer curves into smaller parts, which are + drawn individually to increase the accuracy. When such splitting + occurs, can be configured using the following command: + \begin{command}{\pgfsettransformnonlinearflatness\marg{dimension} + (initially 5pt)} + Whenever in a to-be-drawn curve the $L^\infty$-distance (maximum + of the distances in $x$- and $y$-directions) between the start of + a curve and its first control point or between the first and + second control points or between the second control point and the + end is more than \meta{distance}, the curve gets split in the + middle (more precisely, at time $t= 0.5$) and we draw the two + parts individually (for them, splitting may occur again, if the + curve is still too long). +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + \draw[red] (0:20mm) arc [start angle=0, end angle=90, radius=2cm]; + { + \pgftransformnonlinear{\polartransformation} + \pgfsettransformnonlinearflatness{2pt} % very precise + \draw (0,20mm) -- (90pt,20mm); + } +\end{tikzpicture} +\end{codeexample} + \end{command} +\end{enumerate} + + +\subsubsection{Applying Nonlinear Transformations to Text} + +Earlier, it was pointed that nonlinear transformations do not apply +to text. Nevertheless, when you use |\pgftext| or |\pgfnode|, +\pgfname\ will do a sort of ``best effort'' to render the text in +the nonlinear coordinate system: The point where the text should be +shown can obviously be computed easily. When then temporarily reset +the nonlinear transformation and, instead, setup a linear +transformation that matches the nonlinear transformation at the +point where the text should be. Then, the text is shown. This means +that if the text is longer, it will not ``follow'' the nonlinear +transformation, but near the origin of the text it will look +``correct.'' As an example, let us add some text at the grid point +of the above example: + +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + \pgftransformnonlinear{\polartransformation}% see above + + % Draw something with this transformation in force + \draw (0pt,0mm) grid [xstep=10pt, ystep=5mm] (90pt, 20mm); + + \foreach \angle in {0,30,60,90} + \foreach \dist in {1,2} + { + \pgftransformshift{\pgfpoint{\angle pt}{\dist cm}} + \pgftext{\angle$^\circ$} + } +\end{tikzpicture} +\end{codeexample} + + +\subsubsection{Approximating Nonlinear Transformations Using Linear Transformations} + +At any given point, the current nonlinear transformation can be +approximated using a linear transformation. The following two +functions allow you to install such a local approximation: + +\begin{command}{\pgfapproximatenonlineartransformation} + This command will do two things: + \begin{enumerate} + \item It clears the nonlinear transformations for the rest of the + current \TeX\ scope, so only linear transformations apply. + \item However, before removing the nonlinear transformations, the + linear transformation matrix is modified so that it mimics the + effect the nonlinear transformation had at the origin. That is, + after you call this command, drawing something near the origin + will look almost the same as if you had not called it. + \end{enumerate} + +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + \pgftransformnonlinear{\polartransformation}% see above + \draw (0pt,0mm) grid [xstep=10pt, ystep=5mm] (90pt, 20mm); + + \begin{scope}[shift={(45pt,20mm)}] + % Draw something near "origin": + \draw [red] (-10pt,-10pt) -- (10pt,10pt); + \draw [red] (10pt,-10pt) -- (-10pt,10pt); + + % Now draw the same, but in the "approximate" coordinate system: + \pgfapproximatenonlineartransformation + \draw [] (-10pt,-10pt) -- (10pt,10pt); + \draw [] (10pt,-10pt) -- (-10pt,10pt); + \pgftext{foo}; + \end{scope} +\end{tikzpicture} +\end{codeexample} + This command is used by |\pgftext| and |\pgfnode| to transform text + when a nonlinear transformation is in force. +\end{command} + +\begin{command}{\pgfapproximatenonlineartranslation} + This command works like the normal approximation command, but it + will only approximate how the origin gets translated, it will not + approximate the rotation, skewing, or scaling that is involved. This + is useful for drawing text at the right position, but without + ``mutilating'' the text. +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + \pgftransformnonlinear{\polartransformation}% see above + \draw (0pt,0mm) grid [xstep=10pt, ystep=5mm] (90pt, 20mm); + + \begin{scope}[shift={(45pt,20mm)}] + % Draw something near "origin": + \draw [red] (-10pt,-10pt) -- (10pt,10pt); + \draw [red] (10pt,-10pt) -- (-10pt,10pt); + + % Now draw the same, but in the "approximate" coordinate system: + \pgfapproximatenonlineartranslation + \draw [] (-10pt,-10pt) -- (10pt,10pt); + \draw [] (10pt,-10pt) -- (-10pt,10pt); + \pgftext{foo}; + \end{scope} +\end{tikzpicture} +\end{codeexample} +\end{command} + + +\subsubsection{Nonlinear Transformation Libraries} +\label{section-library-curvilinear} + +\begin{pgflibrary}{curvilinear} + This library defines commands for computing nonlinear + transformations ``along B\'ezier curves''. +\end{pgflibrary} + +Up to now, our running example for a nonlinear transformation was +polar transformation. However, is \pgfname\ nonlinear transformations +are \emph{actually} mainly used for transforming arrow tips; and these +need to be transformed ``along curves.'' The |curvilinear| library +defines a number of commands that offer the necessary computations for +such transformations. + +\begin{command}{\pgfsetcurvilinearbeziercurve\marg{start}\marg{first + support}\marg{second support}\marg{end}} + Prior to using any other command from this library, you first call + this function to ``install'' a B\'ezier curve to which the commands + will refer. This curve will be local to the current \TeX\ scope and + you can install only one curve at a time. + + The main job of this command is to store the passed points + internally and to build a lookup table for distance-to-time + conversions, see the next command. +\begin{codeexample}[code only] +\pgfsetcurvilinearbeziercurve + {\pgfpointorigin} + {\pgfpoint{1cm}{1cm}} + {\pgfpoint{2cm}{1cm}} + {\pgfpoint{3cm}{0cm}} +\end{codeexample} +\end{command} + +\begin{command}{\pgfcurvilineardistancetotime\marg{distance}} + This command does a ``distance-to-time-conversion'': It tries to + compute a time $t$, returned in |\pgf@x|, that corresponds to + travelling \meta{distance} along the curve that has last been + installed using the command |\pgfsetcurvilinearbeziercurve|. The distance-to-time-conversion + uses the precomputations done by that command. Note that several + compromises had to be made between speed and accuracy: + \begin{itemize} + \item The conversion will be best near the start of the curve. + \item The more ``degenerate'' the curve, the worse the results. + \end{itemize} +\end{command} + + +\begin{command}{\pgfpointcurvilinearbezierorthogonal\marg{distance}\marg{offset}} + This command computes the following point: Consider the curve + last installed using the command |\pgfsetcurvilinearbeziercurve|. We + travel along this curve by \meta{distance}, arriving at a point + $p$. Then, we turn by $90^\circ$ and travel by \meta{offset} units + ``aways from the curve,'' arriving at a point $q$. This point $q$ + will now be returned in |\pgf@x| and |\pgf@y|; furthermore, the + transformed local coordinate system at point $q$ will also be + returned |\pgf@xa| and the other registers, see + |\pgftransformnonlinear| for details. + \makeatletter +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + { + \pgfsetcurvilinearbeziercurve + {\pgfpoint{0mm}{20mm}} + {\pgfpoint{11mm}{20mm}} + {\pgfpoint{20mm}{11mm}} + {\pgfpoint{20mm}{0mm}} + \pgftransformnonlinear{\pgfpointcurvilinearbezierorthogonal\pgf@x\pgf@y}% + \draw (0,-30pt) grid [step=10pt] (80pt,30pt); + } + \draw[red, very thick] + (0mm,20mm) .. controls (11mm,20mm) and (20mm,11mm) .. (20mm,0mm); +\end{tikzpicture} +\end{codeexample} + +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + { + \pgfsetcurvilinearbeziercurve + {\pgfpoint{0mm}{20mm}} + {\pgfpoint{10mm}{20mm}} + {\pgfpoint{10mm}{10mm}} + {\pgfpoint{20mm}{10mm}} + \pgftransformnonlinear{\pgfpointcurvilinearbezierorthogonal\pgf@x\pgf@y}% + \draw (0,-30pt) grid [step=10pt] (80pt,30pt); + } + \draw[red, very thick] + (0mm,20mm) .. controls (10mm,20mm) and (10mm,10mm) .. (20mm,10mm); +\end{tikzpicture} +\end{codeexample} +\end{command} + + +\begin{command}{\pgfpointcurvilinearbezierpolar\marg{x}\marg{y}} + This command is similar to the previous version, but the + transformation is different: The idea is that a line form $(0,0)$ to + $(x,0)$ gets transformed to the curve from the start of the curve to + a point at distance $x$ along the curve. This is identical to what + the ``orthogonal'' transformation above also does. The difference is + that a line from $(0,0)$ to $(0,y)$ gets still transformed to an + initial segment of the curve of a length of $y$, but now rotated by + $90^\circ$. In general, the point $p = (x,y)$ gets transferred to a + point that at distance $|p| = \sqrt{x^2+y^2}$ along the curve, but + rotated by the angle of $p$ relative to the $x$-axis. + + All of these computations mainly have the following effect: Two + straight lines from the start of the curve as in a |Straight Barb| + arrow tip get transformed to an initial segment of the curve whose + length is the length of the two lines, but this segment gets rotated + by the angle of the two lines. + \makeatletter +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + { + \pgfsetcurvilinearbeziercurve + {\pgfpoint{0mm}{20mm}} + {\pgfpoint{11mm}{20mm}} + {\pgfpoint{20mm}{11mm}} + {\pgfpoint{20mm}{0mm}} + \pgftransformnonlinear{\pgfpointcurvilinearbezierpolar\pgf@x\pgf@y}% + \draw (0,-30pt) grid [step=10pt] (80pt,30pt); + % Add a "barb": + \draw [blue, very thick] (20pt,10pt) -- (0,0) -- (20pt,-10pt); + } + \draw[red, very thick] + (0mm,20mm) .. controls (11mm,20mm) and (20mm,11mm) .. (20mm,0mm); +\end{tikzpicture} +\end{codeexample} + +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + { + \pgfsetcurvilinearbeziercurve + {\pgfpoint{0mm}{20mm}} + {\pgfpoint{10mm}{20mm}} + {\pgfpoint{10mm}{10mm}} + {\pgfpoint{20mm}{10mm}} + \pgftransformnonlinear{\pgfpointcurvilinearbezierpolar\pgf@x\pgf@y}% + \draw (0,-30pt) grid [step=10pt] (80pt,30pt); + % Add a "barb": + \draw [blue, very thick] (20pt,10pt) -- (0,0) -- (20pt,-10pt); + } + \draw[red, very thick] + (0mm,20mm) .. controls (10mm,20mm) and (10mm,10mm) .. (20mm,10mm); +\end{tikzpicture} +\end{codeexample} +\end{command} %%% Local Variables: %%% mode: latex %%% TeX-master: "pgfmanual" %%% End: + +% LocalWords: nonlineartransformations PGF cx dy pdf PostScript pgfscope xstep +% LocalWords: Reinstalls shiftx backend pgflowlevelscope ystep ezier lookup xa +% LocalWords: precomputations diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-transparency.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-transparency.tex index a286fcfcd34..1243597df54 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-transparency.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-base-transparency.tex @@ -56,7 +56,7 @@ Specifying a stroke and/or fill opacity is quite easy. \end{codeexample} \end{command} -Note the following effect: If you setup a certain opacity for stroking +Note the following effect: If you set up a certain opacity for stroking or filling and you stroke or fill the same area twice, the effect accumulates: @@ -72,6 +72,29 @@ Often, this is exactly what you intend, but not always. You can use transparency groups, see the end of this section, to change this. +\subsection{Specifying a Blend Mode} + +To set the blend mode, use the following command: + +\begin{command}{\pgfsetblendmode\marg{mode}} + Sets the blend mode to one of the values described in + Section~\ref{section-blend-modes}. As described there, blend modes + are an advanced feature of \textsc{pdf} and not always rendered + correctly. + + +\begin{codeexample}[] +\tikz [transparency group] { + \pgfsetblendmode{screen} + + \fill[red!90!black] ( 90:.6) circle (1); + \fill[green!80!black] (210:.6) circle (1); + \fill[blue!90!black] (330:.6) circle (1); +} +\end{codeexample} +\end{command} + + \subsection{Specifying a Fading} The method used by \pgfname\ for specifying fadings is quite @@ -91,9 +114,9 @@ transparent. \begin{command}{\pgfdeclarefading\marg{name}\marg{contents}} - This command declare a fading named \meta{name} for later use. The + This command declares a fading named \meta{name} for later use. The ``picture'' on which the fading is based is given by the - \meta{contents}. This \meta{contents} is normally typeset in a \TeX\ + \meta{contents}. The \meta{contents} are normally typeset in a \TeX\ box. The resulting box is then used as the ``picture.'' In particular, inside the \meta{contents} you must explicitly open a |{pgfpicture}| environment if you wish to use \pgfname\ commands. @@ -168,7 +191,7 @@ transparent. \end{command} After having declared a fading, we can use it. As for shadings, there -are two different commands for using fadings: +are different commands for using fadings: \begin{command}{\pgfsetfading\marg{name}\marg{transformations}} This command sets the graphic state parameter ``fading'' to a @@ -177,7 +200,7 @@ are two different commands for using fadings: current scope or until a different transparency setting is chosen. When the fading is installed, it will be centered on the origin with - its natural size. Anything outside the fading pictures's original + its natural size. Anything outside the fading picture's original bounding box will be transparent and, thus, the fading effectively clips against this bounding box. @@ -212,7 +235,7 @@ are two different commands for using fadings: \begin{command}{\pgfsetfadingforcurrentpath\marg{name}\marg{transformations}} This command works like |\pgfsetfading|, but the fading is scaled - are transformed according to the following rules: + and transformed according to the following rules: \begin{enumerate} \item If the current path is empty, the command has the same effect as @@ -257,15 +280,33 @@ are two different commands for using fadings: \end{command} +\begin{command}{\pgfsetfadingforcurrentpathstroked\marg{name}\marg{transformations}} + This command works line |\pgfsetfadingforcurrentpath|, only the + current path is enlarged by the line width in both $x$- and + $y$-direction. This is exactly the enlargement necessary to + compensate for the fact that if the current path will be stroked, + this much needs to be added around the path's bounding box to + actually contain the path. +\begin{codeexample}[] +\begin{tikzpicture} + \pgfsetlinewidth{2mm} + \pgfpathmoveto{\pgfpointorigin} + \pgfpathlineto{\pgfpoint{2cm}{0cm}} + \pgfsetfadingforcurrentpathstroked{fading}{} + \pgfusepath{stroke} +\end{tikzpicture} +\end{codeexample} +\end{command} + \subsection{Transparency Groups} Transparency groups are declared using the following commands. -\begin{environment}{{pgftransparencygroup}} +\begin{environment}{{pgftransparencygroup}\opt{\oarg{options}}} This environment should only be used inside a |{pgfpicture}|. It has the following effect: \begin{enumerate} - \item The \meta{environment contents} is stroked/filled + \item The \meta{environment contents} are stroked/filled ``ignoring any outside transparency.'' This means, all previous transparency settings are ignored (you can still set transparency inside the group, but never mind). This means that if in the @@ -279,7 +320,20 @@ Transparency groups are declared using the following commands. color will be blended with whatever is ``behind'' the group on the page. \end{enumerate} - + + The optional \meta{options} are keys that configure the transparency + group further. Two keys are currently defined: + \begin{itemize} + \item \declare{|knockout|\opt{|=|\meta{true or false}}} Configures + whether the group is a knockout group (if no argument is given, + |true| is assumed; initially the key is always false, even when + the command is used in a nested manner.) See + Section~\ref{section-transparency-groups} for details on knockout groups. + \item \declare{|isolated|\opt{|=|\meta{true or false}}} Similar, but + configures whether the group is an isolated group. Also see + Section~\ref{section-transparency-groups} for details on isolated groups. + \end{itemize} + Note that, depending on the driver, \pgfname\ may have to guess the size of the contents of the transparency group (because such a group is put in an XForm in \textsc{pdf} and a bounding box must be diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-drivers.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-drivers.tex index a9483064435..3674f2f86d9 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-drivers.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-drivers.tex @@ -8,7 +8,7 @@ % See the file doc/generic/pgf/licenses/LICENSE for more details. -\section{Input and Output Formats} +\section{Supported Formats} \label{section-formats} @@ -20,7 +20,7 @@ can be produced. -\subsection{Supported Input Formats} +\subsection{Supported Input Formats: \LaTeX, Plain \TeX, Con\TeX t} \TeX\ does not prescribe exactly how your input should be formatted. While it is \emph{customary} that, say, an opening brace @@ -83,10 +83,6 @@ format if you use |pdftex| or |tex| plus |dvips|. For all other output formats you need to set the macro |\pgfsysdriver| to the correct value. See the description of using output formats later on. -\pgfname\ was originally written for use with \LaTeX\ and this shows -in a number of places. Nevertheless, the plain \TeX\ support is -reasonably good. - Like the \LaTeX\ style files, the plain \TeX\ files like |tikz.tex| also just include the correct |tikz.code.tex| file. @@ -94,9 +90,7 @@ also just include the correct |tikz.code.tex| file. \subsubsection{Using the Con\TeX t Format} -When using the Con\TeX t format\footnote{Note that \pgfname/\tikzname{} - is not supported by recent Con\TeX t versions (like mark IV, the - Lua\TeX-aware part of Con\TeX t).}, you say |\usemodule[pgf]| or +When using the Con\TeX t format, you say |\usemodule[pgf]| or |\usemodule[tikz]|. As for the plain \TeX\ format you also have to replace the start- and end-of-environment tags as follows: Instead of |\begin{pgfpicture}| and |\end{pgfpicture}| you use |\startpgfpicture| @@ -131,7 +125,8 @@ typeset. Producing the output is (conceptually) a two-stage process: \TeX\ typesets your text and graphics. The result of this typesetting is mainly a long list of letter--coordinate pairs, plus (possibly) some ``special'' commands. This long list of pairs - is written to something called a |.dvi|-file. + is written to something called a |.dvi|-file (informally known as + ``device-independent file''). \item Some other program reads this |.dvi|-file and translates the letter--coordinate pairs into, say, PostScript commands for placing @@ -142,7 +137,7 @@ The classical example of this process is the combination of |latex| and |dvips|. The |latex| program (which is just the |tex| program called with the \LaTeX-macros preinstalled) produces a |.dvi|-file as its output. The |dvips| program takes this output and produces a -|.ps|-file (a PostScript) file. Possibly, this file is further +|.ps|-file (a PostScript file). Possibly, this file is further converted using, say, |ps2pdf|, whose name is supposed to mean ``PostScript to PDF.'' Another example of programs using this process is the combination of |tex| and |dvipdfm|. The |dvipdfm| @@ -153,17 +148,17 @@ input and translates the letter--coordinate pairs therein into output, this time it is a |.html| file. The programs |pdftex| and |pdflatex| are special: They directly produce a |.pdf|-file without the intermediate |.dvi|-stage. However, from the programmer's point of -view they behave exactly as if there where an intermediate stage. +view they behave exactly as if there was an intermediate stage. Normally, \TeX\ only produces letter--coordinate pairs as its -``output.'' This obviously makes is difficult to draw, say, a +``output.'' This obviously makes it difficult to draw, say, a curve. For this, ``special'' commands can be used. Unfortunately, these special commands are not the same for the different programs that process the |.dvi|-file. Indeed, every program that takes a |.dvi|-file as input has a totally different syntax for the special commands. -One of the main jobs of \pgfname\ is to ``abstract way'' the +One of the main jobs of \pgfname\ is to ``abstract away'' the difference in the syntax of the different programs. However, this means that support for each program has to be ``programmed,'' which is a time-consuming and complicated process. @@ -204,9 +199,8 @@ exactly the same. |pdftex| or |pdflatex| command. It includes |pgfsys-common-pdf.def|. - This driver has the ``complete'' functionality. This means, - everything \pgfname\ ``can do at all'' is implemented in this - driver. + This driver has a lot of functionality. (Almost) everything + \pgfname\ ``can do at all'' is implemented in this driver. \end{filedescription} \begin{filedescription}{pgfsys-dvipdfm.def} @@ -221,21 +215,13 @@ exactly the same. inclusion and does not support masking. \item In plain \TeX\ mode it does not support image inclusion. - \item - For remembering of pictures (inter-picture connections) you need - to use a recent version of |pdftex| running in DVI-mode. - \item - Patterns are not (cannot) be supported. - \item - Functional shadings are not (cannot) be supported. \end{enumerate} \end{filedescription} \begin{filedescription}{pgfsys-xetex.def} This is a driver file for use with |xe|(|la|)|tex| followed by - |xdvipdfmx|. This driver supports the same operations as the dvipdfm - driver, except that remembering of pictures (inter-picture - connections) always works. + |xdvipdfmx|. This driver supports largely the same operations as the + |dvipdfm| driver. \end{filedescription} \begin{filedescription}{pgfsys-vtex.def} @@ -311,17 +297,61 @@ produce Postscript output. -\subsubsection{Producing HTML / SVG Output} +\subsubsection{Producing SVG Output} + +\begin{filedescription}{pgfsys-dvisvgm.def} + This driver converts \textsc{dvi} files to \textsc{svg} file, + including text and fonts. When you select this driver, \pgfname\ + will output the required raw \textsc{svg} code for the pictures it + produces. + + Since the |graphics| package does not (yet?) support this driver + directly, there is special rule for this driver in \LaTeX: If the + option |dvisvgm| is given to the |tikz| package, this driver gets + selected (normally, the driver selected by |graphics| would be + used). For packages like |beamer| that load \pgfname\ + themselves, this means that the option |dvisvgm| should be given to + the document class. +\begin{codeexample}[code only] +% example.tex +\documentclass[dvisvgm]{minimal} + +\usepackage{tikz} + +\begin{document} +Hello \tikz [baseline] \fill [fill=blue!80!black] (0,.75ex) circle[radius=.75ex]; +\end{document} +\end{codeexample} + + And then run +\begin{codeexample}[code only] +latex example +dvisvgm example +\end{codeexample} + or better +\begin{codeexample}[code only] +lualatex --output-format=dvi example +dvisvgm example +\end{codeexample} + (This is ``better'' since it gives you access to the full power of + Lua\TeX\ inside your \TeX-file. In particular, \tikzname\ is able + to run graph drawing algorithms in this case.) + + Unlike the |tex4ht| driver below, this driver has full support of + text nodes. +\end{filedescription} -The |tex4ht| program converts |.dvi|-files to |.html|-files. While the -\textsc{html}-format cannot be used to draw graphics, the -\textsc{svg}-format can. Using the following driver, you can ask -\pgfname\ to produce an \textsc{svg}-picture for each \pgfname\ -graphic in your text. \begin{filedescription}{pgfsys-tex4ht.def} - This is a driver file for use with the |tex4ht| program. It includes - |pgfsys-common-svg.def|. + This is a driver file for use with the |tex4ht| program. It is + selected automatically when the |tex4ht| style or command is + loaded. It includes |pgfsys-common-svg.def|. + + The |tex4ht| program converts |.dvi|-files to |.html|-files. While the + \textsc{html}-format cannot be used to draw graphics, the + \textsc{svg}-format can. This driver will ask + \pgfname\ to produce an \textsc{svg}-picture for each \pgfname\ + graphic in your text. When using this driver you should be aware of the following restrictions: @@ -338,7 +368,7 @@ graphic in your text. Text inside |pgfpicture|s is not supported very well. The reason is that the \textsc{svg} specification currently does not support text very well and, although it is possible to ``escape - back'' to \textsc{html}, |Tikz| has then to guess what size the text + back'' to \textsc{html}, \tikzname\ has then to guess what size the text rendered by the browser would have. \item Unlike for other output formats, the bounding box of a picture @@ -364,7 +394,7 @@ graphic in your text. \textsc{svg} standard, you may wish to use the following options to modify the way text is handled: - \begin{key}{/tikz/tex4ht node/escape=\meta{boolean} (default |false|)} + \begin{key}{/pgf/tex4ht node/escape=\meta{boolean} (default |false|)} Selects the rendering method for a text node with the tex4ht driver. When this key is set to |false|, text is translated into @@ -386,46 +416,46 @@ graphic in your text. simple as |$\alpha$|, this may corrupt the graphic. \begin{codeexample}[code only] -\tikz \node[draw,tex4ht node/escape=false] {Example : $(a+b)^2=a^2+2ab+b^2$}; +\tikz \node[draw,/pgf/tex4ht node/escape=false] {Example : $(a+b)^2=a^2+2ab+b^2$}; \end{codeexample} - When you write |node[tex4ht node/escape=true] {|\meta{text}|}|, - \tikzname\ escapes back to \textsc{html} to render the + When you write |node[/pgf/tex4ht node/escape=true] {|\meta{text}|}|, + \pgfname\ escapes back to \textsc{html} to render the \meta{text}. This method produces valid \textsc{html} code in most cases and the support for complicated text nodes is much better since - code that renders well outside a |{tikzpicture}|, should also + code that renders well outside a |{pgfpicture}|, should also render well inside a text node. Another advantage is that inside text nodes with fixed width, \textsc{html} will produce line breaks for long lines. On the other hand, you need a browser with good \textsc{svg} support to display the picture. Also, the text will display differently, depending on your browsers, the fonts you have on your system and your settings. Finally, - \tikzname\ has to guess the size of the text rendered by the + \pgfname\ has to guess the size of the text rendered by the browser to scale it and prevent it from sticking from the node. When it fails, the text will be either cropped or too small. \begin{codeexample}[code only] -\tikz \node[draw,tex4ht node/escape=true] +\tikz \node[draw,/pgf/tex4ht node/escape=true] {Example : $\int_0^\infty\frac{1}{1+t^2}dt=\frac{\pi}{2}$}; \end{codeexample} \end{key} - \begin{key}{/tikz/tex4ht node/css=\meta{filename} (default |\string\jobname|)} + \begin{key}{/pgf/tex4ht node/css=\meta{filename} (default |\string\jobname|)} This option allows you to tell the browser what \textsc{css} file it should use to style the display of the node (only with |tex4ht node/escape=true|). \end{key} - \begin{key}{/tikz/tex4ht node/class=\meta{class name} (default foreignobject)} + \begin{key}{/pgf/tex4ht node/class=\meta{class name} (default foreignobject)} This option allows you to give a class name to the node, allowing it to be styled by a \textsc{css} file (only with |tex4ht node/escape=true|). \end{key} - \begin{key}{/tikz/tex4ht node/id=\meta{id name} (default + \begin{key}{/pgf/tex4ht node/id=\meta{id name} (default |\string\jobname\ picture number-node number|)} This option allows you to give a unique id to the node, allowing it to be styled by a \textsc{css} file (only with - |tex4ht node/escape=true|). + |tex4ht node/escape=true|). \end{key} \end{filedescription} @@ -447,7 +477,7 @@ graphic in your text. \begin{itemize} \item Text boxes can be placed in the normal way. \item Lines and curves can be drawn (stroked). If they are not - horizontal or vertical, they are composed of hundred of small + horizontal or vertical, they are composed of hundreds of small rectangles. \item Lines of different width are supported. \item Transformations are supported. diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-axes.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-axes.tex index bb7b9eb0400..f44b1b4ad4a 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-axes.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-axes.tex @@ -7,99 +7,800 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. - \section{Axes} \label{section-dv-axes} + \subsection{Overview} -To be written... +When a data point is visualized, the most obvious way of creating a +visual representation of its many attributes is to +vary \emph{where} the data point is shown. The data visualization +system uses \emph{axes} to turn data point attributes into positions +on a page. The simplest -- and most common -- use of axes is to vary +the horizontal position of data points according to one attribute and +to vary the vertical position according to another attribute. In +contrast, in a polar plot one attribute dictates the distance of the +data point from the origin and another attribute describes the +angle. From the data visualization engine's point of view, in both +cases two \emph{axes} are involved. + +In addition to specifying how the value of a certain attribute is +converted into a displacement on the page, an axis is also typically +(but not always) visualized (``drawn'') somewhere on the page. In this case, it is +also customary to add a visual representation on this axis of which +attribute values correspond to which positions on the page -- +something commonly known as \emph{ticks}. Similar to ticks, \emph{grid + lines} also indicate positions where a certain attribute has a +certain value, but instead of just indicating a single position on an +axis, a grid line goes through all points that share an attribute +value. + +In the following, in Section~\ref{section-dv-axes-main} we first have +a look at how axes can be defined and configured. As you will see, a +lot of powerful configurations are available, but you will rarely +define and configure an axis from scratch. Rather, it is more common +to use a preconfigured axis +instead. Section~\ref{section-dv-axis-systems} introduces \emph{axis + systems}, which are predefined bundles of axes. You can define your +own axis systems, but, again, in most cases it will suffice to just +use one of the many preconfigured axis systems and use a few options +to configure it so that it fits your +need. Section~\ref{section-dv-ticks-and-grids} explains how ticks and +grid lines can be configured. Again, several layers of +options allow you to configure the way ticks look and where they are +placed in great detail. + +This section documents the standard axis systems that are always +available. For polar axis systems, a special library needs to be +loaded, which is documented in Section~\ref{section-dv-polar}. + + + +\subsection{Basic Configuration of Axes} +\label{section-dv-axes-main} + +Inside the data visualization system, an \emph{axis} is roughly a +``systematic, named way of mapping an attribute to a +position on a page''. For instance, the classical ``$x$-axis'' is the +``systematic way of mapping the value of the |x| attribute of data +points to a horizontal position on the page''. An axis is \emph{not} +its visual representation (such as the horizontal line with the ticks +drawn to represent the $x$-axis), but a visual representation can be +created once an axis has been defined. + +The transformation of an attribute value (such as the value |1000000000| +for the |x| attribute) to a specific displacement of the corresponding +data point on the page involves two steps: +\begin{enumerate} +\item First, the range of possible values such as $[-5.6\cdot + 10^{12},7.8\cdot 10^{12}]$ must be mapped to a ``reasonable'' + interval such as $[0\mathrm{cm},5\mathrm{cm}]$ or + $[0^\circ,180^\circ]$. \tikzname's drawing routines will only be + able to cope with values from such a ``reasonable'' interval. +\item Second, the values from the reasonable interval must be mapped + to a transformation. +\end{enumerate} +The first step is always the same for all axes, while the second +requires different strategies. For this reason, the command +|new axis base| is used to create a ``basic'' axis that has a +``scaling mapper'', whose job it is to map the range of values of a +specific attribute to a reasonable interval, but such a basic axis +does not define an actual transformation object. For this second step, +additional objects such as a |linear transformer| need to be created +separately. + + +\subsubsection{Usage} + +To create an axis, the key |new axis base| is used first. Since this key +does not create a transformation object, users typically do not use +this key directly. Rather, it is used internally by other keys +that create ``real'' axes. These keys are listed in +Section~\ref{section-dv-reference-axis-types}. + +\begin{key}{/tikz/data visualization/new axis base=\meta{axis name}} + This key defines a new axis for the current data visualization + called \meta{name}. This has two effects: + \begin{enumerate} + \item A so called \emph{scaling mapper} is created that will monitor + a certain attribute, rescale it, and map it to another + attribute. (This will be explained in detail in a moment.) + \item The \meta{axis name} is made available as a key that can be + used to configure the axis: + \begin{key}{/tikz/data visualization/\meta{axis name}=\meta{options}} + This key becomes available once |new axis base=|meta{axis name} has + been called. It will execute the \meta{options} with the path + prefix |/tikz/data visualization/axis options|. +\begin{codeexample}[code only] +[new axis base=my axis, + my axis={attribute=some attribute}] +\end{codeexample} + \end{key} + \item The \meta{axis name} becomes part of the current set of + axes. This set can be accessed through the following key: + \begin{key}{/tikz/data visualization/all axes=\meta{options}} + This key passes the \meta{options} to all axes inside the + current scope, just as if you had written \meta{some axis + name}|=|\meta{options} for each \meta{some axis name} in the + current scope, including the just-created name \meta{axis name}. + \end{key} + \end{enumerate} + There are many \meta{options} that can be passed to a newly created + axis. They are explained in the rest of this section. +\end{key} +Note the |new axis base| does \emph{not} cause attributes to be mapped to +positions on a page. Rather, special keys like |new Cartesian axis| +first use |new axis base| to create an axis and then create an internal +object that performs a linear mapping of the attribute to +positions along a vectors. + + +\subsubsection{The Axis Attribute} +\label{section-dv-axis-attribute} + +The first main job of an axis is to map the different values of some +attribute to a reasonable interval. To achieve this, the following +options are important (recall that these options are passed to the key +whose name is the name of the axis): + +\begin{key}{/tikz/data visualization/axis options/attribute=\meta{attribute}} + Specifies that the axis is used to transform the data points + according the different values of the key + |/data point/|\meta{attribute}. For instance, when we create a + classical two-dimensional Cartesian coordinate system, then there + are two axes called |x axis| and |y axis| that monitor the values of + the attributes |/data point/x| and |/data point/y|, respectively: +\begin{codeexample}[code only] + [new axis base=x axis, + new axis base=y axis, + x axis={attribute=x}, + y axis={attribute=y}] +\end{codeexample} + In another example, we also create an |x axis| and a + |y axis|. However, this time, we want to plot the values of the + |/data point/time| attribute on the $x$-axis and, say, the value of + the |height| attribute on the $y$-axis: +\begin{codeexample}[code only] + [new axis base=x axis, + new axis base=y axis, + x axis={attribute=time}, + y axis={attribute=height}] +\end{codeexample} + During the data visualization, the \meta{attribute} will be + ``monitored'' during the survey phase. This means that for each data + point, the current value of |/data point/|\meta{attribute} is + examined and the minimum value of all of these values as well as the + maximum value is recorded internally. Note that this works even when + very large numbers like |100000000000| are involved. + + Here is a real-life example. The |scientific axes| create two axes, + called |x axis| and |y axis|, respectively. +\begin{codeexample}[] +\tikz \datavisualization [scientific axes, + x axis={attribute=people, length=2.5cm, ticks=few}, + y axis={attribute=year}, + visualize as scatter] + data { + year, people + 1900, 100 + 1910, 200 + 1950, 200 + 1960, 250 + 2000, 150 + }; +\end{codeexample} +\end{key} -\subsection{Concepts} -\subsubsection{Axes} +\subsubsection{The Axis Attribute Range Interval} + +Once an attribute has been specified for an axis, the data +visualization engine will start monitoring this value. This means that +before anything actual visualization is done, a ``survey phase'' is +used to determine the range of values encountered for the attribute +for all data points. This range of values results in what is called +the \emph{attribute range interval}. Its minimum is the smallest value +encountered in the data and its maximum is the largest value. + +Even though the attribute range interval is computed automatically and +even though you typically do not need to worry about it, there are +some situations where you may wish to set or enlarge the attribute +range interval: +\begin{itemize} +\item You may wish to start the interval with $0$, even though the + range of values contains only positive values. +\item You may wish to slightly enlarge the interval so that, say, the + maximum is some ``nice'' value like |100| or |60|. +\end{itemize} + +The following keys can be used to influence the size of the attribute +range interval: +\begin{key}{/tikz/data visualization/axis options/include + value=\meta{list of value}} + This key ``fakes'' data points for which the attribute's values are + in the comma-separated \meta{list of values}. For instance, when you + write |include value=0|, then the attribute range interval is + guaranteed to contain |0| -- even if the actual data points are all + positive or all negative. +\begin{codeexample}[] +\tikz \datavisualization [scientific axes, all axes={length=3cm}, + visualize as line] + data [format=function] { + var x : interval [5:10]; + func y = \value x * \value x; + }; +\end{codeexample} +\begin{codeexample}[] +\tikz \datavisualization [scientific axes, all axes={length=3cm}, + visualize as line, + x axis={include value=20}, + y axis={include value=0}] + data [format=function] { + var x : interval [5:10]; + func y = \value x * \value x; + }; +\end{codeexample} +\end{key} -\subsubsection{Mayor, Minor, and Subminor Ticks} +\begin{key}{/tikz/data visualization/axis options/min value=\meta{value}} + This key allows you to simply set the minimum value, regardless of + which values are present in the actual data. This key should be used + with care: If there are data points for which the attribute's value + is less than \meta{value}, they will still be depicted, but + typically outside the normal visualization area. Usually, saying + |include value=|\meta{value} will achieve the same as saying + |min value=|\meta{value}, but with less danger of creating + ill-formed visualizations. +\end{key} -\subsubsection{Tick Placement Strategies} -\label{section-dv-concept-tick-placement-strategies} +\begin{key}{/tikz/data visualization/axis options/max value=\meta{value}} + Works like |min value|. +\end{key} -Consider the following problem: The data visualization engine -determines that in a -plot the $x$-values vary between $17.4$ and $34.5$. In this case, we -certainly do not want, say, ten ticks at exactly ten evenly spaced -positions starting with $17.4$ and ending with $34.5$, because this -would yield ticks at positions like $32.6$. Ticks should be placed at -``nice'' positions like $20$, $25$, and $30$. -Determining which positions are ``nice'' is somewhat difficult. In the -above example, the positions $20$, $25$, and $30$ are certainly nice, -but only three ticks may be a bit few of them. Better might be the -tick positions $17.5$, $20$, $22.5$, through to $32.5$. However, users -might prefer even numbers over fractions like $2.5$ as the stepping. +\subsubsection{Scaling: The General Mechanism} -A \emph{tick placement strategy} is a method of automatically deciding -which positions are \emph{good} for placing ticks. The data -visualization engine comes with a number of predefined strategies, see -Section~\ref{section-dv-tick-placement-strategies}, but you can also -define new ones yourself. When the data visualization is requested to -automatically determine -``good'' positions for the placement of ticks on an axis, it uses one -of several possible \emph{basic strategies}. These strategies differ -dramatically in which tick positions they will choose: For a range of -values between $5$ and $1000$, a |linear steps| strategy might place -ticks at positions $100$, $200$, through to $1000$, while an -|exponential steps| strategy would prefer the tick positions $10$, -$100$ and $1000$. The exact number and values of the tick positions -chosen by either strategy can be fine-tuned using additional options -like |step| or |about|. +The above key allows us specify which attribute should be +``monitored''. The next key is used to specify what should happen with +the observed values. -Here is an example of the different stepping chosen when one varies -the tick placement strategy: +\begin{key}{/tikz/data visualization/axis options/scaling=\meta{scaling spec}} + The \meta{scaling spec} must have the following form: + \begin{quote} + \meta{$s_1$}| at |\meta{$t_1$}| and |\meta{$s_2$}| at |\meta{$t_2$} + \end{quote} + This means that monitored values in the interval $[s_1,s_2]$ should + be mapped to values the ``reasonable'' interval $[t_1,t_2]$, + instead. For instance, we might write +\begin{codeexample}[code only] +[y axis = {scaling = 1900 at 0cm and 2000 at 5cm}] +\end{codeexample} + in order to map dates between 1900 and 2000 to the dimension + interval $[0\mathrm{cm},5\mathrm{cm}]$. +\begin{codeexample}[] +\tikz \datavisualization + [scientific axes, + x axis={attribute=people, length=2.5cm, ticks=few}, + y axis={attribute=year, scaling=1900 at 0cm and 2000 at 5cm}, + visualize as scatter] + data { + year, people + 1900, 100 + 1910, 200 + 1950, 200 + 1960, 250 + 2000, 150 + }; +\end{codeexample} + So much for the basic idea. Let us now have a detailed look at what + happens. + \medskip + \textbf{Number format and the min and max keywords.} + The source values $s_1$ and $s_2$ are typically just numbers like + |3.14| or |10000000000|. However, as described in + Section~\ref{section-dv-expressions}, you can also specify + expressions like |(pi/2)|, provided that (currently) you put them in + parentheses. + + Instead of a number, you may alternatively also use the two key + words |min| and |max| for $s_1$ and/or $s_2$. In this case, |min| + evaluates to the smallest value observed for the attribute in the + data, symmetrically |max| evaluates to the largest values. For + instance, in the above example with the |year| attribute ranging + from |1900| to |2000|, the keyword |min| would stand for |1900| and + |max| for |2000|. Similarly, for the |people| attribute |min| stands + for |100| and |max| for |250|. Note that |min| and |max| can only be + used for $s_1$ and $s_2$, not for $t_1$ and $t_2$. + + A typical use of the |min| and |max| keywords is to say +\begin{codeexample}[code only] +scaling = min at 0cm and max at 5cm +\end{codeexample} + to map the complete range of values into an interval of length of + 5cm. + + The interval $[s_1,s_2]$ need not contain all values that the + \meta{attribute} may attain. It is permissible that values are less + than $s_1$ or more than $s_2$. + + \medskip + \textbf{Linear transformation of the attribute.} + As indicated earlier, the main job of an axis is to map values from + a ``large'' interval $[s_1,s_2]$ to a more reasonable interval + $[t_1,t_2]$. Suppose + that for the current data point the value of the key + |/data point/|\meta{attribute} is the number $v$. In the simplest + case, the following happens: A new value $v'$ is computed so that + $v' = t_1$ when $v=s_1$ and $v'=t_2$ when $v=s_2$ and $v'$ is some + value in between $t_1$ and $t_2$ then $v$ is some value in between + $s_1$ and $s_2$. (Formally, in this basic case $v' = t_1 + + (v-s_1)\frac{t_2-t_1}{s_2-s_1}$.) + + Once $v'$ has been computed, it is stored in the key + |/data point/|\meta{attribute}|/scaled|. Thus, the ``reasonable'' + value $v'$ does not replace the value of the attribute, but it is + placed in a different key. This means that both the original value + and the more ``scaled'' values are available when the data point is + visualized. + + As an example, suppose you have written +\begin{codeexample}[code only] +[x axis = {attribute = x, scaling=1000 at 20 and 2000 at 30}] +\end{codeexample} + Now suppose that |/data point/x| equals |1200| for a data + point. Then the key |/data point/x/scaled| will be set to |22| when + the data point is being visualized. + + \medskip + \textbf{Nonlinear transformations of the attribute.} + By default, the transformation of $[s_1,s_2]$ to $[t_1,t_2]$ is the + linear transformation described above. However, in some case you may + be interested in a different kind of transformation: For example, in + a logarithmic plot, values of an attribute may range between, say, + |1| and |1000| and we want an axis of length |3cm|. So, we would + write + \begin{codeexample}[code only] +[x axis = {attribute = x, scaling=1 at 0cm and 1000 at 3cm}] + \end{codeexample} + Indeed, |1| will now be mapped to position |0cm| and |1000| will be + mapped to position |3cm|. Now, the value |10| will be mapped to + approximately |0.03cm| because it is (almost) at one percent between + |1| and |1000|. However, in a logarithmic plot we actually want |10| + to be mapped to the position |1cm| rather than |0.03cm| and we want + |100| to be mapped to the position |2cm|. Such a mapping a + \emph{nonlinear} mapping between the intervals. + + In order to achieve such a nonlinear mapping, the |function| key can + be used, whose syntax is described in a moment. The effect of this key is + to specify a function $f \colon \mathbb R \to \mathbb R$ like, say, + the logarithm function. When such a function is specified, the + mapping of $v$ to $v'$ is computed as follows: + \begin{align*} + v' = t_1 + (f(s_2) - f(v))\frac{t_2 - t_1}{f(s_2)-f(s_1)}. + \end{align*} + + The syntax of the |function| key is described next, but you + typically will not call this key directly. Rather, you will use a + key like |logarithmic| that installs appropriate code for the + |function| key for you. + \begin{key}{/tikz/data visualization/axis options/function=\meta{code}} + The \meta{code} should specify a function $f$ that is applied + during the transformation of the interval $[s_1,s_2]$ to the + interval $[t_1,t_2]$ in the following way: When the \meta{code} is + called, the macro |\pgfvalue| will have been set to an internal + representation of the to-be-transformed value~$v$. You can then + call the commands of the math-micro-kernel of the data + visualization system, see Section~\ref{section-dv-math-kernel}, to + compute a new value. This new value must once more be stored in + |\pgfvalue|. + + The most common use of this key is to say +\begin{codeexample}[code only] +some axis={function=\pgfdvmathln{\pgfvalue}{\pgfvalue}} +\end{codeexample} + This specifies that the function $f$ is the logarithm + function. \begin{codeexample}[] -\begin{tikzpicture} - \datavisualization [scientific axes, visualize as smooth line] - data [format=function] { - var x : interval [1:11]; - func y = \value x*\value x; +\tikz \datavisualization + [scientific axes, + x axis={ticks={major={at={1,10,100,1000}}}, + scaling=1 at 0cm and 1000 at 3cm, + function=\pgfdvmathln{\pgfvalue}{\pgfvalue}}, + visualize as scatter] + data [format=named] { + x={1,100,...,1000}, y={1,2,3} + }; +\end{codeexample} + Another possibility might be to use the square-root function, instead: +\begin{codeexample}[] +\tikz \datavisualization + [scientific axes, + x axis={ticks=few, + scaling=1 at 0cm and 1000 at 3cm, + function=\pgfdvmathunaryop{\pgfvalue}{sqrt}{\pgfvalue}}, + visualize as scatter] + data [format=named] { + x={0,100,...,1000}, y={1,2,3} + }; +\end{codeexample} + \end{key} + + \medskip + \textbf{Default scaling.} + When no scaling is specified, it may seem natural to use $[0,1]$ + both as the source and the target interval. However, this would not + work when the logarithm function is used as transformations: In this + case the logarithm of zero would be computed, leading to an + error. Indeed, for a logarithmic axis it is far more natural to use + $[1,10]$ as the source interval and $[0,1]$ as the target interval. + + For these reasons, the default value for the |scaling| that is used + when no value is specified explicitly can be set using a special + key: + \begin{key}{/tikz/data visualization/axis options/scaling/default=\meta{text}} + The \meta{text} is used as |scaling| whenever no other scaling is + specified. This key is mainly used when a transformation function + is set using |function|; normally, you will not use this key + directly. + \end{key} +\end{key} + +Most of the time, you will not use neither the |scaling| nor the +|function| key directly, but rather you will use one of the following +predefined styles documented in the following. + + +\subsubsection{Scaling: Logarithmic Axes} + +\begin{key}{/tikz/data visualization/axis options/logarithmic} + When this key is used with an axis, three things happen: + \begin{enumerate} + \item The transformation |function| of the axis is setup to the + logarithm. + \item The strategy for automatically generating ticks and grid lines + is set to the |exponential strategy|, see + Section~\ref{section-dv-exponential-strategy} for details. + \item The default scaling is setup sensibly. + \end{enumerate} + All told, to turn an axis into a logarithmic axis, you just need to + add this option to the axis. +\begin{codeexample}[width=8cm] +\tikz \datavisualization [scientific axes, + x axis={logarithmic}, + y axis={logarithmic}, + visualize as line] + data [format=function] { + var x : interval [0.01:100]; + func y = \value x * \value x; + }; +\end{codeexample} + Note that this will work with any axis, + including, say, the degrees on a polar axis: +\begin{codeexample}[] +\tikz \datavisualization + [new polar axes, + angle axis={logarithmic, scaling=1 at 0 and 90 at 90}, + radius axis={scaling=0 at 0cm and 100 at 3cm}, + visualize as scatter] + data [format=named] { + angle={1,10,...,90}, radius={1,10,...,100} + }; +\end{codeexample} +\begin{codeexample}[] +\tikz \datavisualization + [new polar axes, + angle axis={degrees}, + radius axis={logarithmic, scaling=1 at 0cm and 100 at 3cm}, + visualize as scatter] + data [format=named] { + angle={1,10,...,90}, radius={1,10,...,100} + }; +\end{codeexample} +\end{key} + + + +\subsubsection{Scaling: Setting the Length or Unit Length} + +\begin{key}{/tikz/data visualization/axis options/length=\meta{dimension}} + Sets |scaling| to |min at 0cm and max at |\meta{dimension}. The + effect is that the range of all values of the axis's attribute will + be mapped to an interval of exact length \meta{dimension}. + +\begin{codeexample}[] +\tikz \datavisualization [scientific axes, + x axis={length=3cm}, + y axis={length=2cm}, + all axes={ticks=few}, + visualize as line] + data { + x, y + 10, 10 + 20, 20 + 15, 30 + 13, 20 }; -\end{tikzpicture} -\qquad -\begin{tikzpicture} - \datavisualization [scientific axes, visualize as smooth line, - y axis={exponential steps}, - x axis={ticks={quarter about strategy}}, - ] - data [format=function] { - var x : interval [1:11]; - func y = \value x*\value x; +\end{codeexample} +\begin{codeexample}[] +\tikz \datavisualization [scientific axes, + x axis={length=3cm}, + y axis={length=4cm}, + all axes={ticks=few}, + visualize as line] + data { + x, y + 10, 10 + 20, 20 + 15, 30 + 13, 20 + }; +\end{codeexample} + +\end{key} + +\begin{key}{/tikz/data visualization/axis + options/unit length=\meta{dimension}\opt{| per |\meta{number}| units|}} + Sets |scaling| to |0 at 0cm and 1 at |\meta{dimension}. In other + words, this key allows you to specify how long a single unit should + be. This key is particularly useful when you wish to ensure that the + same scaling is used across multiple axes or pictures. +\begin{codeexample}[] +\tikz \datavisualization [scientific axes, + all axes={ticks=few, unit length=1mm}, + visualize as line] + data { + x, y + 10, 10 + 40, 20 + 15, 30 + 13, 20 }; +\end{codeexample} + The optional |per |\meta{number}| units| allows you to apply more + drastic scaling. Suppose that you want to plot a graph where one + billion corresponds to one centimeter. Then the unit length would be + need to be set to a hundredth of a nanometer -- much too small for + \TeX\ to handle as a dimension. In this case, you can write + |unit length=1cm per 1000000000 units|: +\begin{codeexample}[] +\tikz \datavisualization + [scientific axes, + x axis={unit length=1mm per 1000000000 units, ticks=few}, + visualize as line] + data { + x, y + 10000000000, 10 + 40000000000, 20 + 15000000000, 30 + 13000000000, 20 + }; +\end{codeexample} +\end{key} +\begin{key}{/tikz/data visualization/axis + options/power unit length=\meta{dimension}} + This key is used in conjunction with the |logarithmic| setting. It + cases the |scaling| to be set to + |1 at 0cm and 10 at |\meta{dimension}. This causes a ``power unit,'' + that is, one power of ten in a logarithmic plot, to get a length of + \meta{dimension}. Again, this key is useful for ensuring that the + same scaling is used across multiple axes or pictures. +\begin{codeexample}[width=8cm] +\tikz \datavisualization + [scientific axes, + y axis={logarithmic, power unit length=1mm, grid}, + visualize as line] + data { + x, y + 0, 0.0000000001 + 1, 1 + 2, 100000 + 3, 100000000000 + 4, 10000000000000000000000000000000 + 5, 500000000 + 6, 5000000000000000000 + }; +\end{codeexample} +\end{key} + + + +\subsubsection{Axis Label} + +An axis can have a \emph{label}, which is a textual representation of +the attribute according to which the axis varies the position of the +page. You can set the attribute using the following key: + +\begin{key}{/tikz/data visualization/axis + options/label=\opt{|\char`\{[|\meta{options}|]|}\meta{text}\opt{|\char`\}|} + (default \normalfont axis's label in math mode)} + This key sets the label of an axis to \meta{text}. This text will + typically be placed inside a |node| and the \meta{options} can be + used to further configure the way this node is rendered. The + \meta{options} will be executed with the path prefix + |/tikz/data visualization/|, so you need to say |node style| to + configure the styling of a node, see Section~\ref{section-dv-style}. +\begin{codeexample}[] +\tikz \datavisualization [ + scientific axes, + x axis = {label, length=2.5cm}, + y axis = {label={[node style={fill=blue!20}]{$x^2$}}}, + visualize as smooth line] + data [format=function] { + var x : interval [-3:5]; + func y = \value x * \value x; + }; +\end{codeexample} +\end{key} + +Note that using the |label| key does not actually cause a node to be +created, because it is somewhat unclear where the label should be +placed. Instead, the |visualize label| key is used (typically +internally by an axis system) to show the label at some sensible +position. This key is documented in +Section~\ref{section-dv-visualize-label}. + + + +\subsubsection{Reference: Axis Types} + +\label{section-dv-reference-axis-types} + +As explained earlier, when you use |new axis base| to create a new axis, +a powerful scaling and attribute mapping mechanism is installed, but +no mapping of values to positions on the page is performed. For this, +a \emph{transformation object} must be installed. The following keys +take care of this for you. Note, however, that even these keys do not +cause a visual representation of the axis to be added to the +visualization -- this is the job of an axis system, see +Section~\ref{section-dv-axis-systems}. + +\begin{key}{/tikz/data visualization/new Cartesian axis=\meta{name}} + This key creates a new ``Cartesian'' axis, named \meta{name}. For + such an axis, the (scaled) values of the axis's attribute are + transformed into a displacement on the page along a straight + line. The following key is used to configure in which ``direction'' + the axis points: + \begin{key}{/tikz/data visualization/axis options/unit + vector=\meta{coordinate} (initially {(1pt,0pt)})} + Recall that an axis takes the values of an attribute and rescales + them so that they fit into a ``reasonable'' interval + $[t_1,t_2]$. Suppose that $v'$ is the rescaled dimension in (\TeX) + points. Then when the data point is visualized, the coordinate + system will be shifted by $v'$ times the \meta{coordinate}. + + As an example, suppose that you have said + |scaling=0 and 10pt and 50 and 20pt|. Then when the underlying + attribute has the value |25|, it will be mapped to a $v'$ of $15$ + (because |25| lies in the middle of |0| and |50| and |15pt| lies + in the middle of |10pt| and |20pt|). This, in turn, causes the + data point to be displaced by $15$ times the \meta{coordinate}. + + The bottom line is that the \meta{coordinate} should usually + denote a point that is at distance |1pt| from the origin and that + points into the direction of the axis. +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + + \datavisualization + [new Cartesian axis=x axis, x axis={attribute=x}, + new Cartesian axis=y axis, y axis={attribute=y}, + x axis={unit vector=(0:1pt)}, + y axis={unit vector=(60:1pt)}, + visualize as scatter] + data { + x, y + 0, 0 + 1, 0 + 2, 0 + 1, 1 + 2, 1 + 1, 1.5 + 2, 1.5 + }; \end{tikzpicture} \end{codeexample} +\end{key} +\end{key} -\subsubsection{Grids} +\subsection{Axis Systems} +\label{section-dv-axis-systems} -\subsection{Usage} +An \emph{axis system} is, as the name suggests, a whole family of axes +that act in concert. For example, in the ``standard'' axis system there +is a horizontal axis called the $x$-axis that monitors the |x| +attribute (by default, you can change this easily) and a vertical axis +called the $y$-axis. Furthermore, a certain number of ticks are added +and labels are placed at sensible positions. -\subsection{Reference: Standard Axis Systems} +\subsubsection{Usage} -In this section the axis system commonly used in data visualizations -are described. +Using an axis system is usually pretty easy: You just specify a key +like |scientific axes| and the necessary axes get initialized with +sensible default values. You can then start to modify these default +values, if necessary. -\subsubsection{Scientific Axis Systems} +First, you can (and should) set the attributes to which the difference +axes refer. For instance, if the |time| attribute is plotted along the +$x$-axis, you would write +\begin{codeexample}[code only] +x axis = {attribute = time} +\end{codeexample} + +Second, you may wish to modify the lengths of the axes. For this, you +can use keys like |length| or further keys as described in the +references later on. + +Third, you may often wish to modify how many ticks and grid lines are +shown. By default, no grid lines are shown, but you can say the +following in order to cause grid lines to be shown: +\begin{codeexample}[code only] +all axes={grid} +\end{codeexample} +Naturally, instead of |all axes| you can also specify a single axis, +causing only grid lines to be shown for this axis. +In order to change the number of ticks that are shown, you can say +\begin{codeexample}[code only] +all axes={ticks=few} +\end{codeexample} +or also |many| instead of |few| or even |none|. Far more fine-grained +control over the tick placement and rendering is possible, +see Section~\ref{section-dv-ticks-and-grids} for details. + +Fourth, consider adding units (like ``cm'' for centimeters or +``$\mathrm m/\mathrm s^2$'' for acceleration) to your ticks: +\begin{codeexample}[code only] +x axis={ticks={tick unit=cm}}, y axis={ticks={tick unit=m/s^2}} +\end{codeexample} + + +Finally, consider adding labels to your axes. For this, use the label +option: +\begin{codeexample}[code only] +x axes={time $t$ (ms)}, y axis={distance $d$ (mm)} +\end{codeexample} + +Here is an example that employs most of the above features: + +\begin{codeexample}[width=8.5cm] +\tikz \datavisualization [ + scientific axes=clean, + x axis={attribute=time, ticks={tick unit=ms}, + label={elapsed time}}, + y axis={attribute=v, ticks={tick unit=m/s}, + label={speed of disc}}, + all axes=grid, + visualize as line] +data { + time, v + 0, 0 + 1, 0.001 + 2, 0.002 + 3, 0.004 + 4, 0.0035 + 5, 0.0085 + 6, 0.0135 +}; +\end{codeexample} -\begin{key}{/tikz/data visualization/scientific axes} + + +\subsubsection{Reference: Scientific Axis Systems} + +\begin{key}{/tikz/data visualization/scientific axes=\opt{\meta{options}}} This key installs a two-dimensional coordinate system based on the attributes |/data point/x| and |/data point/y|. -\begin{codeexample}[] +\begin{codeexample}[width=7cm] \begin{tikzpicture} - \datavisualization [scientific axes, visualize as smooth line] + \datavisualization [scientific axes, + visualize as smooth line] data [format=function] { var x : interval [0:100]; func y = sqrt(\value x); @@ -113,7 +814,14 @@ are described. be. The name |scientific axes| is intended to indicate that this axis system is often used in scientific publications. - Note, however, that this axis system will always distort the + You can use the \meta{options} to fine tune the axis system. The + \meta{options} will be executed with the following path prefix: +\begin{codeexample}[code only] +/tikz/data visualization/scientific axes +\end{codeexample} + All keys with this prefix can thus be passed as \meta{options}. + + This axis system will always distort the relative magnitudes of the units on the two axis. If you wish the units on both axes to be equal, consider directly specifying the unit length ``by hand'': @@ -149,20 +857,45 @@ are described. origin. The maximum value is at the top of the axis. \item Lines (forming a frame) are depicted at the minimum and maximum values of the axes in 50\% black. - \item Ticks are drawn `` on the outside'' of the frame so that they - interfere as little as possible with the data. - \item Tick labels and axis labels (if present) are drawn left and - below. \end{itemize} + + The following keys are executed by default as options: |outer ticks| + and |standard labels|. + + You can use the following style to overrule the defaults: + + \begin{stylekey}{/tikz/data visualization/every scientific axes} + \end{stylekey} +\end{key} + +The keys described in the following can be used to fine-tune the way +the scientific axis system is rendered. + +\begin{key}{/tikz/data visualization/scientific axes/outer ticks} + This causes the ticks to be drawn `` on the outside'' of the frame + so that they interfere as little as possible with the data. It is + the default. + +\begin{codeexample}[width=7cm] +\begin{tikzpicture} + \datavisualization [scientific axes=outer ticks, + visualize as smooth line] + data [format=function] { + var x : interval [-12:12]; + func y = \value x*\value x*\value x; + }; +\end{tikzpicture} +\end{codeexample} \end{key} -\begin{key}{/tikz/data visualization/scientific inner axes} +\begin{key}{/tikz/data visualization/scientific axes/inner ticks} This axis system works like |scientific axes|, only the ticks are on the ``inside'' of the frame. -\begin{codeexample}[] +\begin{codeexample}[width=7cm] \begin{tikzpicture} - \datavisualization [scientific inner axes, visualize as smooth line] + \datavisualization [scientific axes=inner ticks, + visualize as smooth line] data [format=function] { var x : interval [-12:12]; func y = \value x*\value x*\value x; @@ -175,16 +908,17 @@ are described. seen in the following example: \begin{codeexample}[] \begin{tikzpicture} - \datavisualization [scientific inner axes, scientific axes/width=3.2cm, + \datavisualization [scientific axes={inner ticks, width=3.2cm}, + style sheet=cross marks, visualize as scatter/.list={a,b}] - data [a] { + data [set=a] { x, y 0, 0 1, 1 0.5, 0.5 2, 1 } - data [b] { + data [set=b] { x, y 0.05, 0 1.5, 1 @@ -196,20 +930,19 @@ are described. \end{key} -\begin{key}{/tikz/data visualization/scientific clean axes} - This axis system is another version of |scientific axes|. However, the - axes and the ticks are completely removed from the actual data, +\begin{key}{/tikz/data visualization/scientific axes/clean} + The axes and the ticks are completely removed from the actual data, making this axis system especially useful for scatter plots, but also for most other scientific plots. -\begin{codeexample}[] -\begin{tikzpicture} - \datavisualization [scientific clean axes, visualize as smooth line] - data [format=function] { - var x : interval [-12:12]; - func y = \value x*\value x*\value x; - }; -\end{tikzpicture} +\begin{codeexample}[width=7.5cm] +\tikz \datavisualization [ + scientific axes=clean, + visualize as smooth line] +data [format=function] { + var x : interval [-12:12]; + func y = \value x*\value x*\value x; +}; \end{codeexample} The distance of the axes from the actual plot is given by the @@ -220,72 +953,68 @@ are described. For all scientific axis systems, different label placement strategies can be specified. They are discussed in the following. - -\begin{key}{/tikz/data visualization/scientific axes standard labels} +\begin{key}{/tikz/data visualization/scientific axes/standard labels} As the name suggests, this is the standard placement strategy. The label of the $x$-axis is placed below the center of the $x$-axis, the label of the $y$-axis is rotated by $90^\circ$ and placed left of the center of the $y$-axis. -\begin{codeexample}[] -\begin{tikzpicture} - \datavisualization [scientific clean axes, - visualize as smooth line, - scientific axes standard labels, - x axis={label=degree $d$, ticks={tick unit=${}^\circ$}}, - y axis={label=$\sin d$}] - data [format=function] { - var x : interval [-10:10] samples 10; - func y = sin(\value x); - }; -\end{tikzpicture} +\begin{codeexample}[width=8cm] +\tikz \datavisualization + [scientific axes={clean, standard labels}, + visualize as smooth line, + x axis={label=degree $d$, + ticks={tick unit={}^\circ}}, + y axis={label=$\sin d$}] +data [format=function] { + var x : interval [-10:10] samples 10; + func y = sin(\value x); +}; \end{codeexample} \end{key} -\begin{key}{/tikz/data visualization/scientific axes upright labels} +\begin{key}{/tikz/data visualization/scientific axes/upright labels} Works like |scientific axes standard labels|, only the label of the $y$-axis is not rotated. -\begin{codeexample}[] -\begin{tikzpicture} - \datavisualization [scientific clean axes, - visualize as smooth line, - scientific axes upright labels, - x axis={label=degree $d$, ticks={tick unit=${}^\circ$}}, - y axis={label=$\cos d$, - ticks={style={/pgf/number format/.cd,precision=4,fixed zerofill}}}] - data [format=function] { - var x : interval [-10:10] samples 10; - func y = cos(\value x); - }; -\end{tikzpicture} +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes={clean, upright labels}, + visualize as smooth line, + x axis={label=degree $d$, + ticks={tick unit={}^\circ}}, + y axis={label=$\cos d$, include value=1, + ticks={style={ + /pgf/number format/precision=4, + /pgf/number format/fixed zerofill}}}] +data [format=function] { + var x : interval [-10:10] samples 10; + func y = cos(\value x); +}; \end{codeexample} \end{key} -\begin{key}{/tikz/data visualization/scientific axes end labels} +\begin{key}{/tikz/data visualization/scientific axes/end labels} Places the labels at the end of the $x$- and the $y$-axis, similar to the axis labels of a school book axis system. -\begin{codeexample}[] -\begin{tikzpicture} - \datavisualization [scientific clean axes, - visualize as smooth line, - scientific axes end labels, - x axis={label=degree $d$, ticks={tick unit=${}^\circ$}}, - y axis={label=$\tan d$}] - data [format=function] { - var x : interval [-10:10] samples 10; - func y = tan(\value x); - }; -\end{tikzpicture} +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes={clean, end labels}, + visualize as smooth line, + x axis={label=degree $d$, + ticks={tick unit={}^\circ}}, + y axis={label=$\tan d$}] +data [format=function] { + var x : interval [-80:80]; + func y = tan(\value x); +}; \end{codeexample} \end{key} +\subsubsection{Reference: School Book Axis Systems} - -\subsubsection{School Book Axis Systems} - -\begin{key}{/tikz/data visualization/school book axes} +\begin{key}{/tikz/data visualization/school book axes=\meta{options}} This axis system is intended to ``look like'' the coordinate systems often used in school books: The axes are drawn in such a way that they intersect to origin. Furthermore, no automatic @@ -313,21 +1042,39 @@ can be specified. They are discussed in the following. The stepping of the ticks is one unit by default. Using keys like |ticks=some| may help to give better steppings. -\end{key} - + + The \meta{options} are executed with the key itself as path + prefix. Thus, the following subkeys are permissible options: + \begin{key}{/tikz/data visualization/school book axes/unit=\meta{value}} + Sets the scaling so that 1\,cm corresponds to \meta{value} + units. At the same time, the stepping of the ticks will also be + set to \meta{value}. +\begin{codeexample}[] +\begin{tikzpicture} + \datavisualization [school book axes={unit=10}, + visualize as smooth line, + clean ticks, + x axis={label=$x$}, + y axis={label=$f(x)$}] + data [format=function] { + var x : interval [-20:20]; + func y = \value x*\value x/10; + }; +\end{tikzpicture} +\end{codeexample} + \end{key} -\begin{key}{/tikz/data visualization/school book axes standard labels} - This key makes the label of the $x$-axis appear at the right end of - this axis and it makes the label of the $y$-axis appear at the top - of the $y$-axis. + \begin{key}{/tikz/data visualization/school book axes/standard labels} + This key makes the label of the $x$-axis appear at the right end of + this axis and it makes the label of the $y$-axis appear at the top + of the $y$-axis. - Currently, this is the only supported placement strategy for the - school book axis system. + Currently, this is the only supported placement strategy for the + school book axis system. \begin{codeexample}[] \begin{tikzpicture} - \datavisualization [school book axes, + \datavisualization [school book axes={standard labels}, visualize as smooth line, - school book axes standard labels, clean ticks, x axis={label=$x$}, y axis={label=$f(x)$}] @@ -337,13 +1084,12 @@ can be specified. They are discussed in the following. }; \end{tikzpicture} \end{codeexample} + \end{key} \end{key} - - -\subsubsection{Advanced: Underlying Cartesian Axis Systems} +\subsubsection{Advanced Reference: Underlying Cartesian Axis Systems} The axis systems described in the following are typically not used directly by the user. The systems setup \emph{directions} for several @@ -418,116 +1164,249 @@ positions. -\subsection{Reference: Tick Placement Strategies} -\label{section-dv-tick-placement-strategies} +\subsection{Ticks and Grids} +\label{section-dv-ticks-and-grids} + + +\subsubsection{Concepts} + +A \emph{tick} is a small visual indication on an axis of the value of +the axis's attribute at the position where the tick is shown. A tick +may be accompanied additionally by a textual representation, but it +need not. A \emph{grid line} is similar to a tick, but it is not an +indication on the axis, but rather a whole line that indicates all +positions where the attribute has a certain value. Unlike ticks, +grid lines (currently) are not accompanied by a textual +representation. + +Just as for axes, the data visualization system decouples the +specification of which ticks are present \emph{in principle} from +where they are visualized. In the following, I describe how you +specify which ticks and grid lines you would like to be drawn and how +they should look like (their styling). The axis system of your choice +will then visualize the ticks at a sensible position for the chosen +system. For details on how to change where whole axis is shown along +with its ticks, see Section~\ref{section-dv-visualize-ticks}. + +Specifying which ticks you are interested in is done as follows: +First, you use |ticks| key (or, for specifying which grid lines should +be present, the |grid| key). This key takes several possible options, +described in detail in the following, which have different effects: +\begin{enumerate} +\item Keys like |step=10| or |minor steps between steps| cause a + ``semi-automatic'' computation of possible steps. Here, you + explicitly specify the stepping of steps, but the first stepping and + their number are computed automatically according to the range of + possible values for the attribute. +\item Keys like |few|, |some|, or |many| can be passed to |ticks| in + order to have \tikzname\ compute good tick positions + automatically. This is usually what you want to happen, which is why + most axis system will implicitly say |ticks={some}|. +\item Keys like |at| or |also at| provide ``absolute control'' over + which ticks or grid lines are shown. For these keys, you can not only + specify at what value a tick should be shown, but also its styling + and also whether it is a major, minor, or subminor tick or grid line. +\end{enumerate} + +In the following, the main keys |ticks| and |grids| are documented +first. Then the different kinds of ways of specifying where ticks or +grid lines should be shown are explained. + + +\subsubsection{The Main Options: Tick and Grid} + +\begin{key}{/tikz/data visualization/axis options/ticks=\meta{options} + (default some)} + This key can be passed to an axis in order to configure which ticks + are present for the axis. The possible \meta{options} include, for + instance, keys like |step|, which is used to specify a stepping for + the ticks, but also keys like |major| or |minor| for specifying the + positions of major and minor ticks in detail. The list of possible + options is described in the rest of this section. + + Note that the |ticks| option will only configure which ticks should + be shown in principle. The actual rendering is done only when the + |visualize ticks| key is used, documented in + Section~\ref{section-dv-visualize-ticks}, which is typically done + only internally by an axis system. + + The \meta{options} will be executed with the path prefix + |/tikz/data visualization/|. When the |ticks| key is used multiple + times for an axis, the \meta{options} accumulate. +\begin{codeexample}[width=6cm] +\tikz \datavisualization [ + scientific axes, visualize as line, + x axis={ticks={step=24, minor steps between steps=3}, + label=hours}] + data { + x, y + 0, 0 + 10, 0 + 20, 0.5 + 30, 0.75 + 40, 0.7 + 50, 0.6 + 60, 0.5 + 70, 0.45 + 80, 0.47 + }; +\end{codeexample} +\end{key} -As described in \ref{section-dv-concept-tick-placement-strategies}, -it is not a trivial task for the data visualization engine to -correctly automatically determine good positions for the placement of -ticks on axes. When the values on an axis range between, say, $17.4$ -and $34.5$, it is somewhat unclear where ticks should be placed. +\begin{key}{/tikz/data visualization/axis options/grid=\meta{options} + (default at default ticks)} + This key is similar to |ticks|, only it is used to configure where + grid lines should be shown rather than ticks. In particular, the + options that can be passed to the |ticks| key can also be passed to + the |grid| key. Just like |ticks|, the \meta{options} only specify + which grid lines should be drawn in principle; it is the job of the + |visualize grid| key to actually cause any grid lines to be shown. + + If you do not specify any \meta{options}, the default text + |at default ticks| is used. This option causes grid lines to be + drawn at all positions where ticks are shown by default. Since this + usually exactly what you would like to happen, most of the time you + just need to |all axes=grid| to cause a grid to be shown. +\end{key} +\begin{key}{/tikz/data visualization/axis options/ticks and grid=\meta{options}} + This key passes the \meta{options} to both the |ticks| key and also + to the |grid| key. This is useful when you want to specify some + special points explicitly where you wish a tick to be shown and also + a grid line. +\begin{codeexample}[] +\tikz \datavisualization + [scientific axes, + visualize as smooth line, + all axes= {grid, unit length=1.25cm}, + y axis={ ticks=few }, + x axis={ ticks=many, ticks and grid={ major also at={(pi/2) as $\frac{\pi}{2}$}}}] + data [format=function] { + var x : interval [-pi/2:3*pi] samples 50; + func y = sin(\value x r); + }; +\end{codeexample} +\end{key} -\subsubsection{Predefined Strategies} -The following strategies are always available: +\subsubsection{Semi-Automatic Computation of Tick and Grid Line Positions} +\label{section-dv-concept-tick-placement-strategies} -\begin{key}{/tikz/data visualization/axis options/linear steps} - This strategy placed ticks at positions that are evenly spaced by - the current value of |step|. +Consider the following problem: The data visualization engine +determines that in a plot the $x$-values vary between $17.4$ and +$34.5$. In this case, we +certainly do not want, say, ten ticks at exactly ten evenly spaced +positions starting with $17.4$ and ending with $34.5$, because this +would yield ticks at positions like $32.6$. Ticks should be placed at +``nice'' positions like $20$, $25$, and $30$. - In detail, the following happens: Let $a$ be the minimum value of the - data values along the axis and let $b$ be the maximum. Let the - current \emph{stepping} be $s$ (the stepping is set using the |step| - option, see below) and let the current \emph{phasing} be $p$ (set - using the |phase|) option. Then ticks are placed all positions - $i\cdot s + p$ that lie in the interval $[a,b]$, where $i$ ranges - over all integers. +Determining which positions are ``nice'' is somewhat difficult. In the +above example, the positions $20$, $25$, and $30$ are certainly nice, +but only three ticks may be a bit few of them. Better might be the +tick positions $17.5$, $20$, $22.5$, through to $32.5$. However, users +might prefer even numbers over fractions like $2.5$ as the stepping. - The tick positions computed in the way described above are - \emph{mayor} step positions. In addition to these, if the key - |minor steps between steps| is set to some number $n$, then $n$ many - minor ticks are introduced between each two mayor ticks (and also - before and after the last mayor tick, provided the values still lie - in the interval $[a,b]$). Note that is $n$ is $1$, then one minor tick - will be added in the middle between any two mayor ticks. Use a value - of $9$ (not $10$) to partition the interval between two mayor ticks - into ten equally sized minor intervals. +A \emph{tick placement strategy} is a method of automatically deciding +which positions are \emph{good} for placing ticks. The data +visualization engine comes with a number of predefined strategies, but +you can also define new ones yourself. When the data visualization is +requested to automatically determine +``good'' positions for the placement of ticks on an axis, it uses one +of several possible \emph{basic strategies}. These strategies differ +dramatically in which tick positions they will choose: For a range of +values between $5$ and $1000$, a |linear steps| strategy might place +ticks at positions $100$, $200$, through to $1000$, while an +|exponential steps| strategy would prefer the tick positions $10$, +$100$ and $1000$. The exact number and values of the tick positions +chosen by either strategy can be fine-tuned using additional options +like |step| or |about|. + +Here is an example of the different stepping chosen when one varies +the tick placement strategy: \begin{codeexample}[] \begin{tikzpicture} - \datavisualization - [scientific inner axes, scientific axes/width=3cm, - x axis={ticks={step=3, minor steps between steps=2}}, - y axis={ticks={step=.36}}, - visualize as scatter] - data { - x, y - 17, 30 - 34, 32 + \datavisualization [scientific axes, visualize as smooth line] + data [format=function] { + var x : interval [1:11]; + func y = \value x*\value x; }; \end{tikzpicture} -\end{codeexample} -\end{key} - -\begin{key}{/tikz/data visualization/axis options/exponential steps} - This strategy produces ticks at positions that are appropriate for - logarithmic plots. It is automatically selected when you use the - |logarithmic| option with an axis. - - In detail, the following happens: As for |linear steps| let numbers - $a$, $b$, $s$, and $p$ be given. Then, mayor ticks are placed at all - positions $10^{i\cdot s+p}$ that lie in the interval $[a,b]$ for $i - \in \mathbb Z$. - - The minor steps are added in the same way as for |linear steps|. In - particular, they interpolate \emph{linearly} between mayor steps. - -\begin{codeexample}[] +\qquad \begin{tikzpicture} - \datavisualization - [scientific axes, - x axis={logarithmic, length=2cm, ticks={step=1.5}}, - y axis={logarithmic, ticks={step=1, minor steps between steps=9}}, - visualize as scatter] - data { - x, y - 1, 10 - 1000, 1000000 + \datavisualization [scientific axes, visualize as smooth line, + y axis={exponential steps}, + x axis={ticks={quarter about strategy}}, + ] + data [format=function] { + var x : interval [1:11]; + func y = \value x*\value x; }; \end{tikzpicture} \end{codeexample} -\end{key} - - - -\subsubsection{Choosing a Stepping Explicitly} +Two strategies are always available: |linear steps|, which yields +(semi)automatic ticks are evenly spaced positions, and +|exponential steps|, which yields (semi)automatic steps at positions +at exponentially increasing positions -- which is exactly what is +needed for logarithmic plots. These strategies are details in +Section~\ref{section-dv-strategies}. The following options are used to configure tick placement strategies like |linear steps|. Unlike the basic choice of a placement strategy, which is an axis option, the following should be passed to the option -|ticks| or |grid| only.. So, you would write -things like |x axis={ticks={step=2}}|, but |x axis=linear steps|. +|ticks| or |grid| only. So, you would write +things like |x axis={ticks={step=2}}|, but |x axis={linear steps}|. \begin{key}{/tikz/data visualization/step=\meta{value} (initially 1)} The value of this key is used to determine the spacing of the major ticks. The key is used by the |linear steps| and |exponential steps| - strategies described above, see the explanations there. + strategies, see the explanations in + Section~\ref{section-dv-strategies} for details. Basically, all + ticks are placed at all multiples of \meta{value} that lie in the + attribute range interval. +\begin{codeexample}[] +\tikz \datavisualization [ + school book axes, visualize as smooth line, + y axis={ticks={step=1.25}}, + ] + data [format=function] { + var x : interval [0:3]; + func y = \value x*\value x/2; + }; +\end{codeexample} \end{key} \begin{key}{/tikz/data visualization/minor steps between steps=\meta{number} (default 9)} - As for |step|, see the explanation of |linear steps|. + Specifies that between any two major steps (whose positions are + specified by the |step| key), there should be \meta{number} many + minor steps. Note that the default of |9| is exactly the right + number so that each interval between two minor steps is exactly a + tenth of the size of a major step. See also + Section~\ref{section-dv-strategies} for further details. +\begin{codeexample}[] +\begin{tikzpicture} + \datavisualization [school book axes, visualize as smooth line, + x axis={ticks={minor steps between steps=3}}, + y axis={ticks={minor steps between steps}}, + ] + data [format=function] { + var x : interval [-1.5:1.5]; + func y = \value x*\value x; + }; +\end{tikzpicture} +\end{codeexample} \end{key} \begin{key}{/tikz/data visualization/phase=\meta{value} (initially 0)} - As for |step|, see the explanation of |linear steps|. + See Section~\ref{section-dv-strategies} for details on how the phase + of steps influences the tick placement. \end{key} -\subsubsection{Choosing a Stepping Automatically} +\subsubsection{Automatic Computation of Tick and Grid Line Positions} The |step| option gives you ``total control'' over the stepping of ticks on an axis, but you often do not know the correct stepping in @@ -599,8 +1478,8 @@ to request about four ticks to be placed on the $x$-axis. perpendicular={ attribute=perp, unit vector={(1pt,0pt)}, - include values=0, - include values=1 + include value=0, + include value=1 } } } @@ -617,8 +1496,8 @@ to request about four ticks to be placed on the $x$-axis. one dimensional axis, axis={ ticks={about=\about}, - include values=0, - include values=\max + include value=0, + include value=\max } ]; @@ -630,7 +1509,7 @@ to request about four ticks to be placed on the $x$-axis. \end{tikzpicture} } - The net effect of all this is that for the default strategy, the + The net effect of all this is that for the default strategy the only valid stepping are the values $1$, $2$, $2.5$ and $5$ and every value obtainable by multiplying one of these values by a power of ten. The following example shows the effects of, first, setting @@ -678,8 +1557,8 @@ to request about four ticks to be placed on the $x$-axis. axis={ logarithmic, ticks={about=3}, - include values=1, - include values=1e\max + include value=1, + include value=1e\max } ]; \end{scope} @@ -714,6 +1593,13 @@ to request about four ticks to be placed on the $x$-axis. \showstrategy{half about strategy} \end{key} + \begin{key}{/tikz/data visualization/decimal about strategy} + The only permissible value for $m'$ is $1$. This is an even more + radical version of the previous strategy. + + \showstrategy{decimal about strategy} + \end{key} + \begin{key}{/tikz/data visualization/quarter about strategy} Permissible values for $m'$ are: $1$, $2.5$, and $5$. @@ -747,10 +1633,947 @@ to request about four ticks to be placed on the $x$-axis. +\subsubsection{Manual Specification of Tick and Grid Line Positions} + +The automatic computation of ticks and grid lines will usually do a +good job, but not always. For instance, you might wish to have ticks +exactly at, say, prime numbers or at Fibonacci numbers or you might +wish to have an additional tick at $\pi$. In these cases you need more +direct control over the specification of tick positions. + +First, it is important to understand that the data visualization +system differentiates between three kinds of +ticks and grid lines: major, minor, and subminor. The major ticks are +the most prominent ticks where, typically, a textual representation of +the tick is shown; and the major grid lines are the thickest. The +minor ticks are smaller, more numerous, and lie between major +ticks. They are used, for instance, to indicate positions in the +middle between major ticks or at all integer positions between major +ticks. Finally, subminor ticks are even smaller than minor ticks and +they lie between minor ticks. + +Four keys are used to configure the different kinds: + +\begin{key}{/tikz/data visualization/major=\meta{options}} + The key can be passed as an option to the |ticks| key and also to + the |grid| key, which in turn is passed as an option to an axis. The + \meta{options} passed to |major| specify at which positions + major ticks/grid lines should be shown (using the |at| option and + |also at| option) and also any special styling. The different + possible options are described later in this section. +\begin{codeexample}[] +\tikz \datavisualization + [ school book axes, visualize as smooth line, + x axis={ticks={major={at={1, 1.5, 2}}}}] + data [format=function] { + var x : interval [-1.25:2]; + func y = \value x * \value x / 2; + }; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/minor=\meta{options}} + Like |major|, only for minor ticks/grid lines. +\begin{codeexample}[] +\tikz \datavisualization + [ school book axes, visualize as smooth line, + x axis={grid={minor={at={1, 1.5, 2}}}}] + data [format=function] { + var x : interval [-1.25:2]; + func y = \value x * \value x / 2; + }; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/subminor=\meta{options}} + Like |major|, only for subminor ticks/grid lines. +\end{key} + + +\begin{key}{/tikz/data visualization/common=\meta{options}} + This key allows you to specify \meta{options} that apply to |major|, + |minor| and |subminor| alike. It does not make sense to use |common| + to specify positions (since you typically do not want both a major + and a minor tick at the same position), but it can be useful to + configure, say, the size of all kinds of ticks: +\begin{codeexample}[] +\tikz \datavisualization + [ school book axes, visualize as smooth line, + x axis={ticks={minor steps between steps, common={low=0}}} ] + data [format=function] { + var x : interval [-1.25:2]; + func y = \value x * \value x / 2; + }; +\end{codeexample} +\end{key} + + +The following keys can now be passed to the |major|, |minor|, and +|subminor| keys to specify where ticks or grid lines should be shown: + +\begin{key}{/tikz/data visualization/at=\meta{list}} + Basically, the \meta{list} must be a list of values that is + processed with the |\foreach| macro (thus, it can contain ellipses + to specify ranges of value). Empty values are skipped. + + The effect of passing |at| to a |major|, |minor|, or |subminor| key + is that ticks or grid lines on the axis will be placed exactly at + the values in \meta{list}. Here is an example: +\begin{codeexample}[] +\tikz \datavisualization + [ school book axes, visualize as smooth line, + x axis={ticks={major={at={-1,0.5,(pi/2)}}}}] + data [format=function] { + var x : interval [-1.25:2]; + func y = \value x * \value x / 2; + }; +\end{codeexample} + When this option is used, any previously specified tick positions + are overwritten by the values in \meta{list}. Automatically computed + ticks are also overwritten. Thus, this option gives you complete + control over where ticks should be placed. + + Normally, the individual values inside the \meta{list} are just + numbers that are specified in the same way as an attribute + value. However, such a value may also contain the keyword |as|, + which allows you so specify the styling of the tick in + detail. Section~\ref{section-dv-ticks-styling} details how this + works. + + It is often a bit cumbersome that one has to write things like +\begin{codeexample}[code only] +some axis = {ticks = {major = {at = {...}}}} +\end{codeexample} + A slight simplification is given by the following keys, which can be + passed directly to |ticks| and |grid|: + \begin{key}{/tikz/data visualization/major at=\meta{list}} + A shorthand for |major={at={|\meta{list}|}}|. + \end{key} + \begin{key}{/tikz/data visualization/minor at=\meta{list}} + A shorthand for |major={at={|\meta{list}|}}|. + \end{key} + \begin{key}{/tikz/data visualization/subminor at=\meta{list}} + A shorthand for |major={at={|\meta{list}|}}|. + \end{key} +\end{key} + +\begin{key}{/tikz/data visualization/also at=\meta{list}} + This key is similar to |at|, but it causes ticks or grid lines to be + placed at the positions in the \meta{list} \emph{in addition} to the + ticks that have already been specified either directly using |at| or + indirectly using keys like |step| or |some|. The effect of multiple + calls of this key accumulate. However, when |at| is used after an + |also at| key, the |at| key completely resets the positions where + ticks or grid lines are shown. +\begin{codeexample}[] +\tikz \datavisualization + [ school book axes, visualize as smooth line, + x axis={grid, ticks and grid={major={also at={0.5}}}}] + data [format=function] { + var x : interval [-1.25:2]; + func y = \value x * \value x / 2; + }; +\end{codeexample} + As for |at|, there are some shorthands available: + \begin{key}{/tikz/data visualization/major also at=\meta{list}} + A shorthand for |major={also at={|\meta{list}|}}|. + \end{key} + \begin{key}{/tikz/data visualization/minor also at=\meta{list}} + A shorthand for |major={also at={|\meta{list}|}}|. + \end{key} + \begin{key}{/tikz/data visualization/subminor also at=\meta{list}} + A shorthand for |major={also at={|\meta{list}|}}|. + \end{key} +\end{key} + + +\subsubsection{Styling Ticks and Grid Lines: Introduction} + +\label{section-dv-ticks-styling} + +When a tick, a tick label, or a grid line is visualized on the page, a +whole regiment of styles influences the appearance. The reason for +this large number of interdependent styles is the fact that we often +wish to influence only a very certain part of how a tick is rendered +while leaving the other aspects untouched: Sometimes we need to modify +just the font of the tick label; sometimes we wish to change the +length of the tick label and the tick label position at the same time; +sometimes we wish to change the color of grid line, tick, and tick +label; and sometimes we wish to generally change the thickness of all +ticks. + +Let us go over the different kinds of things that can be styled (grid +lines, ticks, and tick labels) one by one and let us have a look at +which styles are involved. We will start with the grid lines, since they +turn out to be the most simple, but first let us have a look at the +general |style| and |styling| mechanism that is used in many placed in +the following: + +\subsubsection{Styling Ticks and Grid Lines: The Style and Node Style Keys} + +\label{section-dv-style} + +All keys of the data visualization system have the path prefix +|/tikz/data visualization|. This is not only true for the main keys +like |scientific axes| or |visualize as line|, but also for keys that +govern how ticks are visualized. In particular, a style like +|every major grid| has the path prefix |/tikz/data visualization| and +all keys stored in this style are also executed with this path +prefix. + +Normally, this does not cause any trouble since most of the keys and +even styles used in a data visualization are intended to configure +what is shown in the visualization. However, at some point, we may +also with to specify options that no longer configure the +visualization in general, but specify the appearance of a line or a +node on the \tikzname\ layer. + +Two keys are used to ``communicate'' with the \tikzname\ layer: + +\begin{key}{/tikz/data visualization/style=\meta{\tikzname\ options}} + This key takes options whose path prefix is |/tikz|, not + |/tikz/data visualization|. These options will be \emph{appended} to + a current list of such options (thus, multiple calls of this key + accumulate). The resulting list of keys is not executed + immediately, but it will be executed whenever the data visualization + engine calls the \tikzname\ layer to draw something (this placed + will be indicated in the following). +\begin{codeexample}[] +\tikz \datavisualization + [scientific axes, + all axes={ticks={style=blue}, length=3cm}, + y axis={grid, grid={minor steps between steps, major={style=red}}}, + visualize as line] + data [format=function] { + var x : interval [5:10]; + func y = \value x * \value x; + }; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/styling} + Executing this key will cause all ``accumulated'' \tikzname\ options + from previous calls to the key |/tikz/data visualization/style| to be + executed. Thus, you use |style| to set \tikzname\ options, but you + use |styling| to actually apply these options. Usually, you do not + call this option directly since this application is only done deep + inside the data visualization engine. +\end{key} + +Similar to |style| (and |styling|) there also exist the +|node style| (and |node styling|) key that takes \tikzname\ options that +apply to nodes only -- in addition to the usual |style|. + +\begin{key}{/tikz/data visualization/node style=\meta{\tikzname\ options}} + This key works like |style|, only it has an effect only on nodes + that are created during a data visualization. This includes tick + labels and axis labels: +\begin{codeexample}[] +\tikz \datavisualization + [scientific axes, + all axes={ticks={node style=red}, length=3cm}, + visualize as line] + data [format=function] { + var x : interval [5:10]; + func y = \value x * \value x; + }; +\end{codeexample} + Note that in the example the ticks themselves (the little thicker + lines) are not red. +\end{key} + +\begin{key}{/tikz/data visualization/node styling} + Executing this key will cause all ``accumulated'' node stylings to + be executed. +\end{key} + + +\subsubsection{Styling Ticks and Grid Lines: Styling Grid Lines} +\label{section-dv-styling-grid-lines} + +When a grid line is visualized, see +Section~\ref{section-dv-visualize-gridlines} for details on when this +happens, the following styles are executed in the specified order. + +\begin{enumerate} +\item + |grid layer|. +\item + |every grid|. +\item |every major grid| or |every minor grid| or + |every subminor grid|, depending on the kind of grid line. +\item + locally specified options for the individual grid line, see + Section~\ref{section-dv-local-styles}. +\item + |styling|, see Section~\ref{section-dv-style}. +\end{enumerate} + +All of these keys have the path prefix +|/tikz/data visualization|. However, the options stored in the first +style (|grid layer|) and also in the last (|styling|) are executed +with the path prefix |/tikz| (see Section~\ref{section-dv-style}). + +Let us now have a look at these keys in detail: + +\begin{stylekey}{/tikz/data visualization/grid layer (initially on background layer)} + \label{section-dv-grid-layer}% + This key is used to specified the \emph{layer} on which grid lines + should be drawn (layers are explained in + Section~\ref{section-tikz-backgrounds}). By default, all grid lines + are placed on the |background| layer and thus behind the data + visualization. This is a sensible strategy since it avoids obscuring + the more important data with the far less important grid + lines. However, you can change this style to ``get the grid lines to + the front'': +\begin{codeexample}[] +\tikz \datavisualization + [scientific axes, + all axes={ + length=3cm, + grid, + grid={minor steps between steps} + }, + grid layer/.style=, % none, so on top of data (bad idea) + visualize as line] + data [format=function] { + var x : interval [5:10]; + func y = \value x * \value x; + }; +\end{codeexample} + When this style is executed, the keys stored in the style will be + executed with the prefix |/tikz|. Normally, you should only set this + style to be empty or to |on background layer|. +\end{stylekey} + +\begin{stylekey}{/tikz/data visualization/every grid} + This style provides overall configuration options for grid lines. By + default, it is set to the following: +\begin{codeexample}[code only] +low=min, high=max +\end{codeexample} + This causes grid lines to span all possible values when they are + visualized, which is usually the desired behaviour (the |low| and + |high| keys are explained in + Section~\ref{section-dv-visualize-ticks}. You can append + the |style| key to this style to configure the overall appearance of + grid lines. In the following example we cause all grid lines to be + dashed (which is not a good idea in general since it creates a + distracting background pattern). +\begin{codeexample}[] +\tikz \datavisualization + [scientific axes, + all axes={length=3cm, grid}, + every grid/.append style={style=densely dashed}, + visualize as line] + data [format=function] { + var x : interval [5:10]; + func y = \value x * \value x; + }; +\end{codeexample} +\end{stylekey} + +\begin{stylekey}{/tikz/data visualization/every major grid} + This style configures the appearance of major grid lines. It does so + by calling the |style| key to setup appropriate \tikzname\ options + for visualizing major grid lines. The default definition of this + style is: +\begin{codeexample}[code only] +style = {help lines, thin, black!25} +\end{codeexample} + In the following example, we use thin major blue grid lines: +\begin{codeexample}[] +\tikz \datavisualization + [scientific axes, + all axes={ + length=3cm, + grid, + grid={minor steps between steps} + }, + every major grid/.style = {style={blue, thin}}, + visualize as line] + data [format=function] { + var x : interval [5:10]; + func y = \value x * \value x; + }; +\end{codeexample} + As can be seen, this is not exactly visually pleasing. The default + settings for the grid lines should work in most situations; you may + wish to increase the blackness level, however, when you experience + trouble during printing or projecting graphics. +\end{stylekey} + +\begin{stylekey}{/tikz/data visualization/every minor grid} + Works like |every major grid|. The default is +\begin{codeexample}[code only] +style = {help lines, black!25} +\end{codeexample} +\end{stylekey} + +\begin{stylekey}{/tikz/data visualization/every subminor grid} + Works like |every major grid|. The default is +\begin{codeexample}[code only] +style = {help lines, black!10} +\end{codeexample} +\end{stylekey} + + + +\subsubsection{Styling Ticks and Grid Lines: Styling Ticks and Tick Labels} + +\label{section-dv-styling-ticks} + +Styling ticks and tick labels is somewhat similar to styling grid +lines. Let us start with the tick \emph{mark}, that is, the small line +that represents the tick. When this mark is drawn, the following styles are applied: + +\begin{enumerate} +\item + |every ticks|. +\item |every major ticks| or |every minor ticks| or + |every subminor ticks|, depending on the kind of ticks to be + visualized. +\item + locally specified options for the individual tick, see + Section~\ref{section-dv-local-styles}. +\item + |tick layer| +\item + |every odd tick| or |every even tick|, see Section~\ref{section-dv-stacking}. +\item + |draw| +\item + |styling|, see Section~\ref{section-dv-style}. +\end{enumerate} + +For the tick label node (the node containing the textual +representation of the attribute's value at the tick position), the +following styles are applied: + +\begin{enumerate} +\item + |every ticks|. +\item |every major ticks| or |every minor ticks| or + |every subminor ticks|, depending on the kind of ticks to be + visualized. +\item + locally specified options for the individual tick, see + Section~\ref{section-dv-local-styles}. +\item + |tick node layer| +\item + |every odd tick| or |every even tick|, see Section~\ref{section-dv-stacking}. +\item + |styling|, see Section~\ref{section-dv-style}. +\item + |node styling|, see Section~\ref{section-dv-style}. +\end{enumerate} + +\begin{stylekey}{/tikz/data visualization/every ticks} + This style allows you to configure the appearance of ticks using the + |style| and |node style| key. Here is (roughly) the default + definition of this style: +\begin{codeexample}[code only] +node style={ + font=\footnotesize, + inner sep=1pt, + outer sep=.1666em, + rounded corners=1.5pt +} +\end{codeexample} +\end{stylekey} + +\begin{stylekey}{/tikz/data visualization/every major ticks} + The default is +\begin{codeexample}[code only] + style={line cap=round}, tick length=2pt +\end{codeexample} +\end{stylekey} + +\begin{stylekey}{/tikz/data visualization/every minor ticks} + The default is +\begin{codeexample}[code only] + style={help lines,thin, line cap=round}, tick length=1.4pt +\end{codeexample} +\end{stylekey} + +\begin{stylekey}{/tikz/data visualization/every subminor ticks} + The default is +\begin{codeexample}[code only] + style={help lines, line cap=round}, tick length=0.8pt +\end{codeexample} +\end{stylekey} + + +\begin{stylekey}{/tikz/data visualization/tick layer (initially on background layer)} + Like |grid layer|, this key specifies on which layer the ticks + should be placed. +\end{stylekey} + +\begin{stylekey}{/tikz/data visualization/tick node layer (initially + \normalfont empty)} + Like |tick layer|, but now for the nodes. By default, tick nodes are + placed on the main layer and thus on top of the data in case that + the tick nodes are inside the data. +\end{stylekey} + + +\subsubsection{Styling Ticks and Grid Lines: Exceptional Ticks} + +You may sometimes wish to style a few ticks differently from the other +ticks. For instance, in the axis system |school book axes| there +should be a tick label at the |0| position only on one axis and then +this label should be offset a bit. In many cases this is easy to +achieve: When you add a tick ``by hand'' using the |at| or |also at| +option, you can add any special options in square brackets. + +However, in some situations the special tick position has been +computed automatically for you, for instance by the |step| key or by +saying |tick=some|. In this case, adding a tick mark with the desired +options using |also at| would cause the tick mark with the correct +options to be shown in addition to the tick mark with the wrong +options. In cases like this one, the following option may be helpful: + +\begin{key}{/tikz/data visualization/options at=\meta{value} |as [|\meta{options}|]|} + This key causes the \meta{options} to be executed for any tick + mark(s) at \meta{value} in addition to any options given already for + this position: +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line, + x axis={ticks={major={ + options at = 3 as [no tick text], + also at = (pi) as + [{tick text padding=1ex}] $\pi$}}}] +data [format=function] { + var x : interval[0:2*pi]; + func y = sin(\value x r); +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/no tick text at=\meta{value}} + Shorthand for |options at=|\meta{value}| as [no tick text]|. +\end{key} + + + +\subsubsection{Styling Ticks and Grid Lines: Styling and Typesetting a Value} + +\label{section-dv-local-styles} +\label{section-dv-tick-labels} + + +The |at| and |also at| key allow you to provide a comma-separated +\meta{list} of \meta{value}s where ticks or grid lines should be +placed. In the simplest case, the \meta{value} is simply a +number. However, the general syntax allows three different kinds of +\meta{value}s: + +\begin{enumerate} +\item + \meta{value} +\item + \meta{value} |as| |[|\meta{local options}|]| +\item + \meta{value} |as| \opt{|[|\meta{local options}|]|} \meta{text} +\end{enumerate} + +In the first case, the \meta{value} is just a number that is +interpreted like any other attribute value. + +In the second case, where the keyword |as| is present, followed by +some option in square brackets, but nothing following the closing +square bracket, when the tick or grid line at position \meta{value} is +shown, the \meta{local options} are executed first. These can use the +|style| key or the |node style| key to configure the appearance of +this single tick or grid line. You can also use keys like |low| or +|high| to influence how large the grid lines or the ticks are or keys +like |tick text at low| to explicitly hide or show a tick label. + +In the third case, which is only important for |ticks| and not for +|grid|, the same happens as in the second case, but the +text that is shown as tick label is \meta{text} rather than the +automatically generated tick label. This automatic generation of tick +labels is explained in the following. + +\begin{codeexample}[] +\tikz \datavisualization + [scientific axes=clean, + x axis={length=2.5cm, ticks={major at={ + 5, + 6 as [style=red], + 7 as [{style=blue, low=-1em}], + 8 as [style=green] $2^3$, + 10 as ten + }}}, + visualize as line] + data [format=function] { + var x : interval [5:10]; + func y = \value x * \value x; + }; +\end{codeexample} + + +A value like ``2'' or ``17'' could just be used as \meta{text} to be +displayed in the node of a tick label. However, things are more +difficult when the to-be-shown value is $0.0000000015$, because we +then would typically (but not always) prefer something like $1.5 \cdot +10^{-9}$ to be shown. Also, we might wish a unit to be added like +$23\mathrm{m}/\mathrm{s}$. Finally, we might wish a number like +$3.141$ to be replaced by $\pi$. For these reasons, the data +visualization system does not simply put the to-be-shown value in a +node as plain text. Instead, the number is passed to a +\emph{typesetter} whose job it is to typeset this number nicely using +\TeX's typesetting capabilities. The only exception is, as indicated +above, the third syntax version of the |at| and |also at| keys, where +\meta{text} is placed in the tick label's node, regardless of what the +typesetting would usually do. + +The text produced by the automatic typesetting is computed as follows: +\begin{enumerate} +\item The current contents of the key |tick prefix| is put into the node. +\item This is followed by a call of the key |tick typesetting| which + gets the \meta{value} of the tick as its argument in scientific + notation. +\item This is followed by the contents of the key |tick suffix|. +\end{enumerate} + +Let us have a look at these keys in detail: + +\begin{key}{/tikz/data visualization/tick prefix=\meta{text} + (initially \normalfont empty)} + The \meta{text} will be put in front of every typeset tick: +\begin{codeexample}[] +\tikz \datavisualization + [scientific axes, all axes={ticks=few, length=2.5cm}, + x axis={ticks={tick prefix=$\langle$, tick suffix=$]$}}, + visualize as line] + data [format=function] { + var x : interval [5:10]; + func y = \value x * \value x; + }; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/tick suffix=\meta{text} + (initially \normalfont empty)} + Works like |tick prefix|. This key is especially useful for adding + units like ``cm'' or ``$\mathrm m/\mathrm s$'' to every tick + label. For this reason, there is a (near) alias that is easier to memorize: + \begin{key}{/tikz/data visualization/tick unit=\meta{roman math text}} + A shorthand for |tick suffix={$\,\rm|\meta{roman math text}|$}|: +\begin{codeexample}[] +\tikz \datavisualization + [scientific axes, all axes={length=3cm}, + x axis={ticks={tick unit=s}}, + y axis={ticks={tick unit=m/s^2}}, + visualize as line] + data [format=function] { + var x : interval [5:10]; + func y = \value x * \value x; + }; +\end{codeexample} + \end{key} +\end{key} + +\begin{key}{/tikz/data visualization/tick typesetting=\meta{value}} + The key gets called for each number that should be typeset. The + argument \meta{value} will be in scientific notation (like |1.0e1| + for $10$). By default, this key applies |\pgfmathprintnumber| to its + argument. This command is a powerful number printer whose + configuration is documented in + Section~\ref{pgfmath-numberprinting}. + + You are invited to code underlying this key so that a different + typesetting mechanism is used. Here is a (not quite finished) + example that shows how, say, numbers could be printed in terms of + multiples of $\pi$: +\begin{codeexample}[] +\def\mytypesetter#1{% + \pgfmathparse{#1/pi}% + \pgfmathprintnumber{\pgfmathresult}$\pi$% +} +\tikz \datavisualization + [school book axes, all axes={unit length=1.25cm}, + x axis={ticks={step=(0.5*pi), tick typesetter/.code=\mytypesetter{##1}}}, + y axis={include value={-1,1}}, + visualize as smooth line] + data [format=function] { + var x : interval [0.5:7]; + func y = sin(\value x r); + }; +\end{codeexample} +\end{key} + + + + +\subsubsection{Stacked Ticks} + +\label{section-dv-stacking} + + + +Sometimes, the text of tick labels are so long or so numerous that the +text of adjacent tick labels overlap (or have too little padding): +\begin{codeexample}[] +\tikz \datavisualization [scientific axes, + all axes={length=2.5cm}, + visualize as smooth line] + data [format=function] { + var y : interval[-100:100]; + func x = \value y*\value y; + }; +\end{codeexample} +There are two ways to address this problem: +\begin{itemize} +\item One can rotate the labels on horizontal axes: +\begin{codeexample}[] +\tikz \datavisualization [scientific axes, + all axes={length=2.5cm}, + x axis={ticks={node style={rotate=90, anchor=east}}}, + visualize as smooth line] + data [format=function] { + var y : interval[-100:100]; + func x = \value y*\value y; + }; +\end{codeexample} + This is often a good solution, but may be hard to read. Also + consider rotating labels only by $45^\circ$ or $30^\circ$. +\item One can specify different shifts of the nodes for the different + ticks, whereby the ticks text no longer overlap. +\begin{codeexample}[] +\tikz \datavisualization [scientific axes, + all axes={length=2.5cm}, + x axis={ticks={major at={0,4000,8000, + 2000 as [node style={yshift=-1em}], + 6000 as [node style={yshift=-1em}], + 10000 as [node style={yshift=-1em}]}}}, + visualize as smooth line] + data [format=function] { + var y : interval[-100:100]; + func x = \value y*\value y; + }; +\end{codeexample} + However, specifying shifts ``by hand'' in the above way is not + always an option, especially when the tick positions should be + computed automatically. Instead, the |stack| option can be used, + which is much easier to use and gives better results: +\begin{codeexample}[] +\tikz \datavisualization [scientific axes, + all axes={length=2.5cm}, x axis={ticks=stack}, + visualize as smooth line] + data [format=function] { + var y : interval[-100:100]; + func x = \value y*\value y; + }; +\end{codeexample} +\end{itemize} + + +The |stack| option is actually just a style that gives you access to +the general even/odd mechanism for ticks with labels. Whenever a tick +mark is created where a tick label is also to be drawn, two special +things happen: + +\begin{enumerate} +\item For every odd tick mark, the |every odd tick| style is executed, + for every even tick mark the |every even tick|. Here, ``odd'' and + ``even'' are with respect to the order in which the ticks have been + added to the list of |at| positions for each major, minor, or + subminor tick list, not with respect to the order in which they will + appear on the axis. Thus, when you write +\begin{codeexample}[code only] +ticks={major at={1,2,3,4}, major at={0,-1,-2}, minor at={9,8,7}} +\end{codeexample} + then for |1|, |3|, |0|, and |-2| as well as |9| and |7| the key + |every odd tick| will be executed, while |every even tick| will be + executed for positions |2|, |4|, |-1|, and also |8|. +\item When a tick node label is shown at the |low| position of the + tick mark, the dimension stored in the key + |tick text low even padding| is added to the |low| value. Provided + that this padding is not zero (which is the default), the length of + the even tick marks will be increased and the tick label node will + be placed at a greater distance from the axis. + + Similar keys exist for padding ticks with labels at high positions + and also at even positions. +\end{enumerate} + + +\begin{key}{/tikz/data visualization/tick text low even + padding=\meta{dimension} (initially 0pt)} + When a tick label is shown at the low position of an even tick, the + \meta{distance} is added to the |low| value, see also + Section~\ref{section-dv-visualize-ticks}. +\begin{codeexample}[] +\tikz \datavisualization [scientific axes, + all axes={length=2.5cm}, + x axis={ticks={tick text low even padding=-1em}}, + visualize as smooth line] + data [format=function] { + var y : interval[-100:100]; + func x = \value y*\value y; + }; +\end{codeexample} + Note that \meta{dimension} should usually be non-positive. +\end{key} + +The following keys work similarly: +\begin{key}{/tikz/data visualization/tick text low odd padding=\meta{dimension} (initially 0pt)} +\end{key} +\begin{key}{/tikz/data visualization/tick text high even padding=\meta{dimension} (initially 0pt)} +\end{key} +\begin{key}{/tikz/data visualization/tick text high odd padding=\meta{dimension} (initially 0pt)} +\end{key} + +\begin{key}{/tikz/data visualization/tick text odd + padding=\meta{dimension}} + A shorthand for setting |tick text odd low padding| and + |tick text odd high padding| at the same time. +\end{key} + +\begin{key}{/tikz/data visualization/tick text even + padding=\meta{dimension}} + A shorthand for setting |tick text even low padding| and + |tick text even high padding| at the same time. +\end{key} + +\begin{key}{/tikz/data visualization/tick text + padding=\meta{dimension}} + Sets all text paddings to \meta{dimension}. +\end{key} + +\begin{key}{/tikz/data visualization/stack=\meta{dimension} (default 1em)} + Shorthand for |tick text even padding=|\meta{dimension}. +\begin{codeexample}[] +\tikz \datavisualization [scientific axes, + all axes={length=2.5cm}, + x axis={ticks={stack=1.5em}}, + visualize as smooth line] + data [format=function] { + var y : interval[-100:100]; + func x = \value y*\value y; + }; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/stack'=\meta{dimension}} + Shorthand for |tick text odd padding=|\meta{dimension}. The + difference to |stack| is that the set of value that are + ``lowered'' is exactly exchanged with the set of value ``lowered'' + by |stack|. +\begin{codeexample}[] +\tikz \datavisualization [scientific axes, + all axes={length=2.5cm}, + x axis={ticks=stack'}, + visualize as smooth line] + data [format=function] { + var y : interval[-100:100]; + func x = \value y*\value y; + }; +\end{codeexample} +\end{key} + +Note that the above keys have an effect on all tick labels of an axis, +also on special ticks that you may have added using the |also at| +key. When using the |stack| key, you should specify a |tick text padding| +explicitly for such keys: + +\begin{codeexample}[width=7cm] +\tikz \datavisualization + [scientific axes, + x axis={ticks={stack, many, major also at= + {(pi) as [{tick text padding=2.5em}] $\pi$}}}, + visualize as smooth line] + data [format=function] { + var x : interval[0:(2*pi)]; + func y = sin(\value x r); + }; +\end{codeexample} + + +\subsubsection{Reference: Basic Strategies} + +\label{section-dv-strategies} + +\begin{key}{/tikz/data visualization/axis options/linear steps} + This strategy places ticks at positions that are evenly spaced by + the current value of |step|. + + In detail, the following happens: Let $a$ be the minimum value of the + data values along the axis and let $b$ be the maximum. Let the + current \emph{stepping} be $s$ (the stepping is set using the |step| + option, see below) and let the current \emph{phasing} be $p$ (set + using the |phase|) option. Then ticks are placed all positions + $i\cdot s + p$ that lie in the interval $[a,b]$, where $i$ ranges + over all integers. + + The tick positions computed in the way described above are + \emph{mayor} step positions. In addition to these, if the key + |minor steps between steps| is set to some number $n$, then $n$ many + minor ticks are introduced between each two mayor ticks (and also + before and after the last mayor tick, provided the values still lie + in the interval $[a,b]$). Note that is $n$ is $1$, then one minor tick + will be added in the middle between any two mayor ticks. Use a value + of $9$ (not $10$) to partition the interval between two mayor ticks + into ten equally sized minor intervals. + +\begin{codeexample}[] +\begin{tikzpicture} + \datavisualization + [scientific axes={inner ticks, width=3cm}, + x axis={ticks={step=3, minor steps between steps=2}}, + y axis={ticks={step=.36}}, + visualize as scatter] + data { + x, y + 17, 30 + 34, 32 + }; +\end{tikzpicture} +\end{codeexample} +\end{key} + +\label{section-dv-exponential-strategy} + +\begin{key}{/tikz/data visualization/axis options/exponential steps} + This strategy produces ticks at positions that are appropriate for + logarithmic plots. It is automatically selected when you use the + |logarithmic| option with an axis. + + In detail, the following happens: As for |linear steps| let numbers + $a$, $b$, $s$, and $p$ be given. Then, mayor ticks are placed at all + positions $10^{i\cdot s+p}$ that lie in the interval $[a,b]$ for $i + \in \mathbb Z$. + + The minor steps are added in the same way as for |linear steps|. In + particular, they interpolate \emph{linearly} between mayor steps. + +\begin{codeexample}[] +\begin{tikzpicture} + \datavisualization + [scientific axes, + x axis={logarithmic, length=2cm, ticks={step=1.5}}, + y axis={logarithmic, ticks={step=1, minor steps between steps=9}}, + visualize as scatter] + data { + x, y + 1, 10 + 1000, 1000000 + }; +\end{tikzpicture} +\end{codeexample} +\end{key} + + -\subsubsection{Advanced: Defining New Placing Strategies} +\subsubsection{Advanced: Defining New Placement Strategies} -\begin{key}{/tikz/data visualization/axis options/tick placement strategy=\meta{macro}} +\begin{key}{/tikz/data visualization/axis options/tick placement + strategy=\meta{macro}} This key can be used to install a so-called \emph{tick placement strategy}. Whenever |visualize ticks| is used to request some ticks to be visualized, it is checked whether some automatic ticks @@ -777,9 +2600,10 @@ to request about four ticks to be placed on the $x$-axis. been set to the name of the axis for which default ticks need to be computed. This allows you to access the minimum and the maximum value stored in the |scaling mapper| of that axis. - \begin{codeexample}[] +\begin{codeexample}[width=7cm] \def\silly{ - \tikzdatavisualizationset{major={at={2,3,5,7,11,13}}} + \tikzdatavisualizationset{major={at={ + 2,3,5,7,11,13}}} } \begin{tikzpicture} \datavisualization [ @@ -795,6 +2619,1079 @@ to request about four ticks to be placed on the $x$-axis. \end{codeexample} \end{key} -\subsection{Advanced: Creating New Axes} + + + \subsection{Advanced: Creating New Axis Systems} + +The data visualization library comes with a number of predefined axis +systems, like |scientific axes=clean|, but it is also possible and +to define new axis systems. Doing so involves the following steps: + +\begin{enumerate} +\item Creating a number of axes. +\item Configuring attributes of these axes like their length or + default scaling. +\item Creating visual representations of the axes. +\item Creating visual representations of the ticks and grid lines. +\end{enumerate} + +The first step uses |new ... axis| keys to create new axes, the +last steps use |visualize ...| keys to create the visual +representations of the axes. + +Note that the axis system has no control over the actual attribute +value ranges and neither over which ticks need to be drawn. The axis +system can only provide good defaults and then specify \emph{how} the +ticks or labels should be drawn and \emph{where} on the page -- but +not at which values. + +In the following, as a running example let us develop an axis system +|our system| that does the following: For the $x$-axis is looks like a +normal scientific axis system, but there are actually two $y$-axes: +One at the left and one at the right, each using a different +attribute, but both coexisting in the same picture. + +\subsubsection{Creating the Axes} + +A new axis system is created as a style key with the prefix +|/tikz/data visualization|. Thus, we would write: +\begin{codeexample}[code only] +\tikzset{ + data visualization/our system/.style={ + ... + } +} +\end{codeexample} + +In our system we need three axis: The $x$-axis, the left axis and the +right axis. Since all of these axes are Cartesian axes, we write the +following: +\begin{codeexample}[code only] +\tikzset{ + data visualization/our system/.style={ + new Cartesian axis=x axis, + new Cartesian axis=left axis, + new Cartesian axis=right axis, + x axis={attribute=x}, + left axis={unit vector={(0cm,1pt)}}, + right axis={unit vector={(0cm,1pt)}}, + } +} +\end{codeexample} +As can be seen, we also configure things so that the $x$-axis will use +the |x| attribute by default (users can later change this by saying +|x axis={attribute=|\meta{some other attribute}|}|), but we do not +configure the attributes of the |left axis| nor the |right axis|. We +also make the left and right axis point upward (the |x axis| needs no +configuration here since a Cartesian axis points right by default). The +reason is the |left| would not be a particularly good attribute name +and this way we ensure that users have to pick names themselves +(hopefully good ones). + +The next step is to define a standard scaling for the axes. Here, we +can use the same as for |scientific axes|, so we would add the +following keys to the definition of |our system|: +\begin{codeexample}[code only] +x axis ={length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/width}}, +left axis ={length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height}}, +right axis={length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height}} +\end{codeexample} + +We now already have enough to try our system, although we will not yet +see any axes or ticks, but we will see the correct scaling of the +attributes. Let us first define a data group: +\begin{codeexample}[] +\tikz \datavisualization data group {people and money} = { + data [set=people 1] { + time, people + 1900, 1000000000 + 1920, 1500000000 + 1930, 2000000000 + 1980, 3000000000 + } + data [set=people 2] { + time, people + 1900, 2000000000 + 1920, 2500000000 + 1940, 4000000000 + 2000, 5700000000 + } + data [set=money 1] { + time, money + 1910, 1.1 + 1920, 2 + 1930, 5 + 1980, 2 + } + data [set=money 2] { + time, money + 1950, 3 + 1960, 3 + 1970, 4 + 1990, 3.5 + } + }; +\end{codeexample} + +\tikzdatavisualizationset{ + our system/.style={ + new Cartesian axis=x axis, + new Cartesian axis=left axis, + new Cartesian axis=right axis, + x axis={attribute=x}, + left axis={unit vector={(0cm,1pt)}}, + right axis={unit vector={(0cm,1pt)}}, + x axis ={length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/width}}, + left axis ={length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height}}, + right axis={length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height}} + } +} +\begin{codeexample}[] +\tikz \datavisualization [ + our system, + x axis={attribute=time, length=4cm}, + left axis ={attribute=money}, + right axis={attribute=people}, + visualize as line/.list={people 1, people 2, money 1, money 2}, + people 1={style={visualizer color=blue}}, + people 2={style={visualizer color=blue!50}}, + money 1={style={visualizer color=red}}, + money 2={style={visualizer color=red!50}}] + data group {people and money}; +\end{codeexample} + + + +\subsubsection{Visualizing the Axes} + +\label{section-dv-visualize-axis} + +We must now show the axes themselves. For this we can use the +|visualize axis| key: + +\begin{key}{/tikz/data visualization/axis options/visualize axis=\meta{options}} + This key is passed to an axis as an option. It causes a visual + representation of the axis to be created during the data visualization. The + \meta{options} are used to determine where the axis should be drawn + and how long it should be. We can specify, for instance, that an + axis should be drawn at the minimum value of another axis or where + another axis has the value |0|. + + \medskip + \textbf{The goto, high, and low Keys.} + In our example, the |left axis| should be shown at the left hand + side. This is the position where the |x axis| has its minimum + value. To specify this, we would use the following code: +\begin{codeexample}[code only] +left axis={ visualize axis={ x axis={ goto=min } } +\end{codeexample} + As can be seen, we can pass another axis as an \meta{option} to + |visualize axis|, where we pass the following key to the axis in + turn: + \begin{key}{/tikz/data visualization/axis options/goto=\meta{value}} + The key can be passed to an axis. It will set the attribute + monitored by the axis to the given \meta{value}, which is usually + some number. However, \meta{value} may also be one of the + following, which causes a special behaviour: + \begin{itemize} + \item + |min|: The attribute is set to the minimal value that the + attribute has attained along this axis. + \item + |max|: Like |min|. + \item + |padded min|: This will also set the \meta{attribute} monitored + by the axis to the same value as |min|. Additionally, however, + the subkey |/data point/|\meta{attribute}|/offset| is set to the + current padding for the minimum, see the description of + |padding min| later on. The effect of this is that the actual + point ``meant'' by the attribute is offset by this padding along + the attribute's axis. + \item + |padded max|: Like |padded min|. + \end{itemize} + \end{key} + + The |right axis| would be visualized the same way, only at + |goto=max|. The $x$-axis actually need to be visualized + \emph{twice}: Once at the bottom and once at the top. Thus, we need + to call |visualize axis| twice for this axis: + +\tikzdatavisualizationset{ + our system/.style={ + new Cartesian axis=x axis, + new Cartesian axis=left axis, + new Cartesian axis=right axis, + x axis={attribute=x}, + left axis={unit vector={(0cm,1pt)}}, + right axis={unit vector={(0cm,1pt)}}, + x axis ={length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/width}}, + left axis ={length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height}}, + right axis={length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height}} + } +} +\begin{codeexample}[] +\tikzset{ + data visualization/our system/.append style={ + left axis= {visualize axis={x axis= {goto=min}}}, + right axis={visualize axis={x axis= {goto=max}}}, + x axis= {visualize axis={left axis={goto=min}}, + visualize axis={left axis={goto=max}}}, + } +} +\tikz \datavisualization [ + our system, + x axis={attribute=time, length=4cm}, + left axis ={attribute=money}, + right axis={attribute=people}, + visualize as line/.list={people 1, people 2, money 1, money 2}] + data group {people and money}; +\end{codeexample} + + There is another key that is similar to |goto|, but has a slightly + different semantics: + \begin{key}{/tikz/data visualization/axis options/goto pos=\meta{fraction}} + The key works like |goto|, only the \meta{fraction} is not + interpreted as a value but as a fraction of the way between the + minimum and the maximum value for this axis. + + Suppose that for an axis the attribute range interval is + $[500,1000]$ and the reasonable interval is $[1,3]$. Then for a + \meta{fraction} of |0|, the mapping process would choose value + $1$ from the reasonable interval, for a \meta{fraction} of |1| the + position $3$ from the reasonable interval, and for a + \meta{fraction} or |0.25| the position $1.5$ since it is one + quarter at the distance from $1$ to $3$. + + Note that neither the attribute range interval nor the + transformation function for the attribute are important for the + |goto pos| option -- the \meta{fraction} is computed with respect + to the reasonable interval. Also note that the values of the + actual attribute corresponding to the fractional positions in the + reasonable interval are not computed. +\begin{codeexample}[] +\tikzset{ + data visualization/our system/.append style={ + x axis= {visualize axis={left axis={goto pos=0.25}}, + visualize axis={left axis={goto pos=0.5}}}, + } +} +\tikz \datavisualization [ + our system, + x axis={attribute=time, length=4cm}, + left axis ={attribute=money}, + right axis={attribute=people}, + visualize as line/.list={people 1, people 2, money 1, money 2}] + data group {people and money}; +\end{codeexample} + \end{key} + + By default, when an axis is visualized, it spans the set of all + possible values for the monitored attribute, that is, from |min| to + |max|. However, there are actually two keys that allow you to adjust + this: + \begin{key}{/tikz/data visualization/low=\meta{value}} + This is the attribute value where the axis visualization + starts. The same special values as for |goto| are permissible + (like |min| or |padded min|, but also |0| or |1|). + \end{key} + \begin{key}{/tikz/data visualization/high=\meta{value}} + Like |low|, only for where the axis ends. + \end{key} + + By default, |low=min| and |high=max| are set for an axis + visualization. Another sensible setting is |low=padded min| and + |high=padded max|. The following key provides a shorthand for this: + \begin{key}{/tikz/data visualization/padded} + Shorthand for |low=padded min, high=padded max|. + \end{key} + As an example, consider the |scientific axes=clean|. Here, each axis + is actually drawn three times: Once at the minimum, once at the + maximum and then once more at the padded minimum. + + + \medskip + \textbf{The axis line.} + When an axis is drawn, \tikzname\ does not simply draw a straight + line from the |low| position to the |high| position. In reality, the + data visualization system uses the two commands |\pgfpathdvmoveto| + and |\pgfpathdvlineto| internally. These will replace the straight + line by a curve in certain situations. For instance, in a polar + coordinate system, if an axis should be drawn along an angle axis + for a fixed radius, an arc will be used instead of a straight line. + + \medskip + \textbf{Styling the axis.} + As can be seen, we now get the axis we want (but without the ticks, + visualizing them will be explained later). The axis is, however, + simply a black line. We can \emph{style} the axis in a manner + similar to styling ticks and grid lines, see + Section~\ref{section-dv-style}. In detail, the following styles get + executed: + \begin{enumerate} + \item |axis layer| + \item |every axis| + \item |styling| + \end{enumerate} + Additionally, even before |every axis| is executed, |low=min| and + |high=max| are executed. + + \begin{stylekey}{/tikz/data visualization/axis layer (initially on + background layer)} + The layer on which the axis is drawn. See the description of + |grid layer| on page~\ref{section-dv-grid-layer} for details. + \end{stylekey} + + \begin{stylekey}{/tikz/data visualization/every axis} + Put styling of the axis here. It is usually a good idea to set + this style to |style={black!50}|. + \end{stylekey} + + Recall that the |styling| key is set using the |style| key, see + Section~\ref{section-dv-style}. +\tikzset{ +} +\begin{codeexample}[] +\tikzset{ + data visualization/our system/.append style={ + every axis/.style={style=black!50}, % make this the default + left axis= {visualize axis={x axis= {goto=min}, style=red!75}}, + right axis={visualize axis={x axis= {goto=max}, style=blue!75}}, + x axis= {visualize axis={left axis={goto=min}}, + visualize axis={left axis={goto=max}}}, + } +} +\tikz \datavisualization [ + our system, + x axis={attribute=time, length=4cm}, + left axis ={attribute=money}, + right axis={attribute=people}, + visualize as line/.list={people 1, people 2, money 1, money 2}] + data group {people and money}; +\end{codeexample} +\tikzset{ + data visualization/our system/.append style={ + every axis/.style={style=black!50}, % make this the default + left axis= {visualize axis={x axis= {goto=min}, style=red!75}}, + right axis={visualize axis={x axis= {goto=max}, style=blue!75}}, + x axis= {visualize axis={left axis={goto=min}}, + visualize axis={left axis={goto=max}}}, + } +} + + \medskip + \textbf{Padding the Axis.} + When an axis is visualized, it is often a good idea to make it ``a + little bit longer'' or to ``remove it a bit from the border,'' because + the visualization of an axis should not interfere with the actual + data. For this reason, a \emph{padding} can be specified for axes: + + \begin{key}{/tikz/data visualization/axis options/padding min=\meta{dimension}} + This is the dimension that is used whenever |goto=padded min| is + used. The \meta{dimension} is then put into the |offset| subkey of + the attribute monitored by the axis. When a data point is + transformed by a linear transformer and when this subkey is + nonzero, this offset is added. (For an angle axis of a polar + transformer, the \meta{dimension} is interpreted as an additional + angle rather than as an additional distance). Note that + \meta{dimension} should typically be negative since + ``adding the \meta{dimension}'' will then make the axis longer + (because it starts at a smaller value). The standard + axis systems set the padding to some default and take its value + into account: +\begin{codeexample}[width=8cm] +\begin{tikzpicture} + \datavisualization [scientific axes=clean, + x axis={padding min=-1cm}, + visualize as smooth line] + data [format=function] { + var x : interval [-3:5]; + func y = \value x * \value x; + }; +\end{tikzpicture} +\end{codeexample} + + Using padded and using the |padded| key, we can visualize our axis + ``a little removed from the actual data'': +\begin{codeexample}[] +\tikzset{ + data visualization/our system/.append style={ + all axes= {padding=.5em}, + left axis= {visualize axis={x axis= {goto=padded min}, padded}}, + right axis={visualize axis={x axis= {goto=padded max}, padded}}, + x axis= {visualize axis={left axis={goto=padded min}, padded}, + visualize axis={left axis={goto=padded max}, padded}}, + } +} +\tikz \datavisualization [ + our system, + x axis={attribute=time, length=3cm}, + left axis ={attribute=money}, + right axis={attribute=people}, + visualize as line/.list={people 1, people 2, money 1, money 2}] + data group {people and money}; +\end{codeexample} + \end{key} + + \begin{key}{/tikz/data visualization/axis options/padding max=\meta{dimension}} + Works like |padding min|, but \meta{dimension} should typically be positive. + \end{key} + + \begin{key}{/tikz/data visualization/axis options/padding=\meta{dimension}} + Sets both |padding min| to the negated value of \meta{dimension} and + |padding max| to \meta{dimension}. + \end{key} +\end{key} + + + +\subsubsection{Visualizing Grid Lines} + +\label{section-dv-visualize-gridlines} + +As explained earlier, the |grid| key is used to specify at which +positions grid lines should be drawn in principle. However, this key +does not actually cause any grid lines to be drawn. Instead, the +|visualize grid| key is used by the axis system to specify how grid +lines are drawn. + +\begin{key}{/tikz/data visualization/axis options/visualize grid=\meta{options}} + This key is passed to an axis. It causes grid lines to be drawn at + the positions specified by the |grid| key for this axis. The + \meta{options} govern where and how the grid lines will be drawn. + + \medskip + \textbf{The direction axis.} + At first sight, one might expect that the grid lines for an axis + should simply be drawn perpendicular to the axis between the minimum + and maximum value of the axis. However, things are somewhat more + difficult in reality: + \begin{enumerate} + \item A grid line is supposed to indicate all positions where a + certain attribute attains a fixed value. But, then, a grid line + does not really need to be a grid \emph{line}. Consider for + instance a three dimensional axis system. A ``grid line'' for the + $x$-coordinate |3| would actually be a ``grid plane.'' + \item For a polar coordinate system and a fixed radius, this set of + positions at a certain radius is not a straight line, but an + arc. For more complicated coordinate systems such as the one + arising from three-dimensional spherical projections, a grid line + may well be a fairly involved curve. + \end{enumerate} + The |visualize grid| command addresses these complications as + follows: + \begin{enumerate} + \item A grid line is always a line, not a plane or a volume. This + means that in the example of a three dimensional axis system and + the $x$-attribute being |3|, one would have to choose whether the + grid line should go ``along'' the $y$-axis or ``along'' the + $z$-axis for this position. One can, however, call the + |visualize grid| command twice, once for each direction, to cause + grid lines to be shown for both directions. + \item A grid line is created by moving to a start position and then + doing a lineto to the target position. However, the ``moveto'' + and ``lineto'' are done by calling special commands of the data + visualization system. These special commands allow coordinate + system to ``notice'' that the line is along an axis and will allow + them to replace the straight line by an appropriate curve. The + polar axes systems employ this strategy, for instance. + \end{enumerate} + + By the above discussion, in order to create a grid line for + attribute $a$ having value $v$, we need to specify an axis ``along'' + which the line should be drawn. When there are only two axes, this + is usually ``the other axis''. This ``other axis'' is specified using the following key: + \begin{key}{/tikz/data visualization/direction axis=\meta{axis name}} + You must pass this key as an \meta{option} each time you use + |visualize axis|. When the grid line is drawn, the attribute $a$ + is set to $v$ and the axis \meta{axis name}'s attribute is set + once to the current value of |low| and once to |high|. Then a line + is drawn between these two positions using |\pgfpathdvlineto|. + \end{key} + The |low| and |high| keys are the same as the ones used in the + |visualize axis| key. + +\begin{codeexample}[] +\tikz \datavisualization [ + xyz Cartesian cabinet, + all axes={visualize axis={low=0, style=->}}, + x axis={visualize grid={direction axis=y axis}, grid=many}, + visualize as scatter] + data { + x, y, z + 0, 0, 1 + 0, 1, 0 + 2, 2, 2 + }; +\end{codeexample} +\begin{codeexample}[] +\tikz \datavisualization [ + xyz Cartesian cabinet, + all axes={visualize axis={low=0, style=->}, grid=many}, + x axis={visualize grid={direction axis=z axis}}, + z axis={visualize grid={direction axis=x axis}, + visualize grid={direction axis=y axis},}, + visualize as scatter] + data { + x, y, z + 0, 0, 1 + 0, 1, 0 + 2, 2, 2 + }; +\end{codeexample} + + \medskip + \textbf{Styling the grid lines.} + When a grid line is draw, styles are applied as described in + Section~\ref{section-dv-styling-grid-lines}. + + \medskip + \textbf{The major, minor, and subminor grid lines.} + The |grid| option allows you to specify for each kind of grid line + (major, minor, or subminor) a set of different values for which + these grid lines should be drawn. Correspondingly, it is also + possible to configure for each kind of grid line how it should be + drawn. For this, the |major|, |minor|, |subminor|, and also the + |common| keys can be used inside the \meta{options} of + |visualize grid|. While as option to |grid| these keys are used to + specify |at| values, as options of |visualize grid| they are used to + configure the different kinds of grid lines. + + Most of the time, no special configuration is necessary since all + styling is best done by configuring keys like + |every major grid|. You need to use a key like |major| only if you + wish to configure for instance the |low| or |high| values of a + |major| grid line differently from those of |minor| grid lines -- + are rather unlikely setting -- or when the styling should deviate + from the usual settings. +\begin{codeexample}[] +\tikz \datavisualization [ + xy Cartesian, + all axes={visualize axis={low=0, style=->}, + grid={some, minor steps between steps}}, + x axis= {visualize grid={ + direction axis=y axis, + minor={low=0.25, high=1.75, style=red!50}}}, + visualize as scatter] + data { + x, y + 0, 0 + 3, 3 + }; +\end{codeexample} +\end{key} + +Returning to the example of |our system| with the two axis systems, it +is straight-forward to configure the grid lines of the $x$-axis: The +direction axis is either of the other two axis (they point in the same +direction and they have the same range). For the other two axes, we +visualize one grid independently of the other, using different colors. + + +\begin{codeexample}[] +\tikzset{ + data visualization/our system/.append style={ + x axis= {visualize grid={direction axis=left axis}}, + left axis= {visualize grid={direction axis=x axis, + common={style=red!50}}}, + right axis={visualize grid={direction axis=x axis, + common={style=blue!50}}}, + } +} +\tikz \datavisualization [ + our system, + x axis={attribute=time, length=3cm, grid=many}, + left axis ={attribute=money, grid=some}, + right axis={attribute=people, grid=few}, + visualize as line/.list={people 1, people 2, money 1, money 2}] + data group {people and money}; +\end{codeexample} + + + +\subsubsection{Visualizing the Ticks and Tick Labels} + +\label{section-dv-visualize-ticks} + +\begin{key}{/tikz/data visualization/axis options/visualize ticks=\meta{options}} + Visualizing a tick involves (possibly) drawing a tick mark and + adding (possibly) the tick node. The process is similar to + |visualize grid|: Users use the |ticks| key to configure how many + ticks they would like for an axis and at which positions. The axis + system uses the |visualize ticks| key to specify where these ticks + should actually be shown. + + Unlike grid lines, which are typically only visualized once for each + combination of an axis and a direction axis, tick marks might be + visualized at different places for the same axis. Consider for + instance the |scientific axes|: +\begin{codeexample}[] +\tikz \datavisualization [scientific axes, all axes={length=3cm}, + x axis={ticks={stack}}, + visualize as smooth line] + data [format=function] { + var x : interval [0:2]; + func y = \value x*\value x; + }; +\end{codeexample} + Have a look at the ticks on the $y$-axis: There are ticks at values |0|, + |1|, |2|, |3|, and~|4|. These are visualized both at the left + side (where the tick nodes are also shown) and additionally also at + the right side, but only as small marks. Similarly, the ticks on the + $x$-axis appear at the bottom, but also (in much simpler versions) + at the top. Both for the $x$-axis and for the $y$-axis the + |visualize ticks| key was called twice. + + \medskip + \textbf{The tick marks.} + Drawing a tick mark is quite similar to visualizing a grid line; + indeed a tick mark can be thought of as a ``mini grid line'': Just + like a grid line it ``points a long an axis.'' However, a tick will + always be a short straight line -- even when the coordinate system + is actually twisted (experimentation has shown that ticks that + follow the curvature of the coordinate system like grid lines are + hard to recognize). For this reason, the |low| and |high| keys have + a different meaning from the one used with the |visualize grid| + key. In detail to configure the size and position of a tick mark for + the value $v$ of attribute $a$, proceed as follows: + \begin{itemize} + \item The |visualize ticks| key will have setup attribute $a$ to be + equal to $v$. + \item You should now use the |goto| or |goto pos| key together with all + \emph{other} axes to configure at which position with respect to + these other options the tick mark should be shown. For instance, + suppose we want tick marks in |our system| for the $x$-axis at the + bottom and at the top. This corresponds to once setting the + |left axis| to its minimal value and once to its maximal value: + +\begin{codeexample}[] +\tikzset{ + data visualization/our system/.append style={ + x axis={visualize ticks={direction axis=left axis, left axis={goto=min}}, + visualize ticks={direction axis=left axis, left axis={goto=max}}, + } + } +} +\tikz \datavisualization [ + our system, + x axis={attribute=time, length=3cm, ticks=many}, + left axis ={attribute=money}, + right axis={attribute=people}, + visualize as line/.list={people 1, people 2, money 1, money 2}] + data group {people and money}; +\end{codeexample} + \item In the above example, we may wish to shorten the ticks a bit + at the bottom and at the top. For this, we use the |low| and + |high| key: + \begin{key}{/tikz/data visualization/low=\meta{dimension}} + When used with the |visualize ticks| option, the |low| key + contains a dimension that specifies the extend of the tick going + ``toward the minimum'' of the direction axis. More precisely, when a tick + mark is visualized, a unit tangent vector at the current data point + in the direction of the |direction axis| is computed and this + vector is multiplied by \meta{dimension} to compute the start + position of the tick line. The end position is given by this + vector times the |high| value. + + Note that the \meta{dimension} should usually be negative for + the |low| key and positive for the |high| key. + + For tick marks where a tick label node is shown, the + \meta{dimension} is increased by the current values of keys like + |tick text even low padding|, see + Section~\ref{section-dv-stacking} for details. + \end{key} + \begin{key}{/tikz/data visualization/high=\meta{dimension}} + Like |low|. + \end{key} + \begin{key}{/tikz/data visualization/tick length=\meta{dimension}} + Shorthand for |low=-|\meta{dimension}|, high=|\meta{dimension}. + \end{key} + + What we want to happen is that in the upper visualization of the + ticks the |low| value is |0pt|, while in the lower one the |high| + value is |0pt|: +\begin{codeexample}[] +\tikzset{ + data visualization/our system/.append style={ + x axis={ + visualize ticks={direction axis=left axis,high=0pt,left axis={goto=min}}, + visualize ticks={direction axis=left axis,low=0pt,left axis={goto=max}}, + } + } +} +\tikz \datavisualization [ + our system, + x axis={attribute=time, length=3cm, ticks=many}, + left axis ={attribute=money}, + right axis={attribute=people}, + visualize as line/.list={people 1, people 2, money 1, money 2}] + data group {people and money}; +\end{codeexample} +\end{itemize} + In order to style the tick mark, use the styling mechanism that is + detailed in Section~\ref{section-dv-styling-ticks}. + + \medskip + \textbf{The tick label node.} + At certain tick positions, we may wish to add a node indicating the + value of the attribute at the given position. The |visualize ticks| + command has no influence over which text should be shown at a node + -- the text is specified and typeset as explained in + Section~\ref{section-dv-tick-labels}. + + Each time |visualize ticks|, for each tick position up to two tick + label nodes will be created: One at the |low| position and one at + the |high| position. The following keys are used to configure which + of these cases happen: + \begin{key}{/tikz/data visualization/tick text at + low=\opt{\meta{true or false}} (default true)} + Pass this option to |visualize ticks| when you want tick label + nodes to be placed at the |low| position of each tick mark. +\begin{codeexample}[] +\tikzset{ + data visualization/our system/.append style={ + x axis={ + visualize ticks={direction axis=left axis, left axis={goto=min}, + high=0pt, tick text at low, stack}, + visualize ticks={direction axis=left axis, left axis={goto=max}, + low=0pt, tick text at high, stack} + } + } +} +\tikz \datavisualization [ + our system, + x axis={attribute=time, length=3cm, ticks=some}, + left axis ={attribute=money}, + right axis={attribute=people}, + visualize as line/.list={people 1, people 2, money 1, money 2}] + data group {people and money}; +\end{codeexample} + \end{key} + \begin{key}{/tikz/data visualization/tick text at + high=\opt{\meta{true or false}} (default true)} + Like |tick text at low|. + \end{key} + + \begin{key}{/tikz/data visualization/no tick text} + Shorthand for |tick text at low=false, tick text at high=false|. +\begin{codeexample}[] +\tikz \datavisualization [scientific axes, all axes={length=3cm}, + x axis={ticks={ + major also at={6.5 as [no tick text]}}}, + visualize as smooth line] + data [format=function] { + var x : interval [5:10]; + func y = \value x * \value x; + }; +\end{codeexample} + \end{key} + + When a tick label node is to be placed at the low or the high + position, the next step is to determine the exact position and the + correct anchor of the node. This is done as follows: + \begin{itemize} + \item In order to compute an appropriate |anchor|, the tick mark is + considered: This is a short line pointing in a certain + direction. For a tick label node at the |low| position, the + |anchor| attribute is setup in such a way that the node label will + be below the |low| position when the tick mark direction points + up, it will be to the right when the direction points left, above + when it points down, and so on also for diagonal + directions. Similarly, for the |high| position, when the direction + points up, the node will be placed above the tick mark and so on. + + This computation is done automatically. + \item The tick label node is styled. The styles that are applied are + described in Section~\ref{section-dv-styling-ticks}. + \item A tick label node for the |low| position is usually anchored + at this |low| position, but an additional padding will be + added as described in Section~\ref{section-dv-stacking}. + \end{itemize} +\end{key} + + + + +\subsubsection{Visualizing the Axis Labels} + +\label{section-dv-visualize-label} + +The |label| option can be used with an axis to specify a text should +be shown next to the axis to indicates which attribute this axis +refers to. Like |ticks| or |grid|, the |label| option does not +actually draw the label, this is the job of the |visualize label| key, +which is configured by the axis system. + +\begin{key}{/tikz/data visualization/axis options/visualize label=\meta{options}} + The \meta{options} should be used to configure a ``good place'' for + the axis label. Usually, you will use the |goto| or the |goto pos| + key. + + For the example of |our system|, we would like the label of the + |x axis| to be placed below at the middle of the axis, so we use + |goto pos=.5| to determine this position. Concerning the other axes, + we want it to be placed at the minimum position of the |left axis| + with a lot of padding. +\begin{codeexample}[width=7cm] +\tikzdatavisualizationset{ + our system/.append style={ + x axis={visualize label={ + x axis={goto pos=.5}, + left axis={padding=1.5em, goto=padded min}}} + } +} +\tikz \datavisualization [ + our system, + x axis={attribute=time, ticks=some, label}, + left axis ={attribute=money}, + right axis={attribute=people}, + visualize as line/.list={ + people 1, people 2, money 1, money 2}] + data group {people and money}; +\end{codeexample} + + In the above example, the |padding| of |1.5em| was rather arbitrary + and ``suboptimal''. It would be outright wrong if the labels on the |x axis| were larger or + if they were missing. It would be better if the vertical position of + the |x axis| label were always ``below'' all other options. For such + cases a slightly strange approach is useful: You position the node + using |node style={at=...}| where |at| + is now the normal \tikzname\ option that is used to specify the + position of a node. Inside the |...|, you specify that the + horizontal position should be the bottom of up-to-now-constructed + data visualization and the vertical position should be at the + ``origin,'' which is, however, the position computed by the |goto| + keys for the axes: +\begin{codeexample}[width=7cm] +\tikzdatavisualizationset{ + our system/.append style={ + x axis={visualize label={ + x axis={goto pos=.5}, + node style={ + at={(0,0 |- data visualization bounding box.south)}, + below +} } } } } +\tikz \datavisualization [ + our system, + x axis={attribute=time, ticks=some, label=Year}, + left axis ={attribute=money}, + right axis={attribute=people}, + visualize as line/.list={ + people 1, people 2, money 1, money 2}] + data group {people and money}; +\end{codeexample} + + Two additional keys are useful for positioning axis labels: + \begin{key}{/tikz/data visualization/axis option/anchor at min} + When passed to an axis, this key sets the |anchor| so that a node + positioned at either the |min| or the |padded min| value of the + axis will be placed ``nicely'' with respect to the axis. For + instance, if the axis points upwards from the |min| value to the + |max| value, the |anchor| would be set to |north| since this gives + a label below the axis's start. Similarly, if the axis points + right, the anchor would be set to |east|, and so on. + \end{key} + \begin{key}{/tikz/data visualization/axis option/anchor at max} + Like |anchor at min|. + \end{key} +\end{key} + + +\subsubsection{The Complete Axis System} + +Here is the code for the complete axis system developed above and an +example of how it is used: + +\begin{codeexample}[code only] +\tikzdatavisualizationset{ our system/.style={ + % The axes + new Cartesian axis=x axis, new Cartesian axis=left axis, new Cartesian axis=right axis, + % The directions of the axes + all axes={padding=.5em}, left axis={unit vector={(0cm,1pt)}}, right axis={unit vector={(0cm,1pt)}}, + % The default attributes, other attributes must be configured + x axis={attribute=x}, + % The lengths of the axes + x axis ={length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/width}}, + left axis ={length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height}}, + right axis={length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height}}, + % The styling of the axes + every axis/.style={style=black!50}, % make this the default + % Visualizing the axes themselves + left axis= {visualize axis={x axis= {goto=padded min}, style=red!75, padded}}, + right axis={visualize axis={x axis= {goto=padded max}, style=blue!75,padded}}, + x axis= {visualize axis={left axis={goto=padded min}, padded}, + visualize axis={left axis={goto=padded max}, padded}}, + % Visualizing the grid, when requested + x axis= {visualize grid={direction axis=left axis}}, + left axis= {visualize grid={direction axis=x axis, common={style=red!50}}}, + right axis={visualize grid={direction axis=x axis, common={style=blue!50}}}, + % Visualizing the ticks, when requested + left axis={visualize ticks={style={red!50!black}, direction axis=x axis, + x axis={goto=padded min}, high=0pt, tick text at low}}, + right axis={visualize ticks={style={blue!80!black}, direction axis=x axis, + x axis={goto=padded max}, low=0pt, tick text at high}}, + x axis={visualize ticks={direction axis=left axis, left axis={goto=padded min}, high=0pt, + tick text at low}, + visualize ticks={direction axis=left axis, left axis={goto=padded max}, low=0pt}}, + % By default, there are ticks on all axes + all axes={ticks}, + % Visualizing the axis labels, when requested + x axis={visualize label={x axis={goto pos=.5}, node style={ + at={(0,0 |- data visualization bounding box.south)}, below}}}, + left axis={visualize label={left axis={goto pos=.5}, node style={ + at={(0,0 -| data visualization bounding box.west)}, rotate=90, anchor=south, red!50!black}}}, + right axis={visualize label={right axis={goto pos=.5}, node style={ + at={(0,0 -| data visualization bounding box.east)}, rotate=-90, anchor=south, blue!80!black}}}, +}} +\end{codeexample} + + +\tikzdatavisualizationset{ + our system/.style={ + % The axes + new Cartesian axis=x axis, + new Cartesian axis=left axis, + new Cartesian axis=right axis, + % The default attributes, other attributes must be configured + x axis={attribute=x}, + % The directions of the axes + all axes={padding=.5em}, + left axis={unit vector={(0cm,1pt)}}, + right axis={unit vector={(0cm,1pt)}}, + % The lengths of the axes + x axis ={length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/width}}, + left axis ={length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height}}, + right axis={length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height}}, + % The styling of the axes + every axis/.style={style=black!50}, % make this the default + % Visualizing the axes themselves + left axis= {visualize axis={x axis= {goto=padded min}, style=red!75, padded}}, + right axis={visualize axis={x axis= {goto=padded max}, style=blue!75,padded}}, + x axis= {visualize axis={left axis={goto=padded min}, padded}, + visualize axis={left axis={goto=padded max}, padded}}, + % Visualizing the grid, when requested + x axis= {visualize grid={direction axis=left axis, padded}}, + left axis= {visualize grid={direction axis=x axis, padded, common={style=red!50}}}, + right axis={visualize grid={direction axis=x axis, padded, common={style=blue!50}}}, + % Visualizing the ticks, when requested + left axis={ + visualize ticks={style={red!50!black}, direction axis=x axis, x axis={goto=padded min}, high=0pt, tick text at low}}, + right axis={ + visualize ticks={style={blue!80!black}, direction axis=x axis, x axis={goto=padded max}, low=0pt, tick text at high}}, + x axis={ + visualize ticks={direction axis=left axis, left axis={goto=padded min}, high=0pt, tick text at low}, + visualize ticks={direction axis=left axis, left axis={goto=padded max}, low=0pt} + }, + % By default, there are ticks on all axes + all axes={ticks}, + % Visualizing the axis labels, when requested + x axis={visualize label={ + x axis={goto pos=.5}, node style={at={(0,0 |- data visualization bounding box.south)}, below}}}, + left axis={visualize label={ + left axis={goto pos=.5}, node style={ + at={(0,0 -| data visualization bounding box.west)}, rotate=90, anchor=south, red!50!black}}}, + right axis={visualize label={ + right axis={goto pos=.5}, node style={ + at={(0,0 -| data visualization bounding box.east)}, rotate=-90, anchor=south, blue!80!black}}}, + } +} + +\begin{codeexample}[] +\tikz \datavisualization [ + our system, + x axis={attribute=time, label=Year, + ticks={tick text padding=2pt, style={/pgf/number format/set thousands separator=}}}, + left axis={attribute=money, label=Spending, + padding min=0, include value=0, grid, + ticks={tick prefix=\$, style={/pgf/number format/fixed, + /pgf/number format/fixed zerofill, /pgf/number format/precision=2}}}, + right axis={attribute=people, + label=Population, + padding min=0, include value=0, + ticks={style=/pgf/number format/fixed}}, + visualize as line/.list={ + people 1, people 2, money 1, money 2}, + people 1={style={visualizer color=blue}}, + people 2={style={visualizer color=blue!50}}, + money 1={style={visualizer color=red}}, + money 2={style={visualizer color=red!50}} ] +data group {people and money}; +\end{codeexample} + + + +\subsubsection{Using the New Axis System Key} + +The axis system |our system| that we developed in the course of the +previous section is not yet ``configurable.'' The only configuration +that was possible was to ``misuse'' the |width| and |height| keys of +the |scientific axes|. + +In order to make |our system| configurable so that we can say +|our system=|\meta{options}, where \meta{options} are executed with +the path prefix +\begin{codeexample}[code only] +/tikz/data visualization/our system +\end{codeexample} +we can use the following key: + +\begin{key}{/tikz/data visualization/new axis system=\marg{axis system + name}\marg{axis setup}\marg{default options}\\ \marg{application + options}} + The |new axis system| key takes four parameters. The first one, + \meta{system name}, is the name of the to-be-created axis system, + |our system| in our case. The |new axis system| will create the + following new key: + \begin{key}{/tikz/data visualization/\meta{axis system + name}=\opt{\meta{options}}} + When the key \meta{axis system name} is used, the following keys + will be executed in the following order: + \begin{enumerate} + \item + The \meta{axis setup} with the path prefix |/tikz/data visualization/|. + \item + The \meta{default options} with the same path prefix. + \item + The following style: + \begin{stylekey}{/tikz/data visualization/every \meta{axis system name}} + Even though this style has the path prefix + |/tikz/data visualization| itself, the keys stored in this + style will be executed with the path prefix + |/tikz/data visualization/|\meta{axis system name}. + \end{stylekey} + \item + The \meta{options} with the path prefix + |/tikz/data visualization/|\meta{axis system name}. + \item + The \meta{application options} with the path prefix |/tikz/data visualization/| + \end{enumerate} + \end{key} + + Let us now have a look at what all of this means. First, the + \meta{axis setup} will contain all options that setup the axis + system in all ways that need not be configured. For instance, the + \meta{axis setup} for the |scientific axes| will create an |x axis| + and also a |y axis| (because these are always present), but will not + setup the label visualization (because this can be configured in + different ways). For |our system|, which cannot be configured at + all, we would place all of our configuration in the \meta{axis + setup}. + + The \meta{default options} can be used to pick default values that + would usually be passed to the \meta{options} of the newly created + axis system. For instance, for |scientific axis|, the + \meta{default options} are set to |outer ticks,standard labels|, + because these are the defaults. + + Finally, the \meta{application options} can be used to actually + apply the configuration that has been chosen by the + \meta{options}. The idea is that \meta{default options}, + \meta{options}, and also |every| \meta{axis system name} all have a + chance of changing, re-changing and re-setting all sorts of styles + and keys. Then, with the last change ``winning,'' the resulting + setting of a style can be executed, which may then cause a label + visualization to be installed. +\end{key} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-backend.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-backend.tex index ef7f0be25f1..23ffe87eb89 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-backend.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-backend.tex @@ -16,7 +16,19 @@ The present section explains the mechanisms behind the data visualization engine. +Until it is documented properly, we will have to make do with the +documentation in the source code. + + \subsection{The Rendering Pipeline} +To be written... + \subsection{Usage} +To be written... + +\subsection{The Mathematical Micro-Kernel} + +\label{section-dv-math-kernel} +To be written... diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-examples.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-examples.tex index fa6ea38fcbb..ce4c95a5e38 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-examples.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-examples.tex @@ -18,7 +18,7 @@ A first example: clean ticks, all axes={grid={step=1,minor steps between steps=1}}, x axis={ - ticks={some, + ticks={ major={ also at={(0.5*pi) as $\pi/2$}, also at={(pi) as $\pi$}, @@ -40,15 +40,15 @@ A first example: \begin{codeexample}[] \begin{tikzpicture}[baseline] \datavisualization [ - scientific clean axes, + scientific axes=clean, visualize as line, all axes={padding=4pt}, x axis={logarithmic, ticks={many, tick unit={ms}, node style={rotate=45,anchor=north east}}, label={time}, - grid=many}, - y axis={ticks={some},label={distance}}, + grid}, + y axis={label={distance}}, ] data { x, y, z @@ -63,7 +63,7 @@ A first example: \begin{codeexample}[] \begin{tikzpicture}[baseline,mark=*] \datavisualization [ - scientific inner axes, + scientific axes=inner ticks, all axes={padding=4pt}, euro about strategy, visualize as scatter, diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-formats.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-formats.tex index 2afb9568a2b..f7a6e54eb09 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-formats.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-formats.tex @@ -157,22 +157,43 @@ angle, radius \end{dataformat} -\begin{dataformat}{key value pairs} - Each line of the data is simply passed to the |\pgfkeys| command - with the path set to |/data point/|. This means that each data line - will typically consist of comma-separated assignments of the form - \meta{attribute}|=|\meta{value}. - \begin{codeexample}[] +\begin{dataformat}{named} + Basically, each line of the data must consist of a comma-separated + sequence of attribute--values pairs like |x=5, lo=500|. This will + cause the attribute |/data point/x| to be set to |5| and + |/data point/lo| to be set to |500|. +\begin{codeexample}[] \begin{tikzpicture} \datavisualization [school book axes, visualize as line] - data [format=key value pairs] { + data [format=named] { x=0, y=0 x=1, y=1 x=2, y=1 x=3, y=0 }; \end{tikzpicture} - \end{codeexample} +\end{codeexample} + However, instead of just specifying a single value for an attribute + as in |x=5|, you may also specify a whole set of values as in + |x={1,2,3}|. In this case, three data points will be created, one + for each value in the list. Indeed, the |\foreach| statement is used + to iterate over the list of values, so you can write things like + |x={1,...,5}|. + + It is also permissible to specify lists of values for more than one + attribute. In this case, a data point is created for each possible + combination of values in the different lists: +\begin{codeexample}[width=7cm] +\tikz \datavisualization + [scientific axes=clean, + visualize as scatter/.list={a,b,c}, + style sheet=cross marks] +data [format=named] { + x=0, y={1,2,3}, set=a + x={2,3,4}, y={3,4,5,7}, set=b + x=6, y={5,7,...,15}, set=c +}; +\end{codeexample} \end{dataformat} \begin{dataformat}{TeX code} @@ -196,6 +217,8 @@ angle, radius \end{dataformat} + + \subsection{Reference: Advanced Formats} \begin{tikzlibrary}{datavisualization.formats.functions} @@ -215,20 +238,25 @@ angle, radius variable declaration signals that a certain attribute will range over a given interval. The function declarations will then, later, be evaluated for values inside this interval. The syntax for a - variable declaration is as follows: - \begin{quote} + variable declaration is one of the following: + \begin{enumerate} + \item |var |\declare{\meta{variable}}| : interval[|\meta{low}|:|\meta{high}|]| - \opt{|samples |\meta{number}} \opt{|step |\meta{step}}|;| - \end{quote} - The |samples| and |step| options cannot be given both at the same - time. If both are missing, |samples| is used with the value stored - in the following key: + \opt{|samples |\meta{number}}|;| + \item + |var |\declare{\meta{variable}}| : interval[|\meta{low}|:|\meta{high}% + |] step |\meta{step}|;| + \item + |var |\declare{\meta{variable}}| : {|\meta{values}|};| + \end{enumerate} + In the first case, if the optional |samples| part is missing, the + number of |samples| is taken from the value stored in the following key: \begin{key}{/pgf/data/samples=\meta{number} (initially 25)} Sets the number of samples to be used when no sample number is specified. \end{key} - The meaning of a declaration like the above is the following: The - attribute named \meta{variable}, that is, the key + The meaning of declaring a variable declaration to range over an + |interval| is that the attribute named \meta{variable}, that is, the key |/data point/|\meta{variable}, will range over the interval $[\meta{low},\meta{high}]$. If the number of |samples| is given (directly or indirectly), the interval is evenly divided into @@ -237,6 +265,10 @@ angle, radius stepping is used to increase \meta{low} iteratively up to the largest value that is still less or equal to \meta{high}. + The meaning of declaring a variable using a list of \meta{values} + is that the variable will simply iterate over the values using + |\foreach|. + You can specify more than one variable. In this case, each variable is varied independently of the other variables. For instance, if you declare an $x$-variable to range over the @@ -268,28 +300,43 @@ angle, radius specification. In this case, all of these functions will be evaluated for each setting of input variables. - \begin{codeexample}[] -\begin{tikzpicture} +\begin{codeexample}[] +\tikz \datavisualization [school book axes, visualize as smooth line] data [format=function] { var x : interval [-1.5:1.5]; func y = \value x * \value x; }; -\end{tikzpicture} - \end{codeexample} - \begin{codeexample}[] -\begin{tikzpicture} - \datavisualization [school book axes, visualize as smooth line, - all axes={ticks={few},unit length=3mm}] - data [format=function] { - var t : interval [0:2*pi]; - - func x = \value t * cos(\value t r); - func y = \value t * sin(\value t r); - }; -\end{tikzpicture} - \end{codeexample} +\end{codeexample} +\begin{codeexample}[width=6cm] +\tikz \datavisualization [ + school book axes, + all axes={unit length=5mm, ticks={step=2}}, + visualize as smooth line] +data [format=function] { + var t : interval [0:2*pi]; + + func x = \value t * cos(\value t r); + func y = \value t * sin(\value t r); +}; +\end{codeexample} +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + scientific axes=clean, + y axis={ticks={style={ + /pgf/number format/fixed, + /pgf/number format/fixed zerofill, + /pgf/number format/precision=2}}}, + x axis={ticks={tick suffix=${}^\circ$}}, + visualize as smooth line/.list={1,2,3,4,5,6}, + style sheet=vary hue] +data [format=function] { + var set : {1,...,6}; + var x : interval [0:50]; + func y = sin(\value x * (\value{set}+10))/(\value{set}+5); +}; +\end{codeexample} \end{dataformat} \end{tikzlibrary} @@ -331,16 +378,16 @@ Let us now have a look at how |\pgfdata| works. The first important option is \meta{source}, which governs which of these two alternatives applies: - \begin{key}{/pgf/data/source=\meta{filename} (initially \normalfont empty)} - If you set the |source| attribute to a non-empty \meta{filename}, + \begin{key}{/pgf/data/read from file=\meta{filename} (initially \normalfont empty)} + If you set the |read from file| attribute to a non-empty \meta{filename}, the data will be read from this file. In this case, no \meta{inline data} may be present, not even empty curly braces - should be provided. If |source| is empty, the data must directly - follow as \meta{inline data}. + should be provided. If |read from file| is empty, the data must + directly follow as \meta{inline data}. \begin{codeexample}[code only] % Data is read from two external files: -\pgfdata[format=table,source=file1.csv] -\pgfdata[format=table,source=file2.csv] +\pgfdata[format=table, read from file=file1.csv] +\pgfdata[format=table, read from file=file2.csv] \end{codeexample} \begin{codeexample}[code only] % Data is given inline: @@ -352,6 +399,10 @@ Let us now have a look at how |\pgfdata| works. } \end{codeexample} \end{key} + \begin{key}{/pgf/data/inline} + This is a shorthand file |read from file={}|. You can add this to + make it clear(er) to the reader that data follows inline. + \end{key} The second important key is |format|, which is used to specify the data format: \begin{key}{/pgf/data/format=\meta{format} (initially table)} @@ -440,6 +491,33 @@ Let us now have a look at how |\pgfdata| works. \end{enumerate} For an example of how this works, see the description of the |\pgfdeclaredataformat| command. + + \medskip + \textbf{Data sets.} + There are three options that allow you to create \emph{data + sets}. Such a data set is essentially a macro that stores a + pre-parsed set of data that can be used multiple times in subsequent + visualizations (or even in the same visualization). + \begin{key}{/pgf/data/new set=\meta{name}} + Creates an empty data set called \meta{name}. If a data set of the + same name already exists, it is overwritten and made empty. Data + sets are global. + \end{key} + \begin{key}{/pgf/data/store in set=\meta{name}} + When this key is set to any non-empty \meta{name} and if this + \meta{name} has previously been used with the |new set| key, then + the following happens: For the current |\pgfdata| command, all + parsed data is not passed to the rendering pipeline. Instead, the + parsed data is appended to the data set \meta{name}. This includes + all options parsed to the |\pgfdata| command, which is why neither + this key nor the previous key should be passed as options to a + |\pgfdata| command. + \end{key} + \begin{key}{/pgf/data/use set=\meta{name}} + This works similar to |read from file|. When this key is used with + a |\pgfdata| command, no inline data may follow. Instead, the data + stored in the data set \meta{name} is used. + \end{key} \end{command} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-main.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-main.tex index a2743a9fb57..1efb972e439 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-main.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-main.tex @@ -111,7 +111,7 @@ since the default format is the one used for the data following the represents a data point. \medskip -\textbf{Number accuracy.} +\textbf{Number accuracy.}\label{section-dv-expressions} Data visualizations typically demand a much higher accuracy and range of values than \TeX\ provides: \TeX\ numbers are limited to 13 bits for the integer part and 16 bits for the fractional part. Because of @@ -202,7 +202,7 @@ predefined styles take care of this for you: \begin{codeexample}[] \begin{tikzpicture} \datavisualization [ - scientific clean axes, + scientific axes=clean, x axis={length=3cm, ticks=few}, all axes={grid}, visualize as smooth line @@ -232,7 +232,7 @@ visualizers or pie chart visualizers. \begin{codeexample}[] \begin{tikzpicture} \datavisualization [ - scientific clean axes, + scientific axes=clean, x axis={length=3cm, ticks=few}, visualize as smooth line ] @@ -245,7 +245,7 @@ visualizers or pie chart visualizers. \begin{codeexample}[] \begin{tikzpicture} \datavisualization [ - scientific clean axes, + scientific axes=clean, x axis={length=3cm, ticks=few}, visualize as scatter ] @@ -291,24 +291,24 @@ coloring and the dashing is varied. \begin{codeexample}[] \begin{tikzpicture}[baseline] - \datavisualization [ scientific clean axes, + \datavisualization [ scientific axes=clean, y axis=grid, visualize as smooth line/.list={sin,cos,tan}, - visualizer style sheet=strong colors, - visualizer style sheet=vary dashing, + style sheet=strong colors, + style sheet=vary dashing, sin={label in legend={text=$\sin x$}}, cos={label in legend={text=$\cos x$}}, tan={label in legend={text=$\tan x$}}, data/format=function ] - data [sin] { + data [set=sin] { var x : interval [-0.5*pi:4]; func y = sin(\value x r); } - data [cos] { + data [set=cos] { var x : interval [-0.5*pi:4]; func y = cos(\value x r); } - data [tan] { + data [set=tan] { var x : interval [-0.3*pi:.3*pi]; func y = tan(\value x r); }; @@ -384,17 +384,17 @@ visualizations. The \meta{options} are executed with the prefix |/pgf/data|. The following options are always available: - \begin{key}{/pgf/data/source=\meta{filename} (initially \normalfont empty)} + \begin{key}{/pgf/data/read from file=\meta{filename} (initially \normalfont empty)} If you set the |source| attribute to a non-empty \meta{filename}, the data will be read from this file. In this case, no \meta{inline data} may be present, not even empty curly braces should be provided. \begin{codeexample}[code only] \datavisualization ... - data [source=file1.csv] - data [source=file2.csv]; + data [read from file=file1.csv] + data [read from file=file2.csv]; \end{codeexample} - The other way round, if |source| is empty, the data must directly + The other way round, if |read from file| is empty, the data must directly follow as \meta{inline data}. \begin{codeexample}[code only] \datavisualization ... @@ -434,12 +434,12 @@ visualizations. command: \begin{codeexample}[code only] \datavisualization... - data [/data point/experiment=7, source=experiment007.csv] - data [/data point/experiment=23, source=experiment023.csv]; + data [/data point/experiment=7, read from file=experiment007.csv] + data [/data point/experiment=23, read from file=experiment023.csv]; \end{codeexample} - \begin{codeexample}[] -\begin{tikzpicture} +\begin{codeexample}[] +\tikz \datavisualization [school book axes, visualize as line] data [/data point/x=1] { y @@ -451,7 +451,6 @@ visualizations. 2 0.5 }; -\end{tikzpicture} \end{codeexample} \medskip @@ -490,6 +489,86 @@ visualizations. \end{datavisualizationoperation} +\begin{datavisualizationoperation}{data point}{\opt{\oarg{options}}} + This command is used to specify data a single data point. The + \meta{options} are simply executed with the path |/data point| and + then a data point is created. This means that inside the + \meta{options} you just specify the values of all attributes in + key-value syntax. +\begin{codeexample}[] +\tikz \datavisualization [school book axes, visualize as line] + data point [x=1, y=1] data point [x=1, y=2] + data point [x=2, y=2] data point [x=2, y=0.5]; +\end{codeexample} +\end{datavisualizationoperation} + +\begin{key}{/tikz/data visualization/data point=\meta{options}} + This key is the ``key version'' of the previous command. The + difference is that this key can be used internally inside styles. +\begin{codeexample}[] +\tikzdatavisualizationset{ + horizontal/.style={ + data point={x=#1, y=1}, data point={x=#1, y=2}}, +} +\tikz \datavisualization +[ school book axes, visualize as line, + horizontal=1, + horizontal=2 ]; +\end{codeexample} +\end{key} + +\begin{datavisualizationoperation}{data group}{\opt{\oarg{options}}\marg{name}\opt{|+=|\marg{data specifications}}} + You can store a whole \meta{data specification} in a \emph{data + group}. This allows you to reuse data in multiple places without + having to write the data to an external file. + + The syntax of this command comes in the following three variants: + \begin{itemize} + \item |data group| \opt{\oarg{options}} \marg{name} |=| \marg{data specifications} + \item |data group| \opt{\oarg{options}} \marg{name} |+=| \marg{data specifications} + \item |data group| \opt{\oarg{options}} \marg{name} + \end{itemize} + In the first case, a new data group called \meta{name} is created (an + existing data group of the same name will be erased) and the following + \meta{data specifications} is stored in this data group. The data group + will not be fed to the rendering pipeline, but it is parsed at this + point as if it were. The defined data group is defined globally, so + you can used it in subsequent visualizations. The \meta{options} are + saved with the parsed \meta{data specifications}. + + In the second case, an already existing data group is extended by + adding the \meta{data specifications} to it. + + In the third case (detected by noting that the \meta{name} is + neither followed by an equal sign nor a plus sign), the contents of + the previously defined data group \meta{name} is inserted. The + \meta{options} are also executed. + + Let is now first create a data group. Note that nothing is drawn since + the ``dummy'' data visualization is empty and used only for the + definition of the data group. +\begin{codeexample}[] +\tikz \datavisualization data group {points} = { + data { + x, y + 0, 1 + 1, 2 + 2, 2 + 5, 1 + 2, 0 + 1, 1 + } +}; +\end{codeexample} + + We can now use this data in different plots: +\begin{codeexample}[] +\tikz \datavisualization [school book axes, visualize as line] data group {points}; +\qquad +\tikz \datavisualization [scientific axes=clean, visualize as line] data group {points}; +\end{codeexample} +\end{datavisualizationoperation} + \begin{datavisualizationoperation}{scope}{\opt{\oarg{options}}\marg{data specification}} @@ -501,14 +580,14 @@ visualizations. \datavisualization... scope [/data point/experiment=7] { - data [source=experiment007-part1.csv] - data [source=experiment007-part2.csv] - data [source=experiment007-part3.csv] + data [read from file=experiment007-part1.csv] + data [read from file=experiment007-part2.csv] + data [read from file=experiment007-part3.csv] } scope [/data point/experiment=23, format=foo] { - data [source=experiment023-part1.foo] - data [source=experiment023-part2.foo] + data [read from file=experiment023-part1.foo] + data [read from file=experiment023-part2.foo] }; \end{codeexample} \end{datavisualizationoperation} @@ -535,7 +614,7 @@ visualizations. func y = sin(\value x r); } info { - \draw [red] (visualization cs: x={(.5*pi)}, y=1) circle (1pt) + \draw [red] (visualization cs: x={(.5*pi)}, y=1) circle [radius=1pt] node [above,font=\footnotesize] {extremal point}; }; \end{tikzpicture} @@ -556,14 +635,40 @@ visualizations. \end{coordinatesystem} \end{datavisualizationoperation} -In order to put information \emph{behind} the data visualization, -you should usually use the |background| library and the background -layer. However, it is also possible to execute code at other points -during the data visualization process. Since this is potentially -more disruptive, special keys documented in -Section~\ref{section-dv-user-code} must be used. +\begin{datavisualizationoperation}{info'}{\opt{\oarg{options}}\marg{code}} + This command works like |info|, only the \meta{code} will be + executed just before the visualization is done. This allows you to + draw things \emph{behind} the visualization. + +\begin{codeexample}[] +\begin{tikzpicture}[baseline] + \datavisualization [ school book axes, visualize as line ] + data [format=function] { + var x : interval [-0.1*pi:2]; + func y = sin(\value x r); + } + info' { + \fill [red] (visualization cs: x={(.5*pi)}, y=1) circle [radius=2mm]; + }; +\end{tikzpicture} +\end{codeexample} +\end{datavisualizationoperation} + +\label{section-dv-bounding-box} +\begin{predefinednode}{data visualization bounding box} + This rectangle node stores a bounding box of the data visualization + that is currently being constructed. This node can be useful inside + |info| commands or when labels need to be added. +\end{predefinednode} +\begin{predefinednode}{data bounding box} + This rectangle node is similar to |data visualization bounding box|, + but it keeps track only of the actual data. The spaces needed for + grid lines, ticks, axis labels, tick labels, and other all other + information that is not part of the actual data is not part of this + box. +\end{predefinednode} \subsection{Advanced: Executing User Code During a Data Visualization} \label{section-dv-user-code} @@ -606,7 +711,7 @@ pipeline as you would normally do. In the following it is assumed that you are familiar with the concepts of Section~\ref{section-dv-backend}. \begin{key}{/tikz/data visualization/new object=\meta{options}} - This key servers two purposes: + This key serves two purposes: \begin{enumerate} \item This method makes it easy to create a new object as part of the diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-polar.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-polar.tex new file mode 100644 index 00000000000..7eb15fde505 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-polar.tex @@ -0,0 +1,433 @@ +% Copyright 2010 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + + + +\section{Polar Axes} + +\label{section-dv-polar} + + +\subsection{Overview} + +\begin{tikzlibrary}{datavisualization.polar} + This library contains keys that allow you to create plots in a polar + axis system is used. +\end{tikzlibrary} + +In a \emph{polar axis system} two attributes are visualized by +displacing a data point as follows: One attribute is used to compute a +an angle (a direction) while a second attribute is used as a radius (a +distance). The angle can be measured in degrees, radians, or can be +scaled arbitrarily. + + +\begin{codeexample}[width=8.5cm] +\tikz \datavisualization [ + scientific polar axes={0 to pi, clean}, + all axes=grid, + style sheet=vary hue, + legend=below + ] + [visualize as smooth line=sin, + sin={label in legend={text=$1+\sin \alpha$}}] + data [format=function] { + var angle : interval [0:pi]; + func radius = sin(\value{angle}r) + 1; + } + [visualize as smooth line=cos, + cos={label in legend={text=$1+\cos\alpha$}}] + data [format=function] { + var angle : interval [0:pi]; + func radius = cos(\value{angle}r) + 1; + }; +\end{codeexample} + +Most of the time, in order to create a polar axis system, you will +just use the |scientific polar axes| key, which takes a number of +options that allow you to configure the axis system in greater +detail. This key is documented in +Section~\ref{section-dv-sci-polar-axes}. Internally, this key uses +more low level keys which are documented in the en suite sections. + +It is worthwhile to note that the axes of a polar axis system are, +still, normal axes of the data visualization system. In particular, +all the configurations possible for, say, Cartesian axes also apply to +the ``angle axis'' and the ``radius axis'' of a polar axis system. For +instance, you can could make both axes logarithmic or style their +ticks: + +\begin{codeexample}[] +\tikz[baseline] \datavisualization [ + scientific axes={clean}, + x axis={attribute=angle, ticks={minor steps between steps=4}}, + y axis={attribute=radius, ticks={some, style=red!80!black}}, + all axes=grid, + visualize as smooth line=sin] + data [format=function] { + var t : interval [-3:3]; + func angle = exp(\value t); + func radius = \value{t}*\value{t}; + }; +\qquad +\tikz[baseline] \datavisualization [ + scientific polar axes={right half clockwise, clean}, + angle axis={logarithmic, + ticks={ + minor steps between steps=8, + major also at/.list={2,3,4,5,15,20}}}, + radius axis={ticks={some, style=red!80!black}}, + all axes=grid, + visualize as smooth line=sin] + data [format=function] { + var t : interval [-3:3]; + func angle = exp(\value t); + func radius = \value{t}*\value{t}; + }; +\end{codeexample} + + +\subsection{Scientific Polar Axis System} +\label{section-dv-sci-polar-axes} + +\begin{key}{/tikz/data visualization/scientific polar axes=\meta{options}} + This key installs a polar axis system that can be used in a + ``scientific'' publication. Two axes are created called the + |angle axis| and the |radius axis|. Unlike ``normal'' Cartesian + axes, these axes do not point in a specific direction. Rather, the + |radius axis| is used to map the values of one attribute to a + distance from the origin while the |angle axis| is used to map the + values of another attribute to a rotation angle. + + The \meta{options} will be executed with the path prefix +\begin{codeexample}[code only] +/tikz/data visualization/scientific polar axes +\end{codeexample} + The permissible keys are documented in the later subsections of this + section. + + Let us start with the configuration of the radius axis since it is + easier. Firstly, you should specify which attribute is linked to the + radius. The default is |radius|, but you will typically wish to + change this. As with any other axis, the |attribute| key is used to + configure the axis, see Section~\ref{section-dv-axis-attribute} for + details. You can also apply all other configurations to the radius + axis like, say, |unit length| or |length| or |style|. Note, however, + that the |logarithmic| key will not work with the radius axis for a + |scientific polar axes| system since the attribute value zero is + always placed at the center -- and for a logarithmic plot the value + |0| cannot be mapped. +\begin{codeexample}[width=8.8cm] +\tikz \datavisualization [ + scientific polar axes, + radius axis={ + attribute=distance, + ticks={step=5000}, + padding=1.5em, + length=3cm, + grid + }, + visualize as smooth line] +data [format=function] { + var angle : interval [0:100]; + func distance = \value{angle}*\value{angle}; +}; +\end{codeexample} + + For the |angle axis|, you can also specify an attribute using the + |attribute| key. However, for this axis the mapping of a value to an + actual angle is a complicated process involving many considerations + of how the polar axis system should be visualized. For this reason, + there are a large number of predefined such mappings documented in + Section~\ref{section-dv-angle-ranges}. + + Finally, as for a |scientific plot|, you can configure where the + ticks should be shown using the keys |inner ticks|, |outer ticks|, + and |clean|, documented below. +\end{key} + + +\subsubsection{Tick Placements} + +\begin{key}{/tikz/data visualization/scientific polar axes/outer ticks} + This key, which is the default, causes ticks to be drawn + ``outside'' the outer ``ring'' of the polar axes: +\begin{codeexample}[width=8.8cm] +\tikz \datavisualization [ + scientific polar axes={outer ticks, 0 to 180}, + visualize as smooth line] +data [format=function] { + var angle : interval [0:100]; + func radius = \value{angle}; +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/scientific polar axes/inner ticks} + This key causes the ticks to be ``turned to the inside.'' I do not + recommend using this key. +\begin{codeexample}[width=8.8cm] +\tikz \datavisualization [ + scientific polar axes={inner ticks, 0 to 180}, + visualize as smooth line] +data [format=function] { + var angle : interval [0:100]; + func radius = \value{angle}; +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/scientific polar axes/clean} + This key separates the area where the data is shown from the area + where the ticks are shown. Usually, this is the best choice for the + tick placement since it avoids a collision of data and + explanations. +\begin{codeexample}[width=8.8cm] +\tikz \datavisualization [ + scientific polar axes={clean, 0 to 180}, + visualize as smooth line] +data [format=function] { + var angle : interval [0:100]; + func radius = \value{angle}; +}; +\end{codeexample} +\end{key} + + +\subsubsection{Angle Ranges} +\label{section-dv-angle-ranges} + +Suppose you create a polar plot in which the radius values vary +between, say, $567$ and $1234$. Then the normal axis scaling mechanisms +can be used to compute a good scaling for the ``radius axis'': Place +the value $1234$ at a distance of , say, $5\,\mathrm{cm}$ from the +origin and place the value $0$ at the origin. Now, by comparison, +suppose that the values of the angle axis's attribute ranged between, +say, $10$ and $75.7$. In this case, we may wish the angles to be +scaled so that the minimum value is horizontal and the maximum value is +vertical. But we may also wish the a value of $0$ is horizontal and a +value of $90$ is vertical. + +Since it is unclear which interpretation is the right one, you have to +use an option to select which should happen. The applicable options +fall into three categories: + +\begin{itemize} +\item Options that request the scaling to be done in such a way that + the attribute is interpreted as a value in degrees and such that the + minimum and maximum of the depicted range is a multiple of + $90^\circ$. For instance, the option |0 to 180| causes the angle + axis to range from $0^\circ$ to $180^\circ$, independently of the + actual range of the values. +\item Options that work as above, but use radians rather than + degrees. An example is the option |0 to pi|. +\item Options that map the minimum value in the data to a horizontal + or vertical line and the maximum value to another such line. This is + useful when the values neither directly correspond to degrees or + radians. In this case, the angle axis may also be a logarithmic + axis. +\end{itemize} + +In addition to the above categories, all of the option documented in +the following implicitly also select quadrants that are used to depict +the data. For instance, the |0 to 90| key and also the |0 to pi half| +key setup the polar axis system in such a way that only first (upper +right) quadrant is used. No check is done whether the data fill +actually lie in this quadrant -- if it does not, the data will ``bleed +outside'' the range. Naturally, with a key like |0 to 360| or +|0 to 2pi| this cannot happen. + +In order to save some space in this manual, in the following the +different possible keys are only given in a table together with a +small example for each key. The examples were created using the +following code: + +\begin{codeexample}[] +\tikz \datavisualization [ + scientific polar axes={ + clean, + 0 to 90 % the option + }, + angle axis={ticks={step=30}}, + radius axis={length=1cm, ticks={step=1}}, + visualize as scatter] +data point [angle=20, radius=0.5] +data point [angle=30, radius=1] +data point [angle=40, radius=1.5]; +\end{codeexample} + +For the options on radians, the angle values have been replaced by +|0.2|, |0.3|, and |0.4| and the stepping has been changed by setting +|step=(pi/6)|. For the quadrant options, no stepping is set at all (it +is computed automatically). + +\def\polarexample#1#2#3#4#5{% + \texttt{#1}% + \indexkey{/tikz/data visualization/scientific polar axes/#1}& + \tikz [baseline]{\path(-2.25cm,0)(2.25cm,0); \datavisualization [ + scientific polar axes={clean, #1}, + angle axis={ticks={#2}}, + radius axis={length=1cm, ticks={step=1}}, + visualize as scatter + ] + data point [angle=#3, radius=0.5] + data point [angle=#4, radius=1] + data point [angle=#5, radius=1.5]; + \path ([yshift=-1em]current bounding box.south); + }& + \tikz [baseline]{\path(-2.25cm,0)(2.25cm,0); \datavisualization [ + scientific polar axes={outer ticks, #1}, + angle axis={ticks={#2}}, + radius axis={length=1cm, ticks={step=1}}, + visualize as scatter + ] + data point [angle=#3, radius=0.5] + data point [angle=#4, radius=1] + data point [angle=#5, radius=1.5]; + \path ([yshift=-1em]current bounding box.south); + } + \\ +} + +\begin{tabular}{lcc} + \emph{Option} & \emph{With clean ticks} & \emph{With outer ticks} \\ + \polarexample{0 to 90}{step=30}{20}{30}{40} + \polarexample{-90 to 0}{step=30}{20}{30}{40} + \polarexample{0 to 180}{step=30}{20}{30}{40} + \polarexample{-90 to 90}{step=30}{20}{30}{40} + \polarexample{0 to 360}{step=30}{20}{30}{40} + \polarexample{-180 to 180}{step=30}{20}{30}{40} +\end{tabular} + +\begin{tabular}{lcc} + \emph{Option} & \emph{With clean ticks} & \emph{With outer ticks} \\ + \polarexample{0 to pi half}{step=(pi/6)}{0.2}{0.3}{0.4} + \polarexample{-pi half to 0}{step=(pi/6)}{0.2}{0.3}{0.4} + \polarexample{0 to pi}{step=(pi/6)}{0.2}{0.3}{0.4} + \polarexample{-pi half to pi half}{step=(pi/6)}{0.2}{0.3}{0.4} + \polarexample{0 to 2pi}{step=(pi/6)}{0.2}{0.3}{0.4} + \polarexample{-pi to pi}{step=(pi/6)}{0.2}{0.3}{0.4} +\end{tabular} + +\begin{tabular}{lcc} + \emph{Option} & \emph{With clean ticks} & \emph{With outer ticks} \\ + \polarexample{quadrant}{}{20}{30}{40} + \polarexample{quadrant clockwise}{}{20}{30}{40} + \polarexample{fourth quadrant}{}{20}{30}{40} + \polarexample{fourth quadrant clockwise}{}{20}{30}{40} + \polarexample{upper half}{}{20}{30}{40} + \polarexample{upper half clockwise}{}{20}{30}{40} + \polarexample{lower half}{}{20}{30}{40} + \polarexample{lower half clockwise}{}{20}{30}{40} +\end{tabular} + +\begin{tabular}{lcc} + \emph{Option} & \emph{With clean ticks} & \emph{With outer ticks} \\ + \polarexample{left half}{}{20}{30}{40} + \polarexample{left half clockwise}{}{20}{30}{40} + \polarexample{right half}{}{20}{30}{40} + \polarexample{right half clockwise}{}{20}{30}{40} +\end{tabular} + + + +\subsection{Advanced: Creating a New Polar Axis System} + +\begin{key}{/tikz/data visualization/new polar axes=|\char`\{|\meta{angle axis + name}|\char`\}||\char`\{|\meta{radius axis name}|\char`\}|} + This key actually creates two axes, whose names are give as + parameters: An \emph{angle axis} and a \emph{radius axis}. These two + axes work in concert in the following way: Suppose a data point has two + attributes called |angle| and |radius| (these attribute names can be + changed by changing the |attribute| of the \meta{angle axis name} or + the \meta{radius axis name}, respectively). These two attributes are + then scaled as usual, resulting in two ``reasonable'' values $a$ + (for the angle) and $r$ (for the radius). Then, the data point gets + visualized (in principle, details will follow) at a position on the + page that is at a distance of $r$ from the origin and at an angle + of~$a$. +\begin{codeexample}[] +\tikz \datavisualization + [new polar axes={angle axis}{radius axis}, + radius axis={length=2cm}, + visualize as scatter] + data [format=named] { + angle={0,20,...,160}, radius={0,...,5} + }; +\end{codeexample} + In detail, the \meta{angle axis} keeps track of two vectors $v_0$ + and $v_{90}$, each of which will usually have unit length (length + |1pt|) and which point in two different directions. Given a radius + $r$ (measured in \TeX\ |pt|s, so if the + radius attribute |10pt|, then $r$ would be $10$) and an angle $a$, + let $s$ be the sine of $a$ and let $c$ be the cosine + of $a$, where $a$ is a number is degrees (so $s$ + would be $1$ for $a = 90$). Then, the current page position is + shifted by $c \cdot r$ times $v_0$ and, additionally, by $s \cdot r$ + times $v_{90}$. This means that in the + ``polar coordinate system'' $v_0$ is the unit vector along the + ``$0^\circ$-axis'' and $v_{90}$ is the unit vector along + ``$90^\circ$-axis''. The values of $v_0$ and $v_{90}$ can be changed + using the following key on the \meta{angle axis}: + \begin{key}{/tikz/data visualization/axis options/unit + vectors=|\char`\{|\meta{unit vector 0 + degrees}|\char`\}\char`\{|\meta{unit vector 90 + degrees}|\char`\}| (initially {\char`\{(1pt,0pt)\char`\}\char`\{(0pt,1pt)\char`\}})} + Both the \meta{unit vector 0 degrees} and the \meta{unit vector 90 + degrees} are \tikzname\ coordinates: +\begin{codeexample}[] +\tikz \datavisualization + [new polar axes={angle axis}{radius axis}, + radius axis={unit length=1cm}, + angle axis={unit vectors={(10:1pt)}{(60:1pt)}}, + visualize as scatter] + data [format=named] { + angle={0,90}, radius={0.25,0.5,...,2} + }; +\end{codeexample} + \end{key} +\end{key} + +Once created, the |angle axis| can be scaled conveniently using the +following keys: + +\begin{key}{/tikz/data visualization/axis options/degrees} + When this key is passed to the angle axis of a polar axis system, it + sets up the scaling so that a value of |360| on this axis + corresponds to a complete circle. +\begin{codeexample}[] +\tikz \datavisualization + [new polar axes={angle axis}{radius axis}, + radius axis={unit length=1cm}, + angle axis={degrees}, + visualize as scatter] + data [format=named] { + angle={10,90}, radius={0.25,0.5,...,2} + }; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/axis options/radians} + In contrast to |degrees|, this option sets up things so that a value + of |2*pi| on this axis corresponds to a complete circle. +\begin{codeexample}[] +\tikz \datavisualization + [new polar axes={angle axis}{radius axis}, + radius axis={unit length=1cm}, + angle axis={radians}, + visualize as scatter] + data [format=named] { + angle={0,1.5}, radius={0.25,0.5,...,2} + }; +\end{codeexample} +\end{key} + + + diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-stylesheets.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-stylesheets.tex index 44c866cd04b..43682ca38e3 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-stylesheets.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-stylesheets.tex @@ -13,17 +13,2430 @@ \subsection{Overview} -To be written... +In many data visualizations, different sets of data need to be +visualized in a single visualization. For instance, in a plot there +might be a line for the sine of~$x$ and another line for the cosine +of~$x$; in another visualization there might be a set of points +representing data from a first experiment and another set of points +representing data from a second experiment; and so on. In order to +indicate to which data set a data point belongs, one might plot the +curve of the sine in, say, black, and the curve of the cosine in red; +we might plot the data from the fist experiment using stars and the +data from the second experiment using circles; and so on. Finally, at +some place in the visualization -- either inside the data or in a +legend next to it -- the meaning of the colors or symbols need to be +explained. + +Just as you would like \tikzname\ to map the data points automatically +onto the axes, you will also typically wish \tikzname\ to choose for +instance the coloring of the lines automatically for you. This is done +using \emph{style sheets}. There are at least two good reasons why you +should prefer style sheets over configuring the styling of each +visualizer ``by hand'' using the |style| key: +\begin{enumerate} +\item It is far more convenient to just say + |style sheet=strong colors| than having to individually + picking the different colors. +\item The style sheets were chosen and constructed rather + carefully. + + For instance, the |strong colors| style sheet does not + pick colors like pure green or pure yellow, which have very low + contrast with respect to a white background and which often lead to + unintelligible graphics. Instead, opposing primary colors with + maximum contrast on a white background were picked that are visually + quite pleasing. + + Similarly, the different dashing style sheets are + constructed in such a way that there are only few and small gaps in + the dashing so that no data points get lost because the dashes are + spaced too far apart. Also dashing patterns were chosen that have a + maximum optical difference. + + As a final example, style sheets for + plot marks are constructed in such a way that even when two plot + marks lie directly on top of each other, they are still easily + distinguishable. +\end{enumerate} +The bottom line is that whenever possible, you should use one of the +predefined style sheets rather than picking colors or dashings at +random. \subsection{Concepts: Style Sheets} +A \emph{style sheet} is a predefined list of styles such as a list of +colors, a list of dashing pattern, a list of plot marks, or a +combinations thereof. A style sheet can be \emph{attached} to a data +point attribute. Then, the value of this attribute is used with data +points to choose which style in the list should be chosen to visualize +the data point. + +In most cases, there is just one attribute to which style sheets get +attached: the |/data point/visualizer| attribute. The effect of +attaching a style sheet to this attribute is that each visualizer is +styled differently. + +For the following examples, let us first define a simple data set: +\begin{codeexample}[] +\tikz \datavisualization data group {function classes} = { + data [set=log, format=function] { + var x : interval [0.2:2.5]; + func y = ln(\value x); + } + data [set=lin, format=function] { + var x : interval [-2:2.5]; + func y = 0.5*\value x; + } + data [set=squared, format=function] { + var x : interval [-1.5:1.5]; + func y = \value x*\value x; + } + data [set=exp, format=function] { + var x : interval [-2.5:1]; + func y = exp(\value x); + } +}; +\end{codeexample} + +\begin{codeexample}[width=6cm] +\tikz \datavisualization [ + school book axes, all axes={unit length=7.5mm}, + visualize as smooth line/.list={log, lin, squared, exp}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} + +\begin{codeexample}[width=6cm] +\tikz \datavisualization [ + school book axes, all axes={unit length=7.5mm}, + visualize as smooth line/.list={log, lin, squared, exp}, + style sheet=vary dashing] +data group {function classes}; +\end{codeexample} + + + \subsection{Concepts: Legends} +\label{section-dv-labels-in} + +A \emph{legend} is a box that is next to a data visualization (or +inside it at some otherwise empty position) that contains a textual +explanation of the different colors or styles used in a data +visualization. + +Just as it is difficult to get colors and dashing patterns right ``by +hand,'' it is also difficult to get a legend right. For instance, when +a small line is shown in the legend that represents the actual line in +the data visualization, if the line is too short and the dashing is +too large, it may be impossible to discern which dashing is actually +meant. Similarly, when plot marks are shown on such a short line, +using a simple straight line may make it hard to read the plot marks +correctly. + +The data visualization engine makes some effort to make it easy to +create high-quality legends. Additionally, it also offers ways of +easily adding labels for visualizers directly inside the data +visualization, which is even better than adding a legend, in general. + +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + school book axes, all axes={unit length=7.5mm}, + x axis={label=$x$}, + visualize as smooth line/.list={log, lin, squared, exp}, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + squared={label in legend={text=$x^2$}}, + exp= {label in legend={text=$e^x$}}, + style sheet=vary dashing] +data group {function classes}; +\end{codeexample} + + +\begin{codeexample}[width=6.3cm] +\tikz \datavisualization [ + school book axes, + x axis={label=$x$}, + visualize as smooth line/.list={log, lin, squared, exp}, + every data set label/.append style={text colored}, + log= {pin in data={text'=$\log x$, when=y is -1}}, + lin= {pin in data={text=$x/2$, when=x is 2, + pin length=1ex}}, + squared={pin in data={text=$x^2$, when=x is 1.1, + pin angle=230}}, + exp= {label in data={text=$e^x$, when=x is -2}}, + style sheet=vary hue] +data group {function classes}; +\end{codeexample} + + +\subsection{Usage: Style Sheets} + +\subsubsection{Picking a Style Sheet} + +To use a style sheet, you need to \emph{attach} it to an +attribute. You can attach multiple style sheets to an attribute and +in this case all of these style sheets can influence the appearance of +the data points. + +Most of the time, you will attach a style sheet to the |set| +attribute. This has the effect that each different data set inside the +same visualization is rendered in a different way. Since this use of +style sheets is the most common, there is a special, easy-to-remember +option for this: + +\begin{key}{/tikz/data visualization/style sheet=\meta{style sheet}} + Adds the \meta{style sheet} to the list of style sheets attached to + the |set| attribute. +\begin{codeexample}[width=6cm] +\tikz \datavisualization [ + school book axes, all axes={unit length=7.5mm}, + visualize as smooth line/.list={log, lin, squared, exp}, + style sheet=vary thickness and dashing, + style sheet=vary hue] +data group {function classes}; +\end{codeexample} +\end{key} + +While the |style sheet| key will attach a style sheet only to the +|set| attribute, the following key handler can be used to attach a +style sheet to an arbitrary attribute: + + +\begin{handler}{{.style sheet}=\meta{style sheet}} + Inside a data visualization you can use this key handler together + with an attribute, that is, with a key having the path prefix + |/data point|. For instance, in order to attach the \meta{style + sheet} |strong colors| to the attribute |set|, you could write +\begin{codeexample}[code only] +/data point/set/.style sheet=strong colors +\end{codeexample} + Indeed, the |style sheet| key is just a shorthand for the above. + + The effect of attaching a style sheet is the following: + \begin{itemize} + \item A new object is created that will monitor the attribute. + \item Each time a special \emph{styling key} is emitted by the data + visualization engine, this object will inspect the current value + of the attribute to which it is attached. + \item Depending on this value, one of the styles stored in the style + sheet is chosen (how this works, exactly, will be explained in a + moment). + \item The chosen style is then locally applied. + \end{itemize} + + In reality, things are a bit more complicated: If the attribute of + the data point happens to have a subkey named in the same way as the + value, then the value of is this subkey is used instead of the value + itself. This allows you to ``rename'' a value. + + In a sense, a style sheet behaves much like a visualizer (see + Section~\ref{section-dv-visualizers}): In accordance with the value + of a certain attribute, the appearance of data points + change. However, there are a few differences: First, the styling of + a data point needs to be triggered explicitly and this triggering is + not necessarily done for each data point individually, but only for + a whole visualizer. Second, styles can be computed even when no data + point is present. This is useful for instance in a legend since, + here, a visual representation of a visualizer needs to be created + independently of the actual data points. +\end{handler} + +\subsubsection{Creating a New Style Sheet} + +Creating a style sheet works as follows: For each +possible value that an attribute can attain we must specify a +style. This is done by creating a style key for each such possible +value with a special path prefix and setting this style key to the +desired value. The special path prefix is +|/pgf/data visualization/style sheets| followed by the name of the +style sheet. + +As an example, suppose we wish to create a style sheet |test| that makes +styled data points |red| when the attribute has value |foo| and +|green| when the attribute has value |bar| and |dashed, blue| when the +attribute is |foobar|. We could then write +\begin{codeexample}[code only] +/pgf/data visualization/style sheets/test/foo/.style={red}, +/pgf/data visualization/style sheets/test/bar/.style={green}, +/pgf/data visualization/style sheets/test/foobar/.style={dashed, blue}, +\end{codeexample} + +We could then attach this style sheet to the attribute |code| as +follows: +\begin{codeexample}[code only] +/data point/code/.style sheet=test +\end{codeexample} + +Then, when |/data point/code=foobar| holds when the styling signal is +raised, the style |dashed, blue| will get executed. + +A natural question arises concerning the situation that the value of +the attribute is not defined as a subkey of the style sheet. In this +case, a special key gets executed: + +\begin{stylekey}{/pgf/data visualization/style sheets/\meta{style + sheet}/default style=\meta{value}} + This key gets during styling whenever + |/pgf/data visualization/style sheet/|\meta{style + sheet}|/|\meta{value} is not defined. +\end{stylekey} + +Let us put all of this together in a real-life example. Suppose we +wish to create a style sheet that makes the first data set |green|, the +second |yellow| and the third one |red|. Further data sets should be, +say, |black|. The attribute that we intend to style is the |set| +attribute. For the moment, we assume that the data sets will be named +|1|, |2|, |3|, and so on (instead of, say, |experiment 1| or |sin| or +something more readable -- we will get rid of this restriction in a +minute). + +We would now write: + +\begin{codeexample}[] +\pgfkeys{ + /pgf/data visualization/style sheets/traffic light/.cd, + % All these styles have the above prefix. + 1/.style={green!50!black}, + 2/.style={yellow!90!black}, + 3/.style={red!80!black}, + default style/.style={black} +} +\tikz \datavisualization [ + school book axes, + visualize as line=1, + visualize as line=2, + visualize as line=3, + style sheet=traffic light] +data point [x=0, y=0, set=1] +data point [x=2, y=2, set=1] +data point [x=0, y=1, set=2] +data point [x=2, y=1, set=2] +data point [x=0.5, y=1.5, set=3] +data point [x=2.25, y=1.75, set=3]; +\end{codeexample} + +In the above example, we have to name the visualizers |1|, |2|, |3| +and so one since the value of the |set| attribute is used both assign +data points to visualizers and also pick a style sheet. However, it +would be much nicer if we could name any way we want. To achieve this, +we use the special rule for style sheets that says that if there is a +subkey of an attribute whose name is the same name as the value, then +the value of this key is used instead. This slightly intimidating +definition is much easier to understand when we have a look at an +example: + +\pgfkeys{ + /pgf/data visualization/style sheets/traffic light/.cd, + % All these styles have the above prefix. + 1/.style={green!50!black}, + 2/.style={yellow!90!black}, + 3/.style={red!80!black}, + default style/.style={black} +} + +\begin{codeexample}[] +% Definition of traffic light keys as above +\begin{tikzpicture} + \datavisualization data group {lines} = { + data point [x=0, y=0, set=normal] + data point [x=2, y=2, set=normal] + data point [x=0, y=1, set=heated] + data point [x=2, y=1, set=heated] + data point [x=0.5, y=1.5, set=critical] + data point [x=2.25, y=1.75, set=critical] + }; + \datavisualization [ + school book axes, + visualize as line=normal, + visualize as line=heated, + visualize as line=critical, + /data point/set/normal/.initial=1, + /data point/set/heated/.initial=2, + /data point/set/critical/.initial=3, + style sheet=traffic light] + data group {lines}; +\end{tikzpicture} +\end{codeexample} + +Now, it is a bit bothersome that we have to set all these +|/data point/set/...| keys by hand. It turns out that this is not +necessary: Each time a visualizer is created, a subkey of +|/data point/set| with the name of the visualizer is created +automatically and a number is stored that is increased for each new +visualizer in a data visualization. This means that the three lines +starting with |/data point| are inserted automatically for you, so +they can be left out. However, you would need them for instance when +you would like several different data sets to use the same styling: + + +\begin{codeexample}[] +% Definition of traffic light keys as above +\tikz \datavisualization [ + school book axes, + visualize as line=normal, + visualize as line=heated, + visualize as line=critical, + /data point/set/critical/.initial=1, % same styling as first set + style sheet=traffic light] +data group {lines}; +\end{codeexample} + +We can a command that slightly simplifies the definition of style +sheets: + +\begin{command}{\pgfdvdeclarestylesheet\marg{name}\marg{keys}} + This command executes the \meta{keys} with the path prefix + |/pgf/data visualization/style sheets/|\penalty0\meta{name}. The above + definition of the traffic light style sheet could be rewritten as + follows: +\begin{codeexample}[code only] +\pgfdvdeclarestylesheet{traffic light}{ + 1/.style={green!50!black}, + 2/.style={yellow!90!black}, + 3/.style={red!80!black}, + default style/.style={black} +} +\end{codeexample} +\end{command} + +As a final example, let us create a style sheet that changes the +dashing pattern according to the value of the attribute. We do not +need to define an large number of styles in this case, but can use the +|default style| key to ``calculate'' the correct dashing. + +\begin{codeexample}[] +\pgfdvdeclarestylesheet{my dashings}{ + default style/.style={dash pattern={on #1pt off 1pt}} +} +\tikz \datavisualization [ + school book axes, + visualize as line=normal, + visualize as line=heated, + visualize as line=critical, + style sheet=my dashings] +data group {lines}; +\end{codeexample} + +\subsubsection{Creating a New Color Style Sheet} + +Creating a style sheet that varies colors according to an attribute +works the same way as creating a normal style sheet: Subkeys lies |1|, +|2|, and so on use the |style| attribute to setup a color. However, +instead of using the |color| attribute to set the color, you should +use the |visualizer color| key to set the color: + +\begin{key}{/tikz/visualizer color=\meta{color}} + This key is used to set the color |visualizer color| to + \meta{color}. This color is used by visualizers to color the data + they visualize, rather than the current ``standard color.'' The + reason for not using the normal current color is simply that it + makes many internals of the data visualization engine a bit + simpler. +\begin{codeexample}[] +\pgfdvdeclarestylesheet{my colors} +{ + default style/.style={visualizer color=black}, + 1/.style={visualizer color=black}, + 2/.style={visualizer color=red!80!black}, + 3/.style={visualizer color=blue!80!black}, +} +\tikz \datavisualization [ + school book axes, + visualize as line=normal, + visualize as line=heated, + visualize as line=critical, + style sheet=my colors] +data group {lines}; +\end{codeexample} +\end{key} + +There is an additional command that makes it easy to define a style +sheet based on a \emph{color series}. Color series are a concept from +the |xcolor| package: The idea is that we start with a certain color +for the first data set and then add a certain ``color offset'' for +each next data point. Please consult the documentation of the |xcolor| +package for details. + +\begin{command}{\tikzdvdeclarestylesheetcolorseries\marg{name}\marg{color + model}\marg{initial color}\marg{step}} + This command creates a new style sheet using + |\pgfdvdeclarestylesheet|. This style sheet will only have a default + style setup that maps numbers to the color in the color series + starting with \meta{initial color} and having a stepping of + \meta{step}. Note that when the value of the attribute is |1|, which + it is the first data set, the \emph{second} color in the color + series is used (since counting starts at |0| for color + series). Thus, in general, you need to start the \meta{initial + color} ``one early.'' +\begin{codeexample}[] +\tikzdvdeclarestylesheetcolorseries{greens}{hsb}{0.3,1.3,0.8}{0,-.4,-.1} +\tikz \datavisualization [ + school book axes, + visualize as line=normal, + visualize as line=heated, + visualize as line=critical, + style sheet=greens] +data group {lines}; +\end{codeexample} + +\end{command} + -\subsection{Usage: Selecting Style Sheets} -\subsection{Usage: Labeling Visualizations} \subsection{Reference: Style Sheets for Lines} +The following style sheets can be applied to visualizations that use +the |visualize as line| and related keys. For the examples, the +following style and data set are used: + +\begin{codeexample}[code only] +\tikzdatavisualizationset { + example visualization/.style={ + scientific axes=clean, + y axis={ticks={style={ + /pgf/number format/fixed, + /pgf/number format/fixed zerofill, + /pgf/number format/precision=2}}}, + x axis={ticks={tick suffix=${}^\circ$}}, + 1={label in legend={text=$\frac{1}{6}\sin 11x$}}, + 2={label in legend={text=$\frac{1}{7}\sin 12x$}}, + 3={label in legend={text=$\frac{1}{8}\sin 13x$}}, + 4={label in legend={text=$\frac{1}{9}\sin 14x$}}, + 5={label in legend={text=$\frac{1}{10}\sin 15x$}}, + 6={label in legend={text=$\frac{1}{11}\sin 16x$}}, + 7={label in legend={text=$\frac{1}{12}\sin 17x$}}, + 8={label in legend={text=$\frac{1}{13}\sin 18x$}} + } +} +\end{codeexample} +\tikzdatavisualizationset { + example visualization/.style={ + scientific axes=clean, + y axis={ticks={style={ + /pgf/number format/fixed, + /pgf/number format/fixed zerofill, + /pgf/number format/precision=2}}}, + x axis={ticks={tick suffix=${}^\circ$}}, + 1={label in legend={text=$\frac{1}{6}\sin 11x$}}, + 2={label in legend={text=$\frac{1}{7}\sin 12x$}}, + 3={label in legend={text=$\frac{1}{8}\sin 13x$}}, + 4={label in legend={text=$\frac{1}{9}\sin 14x$}}, + 5={label in legend={text=$\frac{1}{10}\sin 15x$}}, + 6={label in legend={text=$\frac{1}{11}\sin 16x$}}, + 7={label in legend={text=$\frac{1}{12}\sin 17x$}}, + 8={label in legend={text=$\frac{1}{13}\sin 18x$}} + } +} + +\begin{codeexample}[code only] +\tikz \datavisualization data group {sin functions} = { + data [format=function] { + var set : {1,...,8}; + var x : interval [0:50]; + func y = sin(\value x * (\value{set}+10))/(\value{set}+5); + } +}; +\end{codeexample} +\tikz \datavisualization data group {sin functions} = { + data [format=function] { + var set : {1,...,8}; + var x : interval [0:50]; + func y = sin(\value x * (\value{set}+10))/(\value{set}+5); + } +}; + +\begin{stylesheet}{vary thickness} + This style varies the thickness of lines. It should be used only + when there are only two or three lines, and even then it is not + particularly pleasing visually. +\begin{codeexample}[width=10cm] +\tikz \datavisualization [ + visualize as smooth line/.list= + {1,2,3,4,5,6,7,8}, + example visualization, + style sheet=vary thickness] +data group {sin functions}; +\end{codeexample} +\end{stylesheet} + + +\begin{stylesheet}{vary dashing} + This style varies the dashing of lines. Although it is not + particularly pleasing visually and although visualizations using + this style sheet tend to look ``excited'' (but not necessarily + ``exciting''), this style sheet is often the best choice when the + visualization is to be printed in black and white. +\begin{codeexample}[width=10cm] +\tikz \datavisualization [ + visualize as smooth line/.list= + {1,2,3,4,5,6,7,8}, + example visualization, + style sheet=vary dashing] +data group {sin functions}; +\end{codeexample} + As can be seen, there are only seven distinct dashing patterns. The + eighth and further lines will use a solid line once more. You will + then have to specify the dashing ``by hand'' using the |style| + option together with the visualizer. +\end{stylesheet} + +\begin{stylesheet}{vary dashing and thickness} + This style alternates between varying the thickness and the dashing + of lines. The + difference to just using both the |vary thickness| and + |vary dashing| is that too thick lines are avoided. Instead, this + style creates clearly distinguishable line styles for many lines (up + to 14) with a minimum of visual clutter. This style is the most + useful for visualizations when many different lines (ten or more) + should be printed in black and white. +\begin{codeexample}[width=10cm] +\tikz \datavisualization [ + visualize as smooth line/.list= + {1,2,3,4,5,6,7,8}, + example visualization, + style sheet=vary thickness + and dashing] +data group {sin functions}; +\end{codeexample} + For comparison, here is the must-less-than-satisfactory result of + combining the two independent style sheets: +\begin{codeexample}[width=10cm] +\tikz \datavisualization [ + visualize as smooth line/.list= + {1,2,3,4,5,6,7,8}, + example visualization, + style sheet=vary thickness, + style sheet=vary dashing] +data group {sin functions}; +\end{codeexample} +\end{stylesheet} + + +\subsection{Reference: Style Sheets for Scatter Plots} + +The following style sheets can be used both for scatter plots and also +with lines. In the latter case, the marks are added to the lines. + +\begin{stylesheet}{cross marks} + This style uses different crosses to distinguish between the data + points of different data sets. The crosses were chosen in such a way + that when two different cross marks lie at the same coordinate, + their overall shape allows one to still uniquely determine which + marks are on top of each other. + + This style supports only up to six different data sets. +\begin{codeexample}[width=10cm] +\tikz \datavisualization [ + visualize as scatter/.list= + {1,2,3,4,5,6,7,8}, + example visualization, + style sheet=cross marks] +data group {sin functions}; +\end{codeexample} +\begin{codeexample}[width=10cm] +\tikz \datavisualization [ + visualize as smooth line/.list= + {1,2,3,4,5,6,7,8}, + example visualization, + style sheet=cross marks] +data group {sin functions}; +\end{codeexample} +\end{stylesheet} + + \subsection{Reference: Color Style Sheets} +Color style sheets are very useful for creating visually pleasing data +visualizations that contain multiple data sets. However, there are two +things to keep in mind: + +\begin{itemize} +\item At some point, every data visualization is printed or photo + copied in black and white by someone. In this case, data sets can + often no longer be distinguished. +\item A few people are color blind. They will not be able to + distinguish between red and green lines (and some people are not + even able to distinguish colors at all). +\end{itemize} + +For these reasons, if there is any chance that the data visualization +will be printed in black and white at some point, consider combining +color style sheets with style sheets like |vary dashing| to make data +sets distinguishable in all situations. + + +\begin{stylesheet}{strong colors} + This style sheets uses pure primary colors that can very easily be + distinguished. Although not as visually pleasing as the |vary hue| + style sheet, the visualizations are easier to read when this style + sheet is used. Up to six different data sets are supported. +\begin{codeexample}[width=10cm] +\tikz \datavisualization [ + visualize as smooth line/.list= + {1,2,3,4,5,6,7,8}, + example visualization, + style sheet=strong colors] +data group {sin functions}; +\end{codeexample} +\begin{codeexample}[width=10cm] +\tikz \datavisualization [ + visualize as smooth line/.list= + {1,2,3,4,5,6,7,8}, + example visualization, + style sheet=strong colors, + style sheet=vary dashing] +data group {sin functions}; +\end{codeexample} +\end{stylesheet} + + +Unlike |strong colors|, the following style sheets support, in +principle, an unlimited number of data set. In practice, as always, +more than four or five data sets lead to nearly indistinguishable data +sets. + +\begin{stylesheet}{vary hue} + This style uses a different hue for each data set. +\begin{codeexample}[width=10cm] +\tikz \datavisualization [ + visualize as smooth line/.list= + {1,2,3,4,5,6,7,8}, + example visualization, + style sheet=vary hue] +data group {sin functions}; +\end{codeexample} +\end{stylesheet} + +\begin{stylesheet}{shades of blue} + As the name suggests, different shades of blue are used for different + data sets. +\begin{codeexample}[width=10cm] +\tikz \datavisualization [ + visualize as smooth line/.list= + {1,2,3,4,5,6,7,8}, + example visualization, + style sheet=shades of blue] +data group {sin functions}; +\end{codeexample} +\end{stylesheet} + + +\begin{stylesheet}{shades of red} +\begin{codeexample}[width=10cm] +\tikz \datavisualization [ + visualize as smooth line/.list= + {1,2,3,4,5,6,7,8}, + example visualization, + style sheet=shades of red] +data group {sin functions}; +\end{codeexample} +\end{stylesheet} + + +\begin{stylesheet}{gray scale} + For once, this style sheet can also be used when the visualization + is printed in black and white. +\begin{codeexample}[width=10cm] +\tikz \datavisualization [ + visualize as smooth line/.list= + {1,2,3,4,5,6,7,8}, + example visualization, + style sheet=gray scale] +data group {sin functions}; +\end{codeexample} +\end{stylesheet} + + +\subsection{Usage: Labeling Data Sets Inside the Visualization} + +In a visualization that contains multiple data sets, it is often +necessary to clearly point out which line or mark type corresponds to +which data set. This can be done in the main text via a sentence like +``the normal data (black) lies clearly below the critical values +(red),'' but it often a good idea to indicate data sets ideally +directly inside the data visualization or directly next to it in a +so-called legend. + +The data visualization engine has direct support both for indicating +data sets directly inside the visualization and also for indicating +them in a legend. + +The ``best'' way of indicating where a data set lies or which color is +used for it is to put a label directly inside the data +visualization. The reason this is the ``best'' way is that people do +not have to match the legend entries against the data, let alone +having to look up the meaning of line styles somewhere in the +text. However, adding a label directly inside the visualization is +also the most tricky way of indicating data sets since it is hard to +compute good positions for the labels automatically and since there +needs to be some empty space where the label can be put. + +\subsubsection{Placing a Label Next to a Data Set} + +The following key is used to create a label inside the data +visualization for a data set: + +\begin{key}{/tikz/data visualization/visualizer options/label in data=\meta{options}} + This key is passed to a visualizer that has previously been created + using keys starting |visualize as ...|. It will create a label + inside the data visualization ``next'' to the visualizer (the + details are explained in a moment). You can use this key multiple + times with a visualizer to create multiple labels at different + points with different texts. + + The \meta{options} determine which text is shown and where it is + shown. They are executed with the following path prefix: +\begin{codeexample}[code only] +/tikz/data visualization/visualizer label options +\end{codeexample} + + In order to configure which text is shown and where, use the + following keys inside the \meta{options}: + + \begin{key}{/tikz/data visualization/visualizer label options/text=\meta{text}} + This is the text that will be displayed next to the data. It will + be to the ``left'' of the data, see the description below. + \end{key} + \begin{key}{/tikz/data visualization/visualizer label options/text'=\meta{text}} + Like |text|, only the text will be to the ``right'' of the data. + \end{key} + + The following keys are used to configure where the label will be + shown. They use different strategies to specify one data point where + the label will be anchored. The coordinate of this data point will + be stored in |(label| |visualizer| |coordinate)|. Independently of + the strategy, once the data point has been chosen, the coordinate of + the next data point is stored in |(label| |visualizer| + |coordinate')|. Then, a (conceptual) line is created from the first + coordinate to the second and a node is placed at the beginning of + this line to its ``left'' or, for the |text'| option, on its + ``right.'' More precisely, an automatic anchor is computed for a + node placed implicitly on this line using the |auto| option or, for + the |text'| option, using |auto,swap|. + + The node placed at the position computed in this way will have the + \meta{text} set by the |text| or |text'| option and its styling is + determined by the current |node style|. + + Let us now have a look at the different ways of determining the data + point at which the label in anchored: + \begin{key}{/tikz/data visualization/visualizer label + options/when=\meta{attribute}| is|\meta{number}} + This key causes the value of the \meta{attribute} to be monitored + in the stream of data points. The chosen is data point is the + first data point where the \meta{attribute} is at least + \meta{number} (if this never happens, the last data point is used). +\begin{codeexample}[width=6.3cm] +\tikz \datavisualization [ + school book axes, + x axis={label=$x$}, + visualize as smooth line/.list={log, lin, squared, exp}, + log= {label in data={text'=$\log x$, when=y is -1, + text colored}}, + lin= {label in data={text=$x/2$, when=x is 2}}, + squared={label in data={text=$x^2$, when=x is 1.1}}, + exp= {label in data={text=$e^x$, when=x is -2, + text colored}}, + style sheet=vary hue] +data group {function classes}; +\end{codeexample} + \end{key} + \begin{key}{/tikz/data visualization/visualizer label + options/index=\meta{number}} + This key chooses the \meta{number}th data point belonging to the + visualizer's data set. +\begin{codeexample}[width=6.3cm] +\tikz \datavisualization [ + school book axes, + x axis={label=$x$}, + visualize as smooth line/.list={exp}, + exp= {label in data={text=$5$, index=5}, + label in data={text=$10$, index=10}, + label in data={text=$20$, index=20}, + style={mark=x}}, + style sheet=vary hue] +data group {function classes}; +\end{codeexample} + \end{key} + \begin{key}{/tikz/data visualization/visualizer label options/pos=\meta{fraction}} + This key chooses the first data point belonging to the data set + whose index is at least \meta{fraction} times the number of all + data points in the data set. +\begin{codeexample}[width=6.3cm] +\tikz \datavisualization [ + school book axes, + x axis={label=$x$}, + visualize as smooth line=exp, + exp= {label in data={text=$.2$, pos=0.2}, + label in data={text=$.5$, pos=0.5}, + label in data={text=$.95$, pos=0.95}, + style={mark=x}}, + style sheet=vary hue] +data group {function classes}; +\end{codeexample} + \end{key} + \begin{key}{/tikz/data visualization/visualizer label options/auto} + This key is executed automatically by default. It works like the + |pos| option, where the \meta{fraction} is set to $(\meta{data set's + index}-1/2)/\meta{number of data sets}$. For instance, when + there are $10$ data sets, the fraction for the first one will be + $5\%$, the fraction for the second will be $15\%$, for the third + it will be $25\%$, ending with $95\%$ for the last one. + + The net effect of all this is that when there are several lines, + labels will be placed at different positions along the lines with + hopefully only little overlap. +\begin{codeexample}[width=6.3cm] +\tikz \datavisualization [ + scientific axes=clean, + visualize as smooth line/.list={linear, squared, cubed}, + linear ={label in data={text=$2x$}}, + squared={label in data={text=$x^2$}}, + cubed ={label in data={text=$x^3$}}] +data [set=linear, format=function] { + var x : interval [0:1.5]; + func y = 2*\value x; +} +data [set=squared, format=function] { + var x : interval [0:1.5]; + func y = \value x * \value x; +} +data [set=cubed, format=function] { + var x : interval [0:1.5]; + func y = \value x * \value x * \value x; +}; +\end{codeexample} + As can be seen in the example, the result is not always + satisfactory. In this case, the |pin in data| option might be + preferable, see below. + \end{key} + + The following keys allow you to style labels. + + \begin{key}{/tikz/data visualization/visualizer label + options/node style=\meta{options}} + Just passes the options to |/tikz/data visualization/node style|. + \end{key} + \begin{key}{/tikz/data visualization/visualizer label + options/text colored} + Causes the |node style| to set the text color to + |visualizer color|. The effect of this is that the label's text + will have the same color as the data set to which it is attached. + \end{key} + + \begin{stylekey}{/tikz/data visualization/every data set label} + This style is executed with every label that represents a + data set. Inside this style, use |node style| to change the + appearance of nodes. This style has a default definition, usually + you should just append things to this style. + +\begin{codeexample}[width=6.3cm] +\tikz \datavisualization [ + school book axes, + x axis={label=$x$}, + visualize as smooth line/.list={log, lin, squared, exp}, + every data set label/.append style={text colored}, + log= {label in data={text'=$\log x$, when=y is -1}}, + lin= {label in data={text=$x/2$, + node style=sloped, when=x is 2}}, + squared={label in data={text=$x^2$, when=x is 1.1}}, + exp= {label in data={text=$e^x$, + node style=sloped, when=x is -2}}, + style sheet=vary hue] +data group {function classes}; +\end{codeexample} + \end{stylekey} + + \begin{stylekey}{/tikz/data visualization/every label in data} + Like |every data set label|, this key is also executed with + labels. However, this key is executed after the style sheets have + been executed, giving you a chance to overrule their styling. + \end{stylekey} +\end{key} + +\subsubsection{Connecting a Label to a Data Set via a Pin} + +\begin{key}{/tikz/data visualization/visualizer options/pin in data=\meta{options}} + This key is a variant of the |label in data| key and takes the same + options, plus two additional ones. The difference to |label in data| + is that the label node is shown a bit removed from the data set, but + connected to it via a small line (this is like the difference + between the |label| and |pin| options). +\begin{codeexample}[width=6.3cm] +\tikz \datavisualization [ + scientific axes=clean, + visualize as smooth line/.list={linear, squared, cubed}, + linear ={pin in data={text=$2x$}}, + squared={pin in data={text=$x^2$}}, + cubed ={pin in data={text=$x^3$}}] +data [set=linear, format=function] { + var x : interval [0:1.5]; + func y = \value x; +} +data [set=squared, format=function] { + var x : interval [0:1.5]; + func y = \value x * \value x; +} +data [set=cubed, format=function] { + var x : interval [0:1.5]; + func y = \value x * \value x * \value x; +}; +\end{codeexample} + The following keys can be used additionally: + \begin{key}{/tikz/data visualization/visualizer label options/pin angle=\meta{angle}} + The position of the label of a |pin in data| is mainly computed in + the same way as for a |label in data|. However, once the position + has been computed, the label is shifted as follows: + \begin{itemize} + \item When an \meta{angle} is specified using the present key, the + shift is by the current value of |pin length| in the direction + of \meta{angle}. + \item When \meta{angle} is empty (which is the default), then the + shift is also by the current value of |pin length|, but now in + the direction that is orthogonal and to the left of the line + between the coordinate of the data point and the coordinate of + the next data point. When |text'| is used, the direction is to + the right instead of the left. + \end{itemize} + \end{key} + + \begin{key}{/tikz/data visualization/visualizer label options/pin length=\meta{dimension}} + See the description of |pin angle|. + \end{key} + +\begin{codeexample}[width=6.3cm] +\tikz \datavisualization [ + school book axes, + x axis={label=$x$}, + visualize as smooth line/.list={log, lin, squared, exp}, + every data set label/.append style={text colored}, + log= {pin in data={text'=$\log x$, when=y is -1}}, + lin= {pin in data={text=$x/2$, when=x is 2, + pin length=1ex}}, + squared={pin in data={text=$x^2$, when=x is 1.1, + pin angle=230}}, + exp= {label in data={text=$e^x$, when=x is -2}}, + style sheet=vary hue] +data group {function classes}; +\end{codeexample} +\end{key} + + + +\subsection{Usage: Labeling Data Sets Inside a Legend} + +The ``classical'' way of indicating the style used for the different +data sets inside a visualization is a \emph{legend}. It is a +description next to or even inside the visualization that contains one +line for each data set and displays an iconographic version of the +data set next to some text labeling the data set. Note, however, that +even though legend are quite common, also +consider using a |label in data| or a |pin in data| instead. + +Creating a high-quality legend is by no means simple. A legend should +not distract the reader, so aggressive borders should definitively be +avoided. A legend should make it easy to match the actual +styling of a data set (like, say, using a red, dashed line) to +the ``iconographic'' representation of this styling. An example of +what can go wrong here is using short lines to represent lines dashed +in different way where the lines are so short that the differences in +the dashing cannot be discerned. Another example is showing straight +lines with plot marks on them where the plot marks are obscured by the +horizontal line itself, while the plot marks are clearly visible in +the actual visualization since no horizontal lines occur. + +The data visualization engine comes with a large set of options for +creating and placing high-quality legends next or inside data +visualizations. + +\subsubsection{Creating Legends and Legend Entries} + +A data visualization can be accompanied by one or more legends. In +order to create a legend, the following key can be used (although, in +practice, you will usually use the |legend| key instead, see below): + +\begin{key}{/tikz/data visualization/new legend=\meta{legend name} + (default main legend)} + This key is used to create a new legend named \meta{legend name}. The + legend is empty by default and further options are needed to add + entries to it. When the key is called a second time for the same + \meta{legend name} nothing happens. + + When a legend is created, a new key is created that can + subsequently be used to configure the legend: + \begin{key}{/tikz/data visualization/\meta{legend name}=\meta{options}} + When this key is used, the \meta{options} are executed with the + path prefix +\begin{codeexample}[code only] +/tikz/data visualization/legend options +\end{codeexample} + The different keys with this path prefix allow you to change the + position where the legend is shown and how it is organised (for + instance, whether legend entries are shown in a row or in a column + or in a square). + + The different possible keys will be explained in the course of + this section. + \end{key} + + In the end, the legend is just a \tikzname\ node, a |matrix| node, + to be precise. The following key is used to style this node: + + + \begin{key}{/tikz/data visualization/legend options/matrix node style=\meta{options}} + Adds the \meta{options} to the list of options that will be + executed when the legend's node is created. +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line/.list= + {log, lin, squared, exp}, + legend={matrix node style={fill=black!25}}, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + squared={label in legend={text=$x^2$}}, + exp= {label in legend={text=$e^x$}}, + style sheet=vary dashing] +data group {function classes}; +\end{codeexample} + \end{key} + + + The following style allows you to configure the default appearance + of every newly created legend: + \begin{stylekey}{/tikz/data visualization/legend options/every new legend} + This key defaults to |east outside, label style=text right|. This means + that by default a legend is placed to the right of the data + visualization and that in the individual legend entries the text + is to the right of the data set visualization. + \end{stylekey} + +\begin{codeexample}[width=6cm] +\tikz \datavisualization [ + scientific axes, x axis={label=$x$}, + visualize as smooth line/.list={log, lin, squared, exp}, + new legend={upper legend}, + new legend={lower legend}, + upper legend=above, + lower legend=below, + log= {label in legend={text=$\log x$, legend=upper legend}}, + lin= {label in legend={text=$x/2$, legend=upper legend}}, + squared={label in legend={text=$x^2$, legend=lower legend}}, + exp= {label in legend={text=$e^x$, legend=lower legend}}, + style sheet=vary dashing] +data group {function classes}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/legend=\meta{options}} + This is a shorthand for |new legend=main legend, main legend=|\meta{options}. + In other words, this key creates a new |main legend| and immediately + passes the configuration \meta{options} to this legend. + +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + scientific axes, x axis={label=$x$}, + visualize as smooth line/.list={log, lin, squared, exp}, + legend=below, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + squared={label in legend={text=$x^2$}}, + exp= {label in legend={text=$e^x$}}, + style sheet=vary dashing] +data group {function classes}; +\end{codeexample} +\end{key} + +As pointed out above, a legend is empty by default. In particular, +the different data sets are not automatically inserted into the +legend. Instead, the key |label in legend| must be used together +with a data set: + +\begin{key}{/tikz/data visualization/visualizer options/label in legend=\meta{options}} + This key is passed to a data set, similar to options like + |pin in data| or |smooth line|. The \meta{options} are used to + configure the following: + \begin{itemize} + \item The legend in which the data set should be visualized. + \item The text that is to be shown in the legend for the data set. + \item The appearance of the legend entries. + \end{itemize} + In detail, the \meta{options} are executed with the path prefix +\begin{codeexample}[code only] +/tikz/data visualization/legend entry options +\end{codeexample} + To configure in which legend the label should appear, use the + following key: + \begin{key}{/tikz/data visualization/legend entry + options/legend=\meta{name} (initially main legend)} + Set this key to the name of a legend that has previously been + created using |new legend|. The label will then be shown in this + legend. + + In most cases, there is only one legend (namely |main legend|) and + there is no need to set this key since it defaults to the main + legend. + + Also note that the legend \meta{name} is automatically created if + it nodes not yet exist. + \end{key} + + \begin{key}{/tikz/data visualization/legend entry options/text=\meta{text}} + Use this key to setup the \meta{text} that is shown as the label + of the data set. + +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, x axis={label=$x$}, + visualize as smooth line/.list= + {log, lin, squared, exp}, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + squared={pin in data ={text=$x^2$, pos=0.1}}, + exp= {label in data ={text=$e^x$}}, + style sheet=vary dashing] +data group {function classes}; +\end{codeexample} + \end{key} + + In addition to the two keys described above, there are further + keys that are described in + Section~\ref{section-dv-label-legend-entry-options}. +\end{key} + + +\subsubsection{Rows and Columns of Legend Entries} + +In a legend, the different legend entries are arranged in a matrix, +which typically has only one row or one column. For the impatient +reader: Say |rows=1| to get everything in a row, say |columns=1| to +get everything in a single column, and skip the rest of this section. + +The more patient reader will appreciate that when there are very many +different data sets in a single visualization, it may be +necessary to use more than one row or column inside the legend. +\tikzname\ comes with a rather powerful mechanism for distributing the +multiple legend entries over the matrix. + +The first thing to decide is in which ``direction'' the entries should +be inserted into the matrix. Suppose we have a $3 \times 3$ matrix and +our entries are $a$, $b$, $c$, and so on. Then, one might place the +$a$ in the upper left corner of the matrix, $b$ in the upper middle +position, $c$ in the upper right position, and $d$ in the middle left +position. This is a ``first right, then down'' strategy. A different +strategy might be to place the $a$ in the upper left corner, but $b$ +in the middle left position, $c$ in the lower left position, and $d$ +then in the upper middle position. This is a ``first down, then +right'' strategy. In certain situations it might even make sense to +place $a$ in the lower right corner and then go ``first up, then +left''. + +All of these strategies are supported by the |legend| command. You can +configure which strategy is used using the following keys: + +\tikzdatavisualizationset { + legend example/.style={ + scientific axes, all axes={length=1cm, ticks=none}, + 1={label in legend={text=1}}, + 2={label in legend={text=2}}, + 3={label in legend={text=3}}, + 4={label in legend={text=4}}, + 5={label in legend={text=5}}, + 6={label in legend={text=6}}, + 7={label in legend={text=7}}, + 8={label in legend={text=8}} + } +} + + +\begin{key}{/tikz/data visualization/legend options/down then right} + Causes the legend entries to fill the legend matrix first downward + and, once a column is full, the next column is begun to the right of + the previous one. This is the default. +\begin{codeexample}[width=6cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={down then right, columns=3}] +data group {sin functions}; +\end{codeexample} + In the example, the |legend example| is the following style: +\begin{codeexample}[code only] +\tikzdatavisualizationset { + legend example/.style={ + scientific axes, all axes={length=1cm, ticks=none}, + 1={label in legend={text=1}}, + 2={label in legend={text=2}}, + 3={label in legend={text=3}}, + 4={label in legend={text=4}}, + 5={label in legend={text=5}}, + 6={label in legend={text=6}}, + 7={label in legend={text=7}}, + 8={label in legend={text=8}} + } +} +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/legend options/down then left} +\begin{codeexample}[width=6cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={down then left, columns=3}] +data group {sin functions}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/legend options/up then right} +\begin{codeexample}[width=6cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={up then right, columns=3}] +data group {sin functions}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/legend options/up then left} +\begin{codeexample}[width=6cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={up then left, columns=3}] +data group {sin functions}; +\end{codeexample} +\end{key} + + +\begin{key}{/tikz/data visualization/legend options/left then up} +\begin{codeexample}[width=6cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={left then up, columns=3}] +data group {sin functions}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/legend options/left then down} +\begin{codeexample}[width=6cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={left then down, columns=3}] +data group {sin functions}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/legend options/right then up} +\begin{codeexample}[width=6cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={right then up, columns=3}] +data group {sin functions}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/legend options/right then down} +\begin{codeexample}[width=6cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={right then down, columns=3}] +data group {sin functions}; +\end{codeexample} +\end{key} + + +Having configured the directions in which the matrix is being filled, +you must next setup the number of rows or columns that are to be +shown. There are actually two different ways of doing so. The first +way is to specify a maximum number of rows or columns. For instance, +you might specify that there should be at most ten rows to a column +and when there are more, a new column should be begun. This is +achieved using the following keys: + +\begin{key}{/tikz/data visualization/legend options/max rows=\meta{number}} + As the legend matrix is being filled, whenever the number of rows in + the current column would exceed \meta{number}, a new column is + started. +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={max rows=3}] +data group {sin functions}; +\end{codeexample} +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={max rows=4}] +data group {sin functions}; +\end{codeexample} +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={max rows=5}] +data group {sin functions}; +\end{codeexample} +\end{key} + + +\begin{key}{/tikz/data visualization/legend options/max columns=\meta{number}} + This key works like |max rows|, only now the number of columns is + monitored. Note that this strategy only really makes sense when the + when you use this key with a strategy that first goes left or right + and then up or down. +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={right then down, max columns=2}] +data group {sin functions}; +\end{codeexample} +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={right then down,max columns=3}] +data group {sin functions}; +\end{codeexample} +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={right then down,max columns=4}] +data group {sin functions}; +\end{codeexample} +\end{key} + + +The second way of specifying the number of entries in a row or column +is to specify an ``ideal number of rows or columns.'' The idea is as +follows: Suppose that we use the standard strategy and would like to +have everything in two columns. Then if there are eight entries, the +first four should go to the first column, while the next four should +go to the second column. If we have 20 entries, the first ten should +go the first column and the next ten to the second, and so on. So, in +general, the objective is to distribute the entries evenly so the this +``ideal number of columns'' is reached. Only when there are too few +entries to achieve this or when the number of entries per column would +exceed the |max rows| value, will the number of columns deviate from +this ideal value. + + + +\begin{key}{/tikz/data visualization/legend options/ideal number of columns=\meta{number}} + Specifies, that the entries should be split into \meta{number} + different columns, whenever possible. However, when there would be + more than the |max rows| value of rows per column, more columns than + the ideal number are created. +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={ideal number of columns=2}] +data group {sin functions}; +\end{codeexample} +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={ideal number of columns=4}] +data group {sin functions}; +\end{codeexample} +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={max rows=3,ideal number of columns=2}] +data group {sin functions}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/legend + options/rows=\meta{number}} + Shorthand for |ideal number of rows=|\meta{number}. +\end{key} + + +\begin{key}{/tikz/data visualization/legend options/ideal number of rows=\meta{number}} + Works like |ideal number of columns|. +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={ideal number of rows=2}] +data group {sin functions}; +\end{codeexample} +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={ideal number of rows=4}] +data group {sin functions}; +\end{codeexample} +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + visualize as smooth line/.list={1,2,3,4,5,6,7,8}, + legend example, style sheet=vary hue, + main legend={max columns=3,ideal number of rows=2}] +data group {sin functions}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/legend + options/columns=\meta{number}} + Shorthand for |ideal number of columns=|\meta{number}. +\end{key} + + +\subsubsection{Legend Placement: The General Mechanism} + +A legend can either be placed next to the data visualization or inside +the data visualization at some place where there are no data +entries. Both approached have advantages: Placing the legend next to +the visualization minimises the ``cluttering'' by keeping all the +extra information apart from the actual data, while placing the legend +inside the visualization minimises the distance between the data sets +and their explanations, making it easier for the eye to connect them. + +For both approaches there are options that make the placement easier, +see Sections \ref{section-dv-legend-outside} +and~\ref{section-dv-legend-inside}, but these options internally just +map to the following two options: + +\begin{key}{/tikz/data visualization/legend + options/anchor=\meta{anchor}} + The whole legend is a \tikzname-matrix internally. Thus, + in particular, it is stored in a node, which has anchors. Like for + any other node, when the node is shown, the node is shifted in such + a way that the \meta{anchor} of the node lies at the current |at| + position. +\end{key} + +\begin{key}{/tikz/data visualization/legend + options/at=\meta{coordinate}} + Configures the \meta{coordinate} at which the \meta{anchor} of the + legend's node should lie. + + It may seem hard to predict a good \meta{coordinate} for a legend + since, depending of the size of the axis, different positions need + to the chosen for the legend. However, it turns out that one + can often use the coordinates of the special nodes + |data bounding box| and |data visualization bounding box|, + documented in Section~\ref{section-dv-bounding-box}. + + As an example, let us put a legend to the right of the + visualization, but so that the first entry starts at the top of the + visualization: +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, x axis={label=$x$}, + visualize as smooth line/.list= + {log, lin, squared, exp}, + legend={anchor=north west, at= + (data visualization bounding box.north east)}, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + squared={label in legend={text=$x^2$}}, + exp= {label in legend={text=$e^x$}}, + style sheet=vary dashing] +data group {function classes}; +\end{codeexample} + As can be seen, a bit of an additional shift might have been in + order, but the result is otherwise quite satisfactory. +\end{key} + + +\subsubsection{Legend Placement: Outside to the Data Visualization} +\label{section-dv-legend-outside} + +The following keys make it easy to place a legend outside the data +visualization. + +\begin{key}{/tikz/data visualization/legend options/east outside} + Placing the legend to the right of the data visualization is the default: +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line/.list= + {log, lin, squared, exp}, + legend=east outside, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + squared={label in legend={text=$x^2$}}, + exp= {label in legend={text=$e^x$}}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} + + \begin{key}{/tikz/data visualization/legend options/right} + This is an easier-to-remember alias. + \end{key} +\end{key} + +\begin{key}{/tikz/data visualization/legend options/north east outside} + A variant, where the legend is to the right, but aligned with the + northern end of the data visualization: +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line/.list= + {log, lin, squared, exp}, + legend=north east outside, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + squared={label in legend={text=$x^2$}}, + exp= {label in legend={text=$e^x$}}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/legend options/south east outside} +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line/.list= + {log, lin, squared, exp}, + legend=south east outside, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + squared={label in legend={text=$x^2$}}, + exp= {label in legend={text=$e^x$}}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/legend options/west outside} + The legend is placed left. Note that the text also swaps its + position. +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line/.list= + {log, lin, squared, exp}, + legend=west outside, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + squared={label in legend={text=$x^2$}}, + exp= {label in legend={text=$e^x$}}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} + \begin{key}{/tikz/data visualization/legend options/left} + This is an easier-to-remember alias. + \end{key} +\end{key} + +\begin{key}{/tikz/data visualization/legend options/north west outside} +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line/.list= + {log, lin, squared, exp}, + legend=north west outside, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + squared={label in legend={text=$x^2$}}, + exp= {label in legend={text=$e^x$}}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/legend options/south west outside} +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line/.list= + {log, lin, squared, exp}, + legend=south west outside, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + squared={label in legend={text=$x^2$}}, + exp= {label in legend={text=$e^x$}}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} +\end{key} + + +\begin{key}{/tikz/data visualization/legend options/north outside} + The legend is placed above the data. Note that the legend entries + now for a row rather than a column. +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line/.list= + {log, lin, squared, exp}, + legend=north outside, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + squared={label in legend={text=$x^2$}}, + exp= {label in legend={text=$e^x$}}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} + \begin{key}{/tikz/data visualization/legend options/above} + This is an easier-to-remember alias. + \end{key} +\end{key} + +\begin{key}{/tikz/data visualization/legend options/south outside} +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line/.list= + {log, lin, squared, exp}, + legend=south outside, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + squared={label in legend={text=$x^2$}}, + exp= {label in legend={text=$e^x$}}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} + \begin{key}{/tikz/data visualization/legend options/below} + This is an easier-to-remember alias. + \end{key} +\end{key} + + + +\subsubsection{Legend Placement: Inside to the Data Visualization} +\label{section-dv-legend-inside} + +There are two sets of options for placing a legend directly inside a +data visualization: First, there are options for placing it inside, +but next to some part of the border. Second, there are options for +positioning it relative to a coordinate given by a certain data point. + + + +\begin{key}{/tikz/data visualization/legend options/south east inside} + Puts the legend in the upper right corner of the data. +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line/.list= + {log, lin}, + legend=south east inside, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} + + Note that the text is now a little smaller since there tends to be + much less space inside the data visualization than next to it. Also, + the legend's node is filled in white by default to ensures that the + legend is clearly legible even in the presence of, say, a grid or + data points behind it. This behaviour is triggered by the following + style key: + + \begin{stylekey}{/tikz/data visualization/legend options/every legend inside} + Executed the keys |opaque| by default and sets the text size to + the size of footnotes. + \end{stylekey} +\end{key} + +In order to further configure the default appearance of an inner +legend, the following keys might be useful: + +\begin{key}{/tikz/data visualization/legend + options/opaque=\meta{color} (default white)} + When this key is used, the legend's node will be filled with the + \meta{color} and its corners will be rounded. Additionally, the + inner and outer separations will be set to sensible values. +\end{key} +\begin{key}{/tikz/data visualization/legend + options/transparent} + Sets the filling of the legend node to |none|. +\end{key} + +The following keys work much the same way as |south east inside|: + +\begin{key}{/tikz/data visualization/legend options/east inside} +\end{key} +\begin{key}{/tikz/data visualization/legend options/north east inside} +\end{key} +\begin{key}{/tikz/data visualization/legend options/south west inside} +\end{key} +\begin{key}{/tikz/data visualization/legend options/west inside} +\end{key} +\begin{key}{/tikz/data visualization/legend options/north west inside} +\end{key} + +The keys |south inside| and |north inside| are a bit different: They use a row +rather than a column for the legend entries: + +\begin{key}{/tikz/data visualization/legend options/south inside} + Puts the legend in the upper right corner of the data. Note that the + text is now a little smaller since there tends to be much less space + inside the data visualization than next to it. +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line/.list={log, lin}, + legend=south inside, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/legend options/north inside} + As above. +\end{key} + +The above keys do not always give you as fine a control as you may +need over the placement of the legend. In such cases, the following +keys may help (or you can revert to directly setting the |at| and the +|anchor| keys): + +\begin{key}{/tikz/data visualization/legend options/at + values=\meta{data point}} + This key allows you to specify the desired center of the legend in + terms of a data point. The \meta{data point} should be a list of + comma-separated key--value pairs that specify a data point. The + legend will then be centered at this data point. +\begin{codeexample}[width=6cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line/.list={log, lin}, + legend={at values={x=-1, y=2}}, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/legend options/right + of=\meta{data point}} + Works like |at values|, but the anchor is set to |west|: +\begin{codeexample}[width=6cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line/.list={log, lin}, + legend={right of={x=-1, y=2}}, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} +\end{key} + +The following keys work similarly: +\begin{key}{/tikz/data visualization/legend options/above right of=\meta{data point}} +\end{key} +\begin{key}{/tikz/data visualization/legend options/above of=\meta{data point}} +\end{key} +\begin{key}{/tikz/data visualization/legend options/above left of=\meta{data point}} +\end{key} +\begin{key}{/tikz/data visualization/legend options/left of=\meta{data point}} +\end{key} +\begin{key}{/tikz/data visualization/legend options/below left of=\meta{data point}} +\end{key} +\begin{key}{/tikz/data visualization/legend options/below of=\meta{data point}} +\end{key} +\begin{key}{/tikz/data visualization/legend options/below right of=\meta{data point}} +\end{key} + + + + +\subsubsection{Legend Entries: General Styling} + +\label{section-dv-label-legend-entry-options} + +The entries in a legend can be styled in several ways: + +\begin{itemize} +\item + You can configure the styling of the text node. +\item + You can configure the relative placement of the text node and the + little picture depicting the data set's styling. +\item + You can configure how the data set's styling is depicted. +\end{itemize} + +Before we have look at how each of these are configured, in detail, +let us first have a look at the keys that allow us to save a set of +such styles: + +\begin{stylekey}{/tikz/data visualization/every label in legend} + This key is executed with every label in a legend. However, the + options stored in this style are executed with the path prefix + |/tikz/data visualization/legend entry options|. Thus, this key can + use keys like |node style| to configure the styling of all text + nodes: +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, + every label in legend/.style={node style= + {fill=red!30}}, + visualize as smooth line/.list= + {log, lin, squared, exp}, + legend=north east outside, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$, + node style={circle, draw=red}}}, + squared={label in legend={text=$x^2$}}, + exp= {label in legend={text=$e^x$}}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} +\end{stylekey} + +\begin{key}{/tikz/data visualization/legend options/label style=\meta{options}} + This key can be used with a legend. It will simply add the + \meta{options} to the |every label in legend| style for the given + legend. +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line/.list= + {log, lin, squared, exp}, + legend={label style={node style=draw}}, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$, + node style={circle, draw=red}}}, + squared={label in legend={text=$x^2$}}, + exp= {label in legend={text=$e^x$}}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} +\end{key} + + +\subsubsection{Legend Entries: Styling the Text Node} + +The appearance of the text nodes is easy to configure. + +\begin{key}{/tikz/data visualization/legend entry options/node style=\meta{options}} + This key adds \meta{options} to the styling of the text nodes of the + label. +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line/.list= + {log, lin, squared, exp}, + legend=north east outside, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$, + node style={circle, draw=red}}}, + squared={label in legend={text=$x^2$}}, + exp= {label in legend={text=$e^x$}}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/legend entry options/text colored} + Causes the |node style| to set the text color to + |visualizer color|. The effect of this is that the label's text + will have the same color as the data set to which it is attached. +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line/.list= + {log, lin, squared, exp}, + legend={label style=text colored}, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + squared={label in legend={text=$x^2$}}, + exp= {label in legend={text=$e^x$}}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} +\end{key} + + +\subsubsection{Legend Entries: Text Placement} + +Three keys govern where the text will be placed relative to the data +set style visualization. + +\begin{key}{/tikz/data visualization/legend entry options/text right} + Placed the text node to the right of the data set style + visualization. This is the default for most, but not all, legends. +\end{key} +\begin{key}{/tikz/data visualization/legend entry options/text left} + Placed the text node to the left of the data set style + visualization. +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line/.list= + {log, lin, squared, exp}, + legend={label style=text left}, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + squared={label in legend={text=$x^2$}}, + exp= {label in legend={text=$e^x$}}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} +\end{key} +\begin{key}{/tikz/data visualization/legend entry options/text only} + Shows only the text nodes and no data set style visualization at + all. This options only makes sense in conjunction with the + |text colored| options, which is why this options is also selected + implicitly. +\begin{codeexample}[width=8cm] +\tikz \datavisualization [ + scientific axes, + visualize as smooth line/.list= + {log, lin, squared, exp}, + legend={south east inside, rows=2, + label style=text only}, + log= {label in legend={text=$\log x$}}, + lin= {label in legend={text=$x/2$}}, + squared={label in legend={text=$x^2$}}, + exp= {label in legend={text=$e^x$}}, + style sheet=strong colors] +data group {function classes}; +\end{codeexample} +\end{key} + + + + + +\subsubsection{Advanced: Labels in Legends and Their Visualizers} + +\label{section-dv-legend-entries} + +The following explanations are important only for you if you intend to +create a new visualizer and an accompanying label in legend +visualizer; otherwise you can safely proceed with the next section. + +A legend entry consists not only of some explaining text, but, even +more importantly, of a visual representation of the style used for the +data points, created by a \emph{label in legend visualizer}. For +instance, when data points are visualized as lines in +different colors, the legend entry for the first line might consist of +the text ``first experiment'' and a short line in black and the second +entry might consist of ``failed experiment'' and a short line in red +-- assuming, of course, that the style sheet makes the first line +black and the second line blue. As another example, when data sets are +visualized as clouds of plot marks, the texts in the legend would be +accompanied by the plot marks used to visualize the data sets. + +For every visualizer, the \emph{label in legend visualizer} creates an +appropriate visualization of the data set's styling. There may be more +than one possible such label in legend visualizer that is appropriate, +in which case options are used to choose between them. + +Let us start with the key for creating a new legend entry. This key +gets called for instance by |label in legend|: + +\begin{key}{/tikz/data visualization/new legend entry=\meta{options}} + This key will add a new entry to the legend that is identified by + the \meta{options}. For this, the \meta{options} are executed once + with the path prefix |/tikz/data visualization/legend entry options| + and the resulting setting of the |legend| key is used to pick which + legend the new entry should belong to. Then, the \meta{options} are + stored away for the time being. + + Later, when the legend is created, the \meta{options} get executed + once more. This time, however, the |legend| key is no longer + important. Instead, the \meta{options} that setup keys like + |text| or |visualizer in legend| now play a role. + + In detail, the following happens: + \begin{itemize} + \item For the legend entry, a little cell picture is created in the + matrix of the legend (see Section~\ref{section-tikz-cell-pictures} + for details on cell pictures). + \item Inside this picture, a node is created whose text is taken + from the key +\begin{codeexample}[code only] +/tikz/data visualization/legend entry options/text +\end{codeexample} + \item Also inside the picture, the code stored in the following key + gets executed: + \begin{key}{/tikz/data visualization/legend entry options/visualizer in legend} + Set this key to some code that paints something in the cell + picture. Typically, this will be a visual representation of the + data set styling, but it could also be something different. +\begin{codeexample}[width=6cm] +\tikz \datavisualization [ + school book axes, visualize as line/.list={a,b}, + style sheet=vary dashing, + a={label in legend={text=a}}, + new legend entry={ + text=spacer, + visualizer in legend={\draw[solid] (0,0) circle[radius=2pt];} + }, + b={label in legend={text=b}}] +data point [x=-1, y=-1, set=a] data point [x=1, y=0, set=a] +data point [x=-1, y=1, set=b] data point [x=1, y=0.5, set=b]; +\end{codeexample} + \end{key} + \end{itemize} + The following styles are applied in the following order before the + cell picture is filled: + \begin{enumerate} + \item |/tikz/data visualization/every data set label| with path + |/tikz/data visualization| + \item |/tikz/data visualization/every label in legend| with path\\ + |/tikz/data visualization/legend entry options|. + \item The \meta{options}. + \item The code in the following key: + \begin{key}{/tikz/data visualization/legend entry options/setup} + Some code to be executed at this point. Mostly, it is used to + setup attributes for style sheets. + \end{key} + \item A styling signal is emitted. + \item Only for the node: The current value of |node style|. + \item Only for the visualizer in legend: The styling that has been + accumulated by calls to the following key: + \begin{stylekey}{/tikz/data visualization/legend entry + options/visualizer in legend style=\\\marg{options}} + Calls to this key accumulate \meta{options} that will be + executed with the path prefix |/tikz| at this point. + \end{stylekey} + \end{enumerate} +\end{key} + +As indicated earlier, the |new legend entry| key is called by the +|label in legend=|\meta{options} key internally. In this case, the +following extra \meta{extra options} are passed to |new legend entry| +key: +\begin{itemize} +\item The styling of the visualizer. +\item The |/tikz/data visualization/every label in legend| style. +\item The |/tikz/every label| style with path |/tikz|. +\item Setting |setup| to |/data point/set=|\meta{name of the visualizer}. +\item The value of the |label legend options| that are stored in the + visualizer. These options can be changed using the following key: + \begin{key}{/tikz/data visualization/visualizer options/label in + legend options=\meta{options}} + Use this key with a visualizer to configure the label in legend + options. Typically, this key is used only internally by a + visualizer upon its creating to set the \meta{options} to setup + the |visualizer in legend| key. + \end{key} +\end{itemize} + + +\subsubsection{Reference: Label in Legend Visualizers for Lines and Scatter Plots} + +Visualizers like |visualize as line| or |visualize as smooth line| +use a label in legend visualizer that draws a short line to represent +the data set inside the legend. However, this line needs not be a +simple straight line, but can be a little curve or a small circle -- +indeed, even the default line is not a simple straight line but rather +a small zig-zag curve. To configure this line, the two keys +are used, although you will only rarely use them directly, but +rather use one of the predefined styles mentioned later on. + +Before we go into the glorious details of all of these keys, let us +first have a look at the keys you are most likely to use in practice: +The keys for globally reconfiguring the default label in legend +visualizers: +\begin{stylekey}{/tikz/data visualization/legend entry options/default + label in legend path} + This style is set, by default, to |zig zag label in legend line|. It + is installed by the styles |straight line|, |smooth line|, and + |gap line|, so changing this style will change the appearance of lines in + legends. The main other sensible option for this key is + |straight label in legend line|. +\begin{codeexample}[width=5cm] +\tikz \datavisualization [ + school book axes, visualize as line/.list={a,b}, + style sheet=vary dashing, + a={label in legend={text=a}}, b={label in legend={text=b}}] +data point [x=-1, y=-1, set=a] data point [x=1, y=0, set=a] +data point [x=-1, y=1, set=b] data point [x=1, y=0.5, set=b]; +\end{codeexample} +\begin{codeexample}[width=5cm] +\tikz \datavisualization [ + school book axes, visualize as line/.list={a,b}, + legend entry options/default label in legend path/.style= + straight label in legend line, + style sheet=vary dashing, + a={label in legend={text=a}}, b={label in legend={text=b}}] +data point [x=-1, y=-1, set=a] data point [x=1, y=0, set=a] +data point [x=-1, y=1, set=b] data point [x=1, y=0.5, set=b]; +\end{codeexample} +\end{stylekey} +\begin{stylekey}{/tikz/data visualization/legend entry options/default + label in legend closed path} + This style is executed by |smooth cycle| and |straight cycle|. There + are (currently) no other predefined sets of coordinates that can be + used instead of the default value |circular label in legend line|. +\end{stylekey} + +\begin{stylekey}{/tikz/data visualization/legend entry options/default + label in legend mark} + This style is executed by |no lines| and, implicitly, by scatter + plots. The default is to use + |label in legend line one mark|. Another possible value is + |label in legend line three marks|. +\begin{codeexample}[width=5cm] +\tikz \datavisualization [ + visualize as scatter/.list={a,b,c}, + style sheet=cross marks, + legend entry options/default label in legend mark/.style= + label in legend three marks, + a={label in legend={text=example a}}, + b={label in legend={text=example b}}, + c={label in legend={text=example c}}]; +\end{codeexample} +\end{stylekey} + +\begin{key}{/tikz/data visualization/legend entry options/label in + legend line coordinates=\\\marg{list of coordinates}} + This key takes a \meta{list of coordinates}, which are + \tikzname-coordinates separated by commas like |(0,0),|\penalty0|(1,1)|. The + effect of setting the key is the following: The label in legend + visualizer used by, for instance, |visualize as line| will draw a + path going through these points. When the line is drawn, the exact + same style will be used as was used for the data set. For instance, + if the |smooth line| key was used and also the |style=red| key, the + line through the \meta{list of coordinates} will also be red and + smooth. When the |straight cycle| key was used, the coordinates will + also be connected by a cycle, and so on. + + When the line connecting the \meta{list of coordinates} is drawn, + the coordinate system will have been shifted and transformed in such + a way that |(0,0)| lies to the left of the text and at half the + height of the character ``x''. This means that the right-most-point + in the list should usually be |(0,0)| and all other $x$-coordinates + should usually be negative. When the |text left| options is used, + the coordinate system will have been flipped, so the \meta{list of + coordinates} is independent of whether the text is to the right or + to the left of the line. + + Let us now have a look at a first, simple example. We create a + legend entry that is just a straight line, so it should start + somewhere to the left of the origin at height $0$ and go to the + origin: +\begin{codeexample}[width=5cm] +\tikz \datavisualization [ + school book axes, visualize as line/.list={a,b}, + style sheet=vary dashing, + a={label in legend={text=a, + label in legend line coordinates={(-1em,0), (0,0)}}}, + b={label in legend={text=b, + label in legend line coordinates={(-2em,0), (0,0)}}}] +data point [x=-1, y=-1, set=a] data point [x=1, y=0, set=a] +data point [x=-1, y=1, set=b] data point [x=1, y=0.5, set=b]; +\end{codeexample} + + Now let us make this a bit more fancy and useful by using shifted lines: +\begin{codeexample}[width=5cm] +\tikz \datavisualization [ + school book axes, visualize as line/.list={a,b}, + legend={up then right}, style sheet=vary dashing, + a={label in legend={text=a, + label in legend line coordinates={(-2em,-.25ex), (0,0)}}}, + b={label in legend={text=b, + label in legend line coordinates={(-2em,.25ex), (0,0)}}}] +data point [x=-1, y=-1, set=a] data point [x=1, y=0, set=a] +data point [x=-1, y=1, set=b] data point [x=1, y=0.5, set=b]; +\end{codeexample} + + In the final example, we use a little ``hat'' to represent lines: +\begin{codeexample}[width=5cm] +\tikz \datavisualization [ + school book axes, visualize as line/.list={a,b}, + legend={up then right}, style sheet=vary dashing, + a={label in legend={text=a, + label in legend line coordinates={ + (-2em,-.2ex), (-1em,.2ex), (0,-.2ex)}}}, + b={label in legend={text=b, + label in legend line coordinates={ + (-2em,-.2ex), (-1em,.2ex), (0,-.2ex)}}}] +data point [x=-1, y=-1, set=a] data point [x=1, y=0, set=a] +data point [x=-1, y=1, set=b] data point [x=1, y=0.5, set=b]; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/legend entry options/label in + legend mark coordinates=\\\marg{list of coordinates}} + This key is similar to |label in legend line coordinates|, but now + the \meta{list of coordinates} is used as the positions where plot + marks are shown. Naturally, plot marks are only shown there if they + are also shown by the visualizer in the actual data -- just like the + line through the coordinates of the previous key is only shown when + there is a line. + + The \meta{list of coordinates} may be the same as the one used for + lines, but usually it is not. In general, it is better to have marks + for instance not at the ends of the line. +\begin{codeexample}[width=5cm] +\tikz \datavisualization [ + school book axes, visualize as line/.list={a,b}, + legend={up then right}, + style sheet=vary dashing, + style sheet=cross marks, + a={label in legend={text=a, + label in legend line coordinates={ + (-2em,-.2ex), (-1em,.2ex), (0,-.2ex)}, + label in legend mark coordinates={ + (-1em,.2ex)}}}, + b={label in legend={text=b, + label in legend line coordinates={ + (-2em,-.2ex), (-1em,.2ex), (0,-.2ex)}, + label in legend mark coordinates={ + (-2em,-.2ex), (0,-.2ex)}}}] +data point [x=-1, y=-1, set=a] data point [x=1, y=0, set=a] +data point [x=-1, y=1, set=b] data point [x=1, y=0.5, set=b]; +\end{codeexample} +\end{key} + + + +Naturally, you typically will not give coordinates explicitly for each +label, but use one of the following styles: + +\begin{key}{/tikz/data visualization/legend entry options/straight label in legend line} + Just gives a straight line and two plot marks. +\begin{codeexample}[width=5cm] +\tikz \datavisualization [visualize as line, + line={style={mark=x}, label in legend={text=example, + straight label in legend line}}]; +\end{codeexample} + This style might seem like a good idea to use in general, but it + does have a huge drawback: Some commonly used plot marks will be impossible to + distinguish -- even though there is no problem distinguishing them + in a graph. +\begin{codeexample}[width=5cm] +\tikz \datavisualization [visualize as line/.list={a,b,c}, + legend entry options/default label in legend path/.style= + straight label in legend line, + a={style={mark=+}, label in legend={text=bad example a}}, + b={style={mark=-}, label in legend={text=bad example b}}, + c={style={mark=|}, label in legend={text=bad example c}}]; +\end{codeexample} + For this reason, this option is not the default, but rather the next one. +\end{key} + +\begin{key}{/tikz/data visualization/legend entry options/zig zag label in legend line} + Uses a small up-down-up line as the label in legend visualizer. The + two plot marks are at the extremal points of the line. It works + pretty well in almost all situations and is the default. +\begin{codeexample}[width=5cm] +\tikz \datavisualization [ + visualize as line=a, + visualize as smooth line/.list={b,c}, + a={style={mark=+}, label in legend={text=better example a}}, + b={style={mark=-}, label in legend={text=better example b}}, + c={style={mark=|}, label in legend={text=better example c}}]; +\end{codeexample} + Even though the above example shows that the marks are easier to + distinguish than with a straight line, the chosen marks are still + not optimal. This is the reason that the |cross marks| style uses + different crosses: +\begin{codeexample}[width=5cm] +\tikz \datavisualization [ + visualize as line/.list={a,b}, + visualize as smooth line=c, + style sheet=cross marks, + a={label in legend={text=good example a}}, + b={label in legend={text=good example b}}, + c={gap line, label in legend={text=good example c}}]; +\end{codeexample} +\end{key} + + +\begin{key}{/tikz/data visualization/legend entry options/circular label in legend line} + This style is especially tailored to represent lines that are + closed. It is automatically selected for instance by the |polygon| + or the |smooth cycle| styles. +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + scientific axes={clean}, all axes={length=3cm}, + visualize as line/.list={a,b,c}, + a={polygon}, b={smooth cycle}, + style sheet=cross marks, + a={label in legend={text=polygon}}, + b={label in legend={text=circle}}, + c={label in legend={text=line}}] +data [format=function, set=a] { + var t : {0,72,...,359}; + func x = cos(\value t); + func y = sin(\value t); +} +data [format=function, set=b] { + var t : [0:2*pi]; + func x = .8*cos(\value t r); + func y = .8*sin(\value t r); +} +data point [x=-1, y=0.5, set=c] +data point [x=1, y=0.25, set=c]; +\end{codeexample} +\end{key} + + +\begin{key}{/tikz/data visualization/legend entry options/gap circular label in legend line} + This style is especially tailored to for the |gap cycle| style and + automatically selected by it: +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + scientific axes={clean}, all axes={length=3cm}, + visualize as line/.list={a,b,c}, + a={gap cycle}, b={smooth cycle}, c={gap line}, + a={style={mark=*, mark size=0.5pt}, + label in legend={text=polygon}}, + b={label in legend={text=circle}}, + c={style={mark=*, mark size=0.5pt, mark options=red}, + label in legend={text=line}}] +data [format=function, set=a] { + var t : {0,72,...,359}; + func x = cos(\value t); + func y = sin(\value t); +} +data [format=function, set=b] { + var t : [0:352]; + func x = .8*cos(\value t); + func y = .8*sin(\value t); +} +data point [x=-1, y=0.5, set=c] +data point [x=1, y=0.25, set=c]; +\end{codeexample} +\end{key} + + + +\begin{key}{/tikz/data visualization/legend entry options/label in legend one mark} + To be used with scatter plots, since no line is drawn. Just displays + a single mark (this is the default with a scatter plot or when the + |no line| is selected. +\begin{codeexample}[width=5cm] +\tikz \datavisualization [visualize as scatter/.list={a,b,c}, + style sheet=cross marks, + a={label in legend={text=example a}}, + b={label in legend={text=example b}}, + c={label in legend={text=example c}}]; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/legend entry options/label in legend three marks} + An alternative to the previous style, where several marks are + shown. +\begin{codeexample}[width=5cm] +\tikz \datavisualization [visualize as scatter/.list={a,b,c}, + style sheet=cross marks, + a={label in legend={text=example a, label in legend three marks}}, + b={label in legend={text=example b, label in legend three marks}}, + c={label in legend={text=example c, label in legend three marks}}]; +\end{codeexample} +\end{key} + + + diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-visualizers.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-visualizers.tex index f7633ceae70..784e838baee 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-visualizers.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-dv-visualizers.tex @@ -13,10 +13,772 @@ \subsection{Overview} -To be written... +In a data visualization a long stream of data points is +\emph{visualized} using \emph{visualizers}. Recall that it is the job +of the axis systems as described in Section~\ref{section-dv-axes} to +determine \emph{where} data points are visualized. It is the job of +the visualizers to determine \emph{how} they are visualized. + +The most basic and common visualizer is the \emph{line visualizer}. It +simply connects subsequent data points by straight lines to indicate +either that the points on these lines interpolate between the real +data points or the straight lines are used to indicate the order in +which the data points appear. A different, more ``conservative'' +visualizer is the \emph{scatter visualizer} or \emph{mark visualizer}, +which just places a small mark at each data point. Such a visualizer +does not imply any interpolation or ordering between the data points. + +Visualizers may, however, also be more complicated. For instance, a +visualizer used for a box plot could visualize a data point as a box +with a median value, standard deviation, outliers, and other +information; a rectangle visualizer might visualize data points as +larger areas; a projection visualizer might visualize the projection +of data points onto different axes; and so. + +Creating a new visualizer is not quite trivial since a new \pgfname\ +class needs to be implemented. Fortunately, using visualizers is much +simpler: For each kind of visualizer there is a key that allows you to +create such a visualizer. You can then use further keys to configure +the visualizer and to connect it to the data. + +In a data visualization multiple visualizers may exist at the same +time. This happens in different situations: +\begin{itemize} +\item A data visualization may contain several independent data sets + that are to be visualized. There might be a line plot, for which a + line visualizer is used, and also a scatter plot, for which a + scatter visualizer would be used. + + In this case, for each data point only one visualizer will do + anything. To achieve this, each data point has an attribute called + |visualizer| which tells the visualizer objects whether they should + ``react'' to the data point or not. +\item A single data point might be visualized several times. For + instance, a scatter visualizer might draw a mark at the data point's + position on the page and a projection visualizer might draw, + additionally, a mark at the projected position. +\end{itemize} -\subsection{Concepts} \subsection{Usage} +\subsubsection{Using a Single Visualizer} + +The simplest scenario for using visualizers are data visualizations in +which there is only a single data set that is visualized in one +style. In this case, all that needs to be done in order to choose a +visualizer is use one of the options starting with |visualize as ...| +together with the |\datavisualization| command: + +\begin{codeexample}[] +% Define a data set: +\tikz \datavisualization data group {example} = { +data { + x, y + 0, 0 + 0.5, 2 + 1, 2 + 1.5, 1.5 + 2, 0.5 +}}; +\tikz \datavisualization [school book axes, visualize as line] data group {example}; +\qquad +\tikz \datavisualization [school book axes, visualize as smooth line] data group {example}; +\qquad +\tikz \datavisualization [school book axes, visualize as scatter] data group {example}; +\end{codeexample} + +Methods for styling visualizers are discussed in Section~\ref{section-dv-visualizer-styling}. + + +\subsubsection{Using Multiple Visualizers} + +A data visualization may contain multiple data groups and for each data +set we might wish to use a different visualizer. In this case, we need +some way of telling the data visualization engine to which visualizer +should be used with the different data points. + +To solve this problem, you can \emph{name} a visualizer. The +visualizer's name can then both be used to configure the visualizer +and also to indicate that data points ``belong'' to the visualizer. + +Naming a visualizer is quite simple: The |visualize as ...| keys +actually take a single parameter, which is the name of the +visualizer. For instance, the following code creates three +visualizers, named |sin|, |cos|, and |tan|: + +\begin{codeexample}[code only] +visualize as line=sin, +visualize as line=cos, +visualize as scatter=tan +\end{codeexample} + +(When you just say |visualize as line| without providing a name, the +name |line| is chosen as a default, for |visualize as scatter| the +name |scatter| is the default and so.) + +In order to indicate which data points should be visualized by which +of these visualizers, the following key is important: + +\begin{key}{/data point/set} + A visualizer will only act on a data point when its name matches the + value of this key. Initially, this key is set to the last visualizer + created, so if there is only one, there is no need to set or worry + about this key. +\end{key} + +Since the |set| key has the path prefix |/data point|, it can +be set like any other attribute of a data key: + +\begin{codeexample}[width=7cm] +\tikz \datavisualization + [scientific axes=clean, + visualize as line=sin, + visualize as line=cos, + visualize as scatter=tan] +data { + x, y, set + 0, 0, sin + 1, 1, sin + 2, 0, sin + 3, -1, sin + 4, 0, sin + 0, 1, cos + 1, 0, cos + 0, 0, tan + 1, 1, tan + 2, 2, tan + 3, 4, tan + 2, -1, cos + 3, 0, cos + 4, 1, cos +}; +\end{codeexample} + +As can be seen, the data points with the same |set| attribute +do not need to be consecutive. + +The above method of specifying the visualizer works nicely, but in +most cases it would be more natural to keep the |set| attribute +out of the table. This is easy to achieve by using multiple |data| and +using the following key: + +\begin{key}{/pgf/data/set=\meta{name}} + Shorthand for |/data point/set=|\meta{name}. +\begin{codeexample}[width=7cm] +\tikz \datavisualization + [scientific axes=clean, + visualize as line=sin, + visualize as line=cos] +data [set=sin] { + x, y + 0, 0 + 1, 1 + 2, 0 + 3, -1 + 4, 0 +} +data [set=cos] { + x, y + 0, 1 + 1, 0 + 2, -1 + 3, 0 + 4, 1 +}; +\end{codeexample} +\end{key} + +When you need to visualize several similar things in a single plot +(like ten lines that all get visualized by |visualize as line|), it is +somewhat cumbersome having to write this ten times. In this case you +can shorten your code by making use of the |.list| key handler: When +you add it to a key, the ``value'' passed to the key is parsed as a +list of values. The key is then executed once for each of these +values: + +\begin{codeexample}[width=7cm] +\tikz \datavisualization + [scientific axes=clean, + visualize as line/.list={sin, cos, tan}] +data [set=sin, format=function] { + var x : interval[0:3*pi]; + func y = sin(\value x r); +} +data [set=cos, format=function] { + var x : interval[0:3*pi]; + func y = cos(\value x r); +} +data [set=tan, format=function] { + var x : interval[0:pi/2.2]; + func y = tan(\value x r); +}; +\end{codeexample} + + + +\subsubsection{Styling a Visualizer} +\label{section-dv-visualizer-styling} + +In order to style a visualizer that has been created using for +instance |visualize as line=|\meta{visualizer name}, you can use the +following key: + +\begin{key}{/tikz/data visualization/\meta{visualizer + name}=\meta{options}} + For each visualizer, a key of the same name is created with the path + prefix |/tikz/data visualization|. This key takes the \meta{options} + and executes them with the path prefix +\begin{codeexample}[code only] +/tikz/data visualization/visualizer options/ +\end{codeexample} + These options are then used to configure the appearance of the + current visualizer. (This is quite similar to the way options are + passed to an axis in order to configure the axis.) + Possible options include |style|, but also |label in legend| and + |label in data|. The latter two options are discussed in + Section~\ref{section-dv-labels-in}, the first option below. + +\begin{codeexample}[width=7cm] +\tikz \datavisualization + [scientific axes=clean, + visualize as smooth line/.list={sin, cos}, + sin={style=red}, + cos={style=blue}] +data [set=sin, format=function] { + var x : interval[0:3*pi]; + func y = sin(\value x r); +} +data [set=cos, format=function] { + var x : interval[0:3*pi]; + func y = cos(\value x r); +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/visualizer + options/style=\meta{options}} + The \meta{options} given to this key should be normal \tikzname\ + options. They will be executed when the visualizer is used. + +\begin{codeexample}[width=7cm] +\tikz \datavisualization + [scientific axes=clean, + visualize as smooth line=sin, + sin={style={red, densely dotted}}, + visualize as smooth line=cos, + cos={style={mark=x}}, +] +data [set=sin, format=function] { + var x : interval[0:3*pi]; + func y = sin(\value x r); +} +data [set=cos, format=function] { + var x : interval[0:3*pi]; + func y = cos(\value x r); +}; +\end{codeexample} + + When you have multiple visualizers in a single data visualization, + you can use the |style| option with each visualizer to configure + their different appearances as in the above example. However, it is + usually much better (and easier) to use a style sheet, see + Section~\ref{section-dv-style-sheets}. + + +\begin{codeexample}[width=7cm] +\tikz \datavisualization + [scientific axes={clean, end labels}, + x axis={label=$x$}, y axis={grid={major also at=0}}, + visualize as smooth line/.list={sin,cos,sin 2,cos 2}, + legend={below, rows=2}, + sin={label in legend={text=$\sin x$}}, + cos={label in legend={text=$\cos x$}}, + sin 2={label in legend={text=$\sin 2x$}}, + cos 2={label in legend={text=$\cos 2x$}}, + style sheet=strong colors] +data [set=sin, format=function] { + var x : interval[0:3*pi]; + func y = sin(\value x r); +} +data [set=cos, format=function] { + var x : interval[0:3*pi]; + func y = cos(\value x r); +} +data [set=sin 2, format=function] { + var x : interval[0:3*pi]; + func y = sin(2*\value x r); +} +data [set=cos 2, format=function] { + var x : interval[0:3*pi]; + func y = cos(2*\value x r); +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/visualizer options/ignore style + sheets} + This option, which should be passed to a visualizer after its + creation before another visualizer is created, causes style sheets + \emph{not} to apply to the visualizer (but the |style| option will + still have an effect). This allows you to create visualizers that + are used for special purposes and that do not ``take part'' in the + usual styling. For instance, a visualizer might be used internally + to depict a regression line, even though the regression line itself + should not participate in the usual styling by, say, dashing or + different coloring. +\end{key} + +In addition to the options passed to a visualizer via |style|, the +following also gets executed when a visualizer is used: + +\begin{stylekey}{/tikz/data visualization/every visualizer} + This style is used with every visualizer. Note that it should + contain normal \tikzname\ keys. + +\begin{codeexample}[width=7cm] +\tikz \datavisualization + [scientific axes=clean, + every visualizer/.style={dashed}, + visualize as smooth line] +data [format=function] { + var x : interval[0:3*pi]; + func y = sin(\value x r); +}; +\end{codeexample} +\end{stylekey} + + \subsection{Reference: Basic Visualizers} + +\subsubsection{Visualizing Data Points Using Lines} + +\begin{key}{/tikz/data visualizers/visualize as line=\meta{visualizer + name} (default line)} + Creates a new visualizer named \meta{visualizer name}. Basically, + this visualizer connects all data points for which the + |/data point/set| attribute equals \meta{visualizer name} by + a line that is styled by the visualizer's style. + + In more detail, the following happens: + \begin{enumerate} + \item A new object is created (of class |plot handler visualizer|) + that is configured to collect the canvas positions of all data + points whose |set| attribute equals \meta{visualizer name}. + \item During the end of the data visualization, \pgfname's plotting + mechanism (see Section~\ref{section-plots}) is used to plot the + stream of recorded data points. + + This means that, in principle, all of the plot handlers available + in \tikzname\ could be used for the visualization (such as the + |smooth| handler). However, some plot handlers such as, say, the + |xcomb| are unsuitable as plot handlers since they do not support + the advanced axis handling done by the data visualization + engine. Because of this (and also for other reasons), you cannot + set the plot handler directly, but must use one of the options + like |straight line|, |smooth line| and others, documented in a + moment. + \item Additionally, plot marks can be drawn at the collected data + points. Here, all of the options available to \tikzname\ for + drawing plot marks are available. To configure them, all options + offered by \tikzname\ for configuring marks are available such as + |mark repeat|: +\begin{codeexample}[width=7cm] +\tikz \datavisualization + [scientific axes=clean, + visualize as line=my data, + my data={style={mark=x, mark repeat=3}}] +data [format=function] { + var x : interval [0:pi] samples 10; + func y = sin(\value x r); +}; +\end{codeexample} + \end{enumerate} + + The line visualizer also provides a method of dealing with gaps in a + line. Take for instance the function $f(x) = \tan x$. When this + function is plotted over the interval $[0,\pi]$, then the function + will go to $\pm \infty$ at $\pi/2$. When we plot this, we might plot + the function in the interval $[0,\frac{\pi}{2}-\epsilon]$ and then + continue in the interval $[\frac{\pi}{2}+\epsilon,\pi]$. However, we + do not want the point at coordinate $\bigl(\frac{\pi}{2}- \epsilon, + \tan(\frac{\pi}{2}- \epsilon)\bigr)$ to be connected to the + coordinate $\bigl(\frac{\pi}{2}+ \epsilon, \tan(\frac{\pi}{2}+ + \epsilon)\bigr)$ by a line. Rather, there should be a ``gap'' or a + ``jump'' between these coordinates. To achieve this, the following + key can be used: + \begin{key}{/data point/outlier=\meta{value} (default true, initially \normalfont empty)} + When this key is set to anything non-empty value, a visualizer + will consider this data point to be an ``outlier.'' For a line + visualizer this means that the point is not shown and that the + current line ends at the previous data point and a new line starts + at the next data point. +\begin{codeexample}[width=7cm] +\tikz \datavisualization + [scientific axes=clean, x axis={grid={major at=(pi/2)}}, + visualize as smooth line] +data [format=function] { + var x : interval[0:pi/2-0.1]; + func y = tan(\value x r); +} +data point [outlier] +data [format=function] { + var x : interval[pi/2+0.1:pi]; + func y = tan(\value x r); +}; +\end{codeexample} + \end{key} +\end{key} + + +\begin{key}{/tikz/data visualizers/visualize as smooth line=\meta{visualizer + name} (default line)} + A shorthand |visualize as line=|\meta{visualizer name} + followed \meta{visualizer name}|=smooth line|. +\end{key} + + +\begin{key}{/tikz/data visualization/visualizer options/straight line} + Causes the data points to be connected by straight lines. +\begin{codeexample}[] +\tikz [scale=.55] \datavisualization + [scientific axes=clean, all axes={ticks=few}, + visualize as smooth line=my data, my data={straight line}] +data [format=function] { + var t : interval [0:4] samples 5; + func x = cos(\value t r); + func y = sin(\value t r); +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/visualizer options/straight cycle} + Causes the data points to be connected by a polygon. +\begin{codeexample}[] +\tikz [scale=.55] \datavisualization + [scientific axes=clean, all axes={ticks=few}, + visualize as smooth line=my data, my data={straight cycle}] +data [format=function] { + var t : interval [0:4] samples 5; + func x = cos(\value t r); + func y = sin(\value t r); +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/visualizer options/polygon} + This is an alias for |straight cycle|. +\end{key} + +\begin{key}{/tikz/data visualization/visualizer options/smooth line} + Causes the data points to be connected by a line that is smoothed + at the joins: +\begin{codeexample}[] +\tikz [scale=.55] \datavisualization + [scientific axes=clean, all axes={ticks=few}, + visualize as smooth line=my data, my data={smooth line}] +data [format=function] { + var t : interval [0:4] samples 5; + func x = cos(\value t r); + func y = sin(\value t r); +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/visualizer options/smooth cycle} + Causes the data points to be connected by a circular line that is + smoothed at the joins: +\begin{codeexample}[] +\tikz [scale=.55] \datavisualization + [scientific axes=clean, all axes={ticks=few}, + visualize as smooth line=my data, my data={smooth cycle}] +data [format=function] { + var t : interval [0:4] samples 5; + func x = cos(\value t r); + func y = sin(\value t r); +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/visualizer options/gap line} + This key causes the data points to be connected by lines that ``do + not quite touch'' the data points. This is implemented by using the + |\pgfplothandlergaplineto|, see Section~\ref{section-plot-gapped}. +\begin{codeexample}[] +\tikz [scale=.55] \datavisualization + [scientific axes=clean, all axes={ticks=few}, + visualize as smooth line=my data, my data={gap line}] +data [format=function] { + var t : interval [0:4] samples 5; + func x = cos(\value t r); + func y = sin(\value t r); +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/visualizer options/gap cycle} + Like |gapped line|, only with a cycle: +\begin{codeexample}[] +\tikz [scale=.55] \datavisualization + [scientific axes=clean, all axes={ticks=few}, + visualize as smooth line=my data, my data={gap cycle}] +data [format=function] { + var t : interval [0:4] samples 5; + func x = cos(\value t r); + func y = sin(\value t r); +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/data visualization/visualizer options/no lines} + Suppresses the line. This option only makes sense when the |mark| + option is used. +\begin{codeexample}[] +\tikz [scale=.55] \datavisualization + [scientific axes=clean, all axes={ticks=few}, + visualize as smooth line=my data, my data={no lines, style={mark=x}}] +data [format=function] { + var t : interval [0:4] samples 5; + func x = cos(\value t r); + func y = sin(\value t r); +}; +\end{codeexample} +\end{key} + + + +\subsubsection{Visualizing Data Points Using Marks} + +\begin{key}{/tikz/data visualizers/visualize as scatter=\meta{visualizer + name} (default scatter)} + A shorthand |visualize as line=|\meta{visualizer name} + followed \meta{visualizer name}|=no lines| and setting + the |style| of the visualizer so that is will use |mark=x| (plus + some size adjustments) to draw marks at the data points. +\begin{codeexample}[width=7cm] +\tikz \datavisualization + [scientific axes=clean, + visualize as scatter] +data [format=function] { + var x : interval [0:pi] samples 10; + func y = sin(\value x r); +}; +\end{codeexample} +\end{key} + + +\subsection{Advanced: Creating New Visualizers} + +Creating a new visualizer is a two-stage process that does, +unfortunately, require in-depth knowledge of the data +visualization backend: +\begin{enumerate} +\item First, you need to create a new class using |\pgfooclass| whose + instances react to the signal |visualize datapoint signal|. This requires + detailed knowledge of the data visualization engine, see + Section~\ref{section-dv-backend}. +\item Second, you should provide keys on the \tikzname\ level for + creating the necessary objects. These keys invoke the key + |new visualizer| internally. +\end{enumerate} + +\begin{key}{/tikz/data visualization/new + visualizer=\marg{name}\marg{options}\marg{legend entry options}} + This key configures a new visualizer named \meta{name}. This entails + the following actions: + \begin{itemize} + \item The key |/tikz/data visualization/|\meta{name} is + created. As described earlier, this key can be used to pass + for instance |style| options to the visualizer. + \item The style key |/tikz/data visualization/visualizers/|\meta{name}|/styling| + is created and made empty. This is the key in which the |style| + key will store the options passed to the visualizer. + \item The style key |/tikz/data visualization/visualizers/|\meta{name}|/label in legend options| + is set to \meta{legend entry options}. These options are used to + configure how the visualizer should be rendered in a legend, see + Section~\ref{section-dv-legend-entries} for details. + \item The key |/data point/set/|\meta{name} is set to a + number that is increased for each visualizer in the current data + visualization. This number is important for style sheets, see + Section~\ref{section-dv-style-sheets}. + \item The key |/data point/|\meta{name}|/execute at begin| is set to + code that creates a |{scope}| that executes the following styles + as options: + \begin{enumerate} + \item The \meta{options} passed to the |new visualizer| key. + \item The |every visualizer| style. + \item The styling from the currently active style sheets, see + Section~\ref{section-dv-style-sheets}. + \item The styling stored in the |styling| key mentioned above. + \end{enumerate} + \item The key |/data point/|\meta{name}|/execute at end| is set to + code that will finish all paths that may have been created by the + visualizer and closes the scope. + \end{itemize} + + All of the above mean the following in practice: + \begin{itemize} + \item Inside a new |visualize as ...| key, you pass the name of + the to-be-created to |new visualizer| as the first parameter and + any special default styling setup of the visualizer as the second + parameter. + \item The new |visualize as ...| key should also create a visualizer + object using |new object|. + \item When this object finally is about to create the actual + visualization, it should surround the code by invoking the code + stored in the |execute at begin| and the |execute at end| keys of + the visualizer. + \end{itemize} + + Everything else is usually taken care of by the |new visualizer| key + automatically. +\end{key} + + +As an example, let us create a simple visualizer that creates a +circle whose radius is dictated by the |radius| attribute. To keep +things simple in this example, this attribute cannot be configured. + +First, we need the visualizer class. For this example I have boiled it +down to a minimum: + +\begin{codeexample}[code only] +\pgfooclass{circle visualizer} +{ + % Stores the name of the visualizer. This is needed for filtering and configuration + \attribute name; + + % The constructor. Just setup the attribute. + \method circle visualizer(#1) { \pgfooset{name}{#1} } + + % Connect to visualize signal. + \method default connects() { + \pgfoothis.get handle(\me) + \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\me,visualize,visualize datapoint signal) + } + + % This method is invoked for each data point. It checks whether the data point belongs to the correct + % visualizer and, if so, calls the macro \dovisualization to do the actual visualization. + \method visualize() { + \pgfdvfilterpassedtrue + \pgfdvnamedvisualizerfilter + \ifpgfdvfilterpassed + \dovisualization + \fi + } +} +\end{codeexample} + +The |\dovisualization| method must now do the correct +visualization. + +\begin{codeexample}[code only] +\def\dovisualization{ + \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at begin} + \pgfpathcircle{\pgfpointdvdatapoint}{\pgfkeysvalueof{/data point/radius}} + % \pgfusepath is done by |execute at end| + \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at end} +} +\end{codeexample} + +Finally, we create a |visualize as| key: + +\begin{codeexample}[code only] +\tikzdatavisualizationset{ + visualize as circle/.style={ + new object={ + when=after survey, + store=/tikz/data visualization/visualizers/#1, + class=circle visualizer, + arg1=#1 + }, + new visualizer={#1}{% + color=visualizer color, % a color setup by the style sheet + every path/.style={fill,draw}, % fill and draw the circle by default, + }{}, % let's ignore legends in this example + /data point/set=#1 + }, + visualize as circle/.default=circle +} +\end{codeexample} + +Now, let's see how this works: + + +\pgfooclass{circle visualizer} +{ + % Stores the name of the visualizer. This is needed for filtering + % and configuration + \attribute name; + + % The constructor. Just setup the attribute. + \method circle visualizer(#1) { \pgfooset{name}{#1} } + + % Connect to visualize signal. + \method default connects() { + \pgfoothis.get handle(\me) + \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\me,visualize,visualize datapoint signal) + } + + % This method is invoked for each data point. It checks whether the + % data point belongs to the correct visualizer and, if so, calls the + % macro \dovisualization to do the actual visualization. + \method visualize() { + \pgfdvfilterpassedtrue + \pgfdvnamedvisualizerfilter + \ifpgfdvfilterpassed + \dovisualization + \fi + } +} + +\def\dovisualization{ + \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at begin} + \pgfpathcircle{\pgfpointdvdatapoint}{\pgfkeysvalueof{/data point/radius}} + % \pgfusepath is done by |execute at end| + \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at end} +} + +\tikzdatavisualizationset{ + visualize as circle/.style={ + new object={ + when=after survey, + store=/tikz/data visualization/visualizers/#1, + class=circle visualizer, + arg1=#1 + }, + new visualizer={#1}{% + color=visualizer color, % a color setup by the style sheet + every path/.style={fill,draw}, % fill and draw the circle by default, + }{}, + /data point/set=#1 + }, + visualize as circle/.default=circle +} + + +\begin{codeexample}[width=7cm] +\tikz \datavisualization [ + scientific axes=clean, + visualize as circle/.list={a, b, c}, + style sheet=strong colors] +data [set=a] { + x, y, radius + 0, 0, 2pt + 1, 1, 3pt + 1, 2, 3pt + 2, 0, 1pt +} +data [set=b] { + x, y, radius + 0.5, 0.5, 5pt + 1, 1.5, 2pt + 1, 2.5, 3pt + 0, 2, 4pt +} +data [set=c] { + x, y, radius + 3, 2, 3pt + 2.5, 0.5, 4pt +}; +\end{codeexample} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-algorithm-layer.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-algorithm-layer.tex new file mode 100644 index 00000000000..b02a61319cb --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-algorithm-layer.tex @@ -0,0 +1,851 @@ +% Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster +% Copyright 2011 by Till Tantau +% Copyright 2011 by Jannis Pohlmann +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + +\section{The Algorithm Layer} + +\label{section-gd-algorithm-layer} + +\noindent{\emph{by Till Tantau}} + +\ifluatex\else This section of the manual can only be typeset using Lua\TeX.\expandafter\endinput\fi + +\subsection{Overview} + +The present section is addressed at readers interested in implementing +new graph drawing algorithms for the graph drawing system. Obviously, +in order to do so, you need to have an algorithm in mind and also some +programming skills; but fortunately only in the Lua programming +language: Even though the graph drawing system was originally +developed as an extension of \tikzname, is has been restructured so +that the ``algorithm layer'' where you define algorithms is +scrupulously separated from \tikzname. In particular, an algorithm +declared and implemented on this layer can be used in with every ``display +layers,'' see Section~\ref{section-gd-display-layer}, without change. Nevertheless, in +the following we will use the \tikzname\ display layer and syntax in +our examples. + +Normally, new graph drawing algorithms can and must be implemented in +the Lua programming language, which is a small, easy-to-learn (and +quite beautiful) language integrated into current versions of +\TeX. However, as explained in Section~\ref{section-algorithms-in-c}, +you can also implement algorithms in C or C++ (and, possibly, in the +future also in other languages), but this comes at a great cost +concerning portability. In the present section, I assume that you are +only interested in writing an algorithm using Lua. + +In the following, after a small ``hello world'' example of graph +drawing and a discussion of technical details like +how to name files so that \TeX\ will find them, we have a look at the +main parts of the algorithm layer: + +\begin{itemize} +\item Section~\ref{section-gd-namespaces} gives and overview of the + available namespaces and also of naming conventions used in the + graph drawing system. +\item Section~\ref{section-gd-gd-scope} explores what graph + drawing scopes ``look like on the algorithm layer.'' As the graph + of a graph drawing scope is being parsed on the display layer, a lot + of information is gathered: The nodes and edges of the graph are + identified and the + object-oriented model is built, but other information is also + collected. For instance, a sequence of \emph{events} is created + during the parsing process. As another example, numerous kinds of + \emph{collections} may be identified by the parser. The parsed graph + together with the event sequence and the collections are all + gathered in a single table, called the \emph{scope table} of the + current graph drawing scope. Algorithms can access this table to + retrieve information that goes beyond the ``pure'' graph model. + + One entry in this table is of particular importance: The + \emph{syntactic digraph.} While most graph drawing + algorithms are not really interested in the ``details'' of how a + graph was specified, for some algorithms it makes a big difference + whether you write |a -> b| or |b <- a| in your specification of the + graph. These algorithms can access the ``fine details'' of how the + input graph was specified through the syntactic digraph; all other + algorithms can access their |digraph| or |ugraph| fields and do not + have to worry about the difference between |a -> b| and |b <- a|. +\item Section~\ref{section-gd-models} explains the object-oriented + model of graphs used throughout the graph drawing system. Graph + drawing algorithms do not get the ``raw'' specification used by the + user to specify a graph (like |{a -> {b,c}}| in the |graph| + syntax). Instead, what a graph drawing algorithm sees is ``just'' a + graph object that provides methods for accessing the vertices and + arcs. +\item Section~\ref{section-gd-transformations} explains how the + information in the graph drawing scope is processed. One might + expect that we simply run the algorithm selected by the user; + however, things are more involved in practice. When the layout of a + graph needs to be computed, only very few algorithms will actually + be able to compute positions for the nodes of \emph{every} + graph. For instance, most algorithms implicitly assume that the + input graph is connected; algorithms for computing layouts for trees + assume that the input is, well, a tree; and so on. For this reason, + graph drawing algorithms will not actually need the original input + graph as their input, but some \emph{transformed} version of + it. Indeed, \emph{all} graph drawing algorithms are treated as graph + transformations by the graph drawing engine. + + This section explains how transformations are chosen and which + transformations are applied by default. +\item Section~\ref{section-gd-interface-to-algorithms} documents the + interface-to-algorithm class. This interface encapsulates all that + an algorithm ``sees'' of the graph drawing system (apart from the + classes in |model| and |lib|). +\item Section~\ref{section-gd-examples} provides a number of complete + examples that show how graph drawing algorithms can, actually, be + implemented. +\item Section~\ref{section-gd-libs} documents the different + libraries functions that come with the graph drawing engine. For + instance, there are library functions for computing the (path) + distance of nodes in a graph; a parameter that is needed by some + algorithms. +\end{itemize} + + + +\subsection{Getting Started} + +In this section, a ``hello world'' example of a graph +drawing algorithm is given, followed by an overview of the +organization of the whole engine. + + +\subsubsection{The Hello World of Graph Drawing} + +Let us start our tour of the algorithm layer with a ``hello world'' +version of graph drawing: An algorithm that simply places all nodes of +a graph in a circle of a fixed radius. Naturally, this is not a +particularly impressive or intelligent graph drawing algorithm; but +neither is the classical ``hello world''$\dots$\ Here is a minimal +version of the needed code (this is not the typical way of formulating +the code, but it is the shortest; we will have a look at the more +standard and verbose way in a moment): + +\begin{codeexample}[code only, tikz syntax=false] +pgf.gd.interface.InterfaceToAlgorithms.declare { + key = "very simple demo layout", + algorithm = { + run = + function (self) + local alpha = (2 * math.pi) / #self.ugraph.vertices + for i,vertex in ipairs(self.ugraph.vertices) do + vertex.pos.x = math.cos(i * alpha) * 25 + vertex.pos.y = math.sin(i * alpha) * 25 + end + end + } +} +\end{codeexample} +\directlua{ +pgf.gd.interface.InterfaceToAlgorithms.declare { + key = "very simple demo layout", + algorithm = { + run = + function (self) + local alpha = (2 * math.pi) / \luaescapestring{#}self.ugraph.vertices + for i,vertex in ipairs(self.ugraph.vertices) do + vertex.pos.x = math.cos(i * alpha) * 25 + vertex.pos.y = math.sin(i * alpha) * 25 + end + end + } +} +} + +This code \emph {declares} a new algorithm (|very simple demo layout|) +and includes an implementation of the algorithm (through the |run| +field of the |algorithm| field). When the |run| method is called, the +|self| parameter will contain the to-be-drawn graph in its |ugraph| +field. It is now the job of the code to modify the positions of the +vertices in this graph (in the example, this is done by assigning +values to |vertex.pos.x| and |vertex.pos.y|). + +In order to actually \emph{use} the algorithm, the above code first +needs to be executed somehow. For \tikzname, one can just call +|\directlua| on it or put it in a file and then use |\directlua| plus +|require| (a better alternative) or you put it in a file like +|simpledemo.lua| and use |\usegdlibrary{simpledemo}| (undoubtedly the +``best'' way). For another display layer, like a graphical editor, the +code could also be executed through the use of |require|. + +Executing the code ``just'' declares the algorithm, this is what the +|declare| function does. Inside some internal tables, the algorithm +layer will store the fact that a |very simple demo layout| is now +available. The algorithm layer will also communicate with the display +layer through the binding layer to advertise this fact to the +``user.'' In the case of \tikzname, this means that the option key +|very simple demo layout| becomes available at this point and we can +use it like this: + +\begin{codeexample}[] +\tikz [very simple demo layout] + \graph { f -> c -> e -> a -> {b -> {c, d, f}, e -> b}}; +\end{codeexample} + +It turns out, that our little algorithm is already more powerful than +one might expect. Consider the following example: +\begin{codeexample}[] +\tikz [very simple demo layout, componentwise] + \graph { + 1 -> 2 ->[orient=right] 3 -> 1; + a -- b --[orient=45] c -- d -- a; + }; +\end{codeexample} + +Note that, in our algorithm, we ``just'' put all nodes on a circle +around the origin. Nevertheless, the graph gets decomposed into two +connected components, the components are rotated so that the edge from +node |2| to node |3| goes from left to right and the edge from |b| to +|c| goes up at an angle of $45^\circ$, and the components are placed +next to each other so that some spacing is achieved. + +The ``magic'' that achieves all this behind the scenes is called +``graph transformations.'' They will heavily pre- and postprocess the +input and output of graph drawing algorithms to achieve the above +results. + +Naturally, some algorithms may not wish their inputs and/or +outputs to be ``tampered'' with. An algorithm can easily configure +which transformations should be applied, by passing appropriate options +to |declare|. + + +\subsubsection{Declaring an Algorithm} + +Let us now have a look at how one would ``really'' implement the +example algorithm. First of all, we place our algorithm in a +separate file called, say, |ExampleLayout.lua|. This way, by putting +it in a separate file, all display layers can easily install the +algorithm at runtime by saying |require "ExampleLayout"|. + +Next, the |declare| function is needed quite often, so it makes sense +to create a short local name for it: + +\begin{codeexample}[code only, tikz syntax=false] +-- This is the file ExampleLayout.lua +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare +\end{codeexample} + +The |declare| function is the work-horse of the algorithm layer. It +takes a table that contains at least a |key| field, which must be a +unique string, and some other fields that specify in more detail what +kind of key is declared. Once declared through a call of |declare|, +the ``key'' can be used on the display layer. + +For declaring an algorithm, the table passed to |declare| must contain +a field |algorithm|. This field, in turn, must (normally) be set to a +table that will become the algorithm class. In the above example, our +algorithm was so simple that we could place the whole definition of +the class inside the call of |declare|, but normally the class is +defined in more detail after the call to |declare|: + +\begin{codeexample}[code only, tikz syntax=false] +local ExampleClass = {} -- A local variable holding the class table + +declare { + key = "very simple demo layout", + algorithm = ExampleClass +} + +function ExampleClass:run () + local alpha = (2 * math.pi) / #self.ugraph.vertices + ... +end +\end{codeexample} + +The effect of the |declare| will be that the table stored in +|ExampleClass| is setup to form a class in the sense of +object-oriented programming. In particular, a static |new| function +is installed. + +Now, whenever the user uses the key |very simple demo layout| on a +graph, at some point the graph drawing engine will create a new +instance of the |ExampleClass| using |new| and will then call the +|run| method of this class. The class can have any number of other +methods, but |new| and |run| are the only ones directly called by the +graph drawing system. + + +\subsubsection{The Run Method} + +The |run| method of an algorithm classes lies at the heart of any +graph drawing algorithm. This method will be called whenever a graph +needs to be laid out. Upon this call, the |self| object will have +some important fields set: +\begin{itemize} +\item |ugraph| This stands for ``undirected graph'' and is the + ``undirected'' version of the to-be-laid out graph. In this graph, + whenever there is an arc between $u$ and $v$, there is also an arc + between $v$ and $u$. It is obtained by considering the syntactic + digraph and then ``forgetting'' about the actual direction of the + edges. + + When you have set certain |preconditions| in your algorithm class, + like |connected=true|, the |ugraph| will satisfy these + conditions. In particular, the |ugraph| typically will not be the + underlying undirected graph of the complete syntactic digraph, but + rather of some part of it. The use of (sub)layouts will also modify + the syntactic digraph is fancy ways. + + Refer to this graph whenever your algorithm is ``most comfortable'' + with an undirected graph, as is the case for instance for most + force-base algorithms. +\item |digraph| This stands for ``directed graph'' and is the + ``semantically directed'' version of the to-be-laid out + graph. Basically, when happens is that reverse edges in the + syntactic digraph (an edge like |b <- a|) will yield an |Arc| from + |a| to |b| in the |digraph| while they yield a |b| to |a| arc and + edge in the syntactic digraph. Also, undirected edges like |a -- b| + are replaced by directed edges in both directions between the + vertices. +\item |scope| The graph drawing scope. +\item |layout| The layout object for this graph. This is a collection + of kind |layout|. +\end{itemize} + + +\subsubsection{Loading Algorithms on Demand} + +In order to use the |very simple demo layout| on the display layer, +|declare| must have been called for this key. However, we just saw +that the |declare| function takes the actual class table as parameter +and, thus, whenever an algorithm is declared, it is also completely +loaded and compiled at this point. + +This is not always desirable. A user may wish to include a number of +libraries in order to declare a large number of potentially useful +algorithms, but will not actually use all of them. Indeed, at least +for large, complex algorithms, it is preferable that the algorithm's +code is loaded only when the algorithm is used for the first time. + +Such a ``loading of algorithms on demand'' is supported through the +option of setting the |algorithm| field in a |declare| to a +string. This string must now be the file name of a Lua file that +contains the code of the actual algorithm. When the key is actually +used for the first time, this file will be loaded. It must return a +table that will be plugged into the |algorithm| field; so subsequent +usages of the key will not load the file again. + +The net effect of all this is that you can place implementations of +algorithms in files separate from interface files that just contain +the |declare| commands for these algorithms. You will typically do +this only for rather large algorithms. + +For our example, the code would look like this: + +\begin{codeexample}[code only, tikz syntax=false] +-- File ExampleLayout.lua +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare +declare { + key = "very simple demo layout", + algorithm = "ExampleLayoutImplementation" +} +\end{codeexample} + +\begin{codeexample}[code only, tikz syntax=false] +-- File ExampleLayoutImplementation.lua +local ExampleClass = {} +function ExampleClass:run () + local alpha = (2 * math.pi) / #self.ugraph.vertices + ... +end +return ExampleClass +\end{codeexample} + + +\subsubsection{Declaring Options} + +Let us now make our example algorithm a bit more ``configurable''. For +this, we use |declare| once more, but instead of the |algorithm| +field, we use a |type| field. This tells the display layer that the +key is not used to select an algorithm, but to configure ``something'' +about the graph or about nodes or edges. + +In our example, we may wish to configure the radius of the graph. So, +we introduce a |radius| key (actually, this key already exists, so we +would not need to declare it, but let us do so anyway for example +purposes): + +\begin{codeexample}[code only, tikz syntax=false] +declare { + key = "radius", + type = "length", + initial = "25pt" +} +\end{codeexample} + +This tells the display layer that there is now an option called +|radius|, that users set it to some ``length'', and that if it is not +set at all, then the 25pt should be used. + +To access what the user has specified for this key, an algorithm can +access the |options| field of a graph, vertex, or arc at the +key's name: + +\begin{codeexample}[code only, tikz syntax=false] + vertex.pos.x = math.cos(i * alpha) * vertex.options.radius + vertex.pos.y = math.sin(i * alpha) * vertex.options.radius +\end{codeexample} + + + +\subsubsection{Adding Inline Documentation} + +You should always document the keys you |declare|. For this, the +|declare| function allows you to add three fields to its argument +table: +\begin{itemize} +\item |summary| This should be a string that succinctly summarizes the + effect this key has. The idea is that this text will be shown as a + ``tooltip'' in a graphical editor or will be printed out by a + command line tool when a user requests help about the key. + You can profit from using Lua's |[[| and |]]| syntax for specifying + multi-line strings. + + Also, when the file containing the key is parsed for + this manual, this text will be shown. +\item |documentation| When present, this field contains a more + extensive documentation of the key. It will also be shown in this + manual, but typically not as a tool tip. +\item |examples| This should either be a single string or an array of + strings. Each string should be an example demonstrating how the key + is used in \tikzname. They will all be included in the manual, each + surrounded by a |codeexample| environment. +\end{itemize} + +Let us augment our |radius| key with some documentation. The three +dashes before the |declare| are only needed when the declaration is +part of this manual and they will trigger an inclusion of the key in +the manual. + +\begin{codeexample}[code only, tikz syntax=false] +--- +declare { + key = "radius", + type = "length", + initial = "25pt", + summary = [[ + Specifies the radius of a circle on which the nodes are placed when + the |very simple example layout| is used. Each vertex can have a + different radius. + ]], + examples = [[ + \tikz \graph [very simple example layout, radius=2cm] { + a -- b -- c -- d -- e; + }; + ]] +} +\end{codeexample} + +As a courtesy, all of the strings given in the documentation can start +and end with quotation marks, which will be removed. (This helps +syntax highlighting with editors that do not recognize the |[[| to |]]| +syntax.) Also, the indentation of the strings is removed (we compute +the minimum number of leading spaces on any line and remove this many +spaces from all lines). + + + +\subsubsection{Adding External Documentation} +\label{section-gd-documentation-in} + +As an alternative to inlining documentation, you can also store the +documentation of keys in a separate file that is loaded only when the +documentation is actually accessed. Since this happens only rarely +(for instance, not at all, when \tikzname\ is run, except for this +manual), this will save time and space. Also, for C code, it is +impractical to store multi-line documentation strings directly in the C +file. + +In order to store documentation externally, instead of the |summary|, +|documentation|, and |examples| keys, you provide the key +|documentation_in|. The |documentation_in| key must be set +to a string that is input using |require|. + +In detail, when someone tries to access the |summary|, |documentation|, or +|examples| field of a key and these keys are not (yet) defined, the +system checks whether the |documentation_in| key is set. If so, we +apply |require| to the string stored in this field. The file loaded in +this way can now setup the missing fields of the current key and, +typically, also of all other keys defined in the same file as the +current key. For this purpose, it is advisable to use the |pgf.gd.doc| +class: + +\includeluadocumentationof{pgf.gd.doc} + +As a longer example, consider the following declarations: + +\begin{codeexample}[code only, tikz syntax=false] +--- +declare { + key = "very simple demo layout", + algorithm = ExampleClass, + documentation_in = "documentation_file" +} + +--- +declare { + key = "radius", + type = "length", + initial = "25", + documentation_in = "documentation_file" +} +\end{codeexample} + +The file |documentation_file.lua| would look like this: + +\begin{codeexample}[code only, tikz syntax=false] +-- File documentation_file.lua +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + +key "very simple demo layout" +documentation "This layout is a very simple layout that, ..." + +key "radius" +summary "Specifies the radius of a circle on which the nodes are placed." +documentation +[[ +This key can be used together with |very simple example layout|. An +important feature ist that... +]] +example +[[ +\tikz \graph [very simple example layout, radius=2cm] +{ a -- b -- c -- d -- e; }; +]] +\end{codeexample} + + + + +\subsection{Namespaces and File Names} + +\label{section-gd-namespaces} + +\subsubsection{Namespaces} + +All parts of the graph drawing library reside in the Lua ``namespace'' +|pgf.gd|, which is itself a ``sub-namespace'' of |pgf|. For your own +algorithms, you are free to place them in whatever namespace you like; +only for the official distribution of \pgfname\ everything has been +put into the correct namespace. + +Let us now have a more detailed look at these namespaces. A namespace +is just a Lua table, and sub-namespaces are just subtables of +namespace tables. Following the Java convention, namespaces are in +lowercase letters. The following namespaces are part of the core of +the graph drawing engine: +\begin{itemize} +\item |pgf| This namespace is the main namespace of \pgfname. Other + parts of \pgfname\ and \tikzname\ that also employ Lua should put an + entry into this table. Since, currently, only the graph drawing + engine adheres to this rule, this namespace is declared inside the + graph drawing directory, but this will change. + + The |pgf| table is the \emph{only} entry into the global table of + Lua generated by the graph drawing engine (or, \pgfname, for that + matter). If you intend to extend the graph drawing engine, do not + even \emph{think} of polluting the global namespace. You will be + fined. +\item |pgf.gd| This namespace is the main namespace of the graph drawing + engine, including the object-oriented models of graphs and the + layout pipeline. Algorithms that are part of the + distribution are also inside this namespace, but if you write your + own algorithms you do not need place them inside this + namespace. (Indeed, you probably should not before they are made + part of the official distribution.) +\item |pgf.gd.interface| This namespace handles, on the one hand, the + communication between the algorithm layer and the binding layer and, + on the other hand, the communication between the display layer + (\tikzname) and the binding layer. +\item |pgf.gd.binding| So-called ``bindings'' between display layers + and the graph drawing system reside in this namespace. +\item |pgf.gd.lib| Numerous useful classes that ``make an algorithm's + your life easier'' are collected in this namespace. Examples are a + class for decomposing a graph into connected components or a class + for computing the ideal distance between two sibling nodes in a + tree, taking all sorts of rotations and separation parameters into + account. +\item |pgf.gd.model| This namespace contains all Lua classes that are + part of the object-oriented model of graphs employed + throughout the graph drawing engine. For readers familiar with the + model--view--controller pattern: This is the namespace containing + the model-part of this pattern. +\item |pgf.gd.control| This namespace contains the ``control logic'' + of the graph drawing system. It will transform graphs according to + rules, disassemble layouts and sublayouts and will call the + appropriate algorithms. For readers still familiar with the + model--view--controller pattern: This is the namespace containing + the control-part of this pattern. +\item |pgf.gd.trees| This namespace contains classes that are useful + for dealing with graphs that are trees. In particular, it contains a + class for computing a spanning tree of an arbitrary connected graph; + an operation that is an important preprocessing step for many + algorithms. + + In addition to providing ``utility functions for trees,'' the + namespace \emph{also} includes actual algorithms for computing graph + layouts like |pgf.gd.trees.ReingoldTilford1981|. It may seem to be a + bit of an ``impurity'' that a namespace mixes utility classes and + ``real'' algorithms, but experience has shown that it is better to + keep things together in this way. + + Concluding the analogy to the model--view--controller pattern, a + graph drawing algorithm is, in a loose sense, the ``view'' part of + the pattern. +\item |pgf.gd.layered| This namespace provides classes and functions + for ``layered'' layouts; the Sugiyama layout method being the most + well-known one. Again, the namespace contains both algorithms to be + used by a user and utility functions. +\item |pgf.gd.force| Collects force-based algorithms and, again, also + utility functions and classes. +\item |pgf.gd.examples| Contains some example algorithms. They are + \emph{not} intended to be used directly, rather they should serve as + inspirations for readers wishing to implement their own algorithms. +\end{itemize} + +There are further namespaces that also reside in the |pgf.gd| +namespace, these namespaces are used to organize different graph +drawing algorithms into categories. + +In Lua, similarly to Java, when a class |SomeClass| is part of, say, +the namespace |pgf.gd.example|, it is customary to put the class's +code in a file |SomeClass.lua| and then put this class in a directory +|example|, that is a subdirectory of a directory |gd|, which is in +turn a subdirectory of a directory |pgf|. When you write +\texttt{require "pgf.gd.example.SomeClass"} the so-called +\emph{loader} will turn this into a request for the file +\texttt{pgf/gd/example/SomeClass.lua} (for Unix systems). + + + +\subsubsection{Defining and Using Namespaces and Classes} + +There are a number of rules concerning the structure and naming of +namespaces as well as the naming of files. Let us start with the +rules for naming namespaces, classes, and functions. They follow the +``Java convention'': + +\begin{enumerate} +\item A namespace is a short lowercase |word|. +\item A function in a namespace is in |lowercase_with_underscores_between_words|. +\item A class name is in |CamelCaseWithAnUppercaseFirstLetter|. +\item A class method name is in |camelCaseWithALowercaseFirstLetter|. +\end{enumerate} + +From Lua's point of view, every namespace and every class is just a +table. However, since these tables will be loaded using Lua's +|require| function, each namespace and each class must be placed +inside a separate file (unless you modify the |package.loaded| table, +but, then, you know what you are doing anyway). Inside such a file, you +should first declare a local variable whose name is the name of the +namespace or class that you intend to define and then assign a +(possibly empty) table to this variable: +\begin{codeexample}[code only, tikz syntax=false] +-- File pgf.gd.example.SomeClass.lua: +local SomeClass = {} +\end{codeexample} +Next, you should add your class to the encompassing namespace. This is +achieved as follows: +\begin{codeexample}[code only, tikz syntax=false] +require("pgf.gd.example").SomeClass = SomeClass +\end{codeexample} +The reason this works is that the |require| will return the table that +is the namespace |pgf.gd.example|. So, inside this namespace, the +|SomeClass| field will be filled with the table stored in the local +variable of the same name -- which happens to be the table +representing the class. + +At the end of the file, you must write +\begin{codeexample}[code only, tikz syntax=false] +return SomeClass +\end{codeexample} +This ensures that the table that is defined in this file gets stored +by Lua in the right places. Note that you need and should not use +Lua's |module| command. The reason is that this command has +disappeared in the new version of Lua and that it is not really +needed. + +Users of your class can import and use your class by writing: +\begin{codeexample}[code only, tikz syntax=false] +... +local SomeClass = require "pgf.gd.examples.SomeClass" +... +\end{codeexample} + + + + +\subsection{The Graph Drawing Scope} + +\label{section-gd-gd-scope} + +\includeluadocumentationof{pgf.gd.interface.Scope} + + + +\subsection{The Model Classes} + +\label{section-gd-models} + +All that a graph drawing algorithm will ``see'' of the graph specified +by the user is a ``graph object.'' Such an object is an +object-oriented model of the user's graph that no longer encodes the +specific way in which the user specified the graph; it only encodes +which nodes and edges are present. For instance, the \tikzname\ graph +specification +\begin{codeexample}[code only] +graph { a -- {b, c} } +\end{codeexample} +\noindent and the graph specification +\begin{codeexample}[code only] +node (a) { a } +child { node (b) {b} } +child { node (c) {c} } +\end{codeexample} +will generate exactly the same graph object. + +\begin{luanamespace}{pgf.gd.}{model} + This namespace contains the classes modeling graphs, + nodes, and edges. Also, the |Coordinate| class is found here, since + coordinates are also part of the modeling. +\end{luanamespace} + + +\subsubsection{Directed Graphs (Digraphs)} + +Inside the graph drawing engine, the only model of a graph that is +available treats graphs as +\begin{enumerate} +\item directed (all edges have a designated head and a designated + tail) and +\item simple (there can be at most one edge between any pair of + nodes). +\end{enumerate} +These two properties may appear to be somewhat at odds with what users +can specify as graphs and with what some graph drawing algorithms +might expect as input. For instance, suppose a user writes +\begin{codeexample}[code only] +graph { a -- b --[red] c, b --[green, bend right] c } +\end{codeexample} +In this case, it seems that the input graph for a graph drawing +algorithm should actually be an \emph{undirected} graph in which there +are \emph{multiple} edges (namely $2$) between |b| and~|c|. +Nevertheless, the graph drawing engine will turn the user's input a +directed simple graph in ways described later. You do not need to +worry that information gets lost during this process: The +\emph{syntactic digraph,} which is available to graph drawing +algorithms on request, stores all the information about which edges +are present in the original input graph. + +The main reasons for only considering directed, simple graphs are speed +and simplicity: The implementation of these graphs has been optimized so +that all operations on these graphs have a guaranteed running time +that is small in practice. + +\includeluadocumentationof{pgf.gd.model.Digraph} + +\subsubsection{Vertices} + +\includeluadocumentationof{pgf.gd.model.Vertex} + +\subsubsection{Arcs} +\label{section-gd-arc-model} + +\includeluadocumentationof{pgf.gd.model.Arc} + +\subsubsection{Edges} + +\includeluadocumentationof{pgf.gd.model.Edge} + +\subsubsection{Collections} + +\includeluadocumentationof{pgf.gd.model.Collection} + +\subsubsection{Coordinates and Transformations} + +\includeluadocumentationof{pgf.gd.model.Coordinate} +\includeluadocumentationof{pgf.gd.lib.Transform} + +\subsubsection{Options and Data Storages for Vertices, Arcs, and Digraphs} + +\includeluadocumentationof{pgf.gd.lib.Storage} + +\subsubsection{Events} + + +\includeluadocumentationof{pgf.gd.lib.Event} + + + +\subsection{Graph Transformations} + +\label{section-gd-transformations} + +\includeluadocumentationof{pgf.gd.control.LayoutPipeline} + + + +\subsection{The Interface To Algorithms} + +\label{section-gd-interface-to-algorithms} + +\includeluadocumentationof{pgf.gd.interface.InterfaceToAlgorithms} + + + + + +\subsection{Examples of Implementations of Graph Drawing Algorithms} +\label{section-gd-examples} + +\includeluadocumentationof{pgf.gd.examples.library} +\includeluadocumentationof{pgf.gd.examples.SimpleDemo} +\includeluadocumentationof{pgf.gd.examples.SimpleEdgeDemo} +\includeluadocumentationof{pgf.gd.examples.SimpleHuffman} + + + + +\subsection{Support Libraries} + +\label{section-gd-libs} + +The present section lists a number of general-purpose libraries that +are used by different algorithms. + +\subsubsection{Basic Functions} + +\includeluadocumentationof{pgf} + +\includeluadocumentationof{pgf.gd.lib} + +\subsubsection{Lookup Tables} + +\includeluadocumentationof{pgf.gd.lib.LookupTable} + +\subsubsection{Computing Distances in Graphs} + +\emph{Still needs to be ported to digraph classes!} + +%\includeluadocumentationof{pgf.gd.lib.PathLengths} + +\subsubsection{Priority Queues} + +\includeluadocumentationof{pgf.gd.lib.PriorityQueue} + + + diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-algorithms-in-c.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-algorithms-in-c.tex new file mode 100644 index 00000000000..09dfc3c4f09 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-algorithms-in-c.tex @@ -0,0 +1,898 @@ +% Copyright 2012 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + + +\section{Writing Graph Drawing Algorithms in C} +\label{section-algorithms-in-c} + +\noindent{\emph{by Till Tantau}} +\bigskip +\ifluatex\else This section of the manual can only be typeset using Lua\TeX.\expandafter\endinput\fi + +\ifgdccodebasic\else +In order to typeset this section, LuaTeX\ must be able to link C code +at runtime and the graph drawing C libraries must be installed on your +system. You will find the sources in the |c| subdirectory of the +installation, where you will also find example Makefiles. +\expandafter\endinput +\fi + +In the present section we have a look at how graph drawing +algorithms written in the C programming language (or in C++) can be +used in the graph drawing framework. + +\begin{quote} + \emph{Warning:} Graph drawing algorithms written in C can be + incredibly fast if you use the facilities of C + correctly. \emph{However,} C code is much less portable than Lua + code in the sense that it has to be compiled for the specific + platform used by the user and that it has to be linked dynamically + during a run of the \TeX\ program. All of this in possible (and + works, as demonstrated by the linking of the \textsc{ogdf} + framework), but it is \emph{much} harder to get right than writing + Lua code. + + Bottom line, \emph{you really should be using this method + only if it is really necessary (namely, when Lua code is simply not + fast enough).} +\end{quote} + +In the following, I first explain how the link between \TeX\ and C +code works, in general. Then, in the subsequent sections, we go over +the different kinds of programming languages and frameworks for which +there is direct support for such a link. + + +\subsection{How C and \TeX\ Communicate} + +In order to use C code for graph drawing algorithms during a run of +the \TeX\ program, there is no need to build a new version of +\TeX. Rather, it is possible that C code is linked into the \TeX\ +executable at runtime. This is made possible by the fact that Lua +(which part of Lua\TeX$\dots$) is able to link C libraries at runtime -- +provided a strict regime of rules is adhered to: + +\begin{enumerate} +\item When you say |require| in Lua, it will normally look for a + |.lua| file; but it will also try to find a |.so| file (a shared C + library) as a fallback. +\item If it finds such a shared library, Lua(\TeX) will try to link + this library dynamically at runtime. +\item Inside the library, there must be a function (called an entry + point) with a special name (it must start with |luaopen_| and it + must otherwise be the path and name of the library with slashes replaced by + underscores). +\item This function gets called by Lua, once. Its job is to setup the + library so that it can be used by Lua. Mainly, this means that + certain C functions get registered in such a way that Lua can call + them. +\item At this point, control returns to Lua and, now, certain + functions have become available on the Lua layer that, when called, + actually invoke the C code of our linked library. +\end{enumerate} + +For each of the above points, there are some bells and whistles: + +\begin{enumerate} +\item Lua\TeX\ looks at slightly inconvenient places for shared + libraries: By default, (currently, 2013) it looks in a |lib| + subdirectory of the directory containing the Lua\TeX\ + executable. The logic behind is that the shared libraries depend on + the specific architecture of the executable. Thus, unlike normal Lua + files, the library needs to be installed ``far away'' from the actual + package of which it is part. +\item Certain vesions of Lua\TeX\ have a broken handling of filenames + of libraries written in C. The TL2013 version of Lua\TeX, for + instance, crashes when the filename of a shared library does not + contain the complete path (while this works for normal + file). Hopefully, this, too, will be fixed in future versions. +\item On certain platforms, the support for dynamic linking against + Lua\TeX\ is broken since the symbol table of the Lua library has been + stripped away. Hopefully, this will be fixed soon; in the meantime, a + highly fragile workaround is to link in another copy of the Lua + library. +\item The entry point that is called by Lua requires a certain + signature (it takes a Lua state as its only parameter) and must + return the number of objects it returns on the Lua stack. +\item The registration process of C functions is somewhat tricky and + changes from Lua version to Lua version. +\item C functions that get called by Lua must follow all sorts of + tricky rules in order to communicate with Lua correctly. +\end{enumerate} + +Despite the above obstacles, one can use graph drawing algorithms +written in C inside Lua, in principle, as follows: One loads an +appropriately prepared and located C library using |require| and this +library uses commands like |declare| to register its own functions +into the graph drawing system so that when the |run| method is called, +a C functions gets called instead. + +Unfortunately, the above approach is extremely tedious and error-prone +and it is ``no fun'' to access Lua data structures (such as the +syntactic digraph) from C. For this reason, I have written some +libraries that encapsulate (as much as possible) of this communication +between C and Lua. Indeed, when you use these libraries, you can focus +entirely on the graph drawing issues and you will not even notice that +your code ``is talking to Lua.'' (Except for the name of the entry +point, which is fixed to start with |luaopen_| and it is impossible to +change this without disrupting a lot inside Lua's module system). + +There are libraries available for simplifying the communication +between the graph drawing system and graph drawing algorithms written +in + +\begin{itemize} +\item C, see Section~\ref{section-gd-c}, +\item C++, see Section~\ref{section-gd-c++}, +\item Open Graph Drawing Framework, see Section~\ref{section-gd-ogdf-interface}. +\end{itemize} + + + +\subsection{Writing Graph Drawing Algorithms in C} + +\label{section-gd-c} + +\subsubsection{The Hello World of Graph Drawing in C} + +As our first example, as always, the ``hello world'' of graph drawing +simply places nodes on a circle. For this, we implement a +function |fast_hello_world| in a file |SimpleDemoC.c|. It starts as +follows: + +\begin{codeexample}[code only, tikz syntax=false] +#include <pgf/gd/interface/c/InterfaceFromC.h> +#include <math.h> + +static void fast_hello_world (pgfgd_SyntacticDigraph* graph) { + ... +} +\end{codeexample} + +As we can see, we first include a special header file of a rather small +library that does all the hard work of translating between Lua and C +for us (|InterfaceFromC|). These header files reside in the |c| +subdirectory of the |pgf| package. Note that we do \emph{not} have to +include the headers of the Lua library; indeed, you do not need access +to the source of Lua to use the interface headers. As a side effect, +we will, however, have to write |struct lua_State| instead of the more common +|lua_State| once in our code, namely in the declaration of the entry +point; but that is the only downside. + +The library |InterfaceFromC| declares the type +|pgfgd_SyntacticDigraph|. In a moment, we will +see that we can setup a key |fast simple demo layout| such that when +this key is used on the display layer, the function +|fast_hello_world| gets called. When it is called, the |graph| +parameter will be a full representation of the to-be-laid-out +graph. We can access the fields of the graph and even directly modify +some of its fields (in particular, we can modify the |pos| fields of +the vertices). Here is the complete code of the algorithm: + +\begin{codeexample}[code only, tikz syntax=false] +static void fast_hello_world (pgfgd_SyntacticDigraph* graph) { + double angle = 6.28318530718 / graph->vertices.length; + double radius = pgfgd_tonumber(graph->options, "fast simple demo radius"); + + int i; + for (i = 0; i < graph->vertices.length; i++) { + pgfgd_Vertex* v = graph->vertices.array[i]; + v->pos.x = cos(angle*i) * radius; + v->pos.y = sin(angle*i) * radius; + } +} +\end{codeexample} + +That is all that is needed; the C library will take care of both +creating the |graph| object as all well as of deleting it and of +copying back the computed values of the |pos| fields of the vertices. + +Our next task is to setup the key |fast simple demo layout|. We can +(and must) also do this from C, using the following code: + +\begin{codeexample}[code only, tikz syntax=false] +int luaopen_pgf_gd_examples_c_SimpleDemoC (struct lua_State *state) { + + pgfgd_Declaration* d = pgfgd_new_key ("fast simple demo layout"); + pgfgd_key_summary (d, "The C version of the hello world of graph drawing"); + pgfgd_key_algorithm (d, fast_hello_world); + pgfgd_key_add_precondition (d, "connected"); + pgfgd_key_add_precondition (d, "tree"); + pgfgd_declare (state, d) + pgfgd_free_key (d); +\end{codeexample} + +The function |luaopen_pgf_gd_examples_c_SimpleDemoC| is the +function that will be called by Lua (we will come to that). More +important for us, at the moment, is the declaration of the key: We use +|pgfgd_new_key| to create a declaration record and then fill the +different fields using appropriate function calls. In particular, the +call |pgfgd_key_algorithm| allows us to link the key with a particular +C function. The |pgfgd_declare| will then pass the whole declaration +back to Lua, so the effect of the above is essentially the same as if +you had written in Lua: +\begin{codeexample}[code only, tikz syntax=false] +declare { + key = "fast simple demo layout", + summary = "The C version of the hello world of graph drawing", + preconditions = { + connected = true, + tree = true, + }, + algorithm = { + run = -- something magic we cannot express in Lua + } +} +\end{codeexample} + +In our algorithm, in addition to the above key, we also use the +|fast simple demo radius| key, which is a simple length key. This key, too, can be +declared on the C layer: + +\begin{codeexample}[code only, tikz syntax=false] + d = pgfgd_new_key ("fast simple demo radius"); + pgfgd_key_summary (d, "A radius value for the hello world of graph drawing"); + pgfgd_key_type (d, "length"); + pgfgd_key_initial (d, "1cm"); + pgfgd_declare (state, d); + pgfgd_free_key (d); + + return 0; +} +\end{codeexample} + +We simply add this code to the startup function above. + +Now it is time to compile and link the code. For this, you must, well, +compile it, link it against the library |InterfaceFromC|, and build a +shared library out of it. Also, you must place it somewhere where +Lua\TeX\ will find it. You will find a Makefile that should be able to +achieve all of this in the directory |pgf/c/graphdrawing/pgf/gd/examples/c|, +where you will also find the code of the above example. + +Now, all you need to do to use it is to write in Lua (after you have +loaded the |pgf.gd| library, of course), would normally be the call + +\begin{codeexample}[code only, tikz syntax=false] +require 'pgf.gd.examples.c.SimpleDemoC' +\end{codeexample} +or in \tikzname +\begin{codeexample}[code only] +\usegdlibrary {examples.c.SimpleDemoC} +\end{codeexample} + +This should cause Lua\TeX\ to find the shared library, load it, and then +call the function in that library with the lengthy name (the name is +always |luaopen_| followed by the path and filename with slashes +replaced by underscores). + +\emph{Remark:} Unfortunately, the above does not work with the \TeX +Live 2013 versions of Lua\TeX\ due to a bugs that causes the ``replace +dots by slashes'' to fail. For this reason, we currently need to +rename our sharded library file to +\begin{codeexample}[code only, tikz syntax=false] +pgf_gd_examples_c_SimpleDemoC.so +\end{codeexample} +and then say +\begin{codeexample}[code only, tikz syntax=false] +require 'pgf_gd_examples_c_SimpleDemoC' +\end{codeexample} +or in \tikzname +\begin{codeexample}[code only] +\usegdlibrary {pgf_gd_examples_c_SimpleDemoC} +\end{codeexample} + +In future versions of Lua\TeX, things should be ``back to normal'' in +this regard. Also, the bug only concerns shared libraries; you can +still create a normal Lua file with a nice name and place at a nice +location and the only contents of this file is then the above +|require| command. + +Anyway, once we have loaded the shared library we can say: + +\begin{codeexample}[] +\tikz \graph [fast simple demo layout, fast simple demo radius=1.25cm] +{ a -> b -> c -> d -> e -> a }; +\end{codeexample} + +\subsubsection{Documenting Algorithms Written in C} +\label{section-gd-documenting-c-algos} + +In our above example, we included a summary with the keys in the C +code. It would be even better if we added a longer documentation and +some examples that show how the key works; but this is a bit +impracticable in C since multi-line strings are hard to write down +in~C. The trick is to use the |documentation_in| field of a key: It +allows us to specify the name of a Lua file that should be loaded +(using |require|) to install the missing documentation fields. As +explained in Section~\ref{section-gd-documentation-in}, this Lua file +may make good use the |pgf.gd.doc| package. Note, also, that for keys +documented in this way the documentation can easily be included in +this manual through the use of the |\includedocumentationof| command. + +In our example, we would first add the following line twice in the +C code (once for each key), assuming that the documentation resides in +the file |pgf/gd/doc/examples/SimpleDemoC.lua|: + +\begin{codeexample}[code only, tikz syntax=false] + pgfgd_key_documentation_in (d, "pgf.gd.doc.examples.SimpleDemoC"); +\end{codeexample} + +Note that since the documentation is a normal Lua file, it will be +searched in the usual places Lua files are located (in the texmf +trees) and not, like the C shared library, in the special |lib| +subdirectory of the Lua\TeX\ binary. + +Here are typical contents of the documentation file: + +\begin{codeexample}[code only, tikz syntax=false] +-- File pgf/gd/doc/examples/SimpleDemoC.lua +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + +key "fast simple demo layout" +documentation +[[ +This layout is used... +]] +example +[[ +\tikz \graph [fast simple example layout] +{ a -- b -- c -- d -- e; }; +]] + +key "fast simple demo radius" +documentation +[[ +The radius parameter is used to ... +]] +example +[[ +\tikz \graph [fast simple demo layout, fast simple demo radius=1.25cm] +{ a -> b -> c -> d -> e -> a }; +]] +\end{codeexample} + + + +\subsubsection{The Interface From C} + +In the above example, we already saw some of the functions from the +library |InterfaceFromC| that translated from Lua to C for us. For a +complete list of all functions available, currently please see +|graphdrawing/c/pgf/gd/interface/c/InterfaceFromC.h| directly. + +Currently, the library provides C functions to directly access all +aspects of the syntactic digraph and also of the graphs computed by +the preprocessing of the layout pipeline. What is missing, however, is +access to the tree of (sub)layouts and to collections. Hopefully, these will +be added in the future. + + + + +\subsection{Writing Graph Drawing Algorithms in C++} + +\label{section-gd-c++} + +Built on top of the C interface presented in the previous section, +there is also a C++ interface available. It encapsulates as much of +the C functions as possible in C++ classes. Thus, this interface is +mostly there for convenience, it does not offer fundamentally new +functionality. + + +\subsubsection{The Hello World of Graph Drawing in C++} + +Let us have a look at how our beloved hello world of graph drawing +looks in C++. Although it is still possible to put graph drawing +algorithms inside functions, it is more natural in C++ to turn them +into methods of a class. Thus, we start the code of +|SimpleDemoCPlusPlus.c++| as follows: + +\begin{codeexample}[code only, tikz syntax=false] +#include <pgf/gd/interface/c/InterfaceFromC++.h> +#include <pgf/gd/interface/c/InterfaceFromC.h> + +#include <math.h> + +struct FastLayout : scripting::declarations, scripting::runner { + ... +} +\end{codeexample} + +As can be seen, we do not only include the interface from C++, but +also that from C (since, currently, not all functionality of the C +library is encapsulated in C++). + +The interesting part is the |struct FastLayout|, which will contain our +algorithm (you could just as well have used a |class| instead of a +|struct|). It is derived from two classes: First, from a +|declarations| class and, secondly, from a |runner| class. Both of +them, just like everything else from the interface, reside in the +namespace |scripting|. This name was chosen since the main purpose of +the interface is to provide ``scripting facilities'' to C code through +the use of Lua. + +We are currently interested in the class |runner|. This class has a +virtual function |run| that gets called when, on the Lua side, someone +has selected the algorithm represented by the class. Thus, we place +our algorithm in this method: + +\begin{codeexample}[code only, tikz syntax=false] +void run () { + pgfgd_SyntacticDigraph* graph = parameters->syntactic_digraph; + + double angle = 6.28318530718 / graph->vertices.length; + double radius = parameters->option<double>("fast simple demo radius c++"); + + for (int i = 0; i < graph->vertices.length; i++) { + pgfgd_Vertex* v = graph->vertices.array[i]; + v->pos.x = cos(angle*i) * radius; + v->pos.y = sin(angle*i) * radius; + } +} +\end{codeexample} + +The |run| method has access to the member variable |parameters|, which +contains all sorts of information concerning the to-be-drawn graph. In +particular, the |syntactic_digraph| field gives us access to the +syntactic digraph structure that was already available in the +interface from plain~C. However, we can also see that a template +function like |option| allows us to access the graph's option table in +a simple way. + +As for C code, our next task is to setup a key that, when used on the +\tikzname\ layer, will run our algorithm. For this, we can use an +object derived from a |declarations|. In our example, the |FastLayout| +is both derived from a |runner| (since it contains an algorithm) and +also from |declarations| (since it also contains the code necessary for +declaring this algorithm). If you prefer, you can split this into two +classes. A |declarations| object must override the |declare| +method. This method gets a |script| object as input, which is the +``representation'' of Lua inside the C++ code: + +\begin{codeexample}[code only, tikz syntax=false] +void declare(scripting::script s) { + using namespace scripting; + + s.declare(key ("fast simple demo layout c++") + .summary ("The C++ version of the hello world of graph drawing") + .precondition ("connected") + .precondition ("tree") + .algorithm (this)); + + s.declare(key ("fast simple demo radius c++") + .summary ("A radius value for the hello world of graph drawing") + .type ("length") + .initial ("1cm")); +} +\end{codeexample} + +For each key that we wish to declare, we call the script's |declare| +method once. This method takes a |key| object as input, which can be +configured through a sequence of calls to different member functions +(like |summary| or |algorithm|). Most of these member functions are +rather self-explaining; only |algorithm| is a bit trickier: It does +not take a function as input, but rather an object of type |runner| +and it will call the |run| method of this object whenever the +algorithm is run. + +Lastly, we also need to write the entry point: + +\begin{codeexample}[code only, tikz syntax=false] +extern "C" int luaopen_pgf_gd_examples_c_SimpleDemoCPlusPlus (struct lua_State *state) { + scripting::script s (state); + s.declare (new FastLayout); + return 0; +} +\end{codeexample} + +Note that it is the job of the interface classes to free the passed +|declarations| object. For this reason, you really need to call |new| +and cannot pass the address of a temporary object. + +As before, because of the bug in some Lua\TeX\ versions, to actually +load the library at runtime, we need to rename it to +\begin{codeexample}[code only, tikz syntax=false] +pgf_gd_examples_c_SimpleDemoCPlusPlus.so +\end{codeexample} +and then say +\begin{codeexample}[code only, tikz syntax=false] +require 'pgf_gd_examples_c_SimpleDemoCPlusPlus' +\end{codeexample} +or in \tikzname +\begin{codeexample}[code only] +\usegdlibrary {pgf_gd_examples_c_SimpleDemoCPlusPlus} +\end{codeexample} + +We can now use it: + +\begin{codeexample}[] +\tikz \graph [fast simple demo layout c++, fast simple demo radius c++=1.25cm] +{ a -> b -> c -> d -> e -> a }; +\end{codeexample} + + +\subsubsection{The Interface From C++} + +The header |graphdrawing/c/pgf/gd/interface/c/InterfaceFromC++.h| +contains, as the name suggest, the interface from C++. A complete +documentation is still missing, but let us go over the main ideas: + +\medskip +\noindent\textbf{Runners.} +Algorithms are represented by objects of type |runner|. An +algorithm will overwrite the |run| method, as we saw in the +example, and it should modify the |parameters| of the runner +object. + +In addition to the |run| method, there are also two more virtual +methods, called |bridge| and |unbrigde|. The first is called before +the |run| method is called and the second afterwards. The idea is that +another framework, such as \textsc{ogdf}, can implement a new class +|ogdf_runner| that overrides these two methods in order to transform +the Lua/C representation of the input graph into an \textsc{ogdf} +representation prior to the |run| method being called. The |run| +method can then access additional member variables that store the +graph representations in \textsc{ogdf} form (or another form, +depending on the framework). The |unbridge| method allows the +framework to translate back. + +Although a |runner| object must be created for every algorithm, an +algorithm can also reside in a function. The class |function_runner| +is a simple wrapper that turns a function into such an object. + + +\medskip +\noindent\textbf{Keys.} +A key object is a temporary object that is passed to the |declare| +method of a script. It represents the table that is passed to the Lua +function |declare|. In order to make setting its field easy, for each +field name there is a corresponding function (like |summary|) that +takes the string that should be set to this field and returns the key +object once more, so that we can chain calls. + +The |algorithm| method gets a runner object as parameter and will +store a pointer to this object inside Lua. Each time the algorithm is +used, this object will be used to ``run'' the algorithm, that is, the +methods |prepare|, |bridge|, |run|, and |unbridge| will be called in +that order. Since the object is reused each time, only one object is +needed; but this object may not be freed prematurely. Indeed, you will +normally create the object using |new| once and will then never delete +it. + +A typical idiom you may find in the code is +\begin{codeexample}[code only, tikz syntax=false] +s.declare (key (...) + .algorithm(this) + ...); +\end{codeexample} +This code is seen inside the |declare| method of objects that are both +declarations and runners. They register ``themselves'' via the above +code. Note, however, that this requires that the |this| pointer is not +a temporary object. (The typing rules of C++ make it hard for this +situation to happen, but it can be achieved.) + + +\medskip +\noindent\textbf{Reading options.} +Once options have been declared, your C++ algorithms will wish to read +them back. For this, the |parameters| field of a runner object +provides a number of templated methods: +\begin{itemize} +\item The |option_is_set| method returns |true| if the passed option + has been set \emph{and} can be cast to the type of the template. So, + |option_is_set<double>("node distance")| will return true if the + |node distance| key has been set for the graph as a whole + (currently, there is no way to read the options of a vertex or an + edge from C++, use the C methods instead). +\item The |option| function comes in two flavours: First, it takes a + single option name and just returns the option's value. If, however, + the option has not been set or has another type, some sort of null + value is returned. So, |option<double>("node distance")| will return + the configured node distance as a double. When an option has an + initial value, this call will always return a sensible value. + + The second flavour of |option| allows you to pass a reference to an + object in which the option's value should be stored and the function + will return true if the option is set (and, thus, something was + written into the reference). This is the ``safest'' way to access + an option: +\begin{codeexample}[code only, tikz syntax=false] +double dist; +if (parameters->option ("node distance", dist)) + ... +\end{codeexample} + + Caution must be taken for |char*| options: The returned string must + be explicitly freed; it will be a copy of the string stored in the + Lua table. +\item + The |configure_option| method is used to set a member of an object + based on the value of a certain option. For this, you must pass a + pointer to a member function that sets the member. Here is an + example: +\begin{codeexample}[code only, tikz syntax=false] +class MyClass { +public: + void setMyDistance (double distance); +... +}; +... + +MyClass m; +parameters->configure_option("node distance", &MyClass::setMyDistance, m); +\end{codeexample} + If the option has not been set or does not have the correct type, + the member function is not called. +\end{itemize} + + +\medskip +\noindent\textbf{Factories and modules.} +A Lua key is normally either a Boolean, a double, or a +string. However, in C++, we may also sometimes wish Lua users to +configure which C function is used to achieve something. One could do +this using strings or numbers and then use search algorithms or a long +|switch|, but this would neither be flexible nor elegant. + +Instead, it is possible to store \emph{factories} in Lua keys. A +factory is a class derived from |factory| that implements the virtual +function |make|. This function will return a new object of a template +type. You can store such a factory in a key. + +The |make| method of a parameters object allows you to invoke the +factory stored in a key. (If no factory is stored in it, |null| is +returned). + +The |configure_module| method is akin to |configure_option|, only +the result of applying the factory is passed to the member function of +the class. + + + +\medskip +\noindent\textbf{Scripts.} +A ``script'' is the abstraction of the communication between Lua and +C++. From C++'s point of view, the script object offers different +|declare| methods that allow us to ``make objects and function +scriptable'' in the sense that they can then be called and configured +from Lua. The script must be initialized with a Lua state and will be +bound to that state (basically, the script only stores this single +pointer). + +When you call |declare|, you either pass a single key object (which is +then declared on the Lua layer) or you pass a |declarations| object, +whose virtual |declare| method is then called. The |declarations| +objects are used to bundle several declarations into a single one. + + + +\subsection{Writing Graph Drawing Algorithms Using OGDF} + +\label{section-gd-ogdf-interface} + +Built on top of the C++ interface, a small interface allows you to +easily link algorithms written for the \textsc{ogdf} (Open Graph +Drawing Framework) with graph drawing in Lua. + + +\subsubsection{The Hello World of Graph Drawing in OGDF -- From Scratch} + +We start with some startup code: + +\begin{codeexample}[code only, tikz syntax=false] +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <math.h> + +using namespace ogdf; +using namespace scripting; +\end{codeexample} + +Note that the interface from \textsc{ogdf} resides in the |ogdf| +folder, not in the |interface| folder. + +Like in the plain C++ interface, we must now subclass the |runner| +class and the |declarations| class. Also like the plain C++ interface, +we can use multiple inheritance. The difference lies in the fact that +we do not directly subclass form |runner|, but rather from +|ogdf_runner|. This class implements the complicated ``bridging'' or +``translation'' process between the world of |InterfaceFromC++| and +\textsc{ogdf}: + +\begin{codeexample}[code only, tikz syntax=false] +struct FastLayoutOGDF : declarations, ogdf_runner { + + void run () { + double angle = 6.28318530718 / graph.numberOfNodes(); + double radius = parameters->option<double>("my radius ogdf"); + + int i = 0; + for (node v = graph.firstNode(); v; v=v->succ(), i++) { + graph_attributes.x(v) = cos(angle*i) * radius; + graph_attributes.y(v) = sin(angle*i) * radius; + } + } +\end{codeexample} + +As can be seen, in a subclass of |ogdf_runner|, the |run| method will +have access to a member called |graph| and to another member called +|graph_attributes|. These will have been setup with the graph from the +Lua layer and, after the algorithm has run, the information stored in +the |x| and |y| fields of the graph attributes and also the bend +information of the edges will be written back automatically. + +Next, we need to declare the algorithm. This is done as in the plain +C++ interface: + +\begin{codeexample}[code only, tikz syntax=false] + void declare(script s) { + using namespace scripting; + + s.declare(key ("fast simple demo layout ogdf") + .summary ("The OGDF version of the hello world of graph drawing") + .precondition ("connected") + .algorithm (this)); + + s.declare(key ("my radius ogdf") + .summary ("A radius value for the hello world of graph drawing") + .type ("length") + .initial ("1cm")); + } +}; +\end{codeexample} + +Finally, we need the entry point, which is also ``as usual'': + +\begin{codeexample}[code only, tikz syntax=false] +extern "C" int luaopen_pgf_gd_examples_c_SimpleDemoOGDF (struct lua_State *state) { + script (state).declare (new FastLayoutOGDF); + return 0; +} +\end{codeexample} + +Yet again, we need to rename the resulting shared library and then say +|require| on it. We can now use it: + +\begin{codeexample}[] +\tikz \graph [fast simple demo layout ogdf, my radius ogdf=1cm] +{ a -> b -> c -> d -> e -> a }; +\end{codeexample} + + + +\subsubsection{The Hello World of Graph Drawing in OGDF -- Adapting Existing Classes} + +In the previous example we implemented a graph drawing algorithm using +\textsc{ogdf} for use with Lua ``from scratch.'' In particular, the +whole algorithm was contained in the |run| method of our main +class. In practice, however, graph drawing algorithms are typically +placed in classes that ``know nothing about scripting.'' For instance, +our hello world of graph drawing might actually be implemented like this: + +\begin{codeexample}[code only, tikz syntax=false] +// File HelloWorldLayout.h +#include <ogdf/module/LayoutModule.h> + +class HelloWorldLayout : puplic ogdf::LayoutModule { +public: + + virtual void call(ogdf::GraphAttributes &GA) + { + using namespace ogdf; + + const Graph &graph = GA.constGraph(); + double angle = 6.28318530718 / graph.numberOfNodes(); + int i = 0; + for (node v = graph.firstNode(); v; v=v->succ(), i++) { + GA.x(v) = cos(angle*i) * radius; + GA.y(v) = sin(angle*i) * radius; + } + } + + void setRadius (double r) { radius = r; } + +private: + + double radius; +}; +\end{codeexample} + +Now, what we actually want to do is to ``make this class +scriptable''. For this, we setup a new class whose |run| method will +produce a new |HelloWorldLayout|, configure it, and then run it. Here +is this run method: + + +\begin{codeexample}[code only, tikz syntax=false] +void run () +{ + HelloWorldLayout layout; + parameters->configure_option("HelloWorldLayout.radius", &HelloWorldLayout::setRadius, layout); + layout.call(graph_attributes); +} +\end{codeexample} + +Next, we need to write the declarations code. This is very similar to the +``from scratch'' version: + +\begin{codeexample}[code only, tikz syntax=false] +void declare(script s) { + using namespace scripting; + + s.declare(key ("HelloWorldLayout") + .summary ("The OGDF version of the hello world of graph drawing") + .precondition ("connected") + .algorithm (this)); + + s.declare(key ("HelloWorldLayout.radius") + .summary ("A radius value for the hello world of graph drawing") + .type ("length") + .alias ("radius")); +} +\end{codeexample} + +Two remarks are in order: First, it is customary to name the keys for +the display system the same way as the classes. Second, the different +configuration options of the algorithm are named with the class name +followed by the option name. This makes it clear who, exactly, is +being configured. However, these keys should then also get an |alias| +field set, which will cause an automatic forwarding of the key to +something more ``user friendly'' like just |radius|. + +It remains to put the above methods in a ``script'' file. It is this +file that, when compiled, must be linked at runtime against Lua\TeX. + +\begin{codeexample}[code only, tikz syntax=false] +// File HelloWorldLayout_script.c++ + +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <HelloWorldLayout.h> + +using namespace ogdf; +using namespace scripting; + +struct HelloWorldLayout_script : declarations, ogdf_runner { + void run () { ... see above ... } + void declare (script s) { ... see above ... } +}; + +extern "C" int luaopen_my_path_HelloWorldLayout_script (struct lua_State *state) { + script (state).declare (new HelloWorldLayout_script); + return 0; +} +\end{codeexample} + + +\subsubsection{Documenting OGDF Algorithms} + +As explained in Section~\ref{section-gd-documenting-c-algos}, we can +add external documentation to algorithms written in C and, using the +|documentation_in| method of the |key| class, we can use the exact +same method to document \textsc{ogdf} algorithms. + +I strongly recommend making use of this feature since, currently, the +documentation of many \textsc{ogdf} classes is sketchy at best and +using \tikzname\ examples seems to be a good way of explaining the +effect of the different parameters algorithms offer. + + + +\subsubsection{The Interface From OGDF} + +The support for \textsc{ogdf} offered inside |InterfaceFromOGDF.h| is +just the class |ogdf_runner| we saw already +in the example. In addition, there is also a wrapper class +|ogdf_function_runner| that allows you to wrap an algorithm +implemented in a function that uses \textsc{ogdf}, but I expect this +to be the case only rarely. diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-binding-layer.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-binding-layer.tex new file mode 100644 index 00000000000..422d7d8d0a2 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-binding-layer.tex @@ -0,0 +1,289 @@ +% Copyright 2010-2011 by Renée Ahrens +% Copyright 2010-2011 by Olof Frahm +% Copyright 2010-2011 by Jens Kluttig +% Copyright 2010-2011 by Matthias Schulz +% Copyright 2010-2011 by Stephan Schuster +% Copyright 2011 by Jannis Pohlmann +% Copyright 2011 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + +\section{The Binding Layer} + +\label{section-gd-binding-layer} + +\ifluatex\else This section of the manual can only be typeset using Lua\TeX.\expandafter\endinput\fi + +\subsection{Overview} + +This section explains how the \emph{binding} of the graph drawing +system to a particular display layer works. Let me stress +that all of this is important only for readers who +\begin{itemize} +\item either wish to write new display system (see + Section~\ref{section-gd-display-layer}) +\item or wish to know more about how the graph drawing system works on + the pure \pgfname\ layer (this is were the binding occurs). +\end{itemize} + +\emph{Bindings} are used to encapsulate the details of the +communication between the graph drawing system and a display system +(see Section~\ref{section-gd-display-layer} for an introduction to +display systems). + +Consider a display system that communicates with the graph drawing +system. At some point, the display system would like to run an +algorithm to lay out a graph. To achieve this, it will call different +functions from the class |InterfaceToDisplay| and the effect of this +is that a representation of the to-be-drawn graph is constructed +internally and that the appropriate algorithms are run. All of this is +in some sense independent of the actual display system, the class +|InterfaceToDisplay| offers the same standard interface to all display +systems. + +At some point, however, the graph drawing system may need to ``talk +back'' to the display system. For instance, once the graph has been +laid out, to trigger the actual rendering of the graph, the graph +drawing system must ``tell'' the display layer where the vertices +lie. For some display systems this is easy: if the display system +itself is written in Lua, it could just access the syntactic digraph +directly. However, for systems like \tikzname\ or systems written in +another language, the graph drawing system needs a set of functions +that it can call that will tell the display system what is going +on. This is were bindings come in. + +The class |Binding| is an interface that defines numerous methods that +will be called by the graph drawing system in different situations (see +the documentation below for details). For instance, there is a +function |renderVertex| that is called by the graph drawing system +whenever a vertex should be rendered by the display system. The class +is really just an interface in the sense of object-oriented +programming. For each display system you need to create a subclass of +|Binding| like |BindingToPGF| or |BindingToASCII| that implement the +methods declared by |Binding|. The number of methods that need to be +implemented depends on the display system. + +In the following, you will find the documentation of the |Binding| +class in Section~\ref{section-gd-binding-doc}. Following this, we +first have a quick look at how the |BindingToPGF| works and then go +over a simple example of a binding to a more or less imaginary +display system. This example should help readers interested in +implementing their own bindings. + + +\subsection{The Binding Class and the Interface Core} +\label{section-gd-binding-doc} + +\includeluadocumentationof{pgf.gd.bindings.Binding} +\includeluadocumentationof{pgf.gd.interface.InterfaceCore} + + +\subsection{The Binding To PGF} + +\includeluadocumentationof{pgf.gd.bindings.BindingToPGF} + + +\subsection{An Example Binding Class} + +\label{section-gd-binding-layer-example} + +In the present section a complete binding is presented to an imaginary +``\textsc{ascii} art display system'' is presented. The idea is that +this display system will depict graphs using just normal letters and +spaces so that, when the text is typeset in a monospace font, a +visualization of the graph results. For instance: + +\bigskip +\noindent +\begin{minipage}[t]{.5\textwidth} +\emph{Graph rendered by |BindingToPGF|:} +\medskip + +\tikz [anchor=base]\graph [layered layout,level distance=2.35cm,sibling +distance=1.2cm,edges={rounded corners,>=spaced stealth'}] { + Alice; + Bob; + Charly; + Dave; + Eve; + Fritz; + George; + Alice -> Bob; + Alice -> Charly; + Charly -> Dave; + Bob -> Dave; + Dave -> Eve; + Eve -> Fritz; + Fritz -> Alice; + George -> Eve; + George -> Fritz; + Alice -> George; +}; +\end{minipage}% +\begin{minipage}[t]{.49\textwidth} +\emph{Graph rendered by |BindingToASCII|:} + +\begin{verbatim} + Alice + ....... + .. . . . + ... . . . + ... .. . .. + .. . . . + Charly Bob . . + .. . . . + . . . . + . . . . + .. . . . + .. . . + Dave George . + .. . ... . + . . .. . + . . ... + .. . . ... + .. . .. + Eve . .. + .. . .. + . . . + . . . + .. . .. + ... + Fritz +\end{verbatim} +\end{minipage} +\bigskip + +The binding will reside in a file |BindingToASCII.lua|, whose contents +is detailed below, and which is used by calling the |bind| function of +|InterfaceToDisplay|, see its documentation for details. + +The binding's code starts with some initializations: + +\begin{codeexample}[code only] +-- File BindingToASCII.lua + +-- Imports +local lib = require "pgf.gd.lib" + +-- Subclass the Binding class: +local BindingToASCII = lib.class { base_class = require "pgf.gd.bindings.Binding" } +\end{codeexample} + +The interesting code is the code for +``rendering'' a graph. The graph drawing system will invoke the +binding's methods |renderStart| and |renderStop| to signal that the +graph drawing algorithms have finished and that the vertices and edges +can now be drawn. + +In our \textsc{ascii} renderer, we use a two-dimensional field holding +characters that severs as the ``drawing canvas''. At the beginning of +the rendering, we initialize it with blanks: + +\begin{codeexample}[code only] +local canvas + +function BindingToASCII:renderStart() + canvas = {} + -- Clear the canvas + for x=-30,30 do + canvas [x] = {} + for y=-30,30 do + canvas[x][y] = ' ' + end + end +end +\end{codeexample} + +In order to ``render'' a vertex, the graph drawing system will call +the |renderVertex| method. The binding of \tikzname\ does a lot of +complicated things in this method to retrieve the underlying node's +box from internal table and to somehow reinstall the box in \TeX's +output stream; for our \textsc{ascii} binding things are much simpler: +We simply put the vertex's name at the canvas position corresponding +to the vertex's |pos| coordinate. Note that this simple version of an +\textsc{ascii} renderer does not try to scale things; thus, array out +of bounds might occur here. + +\begin{codeexample}[code only] +function BindingToASCII:renderVertex(v) + canvas [math.floor(v.pos.x)][math.floor(v.pos.y)] = v.name +end +\end{codeexample} + +The rendering of edges is a more complicated process. Given two +vertices, we put dots at the canvas positions between them; provided +there are no vertices (so edges are behind the nodes). Here is the +essential part of the code (for the complete code, have a look at +|pgf/gd/examples/BindingToASCII.lua|): + + +\begin{codeexample}[code only] +function BindingToASCII:renderEdge(e) + local function connect (p,q) + -- Connect the points p and q + local x1, y1, x2, y2 = math.floor(p.x+0.5), math.floor(p.y+0.5), math.floor(q.x+0.5), math.floor(q.y+0.5) + ... + local delta_x = x2-x1 + local delta_y = y2-y1 + ... + local slope = delta_y/delta_x + for i=x1,x2 do + local x,y = i, math.floor(y1 + (i-x1)*slope + 0.5) + + if canvas[x][y] == " " then + canvas[x][y] = '.' + end + end + ... + end + + -- Iterate over all points on the path from tail to head: + local p = e.tail.pos + for i=1,#e.path do + connect(p, e.tail.pos + e.path[i]) + p = e.tail.pos + e.path[i] + end + connect(p, e.head.pos) +end +\end{codeexample} + + +The methods |renderVertex| and |renderEdge| will be called once for +each vertex and edge of the to-be-rendered graph. At the end, the +|renderStop| method is called. In our case, this method will output +the canvas using |print|. A slight complication arises when node names +are longer than just one character. In this case, the following code +``centers'' them on their coordinate and makes sure that they do not +get overwritten by the dots forming edges: + +\begin{codeexample}[code only] +function BindingToASCII:renderStop() + for y=10,-30,-1 do + local t = {} + for x=-30,30 do + local s = canvas[x][y] + for i=1,#s do + pos = x+30+i-math.floor(#s/2) + if not t[pos] or t[pos] == " " or t[pos] == "." then + t[pos] = string.sub(s,i,i) + end + end + end + print(table.concat(t)) + end +end +\end{codeexample} + +At the end, we need to return the created object: + +\begin{codeexample}[code only] +return BindingToASCII +\end{codeexample} + + diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-circular.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-circular.tex new file mode 100644 index 00000000000..85c27dd2c73 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-circular.tex @@ -0,0 +1,27 @@ +% Copyright 2011 by Jannis Pohlmann +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\section{Graph Drawing Algorithms: Circular Layouts} + +{\noindent {\emph{by Till Tantau}}} + +\label{section-last-graphdrawing-library-in-manual} + +\ifluatex\else This section of the manual can only be typeset using Lua\TeX.\expandafter\endinput\fi + + +\includeluadocumentationof{pgf.gd.circular.library} +\includeluadocumentationof{pgf.gd.circular.Tantau2012} + + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "pgfmanual-pdftex-version" +%%% End: diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-display-layer.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-display-layer.tex new file mode 100644 index 00000000000..d5848375067 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-display-layer.tex @@ -0,0 +1,292 @@ +% Copyright 2010-2011 by Renée Ahrens +% Copyright 2010-2011 by Olof Frahm +% Copyright 2010-2011 by Jens Kluttig +% Copyright 2010-2011 by Matthias Schulz +% Copyright 2010-2011 by Stephan Schuster +% Copyright 2011 by Jannis Pohlmann +% Copyright 2011 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + +\section{The Display Layer} + +{\noindent {\itshape{by Till Tantau}}} + +\ifluatex\else This section of the manual can only be typeset using Lua\TeX.\expandafter\endinput\fi + +\label{section-gd-display-layer} + +\begin{quote} + \itshape You do not need to read this section in order to write new + graph drawing algorithms. It is of interest only to those wishing to + write programs that wish to ``use'' the graph drawing system in a + similar way that \tikzname\ does for laying out graphs that are + generated and then passed down from the program to the graph drawing + system. +\end{quote} + + +\subsection{Introduction: The Interplay of the Different Layers} + +The job of the graph drawing system is to run graph drawing algorithms +on graphs. Since graph drawing is useful in many different contexts, +not only in the context of \tikzname\ for which the present system was +originally developed, the graph drawing system was designed in such a +way that it can be used independently of \tikzname. To achieve this, +the \emph{display layer} provides an interface via which an arbitrary +program (\tikzname, a graph editor, a command line interface, etc.) +``talk'' to the graph drawing system. + +To better understand how this works, let us consider the following +setup: + +\begin{itemize} +\item A program would like to communicate with the graph + drawing system. It is written in Java and its job is to analyse social + networks. This software would like to use graph drawing to produce + drawings of some ``social graphs'' arising from its analyses. This + software will be called ``the display system'' in the following. +\item There are two algorithms that the display system would like to apply to + the graphs its produces. Let us call these algorithms ``A'' and + ``B''. However, the display system would also, ideally, wish to make it + possible that its user chooses other algorithms ``C'' that are not + necessarily part of its binary. +\item The display system has internally generated a ``social graph'' that it + would now like to draw. +\end{itemize} + +For this setup, the communication between the different layers of the +graph drawing system is as follows: + +\begin{enumerate} +\item The display system, being written in Java, must embed Lua to use the + graph drawing system. +\item The display system must initialize the graph drawing system. For this, + it must use |require| on the file |InterfaceToDisplay|, which, as + the name suggests, contains the interface between the display + system and the graph drawing system. + + It must also create a so-called ``binding'' between the + graph drawing system and the display layer. See + Section~\ref{section-gd-binding-layer} for more information on + bindings. +\item The display system now needs to load the declarations of the + algorithms A and B. For this, it just needs to apply |require| to + the files in which the algorithms reside. This will cause the + |declare| function to be called. This function is declared by + |InterfaceToAlgorithms| and allows files to declare that certain + algorithms and options are now available. + + Once this is done, the graph drawing system is fully initialized and + can be used. +\item Later on, the display system wishes to lay out a social graph. Note + that this is known as ``drawing the graph'' in the graph drawing + community, even though this only means the coordinates are computed + for the nodes of the graph. The actual ``rendering'' of the graph on + the display is the job of the display system (hence the name ``display + layer''). +\item To start the layout process, the display system calls the function + |beginGraphDrawingScope| of the class |InterfaceToDisplay|. +\item Next, for each vertex the function |createVertex| of the + interface class must be called and similarly for each edge. These + calls will cause an internal model of the graph to be created on the + algorithm layer. Options that are attached to nodes and edges are + also communicated to the graph drawing system through function calls + like |pushOption|. +\item When the graph is fully specified, the method + |runGraphDrawingAlgorithm| must be called, which is once more a + method of the interface class. This function will internally discern + which algorithms have been chosen (via options) and invoke the code + of the appropriate algorithms. +\item Next, the function |renderGraph| must be called. Its job is to + ``communicate back'' which coordinates have been computed. It will + use the binding for this communication, see + Section~\ref{section-gd-binding-layer}. +\item Finally, by calling |endGraphDrawingScope|, the resources needed + for the layout process for the social graph are freed once more. +\end{enumerate} + +A few points may be noteworthy: +\begin{itemize} +\item The whole communication between the display system and the graph + drawing system goes through the interface class via function + calls. This makes it easy to communicate with display system whose + internal model of graphs is quite different from the one used in Lua + (as is certainly the case for \TeX, but also the ``social graph'' + mentioned above need not even exist as a separate entity inside the + display system). + + \emph{The display system should only rely on the interface + class. All communication has to go through this class, the + display system may not access the internals of the internally + constructed graphs directly.} +\item New algorithms can be loaded at runtime, as long as the + |require| method is supported. +\item The display system can also use the interface class to query which + algorithms and which options are available in principle (and display + this information to the user). The display system can even get access the + documentation of the options at runtime since the documentation is + stored in fields of the declared options. +\end{itemize} + + +In the following, we first present a simple display system other than +\tikzname. The remainder of the section then encompasses a +documentation of the different functions of the class +|InterfaceToDisplay|. + + + +\subsection{An Example Display System} + +In the following, we present the code of a very simple display system +written in Lua (another such display system is \tikzname\ itself, but +the minimal system will allow us to focus on what is really +needed). You will also find it in |pgf.gd.examples.ASCIIDisplayer|. + +The job of this display system is to parse a string that encodes a graph +and to call the appropriate functions of |InterfaceToDisplay| to lay +out the graph. The actual calls for rendering the graph are part of +the binding, which is documented in +Section~\ref{section-gd-binding-layer-example}. + +The syntax of the to-be-laid-out graph is a reduced version of +\tikzname's |graph| syntax: The string must start with +|graph[|\meta{algorithm's name}|]{| and end with |}|. Between the +braces, all lines must either be of the form \meta{node name}|;| or +\meta{name 1}|->|\meta{name 2}|;| with optional spaces around the node +names. + +Let us now have a look at what we must do to use the graph drawing +system. First, we load some libraries and initialize the binding (see +Section~\ref{section-gd-binding-layer-example} for details on the +binding; we can ignore it for now). + +\begin{codeexample}[code only] +local InterfaceToDisplay = require "pgf.gd.interface.InterfaceToDisplay" +InterfaceToDisplay.bind(require "pgf.gd.examples.BindingToASCII") + +-- Load two libraries that define graph drawing algorithms. We can do this only *after* the binding +-- has been created since they call the declare function internally. +require "pgf.gd.layered.library" +require "pgf.gd.force.library" +\end{codeexample} + +Now comes some preparation code that starts a graph drawing scope and +sets up the algorithm to the string provided between the square +brackets: + +\begin{codeexample}[code only] +local algorithm = io.read():match("%s*graph%s*%[(.-)%]") + +InterfaceToDisplay.pushPhase(algorithm, "main", 1) +InterfaceToDisplay.pushOption("level distance", 6, 2) +InterfaceToDisplay.pushOption("sibling distance", 8, 3) +InterfaceToDisplay.beginGraphDrawingScope(3) +InterfaceToDisplay.pushLayout(4) +\end{codeexample} + +The numbers |1| to |4| are the positions on the options stack at which +the options should be placed. See the description of |pushOption| for +more details. + +We are now ready to create the vertices and edges via a very simple +parser: + +\begin{codeexample}[code only] +for line in io.lines() do + if line:match("}") then + break + elseif line:find("-") then + local n1, dir, n2 = string.match(line, "^%s*(.-)%s*(-.)%s*(.-)%s*;") + InterfaceToDisplay.createEdge(n1, n2, dir, 4) + else + local n1 = string.match(line, "^%s*(.-)%s*;") + InterfaceToDisplay.createVertex(n1, "rectangle", nil, 4) + end +end +\end{codeexample} + +The graph is now completely constructed inside the graph drawing +system. We can now invoke the algorithms: + +\begin{codeexample}[code only] +InterfaceToDisplay.runGraphDrawingAlgorithm() +InterfaceToDisplay.renderGraph() +InterfaceToDisplay.endGraphDrawingScope() +\end{codeexample} + +We can now run the resulting file using the Lua interpreter. If we +provide the input shown on the left, we get the output shown on the +right: + +\bigskip +\noindent +\begin{minipage}[t]{.5\textwidth} +\emph{Input given to ASCIIDisplayer:} + +\begin{verbatim} +graph [layered layout] { + Alice; + Bob; + Charly; + Dave; + Eve; + Fritz; + George; + Alice -> Bob; + Alice -> Charly; + Charly -> Dave; + Bob -> Dave; + Dave -> Eve; + Eve -> Fritz; + Fritz -> Alice; + George -> Eve; + George -> Fritz; + Alice -> George; +} +\end{verbatim} +\end{minipage}% +\begin{minipage}[t]{.49\textwidth} +\emph{Output produced by ASCIIDisplayer:} + +\begin{verbatim} + Alice + ....... + .. . . . + ... . . . + ... .. . .. + .. . . . + Charly Bob . . + .. . . . + . . . . + . . . . + .. . . . + .. . . + Dave George . + .. . ... . + . . .. . + . . ... + .. . . ... + .. . .. + Eve . .. + .. . .. + . . . + . . . + .. . .. + ... + Fritz +\end{verbatim} +\end{minipage} + + +\subsection{The Interface to Display Systems} + +\includeluadocumentationof{pgf.gd.interface.InterfaceToDisplay} + diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-examples.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-examples.tex new file mode 100644 index 00000000000..bba5c540ade --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-examples.tex @@ -0,0 +1,14 @@ +% Copyright 2011 by Jannis Pohlmann +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "pgfmanual-pdftex-version" +%%% End: diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-force.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-force.tex new file mode 100644 index 00000000000..1925de99765 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-force.tex @@ -0,0 +1,43 @@ +% Copyright 2011 by Jannis Pohlmann +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\section{Graph Drawing Algorithms: Force-Based Methods} +\label{section-library-graphdrawing-force-based} + +{\emph{by Till Tantau and Jannis Pohlmann}} + +\ifluatex\else This section of the manual can only be typeset using Lua\TeX.\expandafter\endinput\fi + + +\includeluadocumentationof{pgf.gd.force.library} + +\includeluadocumentationof{pgf.gd.force.Control} +\includeluadocumentationof{pgf.gd.force.ControlStart} +\includeluadocumentationof{pgf.gd.force.ControlIteration} +\includeluadocumentationof{pgf.gd.force.ControlSprings} +\includeluadocumentationof{pgf.gd.force.ControlElectric} +\includeluadocumentationof{pgf.gd.force.ControlCoarsening} + + + + +\includeluadocumentationof{pgf.gd.force.SpringLayouts} +\includeluadocumentationof{pgf.gd.force.SpringHu2006} + +\includeluadocumentationof{pgf.gd.force.SpringElectricalLayouts} +\includeluadocumentationof{pgf.gd.force.SpringElectricalHu2006} +\includeluadocumentationof{pgf.gd.force.SpringElectricalWalshaw2000} + + +\endinput + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "pgfmanual-pdftex-version" +%%% End: diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-layered.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-layered.tex new file mode 100644 index 00000000000..f4c1704b827 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-layered.tex @@ -0,0 +1,28 @@ +% Copyright 2012 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\section{Graph Drawing Algorithms: Layered Layouts} + +{\emph{by Till Tantau and Jannis Pohlmann}} + +\ifluatex\else This section of the manual can only be typeset using Lua\TeX.\expandafter\endinput\fi + +\includeluadocumentationof{pgf.gd.layered.library} +\includeluadocumentationof{pgf.gd.layered.Sugiyama} +\includeluadocumentationof{pgf.gd.layered.cycle_removal} +\includeluadocumentationof{pgf.gd.layered.node_ranking} +\includeluadocumentationof{pgf.gd.layered.crossing_minimization} +\includeluadocumentationof{pgf.gd.layered.node_positioning} +\includeluadocumentationof{pgf.gd.layered.edge_routing} + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "pgfmanual-pdftex-version" +%%% End: diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-misc.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-misc.tex new file mode 100644 index 00000000000..8c88238eb39 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-misc.tex @@ -0,0 +1,30 @@ +% Copyright 2011 by Jannis Pohlmann +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\section{Graph Drawing Layouts: Miscellaneous} + + +\begin{tikzlibrary}{graphdrawing.misc} + Load this package when you wish to use the graph drawing algorithms + defined in this library. You should load the |graphdrawing| library first. +\end{tikzlibrary} + + +\begin{gdalgorithm}{simple demo layout}{Simple Demo} + The algorithm used in the examples of this manual for demonstrating + how a trivial graph drawing can be implemented. +\end{gdalgorithm} + + + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "pgfmanual-pdftex-version" +%%% End: diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-ogdf.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-ogdf.tex new file mode 100644 index 00000000000..83868fa380c --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-ogdf.tex @@ -0,0 +1,110 @@ +% Copyright 2012 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\section[Graph Drawing Algorithms: The Open Graph Drawing Framework]{Graph Drawing Algorithms:\\ The Open Graph Drawing Framework} + +{\emph{by Till Tantau (who copied much of the text from + the source documentation of \textsc{ogdf})}} + +\ifluatex\else This section of the manual can only be typeset using Lua\TeX.\expandafter\endinput\fi + +\ifgdccodeogdf +\else +In order to typeset this section, LuaTeX\ must be able to link C code +at runtime and the \textsc{ogdf} graph drawing C libraries must be +installed on your system. You will find the sources in the |c| +subdirectory of the installation, where you will also find example +Makefiles. +\expandafter\endinput +\fi + +\emph{Remark:} The integration of the \textsc{ogdf} library is still under +construction and the examples in this section are more a +proof-of-concept. So, use at your own risk. + +\includeluadocumentationof{pgf.gd.ogdf.library} + +\includeluadocumentationof{pgf.gd.doc.ogdf.layered} + +\includeluadocumentationof{pgf.gd.doc.ogdf.layered.SugiyamaLayout} + +\includeluadocumentationof{pgf.gd.doc.ogdf.module.RankingModule} +\includeluadocumentationof{pgf.gd.doc.ogdf.layered.CoffmanGrahamRanking} +\includeluadocumentationof{pgf.gd.doc.ogdf.layered.LongestPathRanking} +\includeluadocumentationof{pgf.gd.doc.ogdf.layered.OptimalRanking} + +\includeluadocumentationof{pgf.gd.doc.ogdf.module.TwoLayerCrossMin} +\includeluadocumentationof{pgf.gd.doc.ogdf.layered.BarycenterHeuristic} +\includeluadocumentationof{pgf.gd.doc.ogdf.layered.GreedyInsertHeuristic} +\includeluadocumentationof{pgf.gd.doc.ogdf.layered.MedianHeuristic} +\includeluadocumentationof{pgf.gd.doc.ogdf.layered.SiftingHeuristic} +\includeluadocumentationof{pgf.gd.doc.ogdf.layered.SplitHeuristic} + +\includeluadocumentationof{pgf.gd.doc.ogdf.module.AcyclicSubgraphModule} +\includeluadocumentationof{pgf.gd.doc.ogdf.layered.DfsAcyclicSubgraph} +\includeluadocumentationof{pgf.gd.doc.ogdf.layered.GreedyCycleRemoval} + +\includeluadocumentationof{pgf.gd.doc.ogdf.module.HierarchyLayoutModule} +\includeluadocumentationof{pgf.gd.doc.ogdf.layered.FastHierarchyLayout} +\includeluadocumentationof{pgf.gd.doc.ogdf.layered.FastSimpleHierarchyLayout} + + + + +\includeluadocumentationof{pgf.gd.doc.ogdf.energybased} + +\includeluadocumentationof{pgf.gd.doc.ogdf.energybased.SpringEmbedderFR} +\includeluadocumentationof{pgf.gd.doc.ogdf.energybased.SpringEmbedderFRExact} +\includeluadocumentationof{pgf.gd.doc.ogdf.energybased.SpringEmbedderKK} + +\includeluadocumentationof{pgf.gd.doc.ogdf.energybased.FMMMLayout} + +\includeluadocumentationof{pgf.gd.doc.ogdf.energybased.MultilevelLayout} + +\includeluadocumentationof{pgf.gd.doc.ogdf.energybased.GEMLayout} +\includeluadocumentationof{pgf.gd.doc.ogdf.energybased.FastMultipoleEmbedder} + + +\includeluadocumentationof{pgf.gd.doc.ogdf.module.InitialPlacer} + +\includeluadocumentationof{pgf.gd.doc.ogdf.energybased.multilevelmixer.BarycenterPlacer} +\includeluadocumentationof{pgf.gd.doc.ogdf.energybased.multilevelmixer.CirclePlacer} +\includeluadocumentationof{pgf.gd.doc.ogdf.energybased.multilevelmixer.MedianPlacer} +\includeluadocumentationof{pgf.gd.doc.ogdf.energybased.multilevelmixer.RandomPlacer} +\includeluadocumentationof{pgf.gd.doc.ogdf.energybased.multilevelmixer.SolarPlacer} +\includeluadocumentationof{pgf.gd.doc.ogdf.energybased.multilevelmixer.ZeroPlacer} + +\includeluadocumentationof{pgf.gd.doc.ogdf.module.MultilevelBuilder} + +\includeluadocumentationof{pgf.gd.doc.ogdf.energybased.multilevelmixer.EdgeCoverMerger} +\includeluadocumentationof{pgf.gd.doc.ogdf.energybased.multilevelmixer.IndependentSetMerger} +\includeluadocumentationof{pgf.gd.doc.ogdf.energybased.multilevelmixer.LocalBiconnectedMerger} +%\includeluadocumentationof{pgf.gd.doc.ogdf.energybased.multilevelmixer.MatchingMerger} +% \includeluadocumentationof{pgf.gd.doc.ogdf.energybased.multilevelmixer.RandomMerger} +% \includeluadocumentationof{pgf.gd.doc.ogdf.energybased.multilevelmixer.SolarMerger} + + + +\includeluadocumentationof{pgf.gd.doc.ogdf.planarity} + +\includeluadocumentationof{pgf.gd.doc.ogdf.planarity.PlanarizationLayout} +%\includeluadocumentationof{pgf.gd.ogdf.planarity.LayoutPlanRepModule} + + +\includeluadocumentationof{pgf.gd.doc.ogdf.misclayout} + +\includeluadocumentationof{pgf.gd.doc.ogdf.misclayout.BalloonLayout} +\includeluadocumentationof{pgf.gd.doc.ogdf.misclayout.CircularLayout} + + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "pgfmanual-pdftex-version" +%%% End: diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-overview.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-overview.tex new file mode 100644 index 00000000000..cae05728476 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-overview.tex @@ -0,0 +1,317 @@ +% Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster +% Copyright 2011 by Till Tantau +% Copyright 2011 by Jannis Pohlmann +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + + +\section{Introduction to Algorithmic Graph Drawing} + +\emph{by Till Tantau} + +\ifluatex\else This section of the manual can only be typeset using Lua\TeX.\expandafter\endinput\fi + + +\subsection{What Is Algorithmic Graph Drawing?} + + + +\emph{Algorithmic graph drawing} (or just \emph{graph drawing} in the +following) is the process of computing algorithmically where the nodes of +a graph are positioned on a page so that the graph ``looks nice.'' The +idea is that you, as human (or you, as a machine, if you happen to be +a machine and happen to be reading this document) just specify which +nodes are present in a graph and which edges are +present. Additionally, you may add some ``hints'' like ``this node +should be near the center'' or ``this edge is pretty important.'' You +do \emph{not} specify where, exactly, the nodes and edges should +be. This is something you leave to a \emph{graph drawing + algorithm}. The algorithm gets your description of the graph as an +input and then decides where the nodes should go on the page. + +\begin{codeexample}[] +\tikz \graph [binary tree layout, level distance=5mm] { + 4 -- { + 3 -- 0 -- 1[second], + 10 -- { + 8 -- { + 6 -- {5,7}, + 9 + } } } +}; +\end{codeexample} + +\begin{codeexample}[] +\tikz \graph [spring layout, + edge quotes mid, + edges={nodes={font=\scriptsize, fill=white, sloped, inner sep=1pt}}] +{ + 1 ->["Das"] 2 ->["ist"] 3 ->["das"] 4 ->["Haus"] + 2 ->["vom" near start] 5 ->["Ni"] 4 ->["ko" near start] + 1 ->["laus", orient=right] 5; +}; +\end{codeexample} + +Naturally, graph drawing is a bit of a (black?) art. There is no +``perfect'' way of drawing a graph, rather, depending on the +circumstances there are several different ways of drawing the same +graph and often it will just depend on the aesthetic sense of the +reader which layout he or she would prefer. For this reason, there are +a huge number of graph drawing algorithms ``out there'' and there are +scientific conference devoted to such algorithms, where each +year dozens of new algorithms are proposed. + +Unlike the rest of \pgfname\ and \tikzname, which is implemented +purely in \TeX, the graph drawing algorithms are simply too complex to +be implemented directly in \TeX. Instead, the programming language Lua is used +by the graph drawing library -- a programming language that has been +integrated into recent versions of \TeX. This means that (a) as a user +of the graph drawing engine you run \TeX\ on your documents +in the usual way, no external programs are called since Lua is already +integrated into \TeX, and (b) it is pretty easy to implement new graph +drawing algorithms for \tikzname\ since Lua can be used and no \TeX\ +programming knowledge is needed. + + +\subsection{Using the Graph Drawing System} + +``Users'' of the graph drawing engine can invoke the graph +drawing algorithms often by just adding a single option to their +picture. Here is a typical example, where the |layered layout| option +tells \tikzname\ that the graph should be drawn (``should be layed +out'') using a so-called ``layered graph drawing algorithm'' (what +these are will be explained later): +\begin{codeexample}[] +\tikz [>=spaced stealth'] + \graph [layered layout, components go right top aligned, nodes=draw, edges=rounded corners] + { + first root -> {1 -> {2, 3, 7} -> {4, 5}, 6 }, 4 -- 5; + second root -> x -> {a -> {u,v}, b, c -> d -> {w,z} }; + third root -> child -> grandchild -> youngster -> third root; + }; +\end{codeexample} +Here is another example, where a different layout method is used +that is more appropriate for trees: +\begin{codeexample}[] +\tikz [grow'=up, binary tree layout, nodes={circle,draw}] + \node {1} + child { node {2} + child { node {3} } + child { node {4} + child { node {5} } + child { node {6} } + } + } + child { node {7} + child { node {8} + child[missing] + child { node {9} } + } + }; +\end{codeexample} +A final example, this time using a ``spring electrical layout'' +(whatever that might be\dots): +\begin{codeexample}[] +\tikz [spring electrical layout, node distance=1.3cm, + every edge/.style={ + decoration={coil, aspect=-.5, post length=1mm, + segment length=1mm, pre length=2mm}, + decorate, draw}] +{ + \foreach \i in {1,...,6} + \node (node \i) [fill=blue!50, text=white, circle] {\i}; + + \draw (node 1) edge (node 2) + (node 2) edge (node 3) + edge (node 4) + (node 3) edge (node 4) + edge (node 5) + edge (node 6); +} +\end{codeexample} +In all of the example, the positions of the nodes have only been +computed \emph{after} all nodes have been created and the edges have +been specified. For instance, in the last example, without the +option |spring electrical layout|, all of the nodes would have been +placed on top of each other. + + +\subsection{Extending the Graph Drawing System} + +The graph drawing engine is also intended to make is +(relatively) easy to implement new graph drawing algorithms. These +algorithms can either be implemented in the Lua programming +language (which is \emph{much} easier to program than \TeX\ +itself) or in C/C++ (but at a great cost regarding portability). The +Lua code for a graph drawing algorithm gets an +object-oriented model of the input graph as an input and must just +compute the desired new positions of the nodes. The complete +handling of passing options and configurations back-and-forth +between the different \tikzname\ and \pgfname\ layers is handled by +the graph drawing engine. + +As a caveat, the graph drawing engine comes with a library of +functions and methods that simplify the writing of new +graph drawing algorithms. As a typical example, when you implement a +graph drawing algorithm for trees, you typically require that your +input is a tree; but you can bet that users will feed all sorts of +graphs to your algorithm, including disjoint unions of cliques. The +graph drawing engine offers you to say that a precondition to running +your algorithm is that the graph is a |tree| and instead of the original graph your +algorithm will be provided with a spanning tree of the graph on +which it can work. There are numerous further automatic pre- and +postprocessing steps that include orienting, anchoring, and packing +of components, to name a few. + +The bottom line is that the graph drawing engine makes it easy +to try out new graph drawing algorithms for medium sized graphs (up +to a few hundred nodes) in Lua. For larger graphs, C/C++ code must be +used. + + + +\subsection{The Layers of the Graph Drawing System} + +\label{section-gd-layers} + +Even though the graph drawing system presented in the following +sections was developed as part of \pgfname, it can be used +independently of \pgfname\ and \tikzname: It was (re)designed so that +it can be used by arbitrary programs as long as they are able to run +Lua. To achieve this, the graph drawing system consists of three +layers: + +\begin{enumerate} +\item At the ``bottom'' we have the \emph{algorithmic layer}. This + layer, written in Lua, contains all graph drawing + algorithms. Interestingly, options must also be declared on this + layer, so an algorithm together with all options it uses can and + must be specified entirely on this layer. + If you intend to implement a new graph drawing algorithm, you will + only be interested in the functionality of this layer. + + Algorithm ``communicate'' with the graph drawing system through + a well-defined interface, encapsulated in the class + |InterfaceToAlgorithms|. +\item At the ``top'' we have the \emph{display layer}. This layer is + not actually part of the graph drawing system. Rather, it is a piece + of software that ``displays'' graphs and \tikzname\ is just one + example of such a software. Another example might be a graph + editor that uses the graph drawing system to lay out the graph it + displays. Yet another example might be a command line tool for + drawing graphs described in a file. Finally, you may also wish to + use the graph drawing system as a simple subroutine for rendering + graphs produced in a larger program. + + Since the different possible instantiations of the display layer are + quite heterogeneous, all display layers must communicate with the + graph drawing system through a special interface, encapsulated in + the class |InterfaceToDisplay|. + + The main job of this class is to provide a set of methods for + specifying that a graph has certain nodes and edges and that certain + options have been set for them. However, this interface also allows + you to query all options that have been declared by algorithms, + including their documentation. This + way, an editor or a command line tool can display a list of all + graph drawing algorithms and how they can be configured. +\item + The algorithm layer and the display layer are ``bound together'' + through the \emph{binding layer}. Most of the bookkeeping concerning + the to-be-drawn graphs is done by the graph drawing system + independently of which algorithm is used and also independently of + which display layer is used, but some things are still specific to + each display layer. For instance, some algorithms may create new + nodes and the algorithms may then need to know how large these nodes + will be. For this, the display layer must be ``queried'' during a + run of the algorithm -- and it is the job of the binding layer to + achieve this callback. + + As a rule, the binding layer implements the ``backward'' + communication from the graph drawing system back to the display + layer, while the display layer's interface class provides only + functions that are called from the display layer but which will not + ``talk back''. +\end{enumerate} + +All of the files concerned with graph drawing reside in the +|graphdrawing| subdirectory of |generic/pgf|. + +\subsection{Organisation of the Graph Drawing Documentation} + +The documentation of the graph drawing engine is structured as +follows: +\begin{enumerate} +\item Following this overview section, the next section documents + the graph drawing engine from ``the \tikzname\ user's point of + view''. No knowledge of Lua or algorithmic graph drawing is needed + for this section, everyone who intends to use algorithmic graph + drawing in \tikzname\ may be interested in reading it. +\item You will normally only use \tikzname's keys and + commands in order to use the graph drawing system, but, internally, + these keys call more basic \pgfname\ commands that do the ``hard + work'' of binding the world of \TeX\ boxes and macros to the + object-oriented world of Lua. Section~\ref{section-gd-pgf} explains + how this works and which commands are available for authors of + packages that directly need to use the graph drawing system inside + \pgfname, avoiding the overhead incurred by \tikzname. + + Most readers can safely skip this section. +\item The next sections detail which graph drawing algorithms are + currently implemented as part of the \tikzname\ distribution, see + Sections~\ref{section-first-graphdrawing-library-in-manual} + to~\ref{section-last-graphdrawing-library-in-manual}. +\item + Section~\ref{section-gd-algorithm-layer} is addressed at readers + who wish to implement their own graph drawing + algorithms. For this, \emph{no knowledge at all} of \TeX\ + programming is needed. The section explains the graph model used in + Lua, the available libraries, the graph drawing pipeline, and everything + else that is part of the Lua side of the engine. +\item + Section~\ref{section-gd-display-layer} details the + display layer of the graph drawing system. You should read this + section if you wish to implement a new display system (that is, a + non-\TeX-based program) that intends to use the graph drawing system. +\item + Section~\ref{section-gd-binding-layer} explains how binding layers + can be implemented. This section, too, is of interest only to + readers who wish to write new display systems. +\end{enumerate} + + + +\subsection{Acknowledgements} + +Graph drawing in \tikzname\ began as a student's project under my +supervision. Ren\'ee Ahrens, Olof-Joachim Frahm, Jens +Kluttig, Matthias Schulz, and Stephan Schuster wrote the first +prototype of a graph drawing system inside \tikzname\ that uses +Lua\TeX\ for the implementation of graph drawing algorithms. + +This first, early version was greatly extended on the algorithmic side +by Jannis Pohlmann who wrote his Diploma thesis on graph drawing under +my supervision. He implemented, in particular, the Sugiyama method +(|layered layout|) and force based algorithms. Also, he rewrote some +of the code of the prototype. + +At some point it became apparent that the first implementation had a +number of deficiencies, both concerning the structure, the interfaces, +and (in particular) the performance. Because of this, I rewrote +the code of the graph drawing system, both on the \TeX\ side +and on the Lua side in its current form. However, I would like to +stress that without the work of the people mentioned above graph +drawing in \tikzname\ would not exist. + +The documentation was written almost entirely by myself, though I did +copy some paragraphs from Jannis's Diploma thesis, which I can highly +recommend everyone to read. + +In the future, I hope that other people will contribute algorithms, +which will be available as libraries.
\ No newline at end of file diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-phylogenetics.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-phylogenetics.tex new file mode 100644 index 00000000000..28906ec17b5 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-phylogenetics.tex @@ -0,0 +1,82 @@ +% Copyright 2013 by Sarah Mäusle and Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + +\section{Graph Drawing Layouts: Phylogenetic Trees} +\label{section-library-graphdrawing-phylogenetics} + +{\noindent {\emph{by Sarah M\"ausle and Till Tantau}}} + +\ifluatex\else This section of the manual can only be typeset using Lua\TeX.\expandafter\endinput\fi + +\tikzset{/graph drawing/phylogenetic inner node/.style={ + /tikz/.cd, + draw, circle, inner sep=0pt, minimum size=5pt} +} +\tikzset{/graph drawing/phylogenetic edge/.style={ + /tikz/.cd, + thick, rounded corners,edge node={node[auto,font=\tiny, inner sep=2pt]{}}} +} + + +\includeluadocumentationof{pgf.gd.phylogenetics.library} +\includeluadocumentationof{pgf.gd.phylogenetics.PhylogeneticTree} + + +\subsection{Generating a Phylogenetic Tree} + +... + +When a phylogenetic tree is generated, new nodes and edges get +created. In order to give you a chance at styling them, the following +styles are executed: + +\begin{stylekey}{/graph drawing/phylogenetic inner node} + The style is added every newly created inner node. In this manual, + this key is set to: +\begin{codeexample}[code only] +\pgfgdset{phylogenetic inner node/.style={ + /tikz/.cd, draw, circle, inner sep=0pt, minimum size=5pt + } +} +\end{codeexample} +\end{stylekey} + +\begin{stylekey}{/graph drawing/phylogenetic edge=\meta{length}} + The style is added every newly created phylogenetic edge. The + \meta{length} will be set to the computed evolutionary length of the + edge. In this manual, this key is set to: +\begin{codeexample}[code only] +\pgfgdset{phylogenetic edge/.style={ + /tikz/.cd, thick, rounded corners + } +} +\end{codeexample} +\end{stylekey} + + +\includeluadocumentationof{pgf.gd.phylogenetics.AuthorDefinedPhylogeny} +\includeluadocumentationof{pgf.gd.phylogenetics.SokalMichener1958} +\includeluadocumentationof{pgf.gd.phylogenetics.BalancedMinimumEvolution} +\includeluadocumentationof{pgf.gd.phylogenetics.BalancedNearestNeighbourInterchange} + + +\subsection{Laying out the Phylogram} + +\includeluadocumentationof{pgf.gd.phylogenetics.Maeusle2012} + + + +\endinput + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "pgfmanual-pdftex-version" +%%% End: diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-trees.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-trees.tex new file mode 100644 index 00000000000..edfbcdeba4e --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-trees.tex @@ -0,0 +1,34 @@ +% Copyright 2012 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + +\section{Graph Drawing Layouts: Trees} +\label{section-first-graphdrawing-library-in-manual} +\label{section-library-graphdrawing-trees} + +{\noindent {\emph{by Till Tantau}}} + +\ifluatex\else This section of the manual can only be typeset using Lua\TeX.\expandafter\endinput\fi + +\includeluadocumentationof{pgf.gd.trees.library} + +\subsection{The Tree Layouts} +\includeluadocumentationof{pgf.gd.trees.ReingoldTilford1981} + +% Other subsections: +\includeluadocumentationof{pgf.gd.trees.ChildSpec} +\includeluadocumentationof{pgf.gd.trees.SpanningTreeComputation} + +\endinput + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "pgfmanual-pdftex-version" +%%% End: diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-usage-pgf.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-usage-pgf.tex new file mode 100644 index 00000000000..095e3f771a4 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-usage-pgf.tex @@ -0,0 +1,721 @@ +% Copyright 2010-2011 by Renée Ahrens +% Copyright 2010-2011 by Olof Frahm +% Copyright 2010-2011 by Jens Kluttig +% Copyright 2010-2011 by Matthias Schulz +% Copyright 2010-2011 by Stephan Schuster +% Copyright 2011 by Jannis Pohlmann +% Copyright 2011 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + + +\section{Using Graph Drawing in PGF} + +\label{section-gd-pgf} + +{\noindent {\emph{by Till Tantau}}} + +\begin{purepgflibrary}{graphdrawing} + This package provides the core support for graph drawing inside + \pgfname. It does so by providing \pgfname\ macros for controlling + the graph drawing system, but also implements the binding to the + graph drawing system (see Section~\ref{section-gd-binding-layer} for + details on bindings). +\end{purepgflibrary} + +\ifluatex\else This section of the manual can only be typeset using Lua\TeX.\expandafter\endinput\fi + +\subsection{Overview} + +Just like everywhere else in \pgfname, \tikzname\ is ``just a +convenient syntax'' in the context of graph drawing. The ``hard work'' +of binding the internal representations of nodes and edges with the graph +drawing system written in Lua is not done by \tikzname, but rather by +a set of macros that are part of the basic \pgfname\ layer. + +The documentation of the \pgfname\ part of the graph drawing system +that is presented in the following includes only those macros that +other \TeX\ packages could conceivably call in order to use the graph +drawing system without using \tikzname; for instance, for efficiency +reasons. (The internal callback functions defined in the graph drawing +library that are part of the binding between \pgfname\ and the graph +drawing system are not documented, should not be called, and may +change in the future.) + + + +\subsection{How Graph Drawing in PGF Works} + +The core idea behind graph drawing in \pgfname\ is that inside special +\emph{graph drawing scopes} whenever \pgfname\ creates a node, we +intercept this node creation and \emph{do not} immediately place the +node. Rather, we pass it down to Lua part of the graph drawing system +via calls to appropriate methods of the (Lua) class +|InterfaceToDisplay|. The effect will be that the nodes are ``tucked +away'' in some internal tables. For edges, we introduce a +special command called |\pgfgdedge| that tells the graph drawing +system that there is an edge between two tucked-away nodes. Then, +at the end of the graph drawing scope, a graph drawing algorithm +written in Lua starts to work on the graph by computing new positions +for the nodes. Once the algorithm has finished, the graph drawing +system starts sending back the nodes and edges to \pgfname\ via the +methods of the class |BindingToPGF|. These methods reinsert some code +into the \TeX\ output stream that finally places the nodes at +their final positions. Note that graph drawing algorithms are +perfectly oblivious to all of this; indeed, the graph drawing +algorithms can even be used independently of \TeX. + +Let us have a look at a simple example to see what happens when a +graph is specified: + +\begin{codeexample}[] +\tikz[tree layout] + \graph {root [as=Hello] -> World[fill=blue!20]}; +\end{codeexample} + +The key |tree layout| internally calls the key |request scope and layout|, +which in turn calls the macro |\pgfgdbeginscope|, which starts a graph +drawing scope inside the graph drawing system. Once this macro has been +called, until the next call of |\pgfgdendscope|, all nodes that are +created actually get passed down to the graph drawing engine. This is +implemented on the lowest layer, namely by directly intercepting +nodes freshly created using |\pgfnode|. In our example, this happens +in two places: For the |root| node and for the |World| node. The +|graph| library and \tikzname\ internally call the |\pgfnode| macro +for these two nodes (after a large number of internal syntax +translations, but the graph drawing system does not care about them). + +Note that the node boxes will have been fully created before they are +passed down to the graph drawing engine -- only their final position +is not yet fixed. It is not possible to modify the size of nodes +inside the graph drawing engine, but you can create new nodes in +certain situations. + +In contrast, the single edge of the graph that is created by the |->| +command is not fully created before it is passed down to the +graph drawing system. This would not really make sense since before the final +positions of the nodes are fixed, we cannot even begin to compute the +length of this edge, let alone where it should start or end. For this +reason, on the upper \tikzname\ layer, the normal edge creation that +would be caused by |->| via |new ->| is suppressed. Instead, the +command |\pgfgdedge| is called. Similarly, inside a graph drawing +scope, \tikzname\ will suppress both the |edge| and the +|edge from parent| command and cause |\pgfgdedge| to be called +instead. + +An overview of what happens is illustrated by the following call graph: + +\bigskip + +\begin{tikzpicture}[ + class name/.style={draw,minimum size=20pt, fill=blue!20}, + object node/.style={draw,minimum size=15pt, fill=yellow!20}, + p/.style={->,>=spaced stealth'}, + livespan/.style={very thick}, + xscale=0.8] + % class names above + \node (tikz) at (0,4) [class name] {\tikzname\ layer (\TeX)}; + \node (tex) at (6,4) [class name] {\pgfname\ layer (\TeX)}; + \node (interface) at (13,4) [class name] {Display layer (Lua)}; + % lines from the class names to the bottom of the picture + \draw[livespan] (tikz) -- (0,-6.5); + \draw[livespan] (tex) -- (6,-6.5); + \draw[livespan] (interface) -- (13,-6.5); + % first command: \graph{ -- generates new graph in lua interface + \node (tikz-begin-graph) at (0,3) [object node] {|\graph[... layout]{|}; %} + \node (tex-begin-graph) at (6,3) [object node] {|\pgfgdbeginscope|}; + \node (interface-new-graph) at (13,3) [object node] {|beginGraphDrawingScope(|...|)|}; + \draw [p] (tikz-begin-graph.east) -- (tex-begin-graph.west); + \draw [p] (tex-begin-graph.east) -- (interface-new-graph.west); + % second command: a -> b -- generates two nodes in lua + % and one edge + \node (tikz-node) at (0,2) [object node] {|a -> b;|}; + \node (tex-node) at (6,2) [object node, double copy shadow] {|\pgfnode|}; + \draw[p] (tikz-node.east) -- (tex-node.west); + + \node (interface-add-node) at (13,2) [object node, double copy shadow] {|createVertex(|...|)|}; + \draw[p] (tex-node.east) -- (interface-add-node.west); + + \node (tex-add-edge) at (6,1) [object node, double copy shadow] {|\pgfgdedge|}; + \node (interface-add-edge) at (13,1) [object node, double copy shadow] {|createEdge(|...|)|}; + \draw[p] (tikz-node.east) -- (1.5,2) -- (1.5,1) -- (tex-add-edge.west); + \draw[p] (tex-add-edge.east) -- (interface-add-edge.west); + + % scope ends -- cloes graph, layouts it and draws it + \node (tikz-end) at (0,0) [object node] {|};|}; + \node (tex-end) at (6,0) [object node] {|\pgfgdendscope|}; + \node (interface-draw-graph) at (13,0) [object node] {|runGraphDrawingAlgorithm()|}; + \node (interface-finish-graph) at (13,-2) [object node] {|endGraphDrawingScope()|}; + + \node (invoke-algorithm) at (15.5,-1) [object node] {invoke algorithm}; + \draw[p] (tikz-end.east) -- (tex-end.west); + \draw[p] (tex-end.east) -- (interface-draw-graph.west); + \draw[p] (interface-draw-graph.east) -| (invoke-algorithm.20); + \draw[p] (tex-end.east) -- (9.5,0) -- (9.5,-2) -- (interface-finish-graph.west); + + % begin shipout + \node (tex-begin-shipout) at (6,-3) [object node] {|\pgfgdcallbackbeginshipout|}; + + \node (tex-puttexbox) at (6,-4) [object node, double copy shadow] {|\pgfgdcallbackrendernode|}; + \node (tex-putedge) at (6,-5) [object node, double copy shadow] {|\pgfgddefaultedgecallback|}; + + \node (tex-end-shipout) at (6,-6) [object node] {|\pgfgdcallbackendshipout|}; + + \draw [p] (interface-finish-graph.-170) |- (tex-begin-shipout.east); + \draw [p] (interface-finish-graph.-170) |- (tex-puttexbox.east); + \draw [p] (interface-finish-graph.-170) |- (tex-putedge.east); + \draw [p] (interface-finish-graph.-170) |- (tex-end-shipout.east); + %(interface-finish-graph.east) -- (12.5,-2) -- (12.5,-4) -- (sys-puttexbox.west); + + % put edge + %(interface-finish-graph.east) -- (12.5,-2) -- (12.5,-5) -- (sys-put-edge.west); + % end shipout + %(interface-finish-graph.east) -- (12.5,-2) -- (12.5,-6) -- (sys-end-shipout.west); +\end{tikzpicture} +\medskip + +The above diagram glosses over the fact that the display layer does +not actually call any of the macros of \TeX\ directly, but uses a so +called \emph{binding} (see the class |BindingToPGF|). However, this +will not be important for the present section since you cannot access +the binding directly. + + + +\subsubsection{Graph Drawing Scopes} + +\label{section-gd-scopes} + +When the graph drawing system is active, some pretty basic things +inside \pgfname\ change -- such as the fact that nodes are no longer +created in the normal manner. For this reason, the graph drawing +system must be switched on and of explicitly through opening and +closing a so called \emph{graph drawing scope}. These scopes can, in +principle, be nested, namely a graph contains a node that +contains some text that in turn contains a subpicture that contains a +drawing of a graph. However, this is \emph{not} the same as subgraphs +nodes and sublayouts, which are all part of the same graph drawing +scope. Normally, graph drawing scopes are not nested. + +Graph drawing scopes are created using the following commands: + +\begin{command}{\pgfgdbeginscope} + This macro starts a \TeX\ scope inside which the following things + happen: + \begin{enumerate} + \item The display layer method |beginGraphDrawingScope| is + called, which created a new graph drawing scope inside the graph + drawing system and places it on top of an internal stack. From now + on, all subsequent interface calls will refer to this scope until + |\pgfgdendscope| is called, which will pop the scope once more. + \item Inside the \TeX\ scope, nodes are not placed + immediately. Rather, |\pgfpositionnodelater|, see + Section~\ref{section-shapes-deferred-node-positioning}, is used to + call |InterfaceToDisplay.createVertex| for all nodes created + inside the scope. This will cause them to be put inside some internal + table. + \item Some additional \meta{code} is executed, which has been set + using the following command: + \begin{command}{\pgfgdaddspecificationhook\marg{code}} + This command adds the \meta{code} to the code that is executed + whenever a graph drawing scope starts. For instance, the + \tikzname\ library |graphdrawing| uses this macro to add some + \meta{code} that will redirect the |edge| and |edge from parent| + path commands to |\pgfgdedge|. + \end{command} + \item |\pgftransformreset| is called. + \item The following \TeX-if is set to true: + { + \let\ifpgfgdgraphdrawingscopeactive=\relax + \begin{textoken}{\ifpgfgdgraphdrawingscopeactive} + Will be true inside a graph drawing scope. + \end{textoken} + } + \end{enumerate} + The above has a number of consequences for what can happen inside a + graph drawing scope: + \begin{itemize} + \item Since nodes are not actually created before the end of the + scope, you cannot reference these nodes. Thus, you cannot write +\begin{codeexample}[code only] +\tikz [spring layout] { + \node (a) {a}; + \node (b) {b}; + \draw (a) -- (b); +} +\end{codeexample} + The problem is that we cannot connect |(a)| and |(b)| via a + straight line since these nodes do not exist at that point (they + are available only deeply inside the Lua). + \item In order to create edges between nodes inside a graph drawing + scope, you need to call the |\pgfgdedge| command, described below. + \end{itemize} + + Additionally, when \tikzname\ is used, the following things also + happen: + \begin{itemize} + \item If the |graphs| library has been loaded, the default + positioning mechanisms of this library are switched off, leaving + the positioning to the graph drawing engine. Also, when an edge is + created by the |graphs| library, this is signalled to the graph + drawing library. (To be more precise: The keys |new ->| and so on + are redefined so that they call |\pgfgdedge| instead of creating + an edge. + \item The |edge| path command is modified so that it also calls + |\pgfgdedge| instead of immediately creating any edges. + \item The |edge from parent| path command is modified so that is + also calls |\pgfgdedge|. + \item The keys |append after command| and |prefix after command| + keys are modified so that they are executed only via + |late options| when the node has ``reached its final parking + position''. + \end{itemize} + + Note that inside a graph drawing scope you first have to open a + (main) layout scope (using the |\pgfgdbeginlayout| command described + later on) before you can add nodes and edges to the scope. +\end{command} + + +\begin{command}{\pgfgdendscope} + This macro is used to end a graph drawing scope. It must be given on + the same \TeX\ grouping level as the corresponding + |\pgfgdbeginscope|. When the macro is called, it triggers a lot of + new calls: + \begin{enumerate} + \item The special treatment of newly created boxes is ended. Nodes + are once more created normally. + \item The effects of the \meta{code} that was inserted via the + specification hook command also ends (provided it had no global + effects). + \item We call |InterfaceToDisplay.runGraphDrawingAlgorithm|. This + will cause the algorithm(s) for the graph to be executed (since a + graph can have sublayouts, several algorithms may be run). See + Section~\ref{section-gd-layout-scopes} below. + \item Next, we call |InterfaceToDisplay.endGraphDrawingScope|. + This causes all nodes that were intercepted during the + graph drawing scope to be reinserted into the output stream at the + positions that were computed for them. Also, for each edge that + was requested via |\pgfgdedge|, the callback macro is + called (see below). + \end{enumerate} +\end{command} + + +Inside a graph drawing scope, nodes are +automatically passed down to the graph drawing engine, while for edges +a command has to be called explicitly: + +\begin{command}{\pgfgdedge\marg{first node}\marg{second + node}\marg{edge direction}\marg{edge options}\marg{edge nodes}} + This command is used to tell the graph drawing engine that there is + an edge between \meta{first node} and \meta{second node} in your + graph. The ``kind'' of connection is indicated by \meta{direction}, + which may be one of the following: + \begin{itemize} + \item + |->| indicates a directed edge (also known as an arc) from + \meta{first node} to \meta{second node}. + \item |--| indicates an undirected edge between \meta{first node} + and \meta{second node}, + \item |<-| indicates a directed edge from \meta{second node} to + \meta{first node}, but with the ``additional hint'' that this is a + ``backward'' edge. A graph drawing algorithm may or may not take + this hint into account. + \item |<->| indicates a bi-directed edge between \meta{first node} + and \meta{second node}. + \item |-!-| indicates that the edge from \meta{first node} to + \meta{second node} is ``missing''. + \end{itemize} + Note that in all cases, the syntatic digraph will contain an arc + from \meta{first node} to \meta{second node}, regardless of the + value of \meta{direction}. The \meta{direction} is ``just'' a + ``semantic annotation''. + + The parameters \meta{edge options} and \meta{edge nodes} are a bit + more tricky. When an edge between two vertices of a graph is created + via |\pgfgdedge|, nothing is actually done immediately. After all, + without knowing the final positions of the nodes \meta{first node} + and \meta{second node}, there is no way of creating the actual + drawing commands for the edge. Thus, the actual drawing of the edge + is done only when the graph drawing algorithm is done (namely in the + macro |\pgfgdedgecallback|, see later). + + Because of this ``delayed'' drawing of edges, options that influence + the edge must be retained until the moment when the edge is actually + drawn. Parameters \meta{edge options} and \meta{edge nodes} store such + options. + + Let us start with \meta{edge options}. This parameter should be set + to a list of key-value pairs like +\begin{codeexample}[code only] +/tikz/.cd, color=red, very thick, orient=down +\end{codeexample} + Some of these options may be of interest to the graph drawing + algorithm (like the last option) while others will + only be important during the drawing of edge (like the first + option). The options that are important for the graph drawing + algorithm must be pushed onto the graph drawing system's option + stack. + + The tricky part is that options that are of interest to the graph + drawing algorithm must be executed \emph{before} the algorithm starts, + but the options as a whole are usually only executed during the + drawing of the edges, which is \emph{after} the algorithm has finished. + To overcome this problem, the following happens: + + The options in \meta{edge options} are executed ``tentatively'' inside + |\pgfgdedge|. However, this execution is done in a ``heavily guarded + sandbox'' where all effects of the options (like changing the + color or the line width) do not propagate beyond the sandbox. Only + the changes of the graph drawing edge parameters leave the + sandbox. These parameters are then passed down to the graph drawing + system. + + Later, when the edge is drawn using |\pgfgdedgecallback|, the + options \meta{edge options} are available once more and then they + are executed normally. + + Note that when the options in \meta{edge options} are executed, no + path is preset. Thus, you typically need to start it with, say, + |/tikz/.cd|. Also note that the sandbox is not perfect and changing + global values will have an effect outside the sandbox. Indeed, + ``putting things in a sandbox'' just means that the options are + executed inside a \TeX\ scope inside an interrupted path inside a + \TeX\ box that is thrown away immediately. + + The text in \meta{edge nodes} is some ``auxilliary'' text that is + simply stored away and later directed to |\pgfgdedgecallback|. This + is used for instance by \tikzname\ to store its node labels. +\end{command} + + +\begin{command}{\pgfgdsetedgecallback\marg{macro}} + This command allows you to change the \meta{macro} that gets called + form inside the graph drawing system at the end of the creation of a + graph, when the nodes have been positioned. The \meta{macro} will be + called once for each edge with the following parameters: + \begin{quote} + \meta{macro}\marg{first node}\marg{second + node}\marg{direction}\marg{edge options}\marg{edge + nodes}\\ + \marg{algorithm-generated options}\marg{bend information} + \end{quote} + + The first five parameters are the original values that were passed + down to the |\pgfgdedge| command. + + The \meta{algorithm-generated options} have been ``computed by the + algorithm''. For instance, an algorithm might have determined, say, + flow capacities for edges and it might now wish to communicate this + information back to the upper layers. These options should be + executed with the path |/graph drawing|. + + The parameter \meta{bend information} contains + algorithmically-computed information concerning how the + edge should bend. This will be a text like + |(10pt,20pt)--(30pt,40pt)| in \tikzname-syntax and may include the + path commands |--|, |..| (followed by B\'ezier coordintes), and + |--cycle|. + + The default \meta{macro} simply draws a line between the nodes. When + the |graphdrawing| library of the \tikzname\ layer is loaded, a more + fancy \meta{macro} is used that takes all of the parameters into + account. +\end{command} + + + +\subsection{Layout Scopes} +\label{section-gd-layout-scopes} + +As described in Section~\ref{section-gd-sublayouts}, the graph drawing +engine does not always apply only a single algorithm. Rather, several +different algorithm may be applied to different parts of the +graph. How this happens, exactly, is goverened by a hierarchy of +layouts, which are setup using the commands |\pgfgdbeginlayout| and +|\pgfgdendlayout|. + + +\begin{command}{\pgfgdbeginlayout} + This command first starts a new \TeX\ scope and then informs the + display layer that a new (sub)layout should be started. For each + graph there may be a hierarchy of layouts, each of which contains a + certain number of vertices and edges. This hierarchy is created + through calls to this macros and the corresponding calls of + |\pgfgdendlayout|. For each graph drawing scope there has to be + exactly one main layout that encompasses all nodes and edges and + also all sublayouts. Thus, after a graph drawing scope has been + opened, a layout scope also needs to be opened almost immediately. + + For each layout created via this macro, a graph drawing algorithm + will be run later on on the subgraph of all nodes that make up the + layout. Which algorithm is run for the layout is dictated by which + layout key (one of the |... layout| keys) is ``in force'' when the + macro is called. Thus, using a layout key for selecting an algorithm + must always be done \emph{before} the layout is started. (However, + see the discussion of layout keys in the next subsection for more + details on what really happens.) + + A vertex can be part of several layouts, either because they are + nested or because they overlap (this happens when a node is later on + added to another layout by calling |\pgfgdsetlatenodeoption|). This + means that it is not immediately obvious how conflicts arising from + the different ways different algorithms ``would like to place + nodes'' should be resolved. The method for this resolving is + detailed in Section~\ref{section-gd-layout-resolve}. +\end{command} + +\begin{command}{\pgfgdendlayout} + This command ends the \TeX\ scope of the current layout. Once + closed, no nodes or edges can be added to a layout. +\end{command} + + +\begin{command}{\pgfgdsetlatenodeoption\marg{node name}} + This command can only be called when the node named \meta{node name} + has already been created inside the current graph drawing scope. The + effect of calling this macro will be that all options currently on + the graph drawing system's option stack will be added to the node's + option, possibly overwriting the original option + settings. Furthermore, the node will become part of all layouts + currently on the option stack. This means that you can use this + command to add a node to several layouts that are not included in + one another. +\end{command} + + + +\subsection{Layout Keys} + +\emph{Layout keys} are keys like |tree layout| +or |layered layout| that are used to select a specific graph drawing +algorithm. From the graph drawing system's point of view, these keys +``just'' select an algorithm and when several layout keys are used in +a row, the last one would ``win''; just as when you say |orient=90| directly +followed by |orient=0|, the result is that the |orient| key is set to +|0| because the last key ``wins.'' + +Unfortunately, if keys like |tree layout| were ``just'' to select an +algorithm, we would still need a key or some special syntax to +actually start a (sub)layout. In early versions of the system this was +exactly what people had to do and this was somewhat awkward. Because +of this problem, the behaviour of the layout keys in \pgfname\ (and +only there, other display layers need to implement their own +behaviour) is now a bit more involved. When you use a key like +|tree layout| (more precisely, any key that +was declared as an algorithm key on the algorithm layer of the graph +drawing system) in any scope in \pgfname, the following happens: +\begin{enumerate} +\item The graph drawing system is told that a specific algorithm has + been selected (the Reingold--Tilford-algorithm in this case; this + information was communicated to the graph drawing system during the + declaration of the algorithm). Being ``told'' about this means that + a special entry is pushed onto the current options stack of the + graph drawing system. +\item An internal ``request'' for a ``scope and a layout'' is + made. This has several effects: +\item + We first test whether we are already inside a layout scope. If not, + we use |\pgfgdbeginscope| to open a graph drawing scope. This + scope will be closed appropriately (see |\pgfgdsetrequestcallback| + for details). +\item + Next, a layout scope is opened using |\pgfgdbeginlayout|. It will + also be closed appropriately. +\end{enumerate} + +The net effect of the above is that the first use of a layout key in a +picture starts both a graph drawing scope and also a main layout, +while subsequent uses of layout keys inside a picture will only open +sublayouts. + +\begin{command}{\pgfgdsetrequestcallback\marg{macro}} + This command sets up \meta{macro} as the macro that is called + whenever a layout key ``requests'' that a layout and, possibly, a + graph drawing scope is opened. When \meta{macro} is called, it gets + two parameters, the \meta{begin code} and the \meta{end code}. In + addition to whatever setup the \meta{macro} would like to do, it + should execute the \meta{begin code} at the beginning of a \TeX\ + scope (the code will open graph drawing and layout scopes) and the + \meta{end code} at the end of the same \TeX\ scope. + + The need for this slightly strange macro arises from the fact that + in \tikzname\ we often write things like + |[spring layout,node sep=2cm]|. The point is that when the + |spring layout| key is executed, we do \emph{not} wish to open a + layout scope immediately. Rather, this should happen only after the + option |nodes sep=2cm| has been executed. For this reason, \tikzname\ + sets up a special \meta{macro} that ``delays'' the execution of the + \meta{begin code} until the end of the opening of the next scope. + + Because of this, in \tikzname\ layout keys can only be used as an + option when a \tikzname\ scope is started. Thus, you can + pass them to |\tikz|, to |{tikzpicture}|, to |\scoped|, to |{scope}|, + to |graph|, and to |{graph}|. For instance, the |tree layout| option can + be used in the following ways: +\begin{codeexample}[] +\tikz [tree layout] \graph {1 -> {b,c}}; +\tikz \graph [tree layout] {2 -> {b,c}}; +\tikz \path graph [tree layout] {3 -> {b,c}}; + +\begin{tikzpicture}[tree layout] + \graph {4 -> {b,c}}; +\end{tikzpicture} + +\begin{tikzpicture} + \scoped [tree layout] \graph {5 -> {b,c}}; + + \begin{scope}[tree layout, xshift=1.5cm] + \graph {6 -> {b,c}}; + \end{scope} +\end{tikzpicture} +\end{codeexample} + + You can \emph{not} use layout keys with a single + node or on a path. In particular, to typeset a tree given in the + |child| syntax somewhere inside a |{tikzpicture}|, you must prefix + it with the |\scoped| command: +\begin{codeexample}[] +\begin{tikzpicture} + \scoped [tree layout] + \node {root} + child { node {left child} } + child { node {right child} }; +\end{tikzpicture} +\end{codeexample} + Naturally, the above could have been written more succinctly as +\begin{codeexample}[] +\tikz [tree layout] + \node {root} + child { node {left child} } + child { node {right child} }; +\end{codeexample} + Or even more succinctly: +\begin{codeexample}[] +\tikz \graph [tree layout] { root -- {left child, right child} }; +\end{codeexample} +\end{command} + + + +\subsection{Parameters} +\label{section-gd-parameters} + +When a graph drawing algorithm starts working, a set of options, +called ``graph drawing parameters'' or just ``parameters'' can influence +the way the algorithm works. For instance, a graph drawing parameter +might be the average distance between vertices which the algorithm +should take into account. Another example might be the fact the +certain nodes are special nodes and that a certain edge should have +a large label. + +These graph drawing parameters are different from ``usual'' \pgfname\ +options: An alogrithmic parameter influences the way the algorithm +works, while usual options influence the way the result +looks like. For instance, the fact that a node is red is not a +graph drawing parameter, while the shape of a node might be an graph +drawing parameter. + +The possible graph parameters are declared by the algorithmic layer +through the |declare| method; you cannot declare parameters on the +\pgfname\ layer since this would not be compatible across different +display systems. + +Users use a graph parameter in the same way as a normal key. The +difference is that each time a key representing a graph drawing +parameter is used, a special function of the graph drawing system's +interface is called to ``push'' the parameter onto an internal option +stack (and elements are popped from this stack whenever the \TeX\ +scope closes in which the key was used). + +The net effect of all of this is that the graph drawing system keeps +track of a stack of option in parallel to \TeX. You cannot, however, +access the current values of graph drawing parameters from \TeX\ since +they are tucked away deep inside the graph drawing system. + + + +\subsection{Events} + +\emph{Events} are used to pass information from the parser about the +syntactic structure of a graph to graph drawing algorithms. Consider, +for instance, a graph that is actually a tree in which some node +``misses'' its first child. In this case, the information that the +child is missing is neither part of any node (because the node is +missing, after all) nor is it an option of the whole graph. However, +events are created by the parser the allow an algorithm to reconstruct +the fact that the child is missing. Naturally, graph drawing +algorithms may choose to ignore events and most will. + +Most of the creation and handling of events is done automatically. The +only reason you might wish to use the following commands is when you +write a ``parser extension'' together with a new graph drawing +algorithm. For instance, you might come up with new options that, when +used, trigger events. + +\begin{command}{\pgfgdevent\marg{kind}\marg{parameter}} + Calls |createEvent| of the graph drawing system's interface + class. This creates a new |Event| object on the Lua layer whose + |kind| field is set to \meta{kind} and the |parameters| field to + \meta{parameter}. You must be inside a graph drawing scope to use + this command. +\end{command} + +\begin{command}{\pgfgdbegineventgroup\marg{parameter}} + Starts an event group. This just means that an |Event| of kind + |begin| is created with the given \meta{parameter}. +\end{command} + +\begin{command}{\pgfgdendeventgroup} + Ends an event group. This is done by adding an event of kind |end| + without any parameters to the event string. +\end{command} + +\begin{command}{\pgfgdeventgroup\marg{parameters}} + Starts an event group just like |\pgfgdbegineventgroup|, but adds a + corresponding closing |end| event at the end of the current \TeX\ + group (using |\aftergroup|). +\end{command} + + +\subsection{Subgraph Nodes} + +\begin{command}{\pgfgdsubgraphnode\marg{name}\marg{node options}\marg{node text}} + A subgraph node is a node that ``surrounds'' the nodes 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 \pgfname\ level and on the Lua level, but the + actual node is only created inside the layout pipeline using a + callback. The actual node creation happens when the innermost layout + in which the subgraph node is declared has finished. + + When you create a subgraph node using this macro, you also start a + collection (of an internal kind) that stores the subgraph. All + following nodes in the current \TeX\ scope will become part of this + collection. + + The \meta{name} is the node name by which you can refer to this node + in the following. The \meta{node options} are normal \pgfname\ + options (like |red| or |draw| or |circle|) that will influence the + appearance when it is created later on. The \meta{node text} is the + text that will be passed to |\pgfnode| upon creation of the node. + + See |InterfaceToDisplay.pushSubgraphVertex| for more details. +\end{command} + + + + + diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-usage-tikz.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-usage-tikz.tex new file mode 100644 index 00000000000..222898b66e7 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-usage-tikz.tex @@ -0,0 +1,545 @@ +% Copyright 2012 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + +\section{Using Graph Drawing in \tikzname} + +{\noindent {\emph{by Till Tantau}}} + +\begin{tikzlibrary}{graphdrawing} + This package provides capabilities for automatic graph drawing. It + requires that the document is typeset using Lua\TeX. This package + should work with Lua\TeX\ 0.54 or higher. +\end{tikzlibrary} + +\ifluatex\else This section of the manual can only be typeset using Lua\TeX.\expandafter\endinput\fi + + +\subsection{Choosing a Layout and a Library} + +The graph drawing engine is initialized when you load the library +|graphdrawing|. This library provides the basic framework for graph +drawing, including all options and keys described in the present +section. However, this library does \emph{not} load any actual +algorithms for drawing graphs. For this, you need to use the following +command, which is defined by the |graphdrawing| library: + +\begin{command}{\usegdlibrary\marg{list of libraries}} + This command is used to load the special graph drawing libraries + (the |gd| in the name of the command stands for ``graph + drawing''). The \meta{list of libraries} is a comma-separated list + of library written in the Lua programming language (which is why a + special command is needed). + + In detail, this command does the following. For each \meta{name} in + the \meta{list of libraries} we do: + \begin{enumerate} + \item Check whether Lua\TeX\ can call |require| on the library file + |pgf.gd.|\meta{name}|.library|. Lua\TeX's usual file search + mechanism will search the texmf-trees in the usual manner and the + dots in the file name get converted into directory slashes. + \item If the above failed, try to |require| the string + |pgf.gd.|\meta{name}. + \item If this fails, try to |require| the string + \meta{name}|.library|. + \item If this fails, try to |require| the string \meta{name}. If + this fails, print an error message. + \end{enumerate} + The net effect of the above is the following: Authors of graph + drawing algorithms can bundle together multiple algorithms in a + library by creating a |...xyz/library.lua| file that internally just + calls |require| for all files containing declarations. On the other + hand, if a graph drawing algorithm completely fits inside a single + file, it can also be read directly using |\usegdlibrary|. +\begin{codeexample}[code only] +\usetikzlibrary{graphdrawing} +\usegdlibrary{trees,force} +\end{codeexample} + + The different graph drawing libraries are documented in the following + Sections~\ref{section-first-graphdrawing-library-in-manual} to + \ref{section-last-graphdrawing-library-in-manual}. +\end{command} + +Note that in addition to the graph \emph{drawing} libraries, you may +also wish to load the normal \tikzname\ library |graphs|. It provides +the powerful |graph| path command with its easy-to-use syntax for +specifying graphs, but you can use the graph drawing engine +independently of the |graphs| library, for instance in conjunction +with the |child| or the |edge| syntax. Here is a typical setup: + +\begin{codeexample}[code only] +\usetikzlibrary{graphs, graphdrawing} +\usegdlibrary{trees, layered} +\end{codeexample} + +Having set things up, you must then specify for which scopes the +graph drawing engine should apply a layout algorithm to the nodes in +the scope. Typically, you just add an option ending with |... layout| +to the |graph| path operation and then let the graph drawing do its +magic: + +\begin{codeexample}[] +\tikz [rounded corners] + \graph [layered layout, sibling distance=8mm, level distance=8mm] + { + a -> { + b, + c -> { d, e } + } -> + f -> + a + }; +\end{codeexample} + +Whenever you use such an option, you can: +\begin{itemize} +\item Create nodes in the usual way. The nodes will be created + completely, but then tucked away in an internal table. This means + that all of \tikzname's options for nodes can be applied. You can + also name a node and reference it later. +\item Create edges using either the syntax of the |graph| command + (using |--|, |<-|, |->|, or |<->|), or using the |edge| command, + or using the |child| command. These edges will, however, not be + created immediately. Instead, the basic layer's command + |\pgfgdedge| will be called, which stores ``all the information + concerning the edge.'' The actual drawing of the edge will only + happen after all nodes have been positioned. +\item Most of the keys that can be passed to an edge will work as + expected. In particular, you can add labels to edges using the + usual |node| syntax for edges. +\item The |label| and |pin| options can be used in the usual manner + with nodes inside a graph drawing scope. Only, the labels and + nodes will play no role in the positioning of the nodes and they + are added when the nodes are finally positioned. +\item Similarly, nodes that are placed ``on an edge'' using the + implicit positioning syntax can be used in the usual manner. +\end{itemize} +Here are some things that will \emph{not} work: +\begin{itemize} +\item Only edges created using the graph syntax, the |edge| command, + or the |child| command will correctly pass their connection + information to the basic layer. When you write |\draw (a)--(b);| + inside a graph drawing scope, where |a| and |b| are nodes that + have been created inside the scope, you will get an error + message / things will look wrong. The reason is that the usual + |--| is not ``caught'' by the graph drawing engine and, thus, + tries to immediately connect two nodes that do not yet exist + (except inside some internal table). +\item The options of edges are executed twice: Once when the edge is + ``examined'' by the |\pgfgdedge| command (using some magic to shield + against the side effects) and then once more when the edge is + actually created. Fortunately, in almost all cases, this will not be + a problem; but if you do very evil magic inside your edge options, + you must roll a D100 to see what strange things will happen. (Do no + evil, by the way.) +\end{itemize} + +If you are really interested in the ``fine print'' of what happens, +please see Section~\ref{section-gd-pgf}. + + +\subsection{Graph Drawing Parameters} + +Graph drawing algorithms can typically be configured in some way. For +instance, for a graph drawing algorithm that visualizes its nodes as a +tree, it will typically be useful when the user can change the +so-called \emph{level distance} and the \emph{sibling distance}. For +other algorithms, like force-based algorithms, a large number of +parameters influence the way the algorithms work. +Options that influence graph drawing algorithms will be called +\emph{(graph drawing) parameters} in the following. From the user's +point of view, these parameters look like normal \tikzname\ keys and +you set them in the usual way. Internally, they are treated a bit +differently from normal keys since their ``effect'' becomes apparent +only later on, namely during the run of the graph drawing algorithm. + +A graph drawing algorithm may or may not take different graph +parameters into account. After all, these options may even outright +contradict each other, so an algorithm can only try to ``do its +best''. While many graph parameters are very specific to a single +algorithm, a number of graph parameters will be important for many +algorithms and they are documented in the course of the present +section. Here is an example of an option the ``always works'': + +\begin{codeexample}[] +\tikz \graph [spring layout, vertical=1 to 2] { 1--2--3--1 }; +\end{codeexample} + + +\includeluadocumentationof{pgf.gd.control.Distances} +\includeluadocumentationof{pgf.gd.control.Anchoring} +\includeluadocumentationof{pgf.gd.control.Orientation} + + + +\includeluadocumentationof{pgf.gd.control.FineTune} + +\includeluadocumentationof{pgf.gd.control.Components} +\includeluadocumentationof{pgf.gd.control.ComponentOrder} +\includeluadocumentationof{pgf.gd.control.ComponentDirection} +\includeluadocumentationof{pgf.gd.control.ComponentAlign} +\includeluadocumentationof{pgf.gd.control.ComponentDistance} + +\includeluadocumentationof{pgf.gd.control.NodeAnchors} + +\includeluadocumentationof{pgf.gd.model.Hyperedge} + + +\subsection{Using Several Different Layouts to Draw a Single Graph} + +\label{section-gd-sublayouts} + +Inside each graph drawing scope, a main algorithm is used to perform +the graph drawing. However, parts of the graph may be drawn using +different algorithms: For instance, a graph might consist of +several, say, cliques that are arranged in a tree-like fashion. In +this case, it might be useful to layout each clique using a circular +layout, but then lay out all laid out cliques using a tree drawing +algorithm. + +In order to lay out a graph using multiple algorithms, we need two +things: First, we must be able to \emph{specify} which algorithms +should be used where and, second, we must be able to \emph{resolve} +conflicts that may result from different algorithms ``having different +ideas'' concerning where nodes should be placed. + + +\subsubsection{Sublayouts} + +Specifying different layouts for a graph is easy: Inside a graph +drawing scope, simply open scopes, in which you use an option like +|tree layout| for the nodes mentioned in this scope. Inside these +scopes, you can open even subscopes for sublayouts, and so +on. Furthermore, the |graphs| library has special support for +sublayouts. + +Let us start with the ``plain'' syntax for opening sublayouts: You +pass a key for creating layouts to a |scope|: + +\begin{codeexample}[] +\tikz [spring layout] { + \begin{scope}[tree layout] + \node (a) {a}; + \node (b) {b}; + \node (c) {c}; + \draw (a) edge (b) edge (c); + \end{scope} + + \begin{scope}[tree layout] + \node (1) {1}; + \node (2) {2}; + \draw (1) edge (2); + \end{scope} + + \draw (a) edge (1); +} +\end{codeexample} + +Let us see, what is going on here. The main layout (|spring layout|) +contains two sublayouts (the two |tree layouts|). Both of them are +laid out independently (more on the details in a moment). Then, from +the main layout's point of view, the sublayouts behave like ``large +nodes'' and, thus, the edge between |a| and |1| is actually the only +edge that is used by the |spring layout| -- resulting in a simple +layout consisting of one big node at the top and a big node at the +bottom. + +The |graphs| library has a special support for sublayouts: The syntax +is as follows: wherever a normal node would go, you can write + +\begin{quote} + |//| \opt{\oarg{layout options}} |{|\meta{sublayout}|}| +\end{quote} + +Following the double slash, you may provide +\meta{layout options} in square brackets. However, you \emph{must} +provide a sublayout in braces. The contents of \meta{sublayout} will +be parsed using the usual |graph| syntax, but will form a sublayout. + +\begin{codeexample}[] +\tikz \graph [spring layout] { + // [tree layout] { a -- {b, c} }; + // [tree layout] { 1 -- 2 }; + a -- 1; +}; +\end{codeexample} + + +In the above example, there is no node before the double slash, which +means that the two sublayouts will be part of the main graph, but will +not be indicated otherwise. + +\begin{codeexample}[] +\tikz \graph [simple necklace layout] { + // [simple necklace layout] { a -> b -> c -> d -> e -> f -> a }; + + // [tree layout] { % first tentacle + a -> {1, 2}; + }; + + // [tree layout] {% second tentacle + d -> {3, 4 -> {5, 6}} + }; +}; +\end{codeexample} + +In the above example, the first sublayout is the one for the nodes +with letter names. These nodes are arranged using a simple necklace layout +as the sublayout inherits this option from the main layout. The two +small trees (|a -> {1, 2}| and the tree starting at the |d| node) +are also sublayouts, triggered by the |tree layout| option. They are +also arranged. Then, all of the layouts are merged (as described +later). The result is actually a single node, so the main layout +does nothing here. + +Compare the above to the following code: + +\begin{codeexample}[] +\tikz \graph [simple necklace layout] { + // [tree layout] { % first ``giant node'' + a -> {1, 2}; + }; + + a -> b -> c -> d; + + // [tree layout] {% second ``giant node'' + d -> {3, 4 -> {5, 6}} + }, + + d -> e -> f -> a; +}; +\end{codeexample} + +Here, only the two trees are laid out first. They are then +contracted into ``giant nodes'' and these are then part of the set +of nodes that are arranged by the |simple necklace layout|. For details of +how this contracting works, see below. + + +\subsubsection{Subgraph Nodes} + +A \emph{subgraph node} is a special kind of node that ``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 available immediately as a normal node in +the sense that you can connect edges to it. + +The syntax used to declare a subgraph node in a |graph| specification +is as follows: + +\begin{quote} + \opt{|"|}\meta{node + name}\opt{|"|}\opt{|/|\opt{|"|}\meta{text}\opt{|"|}} + \opt{\oarg{node options}} + |//| \opt{\oarg{layout options}} |{|\meta{subgraph}|}| +\end{quote} + +The idea ist that a subgraph node is declared like a normal node +specification, but is followed by a double slash and a subgraph: + +\begin{codeexample}[width=5cm] +\tikz \graph [simple necklace layout] { + tree 1[draw, circle] // [tree layout] { a -> {1, 2}; } + -> b + -> c + -> tree 2[draw] // [tree layout] { d -> {3, 4 -> {5, 6} } } + -> e + -> f + -> tree 1; +}; +\end{codeexample} + +Note how the two subgraph nodes |tree 1| and |tree 2| surround the two +smaller trees. In the example, both had trees as contents and these +trees were rendered using a sublayout. However, a subgraph layout does +not need to have its own layout: If you do \emph{not} provide a layout +name after the double slash, the subgraph node will simply surround +all nodes that were placed by the main layout wherever they were +placed: + +\begin{codeexample}[] +\tikz [subgraph text bottom=text centered, + subgraph nodes={font=\itshape}] + \graph [tree layout] { + a -> { b -> {c, d}, e -> {f, g -> h} }; + + left [draw] // { b, c, d }; + right [draw] // { e, f, g, h}; + + left <-> right; + }; +\end{codeexample} + + + +Every time a subgraph node is created, the following style is execute: + +\begin{key}{/tikz/every subgraph node} + Set a subgraph node style. +\end{key} + +\begin{key}{/tikz/subgraph nodes=\meta{style}} + Sets the |every subgraph node| style to \meta{style}. +\begin{codeexample}[] +\tikz [subgraph text bottom=text centered, + subgraph nodes=red] + \graph [tree layout] { + a -> { b -> {c, d}, e -> {f, g -> h} }; + + left [draw] // { b, c, d }; + right [draw] // { e, f, g, h}; + + left <-> right; + }; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/subgraph text none} + When this option is used, the text of a subgraph node is not + shown. Adding a slash after the node name achieves roughly the same + effect, but this option is useful in situations when subgraph nodes + generally should not have any text inside them. +\begin{codeexample}[] +\tikz [subgraph text none] + \graph [tree layout] { + a -> { b -> {c, d}, e -> {f, g -> h} }; + + left [draw] // { b, c, d }; + right [draw] // { e, f, g, h}; + + left <-> right; + }; +\end{codeexample} + +\end{key} + +\begin{key}{/tikz/subgraph text top=\meta{text alignment + options} (default text ragged right)} + Specifies that the text of a subgraph node should be placed at the + top of the subgraph node: Still inside the node, but above all nodes + inside the subgraph node. +\begin{codeexample}[] +\tikz [subgraph text top=text ragged left] + \graph [tree layout] { + a -> { b -> {c, d}, e -> {f, g -> h} }; + + left [draw] // { b, c, d }; + right [draw] // { e, f, g, h}; + + left <-> right; + }; +\end{codeexample} + You can pass any of the \meta{text alignment options} understood by + \tikzname, such as |text centered|: +\begin{codeexample}[width=5cm] +\tikz [subgraph text top=text centered] + \graph [tree layout] { + a -> { b -> {c, d}, e -> {f, g -> h} }; + + left [draw, circle] // { b, c, d }; + }; +\end{codeexample} + To place a label \emph{outside} the subgraph node, use a label, + typically defined using the |quotes| library: +\begin{codeexample}[] +\tikz \graph [tree layout] { + a -> { b -> {c, d}, e -> {f, g -> h} }; + + / ["left", draw] // { b, c, d } <-> + / ["right", draw] // { e, f, g, h}; + }; +\end{codeexample} +\end{key} + + +\begin{key}{/tikz/subgraph text bottom=\meta{text alignment + options} (default ragged right)} + Works like |subgraph text top|, only the text placed at the bottom. +\end{key} + +Note that there are no keys |subgraph text left| or |... right|, +for somewhat technical reasons. + +\begin{key}{/tikz/subgraph text sep=\meta{dimension} (initially .1em)} + Some space added between the inner nodes of a subgraph node and the + text labels. +\end{key} + + +\subsubsection{Overlapping Sublayouts} + +\label{section-gd-layout-resolve} + +Nodes and edges can be part of several layouts. This +will inevitably lead to conflicts because algorithm will disagree on +where a node should be placed on the canvas. For this reason, there +are some rules governing how such conflicts are resolved: Given a +layout, starting with the main layout, the graph drawing system does +the following: + +\begin{enumerate} +\item We start by first processing the (direct) sublayouts of the + current layout (recursively). Sublayouts may overlap (they may share + one or more nodes), but we run the specified layout algorithm for + each sublayout independently on a ``fresh copy'' of all the nodes + making up the sublayout. In particular, different, conflicting + positions may be computed for nodes when they are present in several + sublayouts. +\item Once all nodes in the sublayouts have been laid out in this way, + we \emph{join} overlapping elements. The idea is that if two layouts + share exactly one vertex, we can shift them around so that his + vertex is at the same position in both layouts. In more detail, the + following happens: + + We build a (conceptual) graph whose nodes are the sublayouts and in + which there is an edge between two nodes if the sublayouts + represented by these elements have a node in common. + Inside the resulting graph, we treat each connected component + separately. Each component has the property that the sublayouts + represented by the nodes in the component overlap by at least one + node. We now \emph{join} them as follows: We start with the first + sublayout in the component (``first'' with respect to the order in + which they appear in the input graph) and ``mark'' this + sublayout. We loop the following instructions as long as possible: + Search for the first sublayout (again, with respect to the order in + which they appear in the input) that is connect by an edge to a + marked sublayout. The sublayout will now have at least one node in + common with the marked sublayouts (possibly, even more). We + consider the first such node (again, first respect to the input + ordering) and shift the whole sublayout is such a way that this + particular node is at the position is has in the marked + sublayouts. Note that after the shift, other nodes that are also + present in the marked sublayouts may lie at a different position in + the current sublayout. In this case, the position in the marked + sublayouts ``wins.'' We then mark the sublayout. +\item When the above algorithm has run, we will have computed + positions for all nodes in all sublayouts of each of the + components. For each component, we contract all + nodes of the component to a single node. This new + node will be ``large'' in the sense that its convex hull is the + convex hull of all the nodes in the component. All nodes that used + to be part of the component are removed and the new large node is + added (with arcs adjusted appropriately). +\item We now run the layout's algorithm on the resulting nodes + (the remaining original nodes and the contracted nodes). +\item In a last step, once the graph has been laid out, we expand the + nodes that were previously contracted. For this, the + nodes that were deleted earlier get reinserted, but shifted by + whatever amount the contraction node got shifted. +\end{enumerate} + + +\subsection{Miscellaneous Options} + +\includeluadocumentationof{pgf.gd.control.library} + +\endinput + diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-guidelines.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-guidelines.tex index 4436a3ab3fb..5a5a7b75957 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-guidelines.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-guidelines.tex @@ -26,13 +26,13 @@ repeat them in the following guidelines. The first thing you should ask yourself when someone presents a bunch of guidelines is: Should I really follow these guidelines? This is an -important questions, because there are good reasons not to follow -general guidelines. The person who setup the guidelines may have had other +important question, because there are good reasons not to follow +general guidelines. The person who set up the guidelines may have had other objectives than you do. For example, a guideline might say ``use the color red for emphasis.'' While this guideline makes perfect sense for, say, a presentation using a projector, red ``color'' has the \emph{opposite} effect of ``emphasis'' when printed using a -black-and-white printer. Guidelines were almost always setup to +black-and-white printer. Guidelines were almost always set up to address a specific situation. If you are not in this situation, following a guideline can do more harm than good. @@ -40,7 +40,7 @@ The second thing you should be aware of is the basic rule of typography is: ``Every rule can be broken, as long as you are \emph{aware} that you are breaking a rule.'' This rule also applies to graphics. Phrased differently, the basic rule states: ``The only -mistakes in typography are things done is ignorance.'' When you are +mistakes in typography are things done in ignorance.'' When you are aware of a rule and when you decide that breaking the rule has a desirable effect, break the rule. @@ -129,7 +129,7 @@ be inlined, meaning they are somewhere ``in the middle of the text'' or they can be placed in stand-alone ``figures.'' Since printers (the people) like to have their pages ``filled,'' (both for aesthetic and economic reasons) stand-alone figures may traditionally be placed on -pages in the document far removed from the main text that refers to +pages in the document far away from the main text that refers to them. \LaTeX\ and \TeX\ tend to encourage this ``drifting away'' of graphics for technical reasons. @@ -269,7 +269,7 @@ following guidelines: \item Labels should be legible. They should not only have a reasonably large size, they also should not be obscured by lines or other - text. This also applies to of lines and text \emph{behind} the + text. This also applies to labels of lines and text \emph{behind} the labels. \item Labels should be ``in place.'' Whenever there is enough space, @@ -297,7 +297,7 @@ default settings of programs like \textsc{gnuplot} or Excel are to blame for this since these programs make it very convenient to create bad plots. -The first question you should ask yourself when creating a plot is, +The first question you should ask yourself when creating a plot is: Are there enough data points to merit a plot? If the answer is ``not really,'' use a table. @@ -377,7 +377,7 @@ the graphic: Sadly, the graphic does not allow us to answer \emph{a single one of these questions}. The table answers all of them directly, except for the last one. In essence, the information density of the graphic is very -nearly zero. The table has a much higher information density; despite +close to zero. The table has a much higher information density; despite the fact that it uses quite a lot of white space to present a few numbers. Here is the list of things that went wrong with the 3D-bar diagram: \begin{itemize} @@ -707,7 +707,7 @@ Here is a non-exhaustive list of things that can distract readers: should be avoided in general. Do not use different dashing patterns to differentiate curves in - plots. You loose data points this way and the eye is not + plots. You lose data points this way and the eye is not particularly good at ``grouping things according to a dashing pattern.'' The eye is \emph{much} better at grouping things according to colors. @@ -716,7 +716,7 @@ Here is a non-exhaustive list of things that can distract readers: horizontal and vertical lines or just dots are almost always distracting and, usually, serve no real purpose. \item - Background images and shadings distract and only seldom add + Background images and shadings distract and only seldomly add anything of importance to a graphic. \item Cute little clip arts can easily draw attention away from the diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-installation.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-installation.tex index 97c2968088b..af964feedac 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-installation.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-installation.tex @@ -11,7 +11,7 @@ There are different ways of installing \pgfname, depending on your system and needs, and you may need to install other -packages as well as, see below. Before installing, you may wish to +packages as well, see below. Before installing, you may wish to review the licenses under which the package is distributed, see Section~\ref{section-license}. @@ -37,18 +37,24 @@ get its (full) functionality. Currently, \pgfname\ supports the following backend drivers: \begin{itemize} \item + |luatex| version 0.76 or higher. Most earlier versions also work. +\item |pdftex| version 0.14 or higher. Earlier versions do not work. \item |dvips| version 5.94a or higher. Earlier versions may also work. - For inter-picture connections, you need process pictures using + For inter-picture connections, you need to process pictures using |pdftex| version 1.40 or higher running in DVI mode. \item |dvipdfm| version 0.13.2c or higher. Earlier versions may also work. - For inter-picture connections, you need process pictures using + For inter-picture connections, you need to process pictures using |pdftex| version 1.40 or higher running in DVI mode. \item + |dvipdfmx| version 0.13.2c or higher. Earlier versions may also work. +\item + |dvisvgm| version 1.2.2 or higher. Earlier versions may also work. +\item |tex4ht| version 2003-05-05 or higher. Earlier versions may also work. \item |vtex| version 8.46a or higher. Earlier versions may also work. @@ -66,9 +72,7 @@ Currently, \pgfname\ supports the following formats: |plain| with complete functionality, except for graphics inclusion, which works only for pdf\TeX. \item - |context| with complete functionality\footnote{Note that - \pgfname/\tikzname{} is not supported by recent Con\TeX t versions - (like mark IV, the Lua\TeX-aware part of Con\TeX t).}, except for + |context| with complete functionality, except for graphics inclusion, which works only for pdf\TeX. \end{itemize} @@ -89,12 +93,7 @@ MiK\TeX\ page first. \subsubsection{Debian} The command ``|aptitude install pgf|'' should do the trick. Sit back -and relax. In detail, the following packages are installed: -\begin{verbatim} -http://packages.debian.org/pgf -http://packages.debian.org/latex-xcolor -\end{verbatim} - +and relax. \subsubsection{MiKTeX} @@ -187,6 +186,6 @@ with the files of the new version (or in all the directories where |pgf| was installed, if you chose a \textsc{tds}-compliant installation). The easiest way to do this is to first delete the old version and then proceed as described above. Sometimes, there are -changes in the syntax of certain command from version to version. If +changes in the syntax of certain commands from version to version. If things no longer work that used to work, you may wish to have a look at the release notes and at the change log. diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-introduction.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-introduction.tex index 7db4aa68733..ece53e719e6 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-introduction.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-introduction.tex @@ -10,29 +10,48 @@ \section{Introduction} -The \pgfname\ package, where ``\pgfname'' is supposed to mean ``portable -graphics format'' (or ``pretty, good, functional'' if you -prefer\dots), is a package for creating graphics in an ``inline'' -manner. It defines a number of \TeX\ commands that draw +Welcome to the documentation of \tikzname\ and the underlying +\pgfname\ system. What began as a small La\TeX\ style for creating the +graphics in my (Till Tantau's) PhD thesis directly with pdf\LaTeX\ has now +grown to become a full-flung graphics language with a manual of over a +thousand pages. The wealth of options offered by \tikzname\ is often +daunting to beginners; but fortunately this documentation comes with a +number slowly-paced tutorials that will teach you almost all you +should know about \tikzname\ without your having to read the rest. + +I wish to start with the questions ``What is \tikzname?'' +Basically, it just defines a number of \TeX\ commands that draw graphics. For example, the code |\tikz \draw (0pt,0pt) -- (20pt,6pt);| yields the line \tikz \draw (0pt,0pt) -- (20pt,6pt); and the code |\tikz \fill[orange] (1ex,1ex) circle (1ex);| yields \tikz -\fill[orange] (1ex,1ex) circle (1ex);. - -In a sense, when you use \pgfname\ you ``program'' your graphics, just -as you ``program'' your document when you use \TeX. You get all -the advantages of the ``\TeX-approach to typesetting'' for your -graphics: quick creation of simple graphics, precise positioning, the -use of macros, often superior typography. You also inherit all the -disadvantages: steep learning curve, no \textsc{wysiwyg}, small -changes require a long recompilation time, and the code does not -really ``show'' how things will look like. - - - -\subsection{Structure of the System} - -The \pgfname\ system consists of different layers: +\fill[orange] (1ex,1ex) circle (1ex);. In a sense, when you use +\tikzname\ you ``program'' your graphics, just as you ``program'' your +document when you use \TeX. This also explains the name: \tikzname\ +is a recursive accronym in the tradition of ``\textsc{gnu} is not +unix'' and means ``\tikzname\ ist \emph{kein} Zeichenprogramm,'' which +translates to ``\tikzname\ is not a drawing program,'' cautioning the +reader as to what to expect. With \tikzname\ you get all the advantages of the +``\TeX-approach to typesetting'' for your graphics: quick creation of +simple graphics, precise positioning, the use of macros, often +superior typography. You also inherit all the disadvantages: steep +learning curve, no \textsc{wysiwyg}, small changes require a long +recompilation time, and the code does not really ``show'' how things +will look like. + +Now that we know what \tikzname\ is, what about ``\pgfname''? +As mentioned earlier, \tikzname\ started out as a project to implement +\TeX\ graphics macros that can be used both with pdf\LaTeX\ and also +with the classical (PostScript-based) \LaTeX. In other words, I wanted +to implement a ``portable graphics format'' for \TeX\ -- hence the +name \pgfname. These early macros are still around and they form the +``basic layer'' of the system described in this manual, but most of +the interaction an author has theses days is with \tikzname\ -- which +has become a whole language of its own. + + +\subsection{The Layers Below \tikzname} + +It turns out that there are actually \emph{two} layers below \tikzname: \begin{description} \item[System layer:] This layer provides a complete abstraction of what is @@ -59,74 +78,62 @@ The \pgfname\ system consists of different layers: you to produce complex graphics in a much easier manner than by using the system layer directly. For example, the system layer provides no commands for creating circles since circles can be composed from - the more basic Bézier curves (well, almost). However, as a user you + the more basic B\'ezier curves (well, almost). However, as a user you will want to have a simple command to create circles (at least I do) instead of having to write down half a page of - Bézier curve support coordinates. Thus, the basic layer provides a + B\'ezier curve support coordinates. Thus, the basic layer provides a command |\pgfpathcircle| that generates the necessary curve coordinates for you. - The basic layer is consists of a \emph{core}, which consists of + The basic layer consists of a \emph{core}, which consists of several interdependent packages that can only be loaded \emph{en bloc,} and additional \emph{modules} that extend the core by more special-purpose commands like node management or a plotting interface. For instance, the \textsc{beamer} package uses only the core and not, say, the |shapes| modules. -\item[Frontend layer:] - A frontend (of which there can be several) is a set of commands - or a special syntax that makes using the basic layer easier. A - problem with directly using the basic layer is that code written for - this layer is often too ``verbose.'' For example, to draw a simple - triangle, you may need as many as five commands when using the basic - layer: One for beginning a path at the first corner of the triangle, - one for extending the path to the second corner, one for going to - the third, one for closing the path, and one for actually painting - the triangle (as opposed to filling it). With the |tikz| frontend - all this boils down to a single simple \textsc{metafont}-like - command: +\end{description} + +In theory, \tikzname itself is just one of several possible +``frontends,'' which are sets of commands or a special syntax that +makes using the basic layer easier. A problem with directly using the +basic layer is that code written for this layer is often too +``verbose.'' For example, to draw a simple +triangle, you may need as many as five commands when using the basic +layer: One for beginning a path at the first corner of the triangle, +one for extending the path to the second corner, one for going to +the third, one for closing the path, and one for actually painting +the triangle (as opposed to filling it). With the \tikzname\ frontend +all this boils down to a single simple \textsc{metafont}-like +command: \begin{verbatim} \draw (0,0) -- (1,0) -- (1,1) -- cycle; \end{verbatim} - There are different frontends: - \begin{itemize} - \item - The \tikzname\ frontend is the ``natural'' frontend for \pgfname. It gives - you access to all features of \pgfname, but it is intended to be - easy to use. The syntax is a mixture of \textsc{metafont} and - \textsc{pstricks} and some ideas of myself. This frontend is % TODOsp: change all `pstricks' to `PStricks'? (ff) - \emph{neither} a complete \textsc{metafont} compatibility layer nor - a \textsc{pstricks} compatibility layer and it is not intended to - become either. - \item - The |pgfpict2e| frontend reimplements the standard \LaTeX\ - |{picture}| environment and commands like |\line| or |\vector| - using the \pgfname\ basic layer. This layer is not really ``necessary'' - since the |pict2e.sty| package does at least as good a job at - reimplementing the |{picture}| environment. Rather, the idea - behind this package is to have a simple demonstration of how a - frontend can be implemented. - \end{itemize} - - It would be possible to implement a |pgftricks| frontend that maps - \textsc{pstricks} commands to \pgfname\ commands. However, I have not - done this and even if fully implemented, many things that work in - \pstricks\ will not work, namely whenever some \pstricks\ command - relies too heavily on PostScript trickery. Nevertheless, such a - package might be useful in some situations. -\end{description} - -As a user of \pgfname\ you will use the commands of a -frontend plus perhaps some commands of the basic layer. For this -reason, this manual explains the frontends first, then the basic -layer, and finally the system layer. - +In practice, \tikzname\ is the only ``serious'' frontend for \pgfname. It +gives you access to all features of \pgfname, but it is intended to be +easy to use. The syntax is a mixture of \textsc{metafont} and +\textsc{pstricks} and some ideas of myself. There are other frontends +besides \tikzname, but they are more intended as ``technology +studies'' and less as serious alternatives to \tikzname. In +particular, the |pgfpict2e| frontend reimplements the standard +\LaTeX\ |{picture}| environment and +commands like |\line| or |\vector| +using the \pgfname\ basic layer. This layer is not really ``necessary'' +since the |pict2e.sty| package does at least as good a job at +reimplementing the |{picture}| environment. Rather, the idea +behind this package is to have a simple demonstration of how a +frontend can be implemented. + +Since most users will only use \tikzname\ and almost no one will use +the system layer directly, this manual is mainly about \tikzname\ in +the first parts; the basic layer and the system layer are explained at +the end. \subsection{Comparison with Other Graphics Packages} -\pgfname\ is not the only graphics package for \TeX. In the following, -I try to give a reasonably fair comparison of the \pgfname-system and +\tikzname\ is not the only graphics package for \TeX. In the following, +I try to give a reasonably fair comparison of \tikzname\ and other packages. \begin{enumerate} \item @@ -138,48 +145,38 @@ other packages. backend drivers. \item The |pstricks| package is certainly powerful enough to create - any conceivable kind of graphic, but it is not portable at all. Most + any conceivable kind of graphic, but it is not really portable. Most importantly, it does not work with |pdftex| nor with any other driver that produces anything but PostScript code. - Compared to \pgfname, |pstricks| has a broader support base. There + Compared to \tikzname, |pstricks| has a similar support base. There are many nice extra packages for special purpose situations that have been contributed by users over the last decade. - The \tikzname\ syntax is more consistent than the |pstricks| syntax as \tikzname\ was developed ``in a more centralized manner'' and also ``with the shortcomings on |pstricks| in mind.'' - - Note that a number of neat tricks that |pstricks| can do are - impossible in \pgfname. In particular, |pstricks| has access to the - powerful PostScript programming language, which allows trickery - such as inline function plotting. \item The |xypic| package is an older package for creating graphics. However, it is more difficult to use and to learn because the syntax and the documentation are a bit cryptic. \item The |dratex| package is a small graphic package for creating a - graphics. Compared to the other package, including \pgfname, it is + graphics. Compared to the other package, including \tikzname, it is very small, which may or may not be an advantage. \item - The |metapost| program is a very powerful alternative to - \pgfname. However, it is an external program, which entails a - bunch of problems. The time needed both to create a small graphic - and also to compile it is much greater than in \pgfname. - The main problem with |metapost|, however, is the inclusion of - labels. This is \emph{much} easier to achieve using \pgfname. + The |metapost| program is a powerful alternative to + \tikzname. It used to be an external program, which entailed a + bunch of problems, but in Lua\TeX\ it is now build in. An obstacle + with |metapost| is the inclusion of labels. This is \emph{much} + easier to achieve using \pgfname. \item The |xfig| program is an important alternative to \tikzname\ for users who do not wish to ``program'' their graphics as is necessary - with \tikzname\ and the other packages above. Their is a conversion - program that will convert |xfig| graphics to both \tikzname\ and - for \pgfname, but it is still under construction. + with \tikzname\ and the other packages above. There is a conversion + program that will convert |xfig| graphics to \tikzname. \end{enumerate} - - \subsection{Utility Packages} The \pgfname\ package comes along with a number of utility package that @@ -215,20 +212,20 @@ closely intertwined with \pgfname. These utility packages are: \subsection{How to Read This Manual} -This manual describes both the design of the \pgfname\ system and -its usage. The organization is very roughly according to +This manual describes both the design of \tikzname\ and +its usage. The organization is very roughly according to ``user-friendliness.'' The commands and subpackages that are easiest and most frequently used are described first, more low-level and esoteric features are discussed later. -If you have not yet installed \pgfname, please read the installation +If you have not yet installed \tikzname, please read the installation first. Second, it might be a good idea to read the tutorial. Finally, you might wish to skim through the description of \tikzname. Typically, you will not need to read the sections on the basic layer. You will only need to read the part on the system layer if you intend to write your own frontend or if you wish to port \pgfname\ to a new driver. -The ``public'' commands and environments provided by the |pgf| package +The ``public'' commands and environments provided by the system are described throughout the text. In each such description, the described command, environment or option is printed in red. Text shown in green is optional and can be left out. @@ -289,7 +286,4 @@ following: somewhat higher if you mail to the \pgfname\ mailing list (naturally, I read this list and answer questions when I have the time). -\item - Please, do not phone me in my office (unless, of course, you attend - one of my lectures). \end{enumerate} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-angles.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-angles.tex new file mode 100644 index 00000000000..c46a6e4204b --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-angles.tex @@ -0,0 +1,89 @@ +% Copyright 2006 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + +\section{Angle Library} + +\label{section-angle} + +\begin{tikzlibrary}{angles} + This library defines pic types for drawing angles. +\end{tikzlibrary} + +\begin{pictype}{angle}{\opt{|=|\meta{A}|--|\meta{B}|--|\meta{C}}} + This pic adds a drawing of an angle to the current path. This + ``drawing of an angle'' consist of a ``sector'' or ``wedge'' or + ``slice'' whose pointed end is at point \meta{B} and whose straight + sides lie on the lines form \meta{B} to \meta{A} and from \meta{B} + to \meta{C}. The length of these lines is governed by the following + key: + \begin{key}{/tikz/angle radius=\meta{dimension} (initially 5mm)} + The length of the sides of the angle's wedge: +\begin{codeexample}[] +\tikz \draw (2,0) coordinate (A) -- (0,0) coordinate (B) + -- (-1,-1) coordinate (C) + pic [fill=black!50] {angle = A--B--C} + pic [draw,->,red,thick,angle radius=1cm] {angle = C--B--A}; +\end{codeexample} + \end{key} + + The three points \meta{A}, \meta{B}, and \meta{C} \emph{must} be the + names of nodes or coordinates; you cannot use direct coordinates like + ``|(1,1)|'' here. + + You can leave out the three points, in this case the text |A--B--C| + is used; so in the above examples we could just have written + |{angle}| in the first pic. + + Concerning the sector that makes up the drawing of the angle, the + angular part of this sector is drawn in front of the path if the + |draw| option is given to the |pic|, while filled sector is drawn + behind the |pic|, provided an option like |fill| or |shade| is + passed to the pic. The following example shows the difference: + +\begin{codeexample}[] +\tikz \draw [line width=2mm] + (2,0) coordinate (A) -- (0,0) coordinate (B) + -- (1,1) coordinate (C) + pic [draw=blue, fill=blue!50, angle radius=1cm] {angle}; +\end{codeexample} + + When |pic text| is set (which you typically do by using the quotes + syntax), a node will be created whose name is empty + (and, thus, inherits the pic's name) and which will be at the + half-way angle between the lines to \meta{A} and \meta{C} and whose + distance from \meta{B} is |angle radius| times the following factor: + \begin{key}{/tikz/angle eccentricity=\meta{factor} (initially 0.6)} +\begin{codeexample}[] +\tikz \draw (2,0) coordinate (A) -- (0,0) coordinate (B) + -- (1,1) coordinate (C) + pic ["$\alpha$", draw, ->] {angle}; +\end{codeexample} +\begin{codeexample}[] +\tikz \draw (2,0) coordinate (A) -- (0,0) coordinate (B) + -- (1,1) coordinate (C) + pic ["$\alpha$", draw, angle eccentricity=1] {angle}; +\end{codeexample} +\begin{codeexample}[] +\tikz { + \draw (2,0) coordinate (A) -- (0,0) coordinate (B) + -- (1,1) coordinate (C) + pic (alpha) ["$\alpha$", draw] {angle}; + + \draw (alpha) circle [radius=5pt]; +} +\end{codeexample} + \end{key} +\end{pictype} + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "pgfmanual-pdftex-version" +%%% End: diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-arrows.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-arrows.tex index da4523a9ff1..6db5b1002ac 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-arrows.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-arrows.tex @@ -11,147 +11,235 @@ \section{Arrow Tip Library} \label{section-library-arrows} -\begin{pgflibrary}{arrows} - The package defines additional arrow tips, which are described - below. Note that neither the standard packages nor - this package defines an arrow name containing |>| or |<|. These are - left for the user to defined as he or she sees fit. -\end{pgflibrary} - -The arrow tips |to|, |stealth|, |latex|, |space|, their reversed -forms, and \verb!|! are predefined, but listed below for completeness, -nevertheless. - - -\subsection{Mathematical Arrow Tips} - -\begin{tabular}{ll} - \symarrow{to} \\ - \symarrow{to reversed} \\ - \symarrowdouble{implies} \\ -\end{tabular} - - -\subsection{Triangular Arrow Tips} - -\begin{tabular}{ll} - \symarrowdouble{latex} \\ - \symarrowdouble{latex reversed} \\ - \symarrow{latex'} \\ - \symarrow{latex' reversed} \\ - \symarrowdouble{stealth} \\ - \symarrowdouble{stealth reversed} \\ - \symarrow{stealth'} \\ - \symarrow{stealth' reversed}\\ - \symarrow{triangle 90} \\ - \symarrow{triangle 90 reversed} \\ - \symarrow{triangle 60} \\ - \symarrow{triangle 60 reversed} \\ - \symarrow{triangle 45} \\ - \symarrow{triangle 45 reversed} \\ - \symarrow{open triangle 90} \\ - \symarrow{open triangle 90 reversed} \\ - \symarrow{open triangle 60} \\ - \symarrow{open triangle 60 reversed} \\ - \symarrow{open triangle 45} \\ - \symarrow{open triangle 45 reversed} \\ -\end{tabular} - - -\subsection{Barbed Arrow Tips} - -\begin{tabular}{ll} - \symarrow{angle 90} \\ - \symarrow{angle 90 reversed} \\ - \symarrow{angle 60} \\ - \symarrow{angle 60 reversed} \\ - \symarrow{angle 45} \\ - \symarrow{angle 45 reversed} \\ - \symarrow{hooks} \\ - \symarrow{hooks reversed} \\ -\end{tabular} - - -\subsection{Bracket-Like Arrow Tips} - -{ -\bigskip -\catcode`\|=12 -\begin{tabular}{ll} - \sarrow{[}{]} \\ - \sarrow{]}{[} \\ - \sarrow{(}{)} \\ - \sarrow{)}{(} \\ - \index{*vbar@\protect\texttt{\protect\myvbar} arrow tip}% - \index{Arrow tips!*vbar@\protect\texttt{\protect\myvbar}} - \texttt{\char`\|-\char`\|} & yields thick - \begin{tikzpicture}[arrows={|-|},thick] - \useasboundingbox (0pt,-0.5ex) rectangle (1cm,2ex); - \draw (0,0) -- (1,0); - \end{tikzpicture} and thin - \begin{tikzpicture}[arrows={|-|},thin] - \useasboundingbox (0pt,-0.5ex) rectangle (1cm,2ex); - \draw (0,0) -- (1,0); - \end{tikzpicture} -\end{tabular} -} - -\subsection{Circle, Diamond and Square Arrow Tips} - - -\begin{tabular}{ll} - \symarrow{o} \\ - \symarrow{*} \\ - \symarrow{diamond} \\ - \symarrow{open diamond} \\ - \symarrow{square} \\ - \symarrow{open square} \\ -\end{tabular} - - - -\subsection{Serif-Like Arrow Tips} - -\begin{tabular}{ll} - \symarrow{serif cm} -\end{tabular} - - -\subsection{Partial Arrow Tips} - -\begin{tabular}{ll} - \symarrow{left to} \\ - \symarrow{left to reversed} \\ - \symarrow{right to} \\ - \symarrow{right to reversed} \\ - \symarrow{left hook} \\ - \symarrow{left hook reversed} \\ - \symarrow{right hook} \\ - \symarrow{right hook reversed} -\end{tabular} - - - -\subsection{Line Caps} - -\begin{tabular}{ll} - \carrow{round cap} \\ - \carrow{butt cap} \\ - \carrow{triangle 90 cap} \\ - \carrow{triangle 90 cap reversed} \\ - \carrow{fast cap} \\ - \carrow{fast cap reversed} \\ -\end{tabular} - - -\subsection{Spacing Tips} - -The spacing arrow tips are useful for combining them with other arrows -to get arrows that do not touch the end of the line. - -\begin{tabular}{ll} - \symarrow{space} \\ -\end{tabular} +The libraries |arrows| and |arrows.spaced| from older +versions of \pgfname\ are still available for compatibility, but they +are considered deprecated. + +The standard arrow tips, which are loaded by the library +|arrows.meta|, are documented in Section~\ref{section-arrows-meta}. + +\endinput + + +% \subsection{Mathematical Arrow Tips} + +% \begin{tabular}{ll} +% \symarrow{to} \\ +% \symarrow{to reversed} \\ +% \symarrowdouble{implies} \\ +% \symarrow{spaced to} \\ +% \symarrow{spaced to reversed} \\ +% \symarrowdouble{spaced implies} \\ +% \end{tabular} + + +% \subsection{Triangular Arrow Tips} + +% \begin{tabular}{ll} +% \symarrowdouble{latex} \\ +% \symarrowdouble{latex reversed} \\ +% \symarrow{latex'} \\ +% \symarrow{latex' reversed} \\ +% \symarrowdouble{stealth} \\ +% \symarrowdouble{stealth reversed} \\ +% \symarrow{stealth'} \\ +% \symarrow{stealth' reversed}\\ +% \symarrow{triangle 90} \\ +% \symarrow{triangle 90 reversed} \\ +% \symarrow{triangle 60} \\ +% \symarrow{triangle 60 reversed} \\ +% \symarrow{triangle 45} \\ +% \symarrow{triangle 45 reversed} \\ +% \symarrow{open triangle 90} \\ +% \symarrow{open triangle 90 reversed} \\ +% \symarrow{open triangle 60} \\ +% \symarrow{open triangle 60 reversed} \\ +% \symarrow{open triangle 45} \\ +% \symarrow{open triangle 45 reversed} \\ +% \end{tabular} + +% \medskip +% \noindent +% \begin{tabular}{ll} +% \symarrowdouble{spaced latex} \\ +% \symarrowdouble{spaced latex reversed} \\ +% \symarrow{spaced latex'} \\ +% \symarrow{spaced latex' reversed} \\ +% \symarrowdouble{spaced stealth} \\ +% \symarrowdouble{spaced stealth reversed} \\ +% \symarrow{spaced stealth'} \\ +% \symarrow{spaced stealth' reversed}\\ +% \end{tabular} + +% \medskip +% \noindent +% \begin{tabular}{ll} +% \symarrow{spaced triangle 90} \\ +% \symarrow{spaced triangle 90 reversed} \\ +% \symarrow{spaced triangle 60} \\ +% \symarrow{spaced triangle 60 reversed} \\ +% \symarrow{spaced triangle 45} \\ +% \symarrow{spaced triangle 45 reversed} \\ +% \symarrow{spaced open triangle 90} \\ +% \symarrow{spaced open triangle 90 reversed} \\ +% \symarrow{spaced open triangle 60} \\ +% \symarrow{spaced open triangle 60 reversed} \\ +% \symarrow{spaced open triangle 45} \\ +% \symarrow{spaced open triangle 45 reversed} \\ +% \end{tabular} + + +% \subsection{Barbed Arrow Tips} + +% \begin{tabular}{ll} +% \symarrow{angle 90} \\ +% \symarrow{angle 90 reversed} \\ +% \symarrow{angle 60} \\ +% \symarrow{angle 60 reversed} \\ +% \symarrow{angle 45} \\ +% \symarrow{angle 45 reversed} \\ +% \symarrow{hooks} \\ +% \symarrow{hooks reversed} \\ +% \end{tabular} + +% \medskip +% \noindent +% \begin{tabular}{ll} +% \symarrow{spaced angle 90} \\ +% \symarrow{spaced angle 90 reversed} \\ +% \symarrow{spaced angle 60} \\ +% \symarrow{spaced angle 60 reversed} \\ +% \symarrow{spaced angle 45} \\ +% \symarrow{spaced angle 45 reversed} \\ +% \symarrow{spaced hooks} \\ +% \symarrow{spaced hooks reversed} \\ +% \end{tabular} + + +% \subsection{Bracket-Like Arrow Tips} + +% { +% \bigskip +% \catcode`\|=12 +% \begin{tabular}{ll} +% \sarrow{[}{]} \\ +% \sarrow{]}{[} \\ +% \sarrow{(}{)} \\ +% \sarrow{)}{(} \\ +% \index{*vbar@\protect\texttt{\protect\myvbar} arrow tip}% +% \index{Arrow tips!*vbar@\protect\texttt{\protect\myvbar}}% +% \texttt{\char`\|-\char`\|} & yields thick +% \begin{tikzpicture}[arrows={|-|},thick] +% \useasboundingbox (-1mm,-0.5ex) rectangle (1.1cm,2ex); +% \fill [black!15] (1cm,-.5ex) rectangle (1.1cm,1.5ex) (-1mm,-.5ex) rectangle (0mm,1.5ex) ; +% \draw (0pt,.5ex) -- (1cm,.5ex); +% \end{tikzpicture} and thin +% \begin{tikzpicture}[arrows={|-|},thin] +% \useasboundingbox (-1mm,-0.5ex) rectangle (1.1cm,2ex); +% \fill [black!15] (1cm,-.5ex) rectangle (1.1cm,1.5ex) (-1mm,-.5ex) rectangle (0mm,1.5ex) ; +% \draw (0pt,.5ex) -- (1cm,.5ex); +% \end{tikzpicture}\\ +% \sarrow{spaced [}{spaced ]} \\ +% \sarrow{spaced ]}{spaced [} \\ +% \sarrow{spaced (}{spaced )} \\ +% \sarrow{spaced )}{spaced (} \\ +% \index{*spaced vbar@\protect\texttt{spaced \protect\myvbar} arrow tip}% +% \index{Arrow tips!*spaced vbar@\protect\texttt{spaced \protect\myvbar}}% +% \texttt{spaced \char`\|-spaced \char`\|} & yields thick +% \begin{tikzpicture}[arrows={spaced |-spaced |},thick] +% \useasboundingbox (-1mm,-0.5ex) rectangle (1.1cm,2ex); +% \fill [black!15] (1cm,-.5ex) rectangle (1.1cm,1.5ex) (-1mm,-.5ex) rectangle (0mm,1.5ex) ; +% \draw (0pt,.5ex) -- (1cm,.5ex); +% \end{tikzpicture} and thin +% \begin{tikzpicture}[arrows={spaced |-spaced |},thin] +% \useasboundingbox (-1mm,-0.5ex) rectangle (1.1cm,2ex); +% \fill [black!15] (1cm,-.5ex) rectangle (1.1cm,1.5ex) (-1mm,-.5ex) rectangle (0mm,1.5ex) ; +% \draw (0pt,.5ex) -- (1cm,.5ex); +% \end{tikzpicture} +% \end{tabular} +% } + +% \subsection{Circle, Diamond and Square Arrow Tips} + + +% \begin{tabular}{ll} +% \symarrow{o} \\ +% \symarrow{*} \\ +% \symarrow{diamond} \\ +% \symarrow{open diamond} \\ +% \symarrow{square} \\ +% \symarrow{open square} \\ +% \end{tabular} + + +% \medskip +% \noindent +% \begin{tabular}{ll} +% \symarrow{spaced o} \\ +% \symarrow{spaced *} \\ +% \symarrow{spaced diamond} \\ +% \symarrow{spaced open diamond} \\ +% \symarrow{spaced square} \\ +% \symarrow{spaced open square} \\ +% \end{tabular} + + +% \subsection{Serif-Like Arrow Tips} + +% \begin{tabular}{ll} +% \symarrow{serif cm} \\ +% \symarrow{spaced serif cm} +% \end{tabular} + + +% \subsection{Partial Arrow Tips} + +% \begin{tabular}{ll} +% \symarrow{left to} \\ +% \symarrow{left to reversed} \\ +% \symarrow{right to} \\ +% \symarrow{right to reversed} \\ +% \symarrow{left hook} \\ +% \symarrow{left hook reversed} \\ +% \symarrow{right hook} \\ +% \symarrow{right hook reversed}\\ +% \symarrow{spaced left to} \\ +% \symarrow{spaced left to reversed} \\ +% \symarrow{spaced right to} \\ +% \symarrow{spaced right to reversed} \\ +% \symarrow{spaced left hook} \\ +% \symarrow{spaced left hook reversed} \\ +% \symarrow{spaced right hook} \\ +% \symarrow{spaced right hook reversed} +% \end{tabular} + + +% \subsection{Line Caps} + +% \begin{tabular}{ll} +% \carrow{round cap} \\ +% \carrow{butt cap} \\ +% \carrow{triangle 90 cap} \\ +% \carrow{triangle 90 cap reversed} \\ +% \carrow{fast cap} \\ +% \carrow{fast cap reversed} \\ +% \carrow{spaced round cap} \\ +% \carrow{spaced butt cap} \\ +% \carrow{spaced triangle 90 cap} \\ +% \carrow{spaced triangle 90 cap reversed} \\ +% \carrow{spaced fast cap} \\ +% \carrow{spaced fast cap reversed} \\ +% \end{tabular} + + +% \subsection{Spacing Tips} + +% The spacing arrow tips are useful for combining them with other arrows +% to get arrows that do not touch the end of the line. + +% \begin{tabular}{ll} +% \symarrow{space} \\ +% \end{tabular} %%% Local Variables: diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-automata.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-automata.tex index 2684d96c71d..48afc09ca87 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-automata.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-automata.tex @@ -41,7 +41,7 @@ To draw an automaton, proceed as follows: \end{enumerate} Let us now see how this works for a real example. Let us consider a -nondeterministic four state automaton that checks whether an contains +nondeterministic four state automaton that checks whether an input contains the sequence $0^*1$ or the sequence $1^*0$. \begin{codeexample}[] \begin{tikzpicture}[shorten >=1pt,node distance=2cm,on grid,auto] @@ -71,7 +71,7 @@ desired kind of styles. By default, the following state styles are defined: \begin{stylekey}{/tikz/state without output} - This node style causes nodes to be drawn circles. Also, this style + This node style causes nodes to be drawn as circles. Also, this style calls |every state|. \end{stylekey} @@ -147,7 +147,7 @@ Let us start with the initial states. Set the place where the text should be shown. Allowed values are |above|, |below|, |left|, and |right|. \end{key} - \begin{key}{/tikz/intial distance=\meta{distance} (initially 3ex)} + \begin{key}{/tikz/initial distance=\meta{distance} (initially 3ex)} Sets the length of the arrow leading from the text to the state node. \end{key} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-backgrounds.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-backgrounds.tex index ed7ed14b624..2b79d042e58 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-backgrounds.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-backgrounds.tex @@ -23,21 +23,23 @@ The first use of this library is to make the following key available: -\begin{key}{/tikz/on background layer} - This key can be used with a |{scope}|. It will cause everything - inside the scope to be typeset on a background layer. Note that the - scope should not be ``deeply nested'' inside the picture since - changes to the graphic state (like the color or the transformation - matrix) ``do not survive a layer switch.'' For more details on - layers see Section~\ref{section-layers}. +\begin{key}{/tikz/on background layer=\meta{options}} + This key can (only) be used with a |{scope}| or |\scoped|. It will + cause everything inside the scope to be typeset on a background + layer. + + The \meta{options} will be executed \emph{inside} background + scope. This is useful since \emph{other} options passed to the + |{scope}| environment will be executed \emph{before} the actual + background material starts and, thus, will have no effect on it. \begin{codeexample}[] \begin{tikzpicture} % On main layer: \fill[blue] (0,0) circle (1cm); - \begin{scope}[on background layer] - \fill[yellow] (-1,-1) rectangle (1,1); + \begin{scope}[on background layer={color=yellow}] + \fill (-1,-1) rectangle (1,1); \end{scope} \begin{scope}[on background layer] @@ -48,6 +50,34 @@ The first use of this library is to make the following key available: \fill[blue!50] (-.5,-1) rectangle (.5,1); \end{tikzpicture} \end{codeexample} + + A scope with this option set should not be ``deeply nested'' inside + the picture since changes to the graphic state (like the color or + the transformation matrix) ``do not survive a layer switch,'' see + also Section~\ref{section-layers} for details. In particular, + setting, say, the line width at the beginning of a picture will not + have an effect on the background picture. + + For this reason, it may be useful to setup the following style: + \begin{stylekey}{/tikz/every on background layer} + This style is executed at the beginning of each background + layer. If you have a global setup in |every picture|, you should + consider putting that part of it that concerns the graphics state + into this style. + +\begin{codeexample}[] +\tikzset{ + every picture/.style={line width=1ex}, + every on background layer/.style={every picture} +} +\begin{tikzpicture} + \draw [->] (0,0) -- (2,1); + + \scoped[on background layer] + \draw[red] (0,1) -- (2,0); +\end{tikzpicture} +\end{codeexample} + \end{stylekey} \end{key} When this package is loaded, the following styles become available: diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-calendar.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-calendar.tex index a61feb19de7..f0e2e8c8e1c 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-calendar.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-calendar.tex @@ -107,7 +107,7 @@ environments (similar to, say, the |\draw| command). \medskip \textbf{Changing the spacing.} In the above calendar, the spacing between the days is determined by - the numerous options. Most arrangement do not use all of these + numerous options. Most arrangements do not use all of these options, but only those that apply naturally. \begin{key}{/tikz/day xshift=\meta{dimension} (initially 3.5ex)} Specifies the @@ -178,7 +178,7 @@ environments (similar to, say, the |\draw| command). \textbf{Changing the appearance of days.} As mentioned before, each day in the above calendar is produced by an execution of the |\tikzdaycode|. Each time this code is executed, - the coordinate system will have been setup appropriately to place + the coordinate system will have been set up appropriately to place the day of the month correctly. You can change both the code and its appearance using the following options. \begin{key}{/tikz/day code=\meta{code} (initially \normalfont see below)} @@ -246,7 +246,7 @@ environments (similar to, say, the |\draw| command). \end{codeexample} \end{key} - \begin{stylekey}{/tikz/every day (initially anchor=base east)} + \begin{key}{/tikz/every day (initially anchor=base east)} This style is executed by the default node code for each day. The |every day| style is useful for changing the way days look. For example, let us make all days red: @@ -254,7 +254,7 @@ environments (similar to, say, the |\draw| command). \tikz[every day/.style=red] \calendar[dates=2000-01-01 to 2000-01-31,week list]; \end{codeexample} - \end{stylekey} + \end{key} \medskip @@ -468,7 +468,7 @@ arrangements. \subsubsection{Creating a Simple List of Days} -We start with a list the days of the calendar, one day below the +We start with a list of the days of the calendar, one day below the other. For this, we simply shift the coordinate system downward at the end of the code for each day. This shift must be \emph{outside} the day scope as we want day shifts to accumulate. Thus, we use the @@ -677,7 +677,7 @@ The following arrangement gives a very compact view of a whole year. \subsection{Month Labels} -For many calendars you may wish to add a labels to each month. We have +For many calendars you may wish to add a label to each month. We have already covered how month nodes are created and rendered in the description of the |\calendar| command: use |month text|, |every month|, and also |month code| (if necessary) to change the @@ -867,7 +867,7 @@ The following example is a futuristic calendar that is all about circles: {1/winter,2/winter,3/spring,4/spring,5/spring,6/summer, 7/summer,8/summer,9/fall,10/fall,11/fall,12/winter} { - % Computer angle: + % Compute angle: \mycount=\month \advance\mycount by -1 \multiply\mycount by 30 @@ -893,7 +893,7 @@ The following example is a futuristic calendar that is all about circles: \end{tikzpicture} \end{codeexample} -Next, lets us have a whole year in a tight column: +Next, let's us have a whole year in a tight column: \begin{codeexample}[leave comments] \begin{tikzpicture} \small\sffamily diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-chains.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-chains.tex index 25f0c1f3433..0c02a736efe 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-chains.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-chains.tex @@ -20,7 +20,7 @@ \subsection{Overview} \emph{Chains} are sequences of nodes that are -- typically -- arranged -in an o row or a column and that are -- typically -- connected by +in a row or a column and that are -- typically -- connected by edges. More generally, they can be used to position nodes of a branching network in a systematic manner. For the positioning of nodes in rows and columns you can also use matrices, see @@ -35,7 +35,7 @@ connections. \subsection{Starting and Continuing a Chain} Typically, you construct one chain at a time, but it is -permissible to have construct multiple chains simultaneously. In this +permissible to construct multiple chains simultaneously. In this case, the chains must be named differently and you must specify for each node which chain it belongs to. @@ -51,7 +51,7 @@ option. used instead. The key starts a chain named \meta{chain name} and makes it - \emph{active}, which means that is currently being constructed. The + \emph{active}, which means that it is currently being constructed. The |start chain| can be issued only once to activate a chain, inside a scope in which a chain is active you cannot use this option once more (for the same chain name). The chain stops being active at the @@ -129,7 +129,7 @@ option. Let us have a look at the two different applications of this option. The first is to change the direction of a chain as it is - begin constructed. For this, just give this option somewhere inside + being constructed. For this, just give this option somewhere inside the scope of the chain. \begin{codeexample}[] \begin{tikzpicture}[start chain=going right,node distance=5mm] @@ -178,7 +178,7 @@ option. last invocation ``wins.'' (To place a node on several chains, use the |\chainin| command repeatedly.) - The \meta{direction} part is optional. If present it sets the + The \meta{direction} part is optional. If present, it sets the direction used for this node, otherwise the \meta{direction} that was given to the original |start chain| option is used (or of the last |continue chain| option, which allows you to change this @@ -186,12 +186,12 @@ option. The effects of this option are the following: \begin{enumerate} - \item An internal counter (there is one, local, counter + \item An internal counter (there is one local counter for each chain) is increased. This counter reflects the current number of the node in the chain, where the first node is node 1, the second is node 2, and so on. - This value of this internal counter is globally stored in the + The value of this internal counter is globally stored in the macro \declare{|\tikzchaincount|}. \item If the node does not yet have a name, (having been given using the |name| option or the name-syntax), the name of the node is set to @@ -248,12 +248,12 @@ option. \item The following style is executed: \begin{stylekey}{/tikz/every on chain} - This key is executed for every node of a chain, including the + This key is executed for every node on a chain, including the first one. \end{stylekey} \end{enumerate} - Recall that the standard replacement rule has a form like + Recall that the standard placement rule has a form like |right=of (\tikzchainprevious)|. This means that each new node is placed to the right of the previous one, spaced by the current value of |node distance|. @@ -387,7 +387,7 @@ following command, which is only defined inside scopes where a This style is executed each time this command is used. \end{stylekey} - Note that is makes sense to call this option several times for a + Note that it makes sense to call this option several times for a node, in order to connect it to several nodes. This is especially useful for joining in branches, see the next section. \begin{codeexample}[] diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-circuits.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-circuits.tex index 496eac52179..9478ed33ad3 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-circuits.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-circuits.tex @@ -144,7 +144,7 @@ current values of parameters like |minimum height| or |inner xsep|. For these reasons, the circuit libraries introduce the concept of a \emph{symbol graphic}. This is a style that causes a |\node| to not only have the correct shape, but also the correct size and the -correct path usage. More generally, this style may setup things in any +correct path usage. More generally, this style may set up things in any way so that the ``symbol looks correct''. When you write, for instance, |\node[diode]|, then the style called |diode graphic| is used, which in turn is set to something like @@ -196,9 +196,8 @@ symbols, use |circuits.logic.IEC|. If you cannot decide, include both: \usetikzlibrary{circuits.logic.US,circuits.logic.IEC} \end{codeexample} To create a picture that contains a US-style circuit you can now use -the option |circuit logic US|. This will setup keys like |and gate| to -create use an appropriate symbol graphic for rendering an and -gate. Using the |circuit logic IEC| instead will setup |and gate| to +the option |circuit logic US|. This will set up keys like |and gate| to +create use an appropriate symbol graphic for rendering an |and gate|. Using the |circuit logic IEC| instead will set up |and gate| to use another symbol graphic. \begin{codeexample}[] @@ -368,7 +367,7 @@ annotation as a parameter to the symbol as in the following example: \end{codeexample} However, in the above example we would not actually see anything - since we have not yet setup the graphic to be used by |foo|. For + since we have not yet set up the graphic to be used by |foo|. For this, we must use a key called |set foo graphic| or, generally, |set| \meta{name} |graphic|. This key gets graphic options as parameter that will be set when a symbol |foo| should be shown: @@ -388,7 +387,7 @@ annotation as a parameter to the symbol as in the following example: \item The |inner sep| is set to |0.5pt|. \item The following style is executed: \begin{stylekey}{/tikz/every circuit symbol} - Use this style to setup things in general. + Use this style to set up things in general. \end{stylekey} \item The graphic options that have been set using |set| \meta{name} |graphic| are set. @@ -434,9 +433,9 @@ annotation as a parameter to the symbol as in the following example: \item This node gets \meta{options} as its option list. \item The node is added by virtue of a special |markings| decoration. This means that a |mark| command is executed that - causes the node to placed as a mark on the path. + causes the node to be placed as a mark on the path. \item The marking decoration will automatically subdivide the path - and cause a line to be drawn to from the start of the path to the + and cause a line to be drawn from the start of the path to the node's border (at the position that lies on a line from the node's center to the start of the path) and then from the node's border (at a position on the other side of the node) to the end of the @@ -484,7 +483,7 @@ rotated. There are two ways of achieving such rotations: \begin{enumerate} \item When you place a symbol on a |to| path, the graphic symbol is automatically rotated such that it ``points along the path.'' Here - is an examples that show how the inductor shape (which looks, + is an examples that shows how the inductor shape (which looks, unrotated, like this: \tikz[circuit ee IEC]\node[inductor]{};) is automatically rotated around: \begin{codeexample}[] @@ -529,10 +528,10 @@ rotated. There are two ways of achieving such rotations: Info labels are used to add text to a circuit symbol. Unlike normal nodes like a rectangle, circuit symbols typically do not have text ``on'' them, but the text is placed next to them (like the text -``$3\Omega$'' next to a resistor). +``$3\,\Omega$'' next to a resistor). \tikzname\ already provides the |label| option for this purpose. The -|info| option is build on top of this option, but it comes in some +|info| option is built on top of this option, but it comes in some predefined variants that are especially useful in conjunction with circuits. @@ -773,7 +772,7 @@ in several ways: black rectangle. \end{stylekey} \begin{stylekey}{/tikz/circuit symbol lines (initially draw)} - This style is used with symbols that consist only of lines the do + This style is used with symbols that consist only of lines that do not surround anything. Examples are a capacitor. \begin{codeexample}[] \tikz [circuit ee IEC, @@ -805,7 +804,7 @@ in several ways: \end{itemize} All circuit environments like |circuit logic IEC| mainly use options -like |set and gate graphic=...| to setup the graphics used for a certain +like |set and gate graphic=...| to set up the graphics used for a certain symbol. It turns out that graphic hidden in the ``|...|'' part is also always available as a separate style, whose name contains the library's initials. For instance, the |circuit logic IEC| option @@ -857,7 +856,7 @@ saying |set resistor graphic| yourself: \subsubsection{Overview} A \emph{logical circuit} is a circuit that contains what we call -\emph{logical gates} like an and-gate or an xor-gate. The logical +\emph{logical gates} like an |and gate| or an |xor gate|. The logical libraries are intended to make it easy to draw such circuits. In the following, we first have a look at the different libraries that @@ -898,7 +897,7 @@ you need to use one of the following libraries, instead: This library provides graphics based on gates recommended by the International Electrotechnical Commission. When you include this library, you can use the following key to - setup a scope that contains a logical circuit where the gates are + set up a scope that contains a logical circuit where the gates are shown in this style. \begin{key}{/tikz/circuit logic IEC} @@ -991,7 +990,7 @@ one of them, all the other work the same way: \begin{key}{/tikz/and gate} This key should be passed to a |node| command. It will cause the - node to ``look like'' an and-gate, where the exact appearance of the + node to ``look like'' an |and gate|, where the exact appearance of the gate is dictated by the which circuit environment is used. To further configure the appearance of the |and gate|, see Section~\ref{section-theming-symbols}. @@ -1011,7 +1010,7 @@ one of them, all the other work the same way: Multiple inputs can be specified for a logic gate (provided they support multiple inputs: a not gate---also known as an inverter---does not). However, there is an upper limit for the - number of inputs which has been set at 1024, which should be \emph{way} + number of inputs which has been set to 1024, which should be \emph{way} more than would ever be needed. The following key is used to configure the inputs. It is available @@ -1273,6 +1272,9 @@ centers of the inputs can be customized using the following keys: node[\placement] {\scriptsize\texttt{(s.\anchor)}}; \end{tikzpicture} \end{codeexample} + + (For the definition of the |shape example| style, see + Section~\ref{section-libs-shapes}.) \end{shape} \end{pgflibrary} @@ -1330,7 +1332,7 @@ centers of the inputs can be customized using the following keys: Set the symbol for the |xor gate|. Note the necessity for braces, as the symbol contains |=|. In \tikzname, when the |use IEC style logic gates| key has been - used, this key can be replaced by |or gate symbol|. + used, this key can be replaced by |xor gate symbol|. \end{key} \begin{key}{/pgf/xnor gate IEC symbol=\meta{text} (initially \char`\{\char`\$=1\char`\$\char`\})} @@ -1399,7 +1401,7 @@ centers of the inputs can be customized using the following keys: This shape is a nand gate. It supports two or more inputs. If less than two inputs are specified an error will result. The anchors for this gate with two - non-inverted inputs are + inverted inputs are shown below. Anchor |30| is an example of a border anchor. \begin{codeexample}[] @@ -1441,7 +1443,7 @@ Just as for logical gates, there are different ways of drawing ee-symbols. Currently, there is one main library for drawing circuits, which uses the graphics from the International Electrotechnical Commission, but you can add your own libs. This is why, just as for -logical gates, there are a base library and more specific libraries. +logical gates, there is a base library and more specific libraries. \begin{tikzlibrary}{circuits.ee} This library declares the ee symbols, but (mostly) does not @@ -1473,7 +1475,7 @@ include |circuits.ee.IEC|. Inside the |circuit ee IEC| scope, you can now use the keys for symbols, units, and annotations listed in the later sections. We have -a more detailed look at one of each of them, all the other work the +a more detailed look at one of each of them, all the others work the same way. Let us start with an example of a symbol: the resistor symbol. The @@ -1555,8 +1557,8 @@ Section~\ref{section-circuits-ee-symbols} and later sections. \medskip\textbf{Inputs, Outputs, and Anchors.} Like the logical gates, all ee-symbols have an |input| - and an |output| anchor. Special purpose nodes may have even more - anchors of this type. Furthermore, the ee-symbols nodes also for + and an |output| anchor. Special-purpose-nodes may have even more + anchors of this type. Furthermore, the ee-symbols-nodes also have four standard compass direction anchors. \medskip\textbf{Changing the Appearance.} @@ -1866,23 +1868,23 @@ directly. happen: \begin{enumerate} \item The size of the shape is computed according to the following - rules: The width of the shape is setup so that the left border of + rules: The width of the shape is set up so that the left border of the shape is at the left end of the arrow tip and the right border is at the right end of the arrow tip. These left and right - ``ends'' of the arrow are the left and right extends specified by + ``ends'' of the arrow are the left and right extents specified by the arrow itself (see the documentation of the |\pgfarrowsdeclare| for details). You usually need not worry about this width setting. - By comparison, the height of the arrow is given my the current - setting of |minimum height|. Thus, this key must have been setup + By comparison, the height of the arrow is given by the current + setting of |minimum height|. Thus, this key must have been set up correctly to reflect the ``real'' height of the arrow tip. The reason is that the height of an arrow is not specified when arrows are declared and is, thus, not available, here. Possibly, the height computation will change in the future to reflect the real height of the arrow, so you should generally - setup the |minimum height| to be the same as the real height. + set up the |minimum height| to be the same as the real height. \item A straight line from left to right inside the shape's boundaries is added to the background path. \item The arrow tip, pointing right, is drawn before the background @@ -1930,7 +1932,7 @@ directly. \begin{shape}{generic circle IEC} This shape inherits from |circle ee|, which in turn is just a normal |circle| with additional |input| and |output| anchors at the left - and right ends. However, additionally, this shapes allows you to + and right ends. However, additionally, this shape allows you to specify a path that should be added before the background path using the following key: \begin{key}{/pgf/generic circle IEC/before background=\meta{code}} @@ -1963,7 +1965,7 @@ directly. \begin{shape}{generic diode IEC} This shape is used to depict diodes. The main shape is taken up by a - ``right pointing'' triangle. The anchors are positioned on border of + ``right pointing'' triangle. The anchors are positioned on the border of a rectangle around the diode, see the below example. The diode's size is based on the current settings of |minimum width| and |minimum height|. @@ -2036,7 +2038,7 @@ directly. This shape is used to depict a variant version of a resistor. Its size is computed as for a rectangle (thus, its size depends things like the |minimum height|). Then, inside this rectangle, a - background path is setup according to the following rule: Starting + background path is set up according to the following rule: Starting from the left end, zigzag segments are added to the path. Each segment consists of a line at a 45 degree angle going up to the top of the rectangle, then going down to the bottom, then going up to @@ -2109,7 +2111,7 @@ directly. \end{shape} \begin{shape}{battery IEC} - This shape is similar to a |capacitor IEC|, only the right line is + This shape is similar to a |capacitor IEC|, however, the right line is only half the height of the left line. \begin{codeexample}[] \tikz \node[shape=battery IEC,shape example,minimum size=2cm, diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-decorations.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-decorations.tex index bb0e6cadad9..4496bc06f4d 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-decorations.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-decorations.tex @@ -1,4 +1,4 @@ -% Copyright 2008 by Mark Wibrow +% Copyright 2013 by Mark Wibrow and Till Tantau % % This file may be distributed and/or modified % @@ -40,27 +40,27 @@ stored in \TeX\ dimension registers while others are stored in macros. value of |2.5pt| means that deforming decorations should deform a path by up to 2.5pt away from the original path. - This key set the \TeX-dimension |\pgfdecorationsegmentamplitude|. + This key sets the \TeX-dimension |\pgfdecorationsegmentamplitude|. \end{key} \begin{key}{/pgf/decoration/meta-amplitude=\meta{dimension} (initially 2.5pt)} This key determines the amplitude for a meta-decoration. - The key set the \TeX-macro (!) |\pgfmetadecorationsegmentamplitude|. + The key sets the \TeX-macro (!) |\pgfmetadecorationsegmentamplitude|. \end{key} \begin{key}{/pgf/decoration/segment length=\meta{dimension} (initially 10pt)} Many decorations are made up of small segments. This key determines the desired length of such segments. - This key set the \TeX-dimension |\pgfdecorationsegmentlength|. + This key sets the \TeX-dimension |\pgfdecorationsegmentlength|. \end{key} \begin{key}{/pgf/decoration/meta-segment length=\meta{dimension} (initially 1cm)} This determined the length of the meta-segments from which a meta-decoration is made up. - This key set the \TeX-macro (!) |\pgfmetadecorationsegmentlength|. + This key sets the \TeX-macro (!) |\pgfmetadecorationsegmentlength|. \end{key} \begin{key}{/pgf/decoration/angle=\meta{degree} (initially 45)} @@ -68,7 +68,7 @@ stored in \TeX\ dimension registers while others are stored in macros. instance, a |wave| decoration consists of arcs and the opening angle of these arcs is given by the |angle|. - This key set the \TeX-macro |\pgfdecorationsegmentangle|. + This key sets the \TeX-macro |\pgfdecorationsegmentangle|. \end{key} \begin{key}{/pgf/decoration/aspect=\meta{factor} (initially 0.5)} @@ -76,7 +76,7 @@ stored in \TeX\ dimension registers while others are stored in macros. for a |brace| decoration the aspect ratio determines where the brace point will be. - This key set the \TeX-macro |\pgfdecorationsegmentaspect|. + This key sets the \TeX-macro |\pgfdecorationsegmentaspect|. \end{key} \begin{key}{/pgf/decoration/start radius=\meta{dimension} (initially 2.5pt)} @@ -86,7 +86,7 @@ stored in \TeX\ dimension registers while others are stored in macros. \end{key} \begin{key}{/pgf/decoration/end radius=\meta{dimension} (initially 2.5pt)} - For some decorations there is a natural radius (of some circle, presumably). + For some decorations there is a natural end radius (of some circle, presumably). This key stores the value directly inside the key. \end{key} @@ -111,13 +111,13 @@ stored in \TeX\ dimension registers while others are stored in macros. \subsection{Path Morphing Decorations} \begin{pgflibrary}{decorations.pathmorphing} - A \emph{path morphing decorations} ``morphs'' or ``deforms'' the + A \emph{path morphing decoration} ``morphs'' or ``deforms'' the to-be-decorated path. This means that what used to be a straight line might afterwards be a snaking curve and have bumps. However, a - line is still and a line and path deforming decorations do not + line is still a line and path deforming decorations do not change the number of subpaths. For instance, if the path used to - consist of two circles and an open arc, the path will after the - decoration process still consist of two closed subpath and one open + consist of two circles and an open arc, the path will, after the + decoration process, still consist of two closed subpaths and one open subpath. \end{pgflibrary} @@ -138,7 +138,7 @@ the paths. \begin{codeexample}[] \begin{tikzpicture}[decoration=lineto] \draw [help lines] grid (3,2); - \draw [decorate,fill=examplefill] + \draw [decorate,fill=yellow!80!black] (0,0) -- (3,1) arc (0:180:1.5 and 1) -- cycle; \end{tikzpicture} \end{codeexample} @@ -152,18 +152,18 @@ the paths. the decoration: \begin{itemize} \item |amplitude| - determines how much the zigzag lines raises above and falls below + determines how much the zigzag line raises above and falls below a straight line to the target point. \item |segment length| determines the length of a complete ``up-down'' cycle. - \item |meta-segment length| + \item |meta-segment length| determines the length of the |curveto| and the |zigzag| decorations. \end{itemize} \begin{codeexample}[] \begin{tikzpicture}[decoration={straight zigzag,meta-segment length=1.1cm}] \draw [help lines] grid (3,2); - \draw [decorate,fill=examplefill] + \draw [decorate,fill=yellow!80!black] (0,0) -- (3,1) arc (0:180:1.5 and 1) -- cycle; \end{tikzpicture} \end{codeexample} @@ -186,7 +186,7 @@ the paths. \begin{tikzpicture} [decoration={random steps,segment length=2mm}] \draw [help lines] grid (3,2); - \draw [decorate,fill=examplefill] + \draw [decorate,fill=yellow!80!black] (0,0) -- (3,1) arc (0:180:1.5 and 1) -- cycle; \end{tikzpicture} \end{codeexample} @@ -205,7 +205,7 @@ the paths. \begin{codeexample}[] \begin{tikzpicture}[decoration=saw] \draw [help lines] grid (3,2); - \draw [decorate,fill=examplefill] + \draw [decorate,fill=yellow!80!black] (0,0) -- (3,1) arc (0:180:1.5 and 1) -- cycle; \end{tikzpicture} \end{codeexample} @@ -217,7 +217,7 @@ the paths. influence the decoration: \begin{itemize} \item |amplitude| - determines how much the zigzag lines raises above and falls below + determines how much the zigzag line raises above and falls below a straight line to the target point. \item |segment length| determines the length of a complete ``up-down'' cycle. @@ -225,7 +225,7 @@ the paths. \begin{codeexample}[] \begin{tikzpicture}[decoration=zigzag] \draw [help lines] grid (3,2); - \draw [decorate,fill=examplefill] + \draw [decorate,fill=yellow!80!black] (0,0) -- (3,1) arc (0:180:1.5 and 1) -- cycle; \end{tikzpicture} \end{codeexample} @@ -237,13 +237,13 @@ the paths. \begin{decoration}{bent} This decoration adds a slightly bent line from the start to the - target. The amplitude of the bent is given |amplitude| + target. The amplitude of the bend is given |amplitude| (an amplitude of zero gives a straight line). \begin{itemize} \item |amplitude| - determines the amplitude of the bent. + determines the amplitude of the bend. \item |aspect| - determines how tight the bent is. A good value is around |0.3|. + determines how tight the bend is. A good value is around |0.3|. \end{itemize} Note that this decoration makes only little sense for curves. You should apply it only to straight lines. @@ -255,7 +255,7 @@ the paths. \end{codeexample} \begin{codeexample}[] \begin{tikzpicture}[decoration={bent,aspect=.3}] - \draw [decorate,fill=examplefill] (0,0) rectangle (3.5,2); + \draw [decorate,fill=yellow!80!black] (0,0) rectangle (3.5,2); \node[circle,draw] (A) at (.5,.5) {A}; \node[circle,draw] (B) at (3,1.5) {B}; \draw[->,decorate] (A) -- (B); @@ -277,7 +277,7 @@ the paths. \begin{codeexample}[] \begin{tikzpicture}[decoration=bumps] \draw [help lines] grid (3,2); - \draw [decorate,fill=examplefill] + \draw [decorate,fill=yellow!80!black] (0,0) -- (3,1) arc (0:180:1.5 and 1) -- cycle; \end{tikzpicture} \end{codeexample} @@ -307,7 +307,7 @@ the paths. \begin{codeexample}[] \begin{tikzpicture}[decoration=coil] \draw [help lines] grid (3,2); - \draw [decorate,fill=examplefill] + \draw [decorate,fill=yellow!80!black] (0,0) -- (3,1) arc (0:180:1.5 and 1) -- cycle; \end{tikzpicture} \end{codeexample} @@ -315,7 +315,7 @@ the paths. \begin{tikzpicture} [decoration={coil,aspect=0.3,segment length=3mm,amplitude=3mm}] \draw [help lines] grid (3,2); - \draw [decorate,fill=examplefill] + \draw [decorate,fill=yellow!80!black] (0,0) -- (3,1) arc (0:180:1.5 and 1) -- cycle; \end{tikzpicture} \end{codeexample} @@ -338,7 +338,7 @@ the paths. \begin{codeexample}[] \begin{tikzpicture}[decoration=curveto] \draw [help lines] grid (3,2); - \draw [decorate,fill=examplefill] + \draw [decorate,fill=yellow!80!black] (0,0) -- (3,1) arc (0:180:1.5 and 1) -- cycle; \end{tikzpicture} \end{codeexample} @@ -355,12 +355,12 @@ the paths. \item |amplitude| determines the sine wave's amplitude. \item |segment length| - determines the sine wave's wave length. + determines the sine wave's wavelength. \end{itemize} \begin{codeexample}[] \begin{tikzpicture}[decoration=snake] \draw [help lines] grid (3,2); - \draw [decorate,fill=examplefill] + \draw [decorate,fill=yellow!80!black] (0,0) -- (3,1) arc (0:180:1.5 and 1) -- cycle; \end{tikzpicture} \end{codeexample} @@ -382,9 +382,9 @@ the paths. \end{pgflibrary} \begin{decoration}{border} - This decoration adds straight lines the path that are at a specific + This decoration adds straight lines to the path that are at a specific angle to the line toward the target. The idea is to add these little - lines to indicate the ``border'' or an area. The following + lines to indicate the ``border'' of an area. The following parameters influence the decoration: \begin{itemize} \item |segment length| @@ -499,11 +499,11 @@ the paths. \begin{decoration}{show path construction} - This decoration allows ``something different'' to be done - for each \emph{type} of input segment (i.e., moveto, lineto, - curveto or closepath). Typically, each segment will be replaced - with another path, but this need not necessarily be the case. - + This decoration allows ``something different'' to be done + for each \emph{type} of input segment (i.e., moveto, lineto, + curveto or closepath). Typically, each segment will be replaced + with another path, but this need not necessarily be the case. + \begin{codeexample}[] \begin{tikzpicture}[>=stealth, every node/.style={midway, sloped, font=\tiny}, decoration={show path construction, @@ -533,10 +533,10 @@ the paths. for each type of input segment. \begin{key}{/pgf/decoration/moveto code=\meta{code} (initially \char`\{\char`\})} - Set the code to be executed for every moveto input segment. - It is important to remember that the transformations applied - by the decoration automaton are turned \emph{off} when \meta{code} - is executed. + Set the code to be executed for every moveto input segment. + It is important to remember that the transformations applied + by the decoration automaton are turned \emph{off} when \meta{code} + is executed. \end{key} \begin{key}{/pgf/decoration/lineto code=\meta{code} (initially \char`\{\char`\})} @@ -544,7 +544,7 @@ the paths. \end{key} \begin{key}{/pgf/decoration/curveto code=\meta{code} (initially \char`\{\char`\})} - Set the code to be executed for every curveto input segment. + Set the code to be executed for every curveto input segment. \end{key} \begin{key}{/pgf/decoration/closepath code=\meta{code} (initially \char`\{\char`\})} @@ -563,19 +563,19 @@ In \tikzname, you can use the following macros inside a \tikzname{} coordinate. \begin{command}{\tikzinputsegmentfirst} - The first point on the current input segment path. + The first point on the current input segment path. \end{command} \begin{command}{\tikzinputsegmentlast} - The last point on the current input segment path. + The last point on the current input segment path. \end{command} \begin{command}{\tikzinputsegmentsupporta} - The first support on the curveto input segment path. + The first support on the curveto input segment path. \end{command} \begin{command}{\tikzinputsegmentsupportb} - The second support on the curveto input segment path. + The second support on the curveto input segment path. \end{command} {\tikzexternaldisable @@ -585,7 +585,7 @@ inside a \tikzname{} coordinate. decoration={ show path construction, curveto code={ - \draw [blue, dashed] + \draw [blue, dashed] (\tikzinputsegmentfirst) -- (\tikzinputsegmentsupporta) node [at end, cross out, draw, solid, red, inner sep=2pt]{}; \draw [blue, dashed] @@ -693,8 +693,8 @@ a path. We start with the most general and most useful of these libraries. \end{codeexample} The |mark| decoration option is used to specify a marking. It comes - in two version: - \begin{key}{/pgf/decoration/mark=|at position| + in two versions: + \begin{key}{/pgf/decoration/mark=\texttt{at position} \meta{pos}| with |\meta{code}} The options specifies that when a |marking| decoration is applied, there should be a marking at position \meta{pos} on the path whose @@ -704,10 +704,10 @@ a path. We start with the most general and most useful of these libraries. \begin{enumerate} \item It can be a non-negative dimension like |0pt| or |2cm| or |5cm/2|. In this case, it refers to the position along the path - that is this far removed from the start. + that is this far displaced from the start. \item It can be a negative dimension like |-1cm-2pt| or |-1sp|. In this case, the position is taken from the end of the path. Thus, - |-1cm| is the position that is $-1$cm removed from the end of + |-1cm| is the position that is $-1$cm displaced from the end of the path. \item It can be a dimensionless non-negative number like |1/2| or |0.333+2*0.1|. In this case, the \meta{pos} is interpreted as a @@ -722,7 +722,7 @@ a path. We start with the most general and most useful of these libraries. is applied, the (high level) coordinate system will have been transformed so that the origin lies at this position and the positive $x$-axis points along the path. For this coordinate - system, the \meta{code} is executed. It can contains all sorts of + system, the \meta{code} is executed. It can contain all sorts of graphic drawing commands, including (even named) nodes. If the position lies past the end of the path (for @@ -767,8 +767,8 @@ a path. We start with the most general and most useful of these libraries. \end{tikzpicture} \end{codeexample} - When the \meta{code} is begin executed, two special keys will have - been setup, whose value may be of interest: + When the \meta{code} is being executed, two special keys will have + been set up, whose value may be of interest: \begin{key}{/pgf/decoration/mark info/sequence number} This key can only be read. Its value (which can be obtained using the |\pgfkeysvalueof| command) is a ``sequence number'' of @@ -825,6 +825,7 @@ a path. We start with the most general and most useful of these libraries. Using the key |sequence number| we can also ``number'' the nodes and even refer to them later on. + % FIXME : the automatic key highlighting fails here! \begin{codeexample}[] \begin{tikzpicture}[decoration={markings, mark=between positions 0 and 1 step 1cm with { @@ -869,9 +870,9 @@ a path. We start with the most general and most useful of these libraries. path. However, this is no longer the case when the following key is set: \begin{key}{/pgf/decoration/mark connection node=\meta{node name} (initially empty)} - When this key is set to a nonempty \meta{node name} while the + When this key is set to a non-empty \meta{node name} while the decoration is being processed, the following happens: The marking - code should, among possibly other things, define node named + code should, among possibly other things, define a node named \meta{node name}. Then, the output path of this decoration will contain a line-to to ``one end'' of this node, followed by a moveto to the ``other end'' of the node. More precisely, the first @@ -914,7 +915,7 @@ a path. We start with the most general and most useful of these libraries. Frequent markings that are hard to create correctly are arrow tips. For them, two special commands are available when the \meta{code} of -a |mark| option is execute. (They are only defined in this code): +a |mark| option is executed. (They are only defined in this code): \begin{command}{\arrow\opt{\oarg{options}}\marg{arrow end tip}} This command simply draws the \meta{arrow end tip} at the origin, @@ -1001,7 +1002,7 @@ a |mark| option is execute. (They are only defined in this code): \end{codeexample} \end{key} \begin{key}{/pgf/decoration/foot angle (initially 10)} - Footprints are rotate by this much. + Footprints are rotated by this much. \begin{codeexample}[] \begin{tikzpicture}[decoration={footprints,foot angle=60}] \fill [decorate] (0,0) -- (3,0); @@ -1086,7 +1087,7 @@ reasons, using the |markings| library is usually preferable. \item |segment length| determines the distance between consecutive triangles. \item |shape height| - determines height of the triangle side that is orthogonal + determines the height of the triangle side that is orthogonal to the path. \item |shape width| determines the width of the triangle. @@ -1094,7 +1095,7 @@ reasons, using the |markings| library is usually preferable. \begin{codeexample}[] \begin{tikzpicture}[decoration=triangles] \draw [help lines] grid (3,2); - \draw [decorate,fill=examplefill] (0,0) -- (3,1) arc (0:180:1.5 and 1); + \draw [decorate,fill=yellow!80!black] (0,0) -- (3,1) arc (0:180:1.5 and 1); \end{tikzpicture} \end{codeexample} \end{decoration} @@ -1103,14 +1104,14 @@ reasons, using the |markings| library is usually preferable. \begin{decoration}{shape backgrounds} This is a general decoration that replaces the to-be-decorated path by repeated copies of the background path of an arbitrary shape that has - previously defined using the |\pgfdeclareshape| command (that is, + previously been defined using the |\pgfdeclareshape| command (that is, you can use any shape in the shape libraries). Please note that the background path of the shapes is used, but \emph{no nodes are created}. This means that \emph{you cannot have text inside the shapes of this path, you cannot name them, or refer to them.} Finally, this decoration \emph{will not work with - shapes that depend strongly of the size of the text box (like the + shapes that depend strongly on the size of the text box (like the arrow shapes).} If any of these restrictions pose a problem, use the |markings| library instead. @@ -1137,13 +1138,13 @@ reasons, using the |markings| library is usually preferable. |anchor| decoration option: \begin{key}{/pgf/decoration/anchor=\meta{anchor} (initially center)} - The anchor used to position the shapes backgrounds. + The anchor used to position the shape backgrounds. \end{key} A shape background path is added at the start point of the path and, if the distance between the shapes is appropriate, at the end point of the path. - + \begin{codeexample}[] \begin{tikzpicture}[decoration={ shape backgrounds,shape=regular polygon,shape size=4mm}] @@ -1190,10 +1191,10 @@ reasons, using the |markings| library is usually preferable. Set the spacing between the shapes on the decorations path. This can be just a distance on its own, but the additional keywords |between centers|, and |between borders| (which must be preceded by a - comma), specify that the distance is between the center anchors of + comma), specify that the distance is between the center anchors of the shapes or between the edges of the \emph{boundaries} of the shape borders. - + \begin{codeexample}[] \begin{tikzpicture}[ decoration={shape backgrounds,shape size=.5cm,shape=signal}, @@ -1202,7 +1203,7 @@ reasons, using the |markings| library is usually preferable. \draw [help lines] grid (3,2); \draw [paint=red, decoration={shape sep=.5cm}] (0,2) -- (3,2); - \draw [paint=green, decoration={shape sep={1cm, between center}}] + \draw [paint=green, decoration={shape sep={1cm, between centers}}] (0,1) -- (3,1); \draw [paint=blue, decoration={shape sep={1cm, between borders}}] (0,0) -- (3,0); @@ -1245,7 +1246,7 @@ reasons, using the |markings| library is usually preferable. By default, shapes are rotated to the slope of the decorations path. If \meta{boolean} is the value |false|, then this rotation is turned off. Internally this sets the \TeX-if |\ifpgfshapedecorationsloped| - appropriately. + accordingly. \begin{codeexample}[] \tikzset{ @@ -1263,11 +1264,11 @@ reasons, using the |markings| library is usually preferable. \end{codeexample} \end{key}% - It is possible to scale the width and height of the shapes across the + It is possible to scale the width and height of the shapes along the length of the decorations path. The shapes are scaled between the starting size and the ending size. The following keys customize the way the decoration shapes are scaled: - + \begin{key}{/pgf/decoration/shape scaled=\meta{boolean} (initially false)} \begin{codeexample}[] \tikzset{ @@ -1297,11 +1298,11 @@ reasons, using the |markings| library is usually preferable. \end{key}% \begin{stylekey}{/pgf/decoration/shape start size=\meta{length}} - Set both the start height and start width simultaneously. + Sets both the start height and start width simultaneously. \end{stylekey}% \begin{key}{/pgf/decoration/shape end width=\meta{length} (initially 2.5pt)} - The recommended ending width of the shape. Note, that this is the + The recommended ending width of the shape. Note that this is the width that a shape will take only if it is drawn exactly at the end of the path. @@ -1351,9 +1352,9 @@ reasons, using the |markings| library is usually preferable. This decoration decorates the path with text. This drawing of the text is a ``side effect'' of the decoration. The to-be-decorated path is only used to determine where the characters should be put - and it is thrown away after the decoration is done. This is why in - the following example no line is shown. - + and it is thrown away after the decoration is done. This is why no line is shown in + the following example. + \begin{codeexample}[] \catcode`\|12 \begin{tikzpicture}[decoration={text along path, @@ -1377,36 +1378,36 @@ reasons, using the |markings| library is usually preferable. transform key should be used. \item No attempt is made to ensure characters do not overlap when - the angle between segments is considerably less than 180\textdegree{} + the angle between segments is considerably less than 180$^\circ$ (this is tricky to do in \TeX{} without a huge processing overhead). In general this should not be too much of a problem, but, once again, kerning can be used in most cases to overcome any undesirable effects. - \item + \item It is only possible to typeset text in math mode under considerable - restrictions. Math mode is entered and exited using any character + restrictions. Math mode is entered and exited using any character of category code 3 (e.g., in plain \TeX{} this is |$|). %$ - Math subscripts and superscripts need to be contained within braces + Math subscripts and superscripts need to be contained within braces (e.g., |{^y_i}|) as do commands like |\times| or |\cdot|. - However, even modestly complex mathematical typesetting is unlikely + However, even modestly complex mathematical typesetting is unlikely to be successful along a path (or even desirable). \item Some inaccuracies in positioning may be particularly apparent at input segment boundaries. This can (unfortunately) only be solved - on case by case basis by individually kerning the offending + on a case-by-case basis by individually kerning the offending characters within a group. \end{itemize} The following keys are used by the |text| decoration: \begin{key}{/pgf/decoration/text=\meta{text} (initially \normalfont empty)} - Set the text to typeset along the curve. + Sets the text to typeset along the curve. Consecutive spaces are ignored, so |\ | (or |\space| in \LaTeX) - should be used to insert multiple spaces. It is possible to + should be used to insert multiple spaces. It is possible to format the text using normal formatting commands, such as |\it|, |\bf| and |\color|, within customizable delimiters. Initially these delimiters are both {\tt\char`\|} (however, care will be needed - regarding the category codes of delimiters --- see below). + regarding the category codes of delimiters --- see below). {\catcode`\|12 \begin{codeexample}[] @@ -1433,7 +1434,7 @@ reasons, using the |markings| library is usually preferable. \end{tikzpicture} \end{codeexample} } - + Internally, the text is stored in the macro |\pgfdecorationtext|. Any characters that have not been typeset when the end of the path has been reached will be stored in |\pgfdecorationrestoftext|. @@ -1444,15 +1445,15 @@ reasons, using the |markings| library is usually preferable. \begin{key}{/pgf/decoration/text format delimiters=\marg{before}\marg{after} (initially \char`\{|\char`\}\char`\{\char`\})} \catcode`\|13 - + Set the characters that the text decoration will use to parse formatting commands. If \meta{after} is empty, then \meta{before} will be used for both delimiters. - In general you should stick to characters whose category codes are + In general you should stick to characters whose category codes are |11| or |12|. As |+| is used to indicate that the specified format commands - are added to any existing ones, you should avoid using |+| as + are added to any existing ones, you should avoid using |+| as a delimiter. \begin{codeexample}[] @@ -1524,12 +1525,12 @@ reasons, using the |markings| library is usually preferable. \end{stylekey} \begin{key}{/pgf/decoration/text align/left indent=\meta{length} (initially 0pt)} - Specify a distance which the automaton should move along + Specifies a distance which the automaton should move along before it starts typesetting the text. \end{key} \begin{key}{/pgf/decoration/text align/right indent=\meta{length} (initially 0pt)} - Specify a distance before the end of the path, where + Specifies a distance before the end of the path, where the automaton should stop typesetting the text. \end{key} @@ -1575,6 +1576,664 @@ reasons, using the |markings| library is usually preferable. +\begin{decoration}{text effects along path} + + This decoration is similar to the |text along path| decoration + except that each character is inserted into the picture + as a \tikzname\ node, and node options (such as |text|, |scale| and |opacity|) + can be used to create `text effects'. + +\begin{codeexample}[] +\bfseries\large +\begin{tikzpicture}[decoration={text effects along path, + text={text effects along path!}, text align=center, + text effects/.cd, + character count=\i, character total=\n, + characters={evaluate={\c=\i/\n*100;}, text along path, text=red!\c!orange}, + character widths={text along path, xslant=0, yscale=1}}] + +\path [postaction={decorate}, preaction={decorate, + text effects={characters/.append={yscale=-1.5, opacity=0.5, + text=gray, xslant=(\i/\n-0.5)*3}}}] + (0,0) .. controls ++(2,1) and ++(-2,-1) .. (3,4); +\end{tikzpicture} +\end{codeexample} + + + There are some important differences between this decoration and the + |text along path| decoration: + + \begin{itemize} + \item + formatting (e.g., font and color) + cannot be specified in the decoration text. They can only be specified + using the keys described below. + \item + as a consequence of using the \tikzname\ node options, this + decoration is only available in \tikzname. + \item + due to the number of computations involved, this is + quite a slow decoration. + + \end{itemize} + + The following keys are shared with the |text along path| + decoration: + +\begin{key}{/pgf/decoration/text=\marg{text}} + + + Set the text this decoration will use. Braces can be + used to group multiple characters together, + or commands that should not be expanded until they are typset, for example + |gr{\"o}{\ss}eren|. You should \emph{not} use the formatting + delimiters or math mode characters + that the |text along path| decoration supports. + +\end{key} + + + +\begin{key}{/pgf/decoration/text align=\meta{align}} + + This sets the alignment of the text along the path. + The \meta{align} argument should be |left|, |right| or |center|. + Spreading the text out, or stretching the spaces between + words is \emph{not} supported. + +\end{key} + + The decoration text can be thought of as consisting + of \emph{characters} arranged in to sequences of \emph{letters} + to make \emph{words} which are separated by a \emph{word separator}. + This, however, does not mean that you are limited to using only + natural language as the decoration text. + +\begin{codeexample}[] +\begin{tikzpicture}[decoration={text effects along path, + text={000-001-010-011-100-101-110-111}, + text effects/.cd, + path from text, + word separator=-, + every letter/.style={shape=rectangle, fill=blue!20, draw=blue!40}}] + +\path [decorate] (0,0); +\end{tikzpicture} +\end{codeexample} + + In addition, it is possible to replace characters + with \tikzname\ code: + +\begin{codeexample}[] +\begin{tikzpicture}[decoration={text effects along path, + text={000-001-010-011-100-101-110-111}, text align=center, + text effects/.cd, + word separator=-, + replace characters=0 with {\fill [purple] circle [radius=2pt]; }, + replace characters=1 with {\fill [orange] circle [radius=2pt]; }, + replace characters=- with {\path circle [radius=2pt]; }, + every letter/.style={shape=rectangle, fill=blue!20, draw=blue!40}}] + +\path [decorate] (0,0) .. controls ++(2,0) and ++(-2,0) .. (3,4); +\end{tikzpicture} +\end{codeexample} + + + There are many keys and styles that can be used to add effects + to the decoration text. + Many of these keys have the parent path |/pgf/decoration/text effects/|, + but for convenience, these keys can be accessed using the following + key: + +\begin{key}{/tikz/text effects=\marg{options}} + + Execute every option in \marg{options} with the + key path for each option temporarily set to |/pgf/decoration/text effects/|. + +\end{key} + + + The following keys can be used to customise the + appearance of text in the |text effects along path| + decoration. + + + + +\begin{stylekey}{/pgf/decoration/text effects/every character} + + Set the effects that will be applied to + every character in the decoration text. The effects + will typically be \tikzname\ node options. + Initially, this style is empty so the decoration simply positions + nodes at the appropriate position along the path. In order to + make the text `follow the path' like the |text along path| decoration + the following key can be added to the |every character| style. + +\end{stylekey} + + +\begin{stylekey}{/pgf/decoration/text effects/text along path} + + This style automatically sets the \tikzname\ keys + |transform shape| (to make the character slope with the path), + |anchor=baseline| (to make the baseline of the characters `sit' on + the path) and |inner xsep=0pt| (to horizontally fit each node to the character + it contains, reducing the spacing between characters). + +\begin{codeexample}[] +\begin{tikzpicture}[decoration={text effects along path, + text={text effects along path!}}] + +\path [draw=red, dotted, postaction={decorate}] + (0,0) .. controls ++(1,0) and ++(-1,0) .. (3,2); +\path [draw=blue, dotted, yshift=1cm, postaction={decorate}, + text effects={text along path}] + (0,0) .. controls ++(1,0) and ++(-1,0) .. (3,2); +\end{tikzpicture} +\end{codeexample} +\end{stylekey} + + +\begin{key}{/pgf/decoration/text effects/characters=\marg{effects}} + + Shorthand for the |every character|. + +\end{key} + +\begin{stylekey}{/pgf/decoration/text effects/character \meta{number}} + + Specify additional effects for the character \meta{number}. + +\end{stylekey} + + +\begin{stylekey}{/pgf/decoration/text effects/every letter} + + Specify additional effects for every letter (i.e., every character + that isn't the word separator) in the decoration text. + +\end{stylekey} + +\begin{stylekey}{/pgf/decoration/text effects/letter \meta{number}} + + Specify the effects for letter \meta{number} in \emph{every} word. + +\end{stylekey} + + +\begin{stylekey}{/pgf/decoration/text effects/every first letter} + + Specify additional effects for the first letter in \emph{every} word. + +\end{stylekey} + + +\begin{stylekey}{/pgf/decoration/text effects/every last letter} + + Specify additional effects for the last letter in \emph{every} word. + +\end{stylekey} + + +\begin{stylekey}{/pgf/decoration/text effects/every word} + + Specify additional effects for every word in the decoration text. + +\end{stylekey} + + + +\begin{stylekey}{/pgf/decoration/text effects/word \meta{number}} + + Specify additional effects for word \meta{number} in the decoration text. + +\end{stylekey} + + + +\begin{stylekey}{/pgf/decoration/text effects/word \meta{m} letter \meta{n}} + + Specify additional effects for letter \meta{n} in word \meta{m} in the decoration text. + +\end{stylekey} + + + +\begin{stylekey}{/pgf/decoration/text effects/every word separator} + + Specify additional effects for every character that is a word separator. + +\end{stylekey} + + + +\begin{key}{/pgf/decoration/text effects/word separator=\meta{character} (initially space)} + + Specify the character that is to be used as the word separator. + This \emph{must} be a single character such as |a| or |-| or + the special value |space| (which should be used to indicate that + spaces should be used as the separator). + +\end{key} + + By default, the width for each character is calculated according + to the bounding box of the node in which it is contained. + However, if the node is rotated or slanted, or has a substantial + |inner sep|, this bounding box + will be quite big. The following key enables different effects + to be applied to the node that is used to calculate the + width. + + + + +\begin{stylekey}{/pgf/decoration/text effects/every character width} + + This style is appplied to the (invisible) nodes used for calculating + the width of a character node. + +\end{stylekey} + + + +\begin{key}{/pgf/decoration/text effects/character widths=\marg{effects}} + + Shorthand for the |every character width| style. + +\begin{codeexample}[] +\begin{tikzpicture}[decoration={text effects along path, + text={text effects along path!}, text align=center, + text effects/.cd, + character count=\i, + characters={xslant=0.5, text along path, name=c-\i}}] + +\path [decorate] (0,0) -- (3,2); +\path [decorate, + text effects={character widths={inner xsep=0pt, xslant=0}}] + (0,1) -- (3,3); +\end{tikzpicture} +\end{codeexample} +\end{key} + + It is possible to parametrize effects, perhaps for doing + calculations, or labelling nodes based on the number of the + character in the decoration text. To access the number + of the character, and the total number of characters + the following keys can be used. + However, these keys should \emph{not} + be used inside the style keys given above. + +\begin{key}{/pgf/decoration/text effects/character count=\meta{macro}} + Store the number of the character being typeset in \meta{macro}. + +\begin{codeexample}[] +\begin{tikzpicture}[decoration={text effects along path, + text={text effects along path!}, + text effects/.cd, + path from text, + character count=\i, every word separator/.style={fill=red!30}, + characters={text along path, shape=circle, fill=gray!50}}] + +\path [decorate, text effects={characters/.append={label=above:\footnotesize\i}}] (0,0); +\end{tikzpicture} +\end{codeexample} + +\end{key} + +\begin{key}{/pgf/decoration/text effects/character total=\meta{macro}} + Store the total number of the characters in the decoration text + in \meta{macro}. + This key can be used with the |character count| key to produce + some quite pleasing effects: + +\begin{codeexample}[] +\begin{tikzpicture}[decoration={text effects along path, + text={text effects along path!}, + text effects/.cd, + character count=\i, character total=\n, + characters={text along path, evaluate={\c=\i/\n*100;}, + text=orange!\c!blue, scale=\i/\n+0.5}}] + +\path [decorate] + (0,0) .. controls ++(1,0) and ++(-1,0) .. (3,2); +\end{tikzpicture} +\end{codeexample} + +\end{key} + +\begin{key}{/pgf/decoration/text effects/letter count=\meta{macro}} + + Store the number of letter being typeset (i.e., the position of the character + in the word) in \meta{macro}. Numbering starts at |1| and + the character acting as a word separator is numbered |0|. + +\begin{codeexample}[] +\begin{tikzpicture}[decoration={text effects along path, + text={text effects along path!}, + text effects/.cd, + path from text, letter count=\i, every word separator/.style={fill=red!30}, + characters={text along path, shape=circle, fill=gray!50}}] + +\path [decorate, text effects={characters/.append={label=above:\footnotesize\i}}] (0,0); +\end{tikzpicture} +\end{codeexample} + +\end{key} + +\begin{key}{/pgf/decoration/text/effetcs/letter total=\meta{macro}} + + Store the number of letters in the current word in \meta{macro}. + When the character is the word separator, this value is |0|. + +\end{key} + +\begin{key}{/pgf/decoration/text effects/word count=\meta{macro}} + Store the number of words in the decoration text in \meta{macro}. + Numbering starts at |1|. + When the character is the word separator, \meta{macro} + takes the number of the previous word. If the decoration text + starts with a word separator \meta{macro} will be |0|. + +\begin{codeexample}[] +\begin{tikzpicture}[decoration={text effects along path, + text={text effects along path!}, + text effects/.cd, + path from text, word count=\i, every word separator/.style={fill=red!30}, + characters={text along path, shape=circle, fill=gray!50}}] + + \path [decorate, text effects={characters/.append={label=above:\footnotesize\i}}] (0,0); +\end{tikzpicture} +\end{codeexample} +\end{key} + +\begin{key}{/pgf/decoration/text effects/word total=\meta{macro}} + + Store the total number of words in the decoration text in \meta{macro}. + +\end{key} + + + It is also possible to apply effects to specific + characters such as coloring every instance of the + character |a|, + or changing the font of every |T| in the decoration text: + +\begin{key}{/pgf/decoration/text effects/style characters=\marg{characters} with \marg{effects}} + + This key enables \meta{effects} to be applied to every character + in the decoration text that is specified in \meta{characters}. + +\begin{codeexample}[] +\begin{tikzpicture}[decoration={text effects along path, + text={Falsches {\"U}ben von Xylophonmusik qu{\"a}lt jeden gr{\"o}{\ss}eren Zwerg}, + text effects/.cd, + path from text, + style characters=aeiou{\"U}{\"a}{\"o} with {text=blue}, + characters={text along path}}] + +\path [decorate] (0,0); +\end{tikzpicture} +\end{codeexample} + +\end{key} + +\begin{key}{/pgf/decoration/text effects/path from text=\opt{\marg{true or false}} (default true)} + When this key is set to |true| and the decorated path + consists only of a single point, the decoration will calculate + the width of the decoration text using all the specified parameters + as if the decorated path was actually a straight line + starting from the given point. This `virtual' + straight line is then decorated with the text. + +\begin{codeexample}[] +\begin{tikzpicture}[decoration={text effects along path, + text={text effects along path!}, + text effects/.cd, + path from text, + character count=\i, character total=\n, + characters={text along path, scale=\i/\n+0.5}}] + +\path [decorate] (0,0); +\end{tikzpicture} +\end{codeexample} + +\end{key} + + + +\begin{key}{/pgf/decoration/text effects/path from text angle=\meta{angle}} + + When used in conjunction with the |path from text| key, + the straight line that is used as the decorated path + is rotated by \meta{angle} around the starting point. + +\begin{codeexample}[] +\begin{tikzpicture}[decoration={text effects along path, + text={text effects along path!}, + text effects/.cd, + path from text, path from text angle=60, + character count=\i, character total=\n, + characters={text along path, scale=\i/\n+0.5}}] + +\path [decorate] (0,0); +\end{tikzpicture} +\end{codeexample} + +\end{key} + + +\begin{key}{/pgf/decoration/text effects/fit text to path=\opt{\meta{true or false}} (default true)} + + This key will make the decoration increase the space between + characters so that the entire path is used by the decoration. + +\begin{codeexample}[] +\begin{tikzpicture}[decoration={text effects along path, + text={text effects along path!}, + text effects/every character/.style={text along path}}] + +\path [draw=gray, postaction={decorate}, rotate=90] + (0,0) .. controls ++(2,0) and ++(-1,0) .. (5,-1); +\path [draw=gray, postaction={decorate}, rotate=90, yshift=-1cm, + text effects={fit text to path}] + (0,0) .. controls ++(2,0) and ++(-1,0) .. (5,-1); +\end{tikzpicture} +\end{codeexample} +\end{key} + + +\begin{key}{/pgf/decoration/text effects/scale text to path=\opt{\meta{true or false}} (default true)} + + This key will make the decoration scale the text + so that the entire path is used by the decoration. + +\begin{codeexample}[] +\begin{tikzpicture}[decoration={text effects along path, + text={text effects along path!}, + text effects/every character/.style={text along path}}] + +\path [draw=gray, postaction={decorate}, rotate=90] + (0,0) .. controls ++(2,0) and ++(-1,0) .. (5,-1); +\path [draw=gray, postaction={decorate}, rotate=90, yshift=-1cm, + text effects={scale text to path}] + (0,0) .. controls ++(2,0) and ++(-1,0) .. (5,-1); +\end{tikzpicture} +\end{codeexample} +\end{key} + + +\begin{key}{/pgf/decoration/text effects/reverse text} + + Reverse the order of the characters in the decoration text. + This may be useful if using `right-to-left` languages. + Unfortunately, any + leading `soft' spaces in the original text will be lost. + +\begin{codeexample}[] +\begin{tikzpicture}[decoration={text effects along path, + text={text effects along path!}, + text effects/.cd, + path from text, path from text angle=60, + reverse text, + character count=\i, character total=\n, + characters={text along path, scale=\i/\n+0.5}}] + +\path [decorate] (0,0) .. controls ++(1,0) and ++(-1,0) .. (3,2); +\end{tikzpicture} +\end{codeexample} + + It is important to note that the |reverse text| key reverses the + text \emph{before} doing anything else. This means that the + numbering of characters, letters and words will still + still be in the normal order, so any parametrized effects + will have to take this into account. + Alternatively, to get the numbering + to follow the reversed text, it is possible to reverse the path and then + invert the scale: + +\begin{codeexample}[] + +\begin{tikzpicture}[decoration={text effects along path, + text={text effects along path!}, + text effects/.cd, + path from text, path from text angle=60, + character count=\i, character total=\n, + characters={text along path, scale=\i/\n+0.5}}] + +\path [decorate, text effects={reverse text}] (0,0); +\path [blue, decorate, decoration={reverse path}, + text effects={characters/.append={scale=-1}}] (1,0); +\end{tikzpicture} +\end{codeexample} +\end{key} + +\begin{key}{/pgf/decoration/text effects/group letters} + + Group sequences of letters together so they are treated + as a single `character'. + +\begin{codeexample}[] +\begin{tikzpicture}[decoration={text effects along path, + text={text effects along path!}, + text effects/.cd, + path from text, path from text angle=60, + every word separator/.style={fill=none}, + character count=\i, character total=\n, + characters={text along path, fill=gray!50, scale=\i/\n+0.5}}] + +\path [decorate] (0,0); +\path [decorate, text effects={group letters, + characters/.append={fill=red!20}}] + (1,0); +\end{tikzpicture} +\end{codeexample} + +\end{key} + + The order in which the |reverse text| and |group letters| keys + are applied is important: + +\begin{codeexample}[] +\begin{tikzpicture}[decoration={text effects along path, + text={text effects along path!}, + text effects/.cd, + path from text, path from text angle=60, + every word separator/.style={fill=none}, + character count=\i, character total=\n, + characters={text along path, fill=gray!50, scale=\i/\n+0.5}}] + +\path [decorate, text effects={reverse text, group letters}] (0,0); +\path [decorate, text effects={group letters, reverse text, + characters/.append={fill=red!20}}] (1,0); +\end{tikzpicture} +\end{codeexample} + +\begin{key}{/pgf/decoration/text effects/repeat text=\opt{\meta{times}}} + + Usually, when the decoration runs out of text, it simply stops. + This key will make the decoration repeat the decoration text + for the specified number of \meta{times}. If no value is given + the text will be repeated until the path is finished. + There are two points to remember however. + Firstly the numbering of characters, letters and words + will be restarted each time the text is repeated. + Secondly, the options for alignment, scaling or fitting + the text to the path, fitting the path to the text, + and so on, are computed using the decoration text before the + decoration starts. If any of these options are given + the behaviour of the |repeat text| key is undefined, but + typically it will be ignored. + +\begin{codeexample}[] +\begin{tikzpicture}[decoration={text effects along path, + text={text effects along path!\ }, + text effects/.cd, + repeat text, + character count=\m, character total=\n, + characters={text along path, scale=0.5+\m/\n/2}}] + +\path [draw=gray, ultra thin, postaction=decorate] + (180:2) \foreach \a in {0,...,12}{ arc (180-\a*90:90-\a*90:1.5-\a/10) }; +\end{tikzpicture} +\end{codeexample} +\end{key} + +\begin{key}{/pgf/decoration/text effects/character command=\meta{macro}} + + This key specifies a command that is executed when + each character is placed in the node. The \meta{macro} should + be an ordinary \TeX\ macro which takes one argument. The + argument will be a macro which when expanded will + contain the current character. + +\begin{codeexample}[] +\def\mycommand#1{#1$_\n$} +\begin{tikzpicture}[decoration={text effects along path, + text={text effects along path!}, + text effects/.cd, + path from text, path from text angle=60, group letters, + word count=\n, + every word/.style={character command=\mycommand}, + characters={text along path}}] + +\path [decorate] (0,0); +\end{tikzpicture} +\end{codeexample} +\end{key} + + +\begin{key}{/pgf/decoration/text effects/replace characters=\meta{characters} with \marg{code}} + + Replace the node for each character in \meta{characters} with \meta{code}. + The \meta{code} can be thought of as describing + a little picture or marking which will be + used instead of the character node. + The origin will be the current point along the + decoration path. + Any transformations associated with + the \meta{characters} (e.g., applied with the |every character| + or |every letter| styles) will also be applied to \meta{code}. + +\begin{codeexample}[] +\begin{tikzpicture}[decoration={text effects along path, + text={text effects along path!}, + text effects/.cd, + path from text, path from text angle=60, + replace characters=e with {\fill [red!20] (0,1mm) circle [radius=1mm];}, + replace characters=a with {\fill [black!20] (0,1mm) circle [radius=1mm];}, + character count=\i, character total=\n, + characters={text along path, scale=\i/\n+0.5}}] + +\path [decorate] (0,0); +\end{tikzpicture} +\end{codeexample} + +\end{key} +\end{decoration} + + + \subsection{Fractal Decorations} \begin{pgflibrary}{decorations.fractals} @@ -1613,7 +2272,7 @@ reasons, using the |markings| library is usually preferable. \begin{decoration}{Koch snowflake} This decoration replaces a straight line by a ``line with a spike.'' - Koch's snowflake's Hausdorff dimension is $\log 4/\log 3$. + The Hausdorff dimension of Koch's snowflake's is $\log 4/\log 3$. \begin{codeexample}[] \begin{tikzpicture}[decoration=Koch snowflake] \draw decorate{ (0,0) -- (3,0) }; @@ -1625,7 +2284,7 @@ reasons, using the |markings| library is usually preferable. \end{decoration} \begin{decoration}{Cantor set} - This decoration replaces a straight line by a ``line with a whole in + This decoration replaces a straight line by a ``line with a gap in the middle.'' The Hausdorff dimension of the Cantor set is $\log 2/\log 3$. \begin{codeexample}[] diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-edges.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-edges.tex index 5a280cd94a9..3fbb14ca195 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-edges.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-edges.tex @@ -183,11 +183,11 @@ exact way this curve looks can be influenced via a number of options. \end{key} \begin{key}{/tikz/out looseness=\meta{number}} - specifies the looseness factor for the out distance only. + Specifies the looseness factor for the out distance only. \end{key} \begin{key}{/tikz/in looseness=\meta{number}} - specifies the looseness factor for the in distance only. + Specifies the looseness factor for the in distance only. \end{key} \begin{key}{/tikz/min distance=\meta{distance}} If the computed distance for the start and target coordinates are @@ -204,13 +204,13 @@ exact way this curve looks can be influenced via a number of options. The maximum distance set only for the start coordinate. \end{key} \begin{key}{/tikz/in min distance=\meta{distance}} - The min distance set only for the target coordinate. + The minimum distance set only for the target coordinate. \end{key} \begin{key}{/tikz/in max distance=\meta{distance}} - The max distance set only for the target coordinate. + The maximum distance set only for the target coordinate. \end{key} \begin{key}{/tikz/distance=\meta{distance}} - Set the min and max distance to the same value \meta{distance}. Note + Set the minimum and maximum distance to the same value \meta{distance}. Note that this causes any computed distance $d$ to be ignored and \meta{distance} to be used instead. \begin{codeexample}[] @@ -222,10 +222,10 @@ exact way this curve looks can be influenced via a number of options. \end{codeexample} \end{key} \begin{key}{/tikz/out distance=\meta{distance}} - Sets the min and max out distance. + Sets the minimum and maximum out distance. \end{key} \begin{key}{/tikz/in distance=\meta{distance}} - Sets the min and max in distance. + Sets the minimum and maximum in distance. \end{key} \begin{key}{/tikz/out control=\meta{coordinate}} This option causes the \meta{coordinate} to be used as the start diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-er.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-er.tex index 177a9611d39..c896037c584 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-er.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-er.tex @@ -16,7 +16,7 @@ \end{tikzlibrary} This library is intended to help you in creating E/R-diagrams. It defines -only very little new styles, but using these style |entity| instead of +only few new styles, but using the style |entity| instead of saying |rectangle,draw| makes the code more expressive. @@ -122,7 +122,7 @@ styles for entities. \begin{stylekey}{/tikz/every attribute} - This style is used with every (key) attribute. + This style is used with every attribute, and therefore also for every key attribute. \begin{codeexample}[] \begin{tikzpicture} [text depth=1pt, diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-external.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-external.tex index 7399ed6f185..7d2130b035b 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-external.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-external.tex @@ -41,7 +41,7 @@ The library always searches for the \emph{next} picture's end, |\end{tikzpicture Consider using the |\tikzexternaldisable| method in case you'd like to skip selected pictures which do not meet the requirements. \subsection{A Word About Con\TeX t And Plain \TeX} -Currently, the basic layer backend |\beginpgfgraphicnamed| $\dotsc$ |\endpgfgraphicnamed| relies on \LaTeX\ only, so externalization is only supported for \LaTeX\ yet. +Currently, the basic layer backend |\beginpgfgraphicnamed| $\dotsc$ |\endpgfgraphicnamed| relies on \LaTeX\ only, so externalization is currently only supported for \LaTeX. %The library comes in three different versions, one for \LaTeX, one for Con\TeX t and one for plain \TeX. For reasons of simplicity, examples in this manual only refer to \LaTeX\ (especially |pdflatex|). \subsection{Externalizing Graphics} @@ -70,7 +70,7 @@ A simple image is \tikz \fill (0,0) circle(5pt);. The method works as follows: if the document is typeset normally, the library searches for replacement images for every picture. Filenames are generated automatically in the default configuration. In our case, the two file names will be |main-figure0| and |main-figure1|. If they exist, those images are simply included and the pictures as such are not processed. If graphics files do not exist, steps are taken to generate the missing ones. Since (currently) only one output file can be set, each missing image needs to be generated by a separate run of \LaTeX\ in which the |\jobname| is set to the desired image file name. In the default configuration |mode=convert with system call|, these commands are issued automatically by using the |\write18| method to call system commands. It is also possible to output every required file name or to generate a |makefile|; users will need to issue the required commands manually (or with |make|). The probably most comfortable way is to use the default configuration with -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] pdflatex -shell-escape main \end{codeexample} \noindent which authorizes |pdflatex| to call itself recursively to generate the images. When it finishes, all images are generated and the document already includes them. @@ -114,7 +114,7 @@ From this point on, successive runs of \LaTeX\ will use the final graphics files if and only if the current document has been typeset with |-shell-escape|\footnote{Note that this is always true for the default configuration. This security consideration applies mainly for \texttt{mode=list and make} which will also work \emph{without} shell escapes.}. For |eps| output, you can (and need to) use -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] \tikzset{external/system call={latex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname "\image" "\texsource"; dvips -o "\image".ps "\image".dvi}} @@ -128,11 +128,11 @@ From this point on, successive runs of \LaTeX\ will use the final graphics files \end{key} \subsubsection{Support for Labels and References In External Files} -The |external| library comes with extra support for |\label| and |\ref| (and other commands which usually store information in the |.aux| file) inside of external files. +The |external| library comes with extra support for |\label| and |\ref| (and other commands which usually store information in the |.aux| file) inside an external files. There are, however, some points which need your attention when you try to use \begin{enumerate} - \item[a)] |\ref| to something in the main document inside of an externalized graphics or + \item[a)] |\ref| to something in the main document inside an externalized graphics or \item[b)] |\label| in the externalized graphics which is referenced in the main document. \end{enumerate} @@ -142,9 +142,14 @@ Point b) is realized automatically by the external library. In detail, a |\label \begin{enumerate} \item The external graphics needs to be generated together with its |.dpth| (usually automatically by \tikzname). \item The main document includes the external graphics and copies the |.dpth| content into its main |.aux| file. - \item The main document needs to be translated one further time to re-read its |.aux| file\footnote{Note that it is not possible to activate the content of an auxiliary file after \texttt{\textbackslash begin\{document\}} in \LaTeX.}. + \item The main document needs to be translated once again to re-read its |.aux| file\footnote{Note that it is not possible to activate the content of an auxiliary file after \texttt{\textbackslash begin\{document\}} in \LaTeX.}. \end{enumerate} There is just one special case: if a |\label|/|\ref| combination is realized itsself by a |tikzpicture| which should be externalized, you need to proceed as for case a) since |mode=convert with system call| can't handle that stuff on its own. Thus, |\label| works automatically, just translate the main document often enough. +\begin{key}{/tikz/external/aux in dpth=\marg{boolean} (initially true)} + Allows to disable the feature. Disabling it will safe one |\newwrite| command, i.e.\ a write register. + + Also see the |disable dependency files| feature. +\end{key} @@ -204,7 +209,7 @@ A simple image is \tikz \fill (0,0) circle(5pt);. % will be written to 'figures/ \end{tikzpicture} \end{document} \end{codeexample} -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] pdflatex -shell-escape main \end{codeexample} \end{command} @@ -276,6 +281,11 @@ pdflatex -shell-escape main \begin{command}{\tikzexternalfiledependsonfile\marg{external graphics}\marg{file name}} A variant of |\tikzpicturedependsonfile| which adds a dependency for an \meta{external graphics}. The argument \meta{external graphics} must be the path as it would have been generated by the external library, i.e.\ without file extension but including any prefixes. \end{command} +\begin{key}{/tikz/external/disable dependency files} + Allows to (irreversibly) disable the generation of file dependencies. Disabling it will safe one |\newwrite| command, i.e.\ a write register. Note that the write register is only allocated if the feature has been used at all. This key needs to be provided as argument to |\tikzexternalize| (or it needs to be set before calling |\tikzexternalize|). + + Also see the |aux in dpth| key. +\end{key} \begin{key}{/tikz/external/force remake=\marg{boolean} (default true)} A boolean which is used to customize the up-to-date checks of all following figures. Every up-to-date check will fail, resulting in automatic regeneration of every following figure. @@ -337,6 +347,25 @@ pdflatex -shell-escape main For \LaTeX, the feature lasts until the next |\end|\marg{$\cdot$} (this holds for every call to |\tikzset|). \end{key} +\begin{key}{/tikz/external/up to date check=\marg{choice} (initially md5)} + The |external| lib has to decide when some existing figure is up-to-date. In such a case, it can be used without remaking it. Outdated pictures will be remade. + + The key |up to date check| allows to choose among a couple of heuristics which are supposed to catch the most important reasons to remake a figure. + + The |up to date check| can be overrule by any of the |force remake| or |remake next| keys: if one of them is true, the figure is not up-to-date. + + The choice \declare{simple} is based on the existence of the file: the file is + up-to-date if and only if it exists. + + The choice \declare{md5} generates an MD5 checksum of the picture for which the up-to-date check is running. The MD5 is compared against the MD5 of the previous run, which, in turn, will be written into an extra file with the extension |.md5|. This file will be modified if and only if the MD5 comparison indicates a difference. The MD5 computation is based on the pdf\TeX\ method |\pdfmdfivesum|. If it is unavailable for some reason, the choice |diff| will be used instead. + + The choice \declare{diff} is the same as MD5 -- except that it compares the picture content as-is instead of a hash. The |.md5| file will be used to compare an old version with the current one -- but its content is some ``normalized'' version of the picture for internal use. + + \paragraph{Attention:} the content--based strategies |md5| and |diff| operate on the picture content -- and only on the picture content. Here, ``picture content'' only includes the top--level tokens; no expansion is applied and no included files are part of the strategies. If you change preamble styles, you have to rebuild the figures manually (for example by deleting the generated graphics files). If you have include files, consider using |\tikzpicturedependsonfile| and its variants. Since this key provides heuristics, you should always remake your figures before you finally publish your document. + + The |up to date check| is applied for |mode=convert with system call| and |mode=list and make|. +\end{key} + \begin{command}{\tikzexternaldisable} Allows to disable the complete externalization. While |export next| will still collect the contents of picture environments, this command uninstalls the hooks for the external library completely. Thus, nested picture environments or environments where |\end{tikzpicture}| is not directly reachable won't produce compilation failures -- although it is not possible to externalize them automatically. @@ -352,7 +381,7 @@ pdflatex -shell-escape main \begin{key}{/tikz/external/figure list=\marg{boolean} (initially true)} A boolean which configures whether a figure list shall be generated. A figure list is an output file named \marg{jobname}|.figlist| which is filled with file names of each figure, one per line. - This file is not used by \TeX\ anymore, its purpose is to issue the required conversion commands |pdflatex -jobname |\marg{picture file name} \marg{main file} manually (or in a script). See section~\ref{sec:external:detail} for the details about the expected system call (or activate |mode=convert with system call| and inspect you log file). + This file is not used by \TeX\ anymore, its purpose is to issue the required conversion commands |pdflatex -jobname |\marg{picture file name} \marg{main file} manually (or in a script). See section~\ref{sec:external:detail} for the details about the expected system call (or activate |mode=convert with system call| and inspect your log file). \begin{codeexample}[code only] \documentclass{article} @@ -386,11 +415,11 @@ A simple image is \tikz \fill (0,0) circle(5pt);. \end{document} \end{codeexample} -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] pdflatex main \end{codeexample} generates |main.figlist| containing -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] figures/trees figures/simple figures/main-figure0 @@ -400,10 +429,11 @@ figures/main-figure0 \begin{key}{/tikz/external/mode=\marg{choice} (initially convert with system call)} Configures what to do with \tikzname\ pictures (unless we are currently externalizing one particular image, in that case, these modes are ignored). - The preconfigured mode |convert with system call| checks whether external graphics files are up-to-date and includes them if that is the case. Any picture which is not up-to-date will be generated automatically using a system call. The system call can be configured using the |system call| template. The up-to-date check is simple: if the file does not exist, it is not up-to-date. Furthermore, if one of the |force remake| or |remake next| keys is true, the figure is not up-to-date. In all other case, the file is considered to be up-to-date. As soon as |convert with system call| is set, the |figure list| will be disabled -- such a file is not required. In case you still need or want it, you can enable it after setting |mode|. + The preconfigured mode |convert with system call| checks whether external graphics files are up-to-date and includes them if that is the case. Any picture which is not up-to-date will be generated automatically using a system call. The system call can be configured using the |system call| template. The up-to-date check is applied according to the |up to date check| key. +As soon as |convert with system call| is set, the |figure list| will be disabled -- such a file is not required. In case you still need or want it, you can enable it after setting |mode|. Please note that system calls may be disabled for security reasons. For pdflatex, they can be enabled using -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] pdflatex -shell-escape \end{codeexample} while other \TeX\ variants may need other switches. The feature is sometimes called |\write18|. @@ -417,7 +447,7 @@ pdflatex -shell-escape Mode |list only| skips every \tikzname\ picture; it only generates the file \marg{main file}|.figlist| containing file names for every picture, the contents of any picture environment is thrown away and a replacement text is shown. This implies |figure list=true|. See also the |list and make| mode which includes available graphics. The mode |list and make| is similar to |list only|: it generates the same file \marg{main file}|.figlist|, but any images which exist already are included as graphics instead of ignoring them. Furthermore, this mode generates an additional file: \marg{main file}.makefile. This allows to use a work flow like -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] % step 1: generate main.makefile: pdflatex main % step 2: generate ALL graphics on 2 processors: @@ -425,7 +455,7 @@ make -j 2 main.makefile % step 3: include the graphics: pdflatex main \end{codeexample} - \noindent This last make method is, however unnecessary: |list and make| just assumes that images are generated somehow (not necessarily with the generated makefile). The generated makefile allows parallel externalization of graphics on multi-core systems and it supports any file dependencies configured with |\tikzpicturedependsonfile|. Furthermore, it respects the |force remake| and |remake next| keys. + \noindent This last make method is optional: |list and make| just assumes that images are generated somehow (not necessarily with the generated makefile). The generated makefile allows parallel externalization of graphics on multi-core systems and it supports any file dependencies configured with |\tikzpicturedependsonfile|. Furthermore, it respects the |force remake| and |remake next| keys. \end{key} @@ -454,7 +484,7 @@ pdflatex main \begin{key}{/tikz/external/optimize command away=\meta{\textbackslash command}\marg{required argument count}} Installs commands to optimize \meta{\textbackslash command} away. As is described above, optimization applies to the case when single pictures are converted: one usually doesn't need to process (probably expensive) commands which do not contribute to the selected picture. - The argument \marg{required argument count} is either empty or a non-negativ integer between $0$ and $9$. It denotes the number of arguments which should be consumed after \meta{\textbackslash command}. In any case, one argument in square brackets after the command will be recognized as well. To be more precise, the following cases for arguments of \meta{\textbackslash command} are supported: + The argument \marg{required argument count} is either empty or a non-negative integer between $0$ and $9$. It denotes the number of arguments which should be consumed after \meta{\textbackslash command}. In any case, one argument in square brackets after the command will be recognized as well. To be more precise, the following cases for arguments of \meta{\textbackslash command} are supported: \begin{enumerate} \item If \marg{required argument count} is empty (the default), \meta{\textbackslash command} may take one optional argument in square brackets and one in curly braces (which is also optional). \item If \marg{required argument count} is not empty, \marg{\textbackslash command} may take one optional argument in square brackets. Furthermore, it expects exactly \marg{required argument count} following arguments. @@ -556,7 +586,7 @@ And this here: \myExpensiveMacro{Argument} also. The standard run |pdflatex |\meta{main document} causes the |external| library to check every occurrence of |\begin{tikzpicture}| and every |\tikz| shortcommand. If it finds a picture which shall be exported, it queries the respective file name and checks whether the file exists already. If so, it includes the external graphics. If not, it requires an externalization which can be done automatically (the default), semi--automatically (with |mode=list and make|) or manually (by issuing the requires system calls somehow). The library can detect whether it runs in ``conversion mode'', i.e.\ if it should only process a single image. To do so, it checks whether the internal macro \declareandlabel{\tikzexternalrealjob} exists. If so, its contents is assumed to be \meta{main document} (without the suffix |.tex|). Usually, this macro is set by the conversion system call, -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] pdflatex -jobname "main-figure0" "\def\tikzexternalrealjob{main}\input{main}" \end{codeexample} \noindent where |main-figure0| is the picture we are currently externalizing and |main.tex| is the main document. @@ -565,7 +595,7 @@ As soon as ``conversion mode'' has been detected, \pgfname\ changes the output r Eventually, the call |\input{main}| returns and the picture is ready. From this point on, the external graphics will be used. There is another possibility to communicate \meta{main document} to the subprocess performing the externalization: namely to write `|\tikzexternalize{main}|' into the document. In this case, the conversion system call will be -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] pdflatex -jobname "main-figure0" "main" \end{codeexample} \noindent and the contents of |\tikzexternalrealjob| is set automatically. This case is detected by |\tikzexternalize|, and the |system call| is updated automatically (by patching its |\texsource| template argument). It is not necessary to change the |system call| manually. @@ -577,7 +607,7 @@ The sequence in which system calls are performed and the decision whether they a \subsection{Using External Graphics Without \textmd{\pgfname}\ Installed} \label{section-libs-external-nopgf} Given that every picture has been exported correctly, one may want to compile a file without \pgfname\ and \tikzname\ installed. \tikzname\ comes with a minimal package which contains just enough commands to replace every |tikzpicture| environment and the |\tikz| short command with the appropriate external graphics. It can be found at -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] latex/pgf/utilities/tikzexternal.sty \end{codeexample} \noindent and needs to be used instead of |\usepackage{tikz}|. So, we uncomment |\usepackage{tikz}| and our example from the beginning becomes @@ -608,14 +638,14 @@ Furthermore, we might want to draw \tikz[baseline]\draw (0,-1) rectangle (1,1); \end{document} \end{codeexample} \noindent where the following files are necessary to compile the document: -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] tikzexternal.sty main.tex main-figure0.pdf main-figure1.pdf main-figure2.pdf \end{codeexample} -\noindent If there are any `|.dpth|' files, for example |main-figure2.dpth|, these files are also required. They contain information for the \tikzname\ |baseline| option (or |\label|s inside of external graphics). +\noindent If there are any `|.dpth|' files, for example |main-figure2.dpth|, these files are also required. They contain information for the \tikzname\ |baseline| option (or |\label|s inside external graphics). Just copy the |.sty| file into the directory of your |main.tex| file and use it as part of your document. @@ -623,7 +653,7 @@ Please keep in mind, that only |tikzpicture| environments and |\tikz| short imag \paragraph{Attention:} Since the simple replacement |\usepackage{tikzexternal}| doesn't support the key--value interface, you \emph{need} to use |\tikzsetexternalprefix| instead of the |prefix| option and |\tikzsetfigurename| instead of the |figure name| option since |\tikzset| is not available in such a context. -\paragraph{Remark:} Some of the features of this library are mainly useful to improve the speed of successive document compilations. In other words: you can't use all features in this context, Keep it simple. +\paragraph{Remark:} Some of the features of this library are mainly useful to improve the speed of successive document compilations. In other words: you can't use all features in this context, keep it simple. \subsection{\eps\ Graphics Export} It is also possible to use \eps\ graphics instead of \pdf\ files. There are different ways to produce them, for example to use |pdflatex| and call |pdftops -eps |\marg{pdf file} \marg{eps file} afterwards. You could add this command to the |system call| option. @@ -655,11 +685,11 @@ The |external| library can be customized to export bitmap images -- with the hel } } \end{codeexample} -\noindent The example above defines a new style called `|png export|' which, when it is set with |\tikzset{png export}| somewhere in the document, modifies the configuration for both, file generation and file input. The file generation is modified by appending the ImageMagick command to |system call| (separated by `|;|' as usual on Linux). This is, in principle, enough to generate a |.png| file. The |include external| command is overwritten such that it uses the |.png| file instead of the |.pdf| file (which exists as well in the configuration above). But since a |.png| file can have a much higher resolution than the desired image dimensions, we have to add |width| and |height| explicitly. Usually, the |external| library does not provide size information (it is unnecessary for |.pdf| or |.eps| since these formats have their bounding box information). To enable size information, the style uses the |external info| key which, in turn, provides the |\pgfexternalwidth| and |\pgfexternalheight| commands. +\noindent The example above defines a new style called `|png export|' which, when it is set with |\tikzset{png export}| somewhere in the document, modifies the configuration for both file generation and file input. The file generation is modified by appending the ImageMagick command to |system call| (separated by `|;|' as usual on Linux). This is, in principle, enough to generate a |.png| file. The |include external| command is overwritten such that it uses the |.png| file instead of the |.pdf| file (which exists as well in the configuration above). But since a |.png| file can have a much higher resolution than the desired image dimensions, we have to add |width| and |height| explicitly. Usually, the |external| library does not provide size information (it is unnecessary for |.pdf| or |.eps| since these formats have their bounding box information). To enable size information, the style uses the |external info| key, which, in turn, provides the |\pgfexternalwidth| and |\pgfexternalheight| commands. -Now, we can use |\tikzset{png export}| either document--wide or just for one particular image. The configuration remains in effect until the end of the actual environment (or until the next closing curly brace `|}|'). +Now we can use |\tikzset{png export}| either document-wide or just for one particular image. The configuration remains in effect until the end of the current environment (or until the next closing curly brace `|}|'). -\begin{key}{/pgf/images/external info=\mchoice{true,false} (initially false)} +\begin{key}{/pgf/images/external info=\marg{boolean} (initially false)} If this key is activated, the size for any externalized image will be stored explicitly into the associated |.dpth| file. When the file is included by |\pgfincludeexternalgraphics| (or automatically by the |external| library), the width is available as \declareandlabel{\pgfexternalwidth} and the height as \declareandlabel{\pgfexternalheight}. diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-fit.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-fit.tex index 5e0dab698db..2a521518498 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-fit.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-fit.tex @@ -23,19 +23,19 @@ When you load this library, the following options become available: \meta{coordinates or nodes} should be a sequence of \tikzname\ coordinates or node names, one directly after the other without commas (like with the |plot coordinates| path operation). Examples - as |(1,0) (2,2)| or |(a) (1,0) (b)|, where |a| and |b| are nodes. + are |(1,0) (2,2)| or |(a) (1,0) (b)|, where |a| and |b| are nodes. For this sequence of coordinates, a minimal bounding box is computed that encompasses all the listed \meta{coordinates or nodes}. For coordinates in the list, the bounding box is guaranteed to contain this coordinate, for nodes it is guaranteed to contain the |east|, |west|, |north| and |south| anchors of the node. In principle (the - details will be explained in a moment), things are now setup such + details will be explained in a moment), things are now set up such that the text box of the node will be exactly this bounding box. Here is an example: We fit several points in a rectangular node. By setting the |inner sep| to zero, we see exactly the text box of the - node. Then we fit these points again in circular node. Note how + node. Then we fit these points again in a circular node. Note how the circle encompasses exactly the same bounding box. \begin{codeexample}[] \begin{tikzpicture}[inner sep=0pt,thick, @@ -63,7 +63,7 @@ When you load this library, the following options become available: \begin{enumerate} \item A minimal bounding box containing all coordinates is computed. Note that if a coordinate like |(a)| is used that - contain a node name, this has the same effect as explicitly + contains a node name, this has the same effect as explicitly providing the |(a.north)| and |(a.south)| and |(a.west)| and |(a.east)|. If you wish to refer only to the center of the |a| node, use |(a.center)| instead. diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-fixedpoint.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-fixedpoint.tex index 335bac3ed2d..1be2d41e7b8 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-fixedpoint.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-fixedpoint.tex @@ -13,7 +13,7 @@ \begin{pgflibrary}{fixedpointarithmetic} This library provides an interface to the \LaTeX{} package |fp| for fixed point arithmetic. In addition to loading this - library you must ensure |fp| is loaded otherwise errors + library you must ensure |fp| is loaded, otherwise errors will occur. \end{pgflibrary} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-folding.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-folding.tex index ce23c8a4026..93f832f826c 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-folding.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-folding.tex @@ -13,19 +13,45 @@ \label{section-calender-folding} \begin{tikzlibrary}{folding} - This library defines commands for creating paper folding - diagrams. Currently, it just contains a single command for creating - a single diagram, but that one is really useful for creating - calendars for your (real) desktop. + This library defines pic types for creating paper folding + diagrams. Many thanks to Nico van Cleemput for providing most of the + code. \end{tikzlibrary} -\begin{command}{\tikzfoldingdodecahedron|[|\meta{options}|];|} - This command draws a folding diagram for a dodecahedron. The syntax - is intended to remind of the |\path| command, but (currently) you - must specify the \meta{options} and nothing else may be specified - between the command name and the closing semicolon. +Here is a big example that produces a diagram for a calendar: + +\begin{codeexample}[leave comments] +\sffamily\scriptsize +\tikz \pic [ + transform shape, + every calendar/.style={ + at={(-8ex,4ex)}, + week list, + month label above centered, + month text=\bfseries\textcolor{red}{\%mt} \%y0, + if={(Sunday) [black!50]} + }, + folding line length=2.5cm, + face 1={ \calendar [dates=\the\year-01-01 to \the\year-01-last];}, + face 2={ \calendar [dates=\the\year-02-01 to \the\year-02-last];}, + face 3={ \calendar [dates=\the\year-03-01 to \the\year-03-last];}, + face 4={ \calendar [dates=\the\year-04-01 to \the\year-04-last];}, + face 5={ \calendar [dates=\the\year-05-01 to \the\year-05-last];}, + face 6={ \calendar [dates=\the\year-06-01 to \the\year-06-last];}, + face 7={ \calendar [dates=\the\year-07-01 to \the\year-07-last];}, + face 8={ \calendar [dates=\the\year-08-01 to \the\year-08-last];}, + face 9={ \calendar [dates=\the\year-09-01 to \the\year-09-last];}, + face 10={\calendar [dates=\the\year-10-01 to \the\year-10-last];}, + face 11={\calendar [dates=\the\year-11-01 to \the\year-11-last];}, + face 12={\calendar [dates=\the\year-12-01 to \the\year-12-last];} +] {dodecahedron folding}; +\end{codeexample} + +The foldings are sorted by number of faces. - The following keys may be used in the \meta{options}: +\begin{pictype}{tetrahedron folding}{} + This pic type draws a folding diagram for a tetrahedron. + The following keys influence the pic: \begin{key}{/tikz/folding line length=\meta{dimension}} Sets the length of the base line for folding. For the dodecahedron this is the length of all the sides of the pentagons. @@ -40,31 +66,22 @@ Same as |face 1|, but for the second face. \end{key} \begin{key}{/tikz/face 3=\meta{code}} - Same as |face 1|, but for the third face. \end{key} - There are further similar options, ending with the following: - \begin{key}{/tikz/face 12=\meta{code}} - Same as |face 1|, but for the last face. + \begin{key}{/tikz/face 4=\meta{code}} \end{key} + There are further similar options for more faces (for commands + shown later). Here is a simple example: \begin{codeexample}[] -\begin{tikzpicture}[transform shape] - \tikzfoldingdodecahedron - [folding line length=6mm, +\tikz \pic [ + transform shape, + folding line length=6mm, face 1={ \node[red] {1};}, face 2={ \node {2};}, face 3={ \node {3};}, - face 4={ \node {4};}, - face 5={ \node {5};}, - face 6={ \node {6};}, - face 7={ \node {7};}, - face 8={ \node {8};}, - face 9={ \node {9};}, - face 10={\node {10};}, - face 11={\node {11};}, - face 12={\node {12};}]; -\end{tikzpicture} + face 4={ \node {4};} +] {tetrahedron folding}; \end{codeexample} The appearance of the cut and folding lines can be influenced using @@ -76,47 +93,141 @@ Executed for every line that should be folded. \begin{codeexample}[] -\begin{tikzpicture}[every cut/.style=red,every fold/.style=dotted] - \tikzfoldingdodecahedron[folding line length=6mm]; -\end{tikzpicture} +\tikz \pic[ + every cut/.style=red, + every fold/.style=dotted, + folding line length=6mm +] { tetrahedron folding }; \end{codeexample} \end{stylekey} -\end{command} + + There is one style that is mainly useful for the present + documentation: + \begin{stylekey}{/tikz/numbered faces} + Sets |face |\meta{i} to |\node {|\meta{i}|};| for all~$i$. + \end{stylekey} + +\end{pictype} -Here is a big example that produces a diagram for a calendar: +\begin{pictype}{tetrahedron truncated folding}{} + A folding of a truncated tetrahedron. +\begin{codeexample}[width=5cm] +\tikz \pic [folding line length=6mm, numbered faces, transform shape] + { tetrahedron truncated folding }; +\end{codeexample} +\end{pictype} -\begin{codeexample}[leave comments] -\sffamily\scriptsize -\begin{tikzpicture} - [transform shape, - every calendar/.style= - { - at={(-8ex,4ex)}, - week list, - month label above centered, - month text=\bfseries\textcolor{red}{\%mt} \%y0, - if={(Sunday) [black!50]} - }] - \tikzfoldingdodecahedron - [ - folding line length=2.5cm, - face 1={ \calendar [dates=\the\year-01-01 to \the\year-01-last];}, - face 2={ \calendar [dates=\the\year-02-01 to \the\year-02-last];}, - face 3={ \calendar [dates=\the\year-03-01 to \the\year-03-last];}, - face 4={ \calendar [dates=\the\year-04-01 to \the\year-04-last];}, - face 5={ \calendar [dates=\the\year-05-01 to \the\year-05-last];}, - face 6={ \calendar [dates=\the\year-06-01 to \the\year-06-last];}, - face 7={ \calendar [dates=\the\year-07-01 to \the\year-07-last];}, - face 8={ \calendar [dates=\the\year-08-01 to \the\year-08-last];}, - face 9={ \calendar [dates=\the\year-09-01 to \the\year-09-last];}, - face 10={\calendar [dates=\the\year-10-01 to \the\year-10-last];}, - face 11={\calendar [dates=\the\year-11-01 to \the\year-11-last];}, - face 12={\calendar [dates=\the\year-12-01 to \the\year-12-last];} - ]; -\end{tikzpicture} + +\begin{pictype}{cube folding}{} + A folding of a cube. +\begin{codeexample}[] +\tikz \pic [folding line length=6mm, numbered faces, transform shape] + { cube folding }; \end{codeexample} +\end{pictype} + + +\begin{pictype}{cube truncated folding}{} + A folding of a truncated cube. +\begin{codeexample}[width=5cm] +\tikz \pic [folding line length=6mm, numbered faces, transform shape] + { cube truncated folding }; +\end{codeexample} +\end{pictype} + +\begin{pictype}{octahedron folding}{} + A folding of an octahedron. +\begin{codeexample}[] +\tikz \pic [folding line length=6mm, numbered faces, transform shape] + { octahedron folding }; +\end{codeexample} +\end{pictype} + + +\begin{pictype}{octahedron folding}{} + A folding of a truncated octahedron. +\begin{codeexample}[] +\tikz \pic [folding line length=6mm, numbered faces, transform shape] + { octahedron truncated folding }; +\end{codeexample} +\end{pictype} + + +\begin{pictype}{dodecahedron folding}{} + A folding of a dodecahedron. + +\begin{codeexample}[] +\tikz \pic [folding line length=6mm, numbered faces, transform shape] + { dodecahedron folding }; +\end{codeexample} +\end{pictype} + +\begin{pictype}{dodecahedron' folding}{} + This is an alternative folding of a dodecahedron. +\begin{codeexample}[] +\tikz \pic [folding line length=6mm, numbered faces, transform shape] + { dodecahedron' folding }; +\end{codeexample} +\end{pictype} + + + + +\begin{pictype}{cuboctahedron folding}{} + A folding of a cuboctahedron. +\begin{codeexample}[] +\tikz \pic [folding line length=6mm, numbered faces, transform shape] + { cuboctahedron folding }; +\end{codeexample} +\end{pictype} + + +\begin{pictype}{cuboctahedron truncated folding}{} + A folding of a truncated cuboctahedron. +\begin{codeexample}[] +\tikz \pic [folding line length=6mm, numbered faces, transform shape] + { cuboctahedron truncated folding }; +\end{codeexample} +\end{pictype} + + +\begin{pictype}{icosahedron folding}{} + A folding of an icosahedron. +\begin{codeexample}[] +\tikz \pic [folding line length=6mm, numbered faces, transform shape] + { icosahedron folding }; +\end{codeexample} +\end{pictype} + + +\begin{pictype}{rhombicuboctahedron folding}{} + A folding of an rhombicuboctahedron. +\begin{codeexample}[] +\tikz \pic [folding line length=6mm, numbered faces, transform shape] + { rhombicuboctahedron folding }; +\end{codeexample} +\end{pictype} + + +\begin{pictype}{snub cube folding}{} + A folding of a snub cube. +\begin{codeexample}[width=5cm] +\tikz \pic [folding line length=6mm, numbered faces, transform shape] + { snub cube folding }; +\end{codeexample} +\end{pictype} + + +\begin{pictype}{icosidodecahedron folding}{} + A folding of an icosidodecahedron. +\begin{codeexample}[] +\tikz \pic [folding line length=6mm, numbered faces, transform shape] + { icosidodecahedron folding }; +\end{codeexample} +\end{pictype} + %%% Local Variables: diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-fpu.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-fpu.tex index 88784f3b9be..7177e771b95 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-fpu.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-fpu.tex @@ -18,23 +18,53 @@ \pgfkeys{/pgf/fpu} \begin{pgflibrary}{fpu} - The floating point unit (fpu) allows the full data range of scientific computing for use in \pgfname. Its core is the \pgfname\ math routines for mantissa operations, leading to a reasonable trade--of between speed and accuracy. It does not require any third--party packages or external programs. + The floating point unit (fpu) allows the full data range of + scientific computing for use in \pgfname. Its core is the \pgfname\ + math routines for mantissa operations, leading to a reasonable + trade--of between speed and accuracy. It does not require any + third--party packages or external programs. \end{pgflibrary} \subsection{Overview} -The fpu provides a replacement set of math commands which can be installed in isolated placed to achieve large data ranges at reasonable accuracy. It provides at least\footnote{To be more precise, the FPU's exponent is currently a 32 bit integer. That means it supports a significantly larger data range than an IEEE double precision number -- but if a future \TeX\ version may provide lowlevel access to doubles, this may change.} the IEEE double precision data range, $\pgfmathprintnumber{-1e+324}, \dotsc, \pgfmathprintnumber{+1e324}$. The absolute smallest number bigger than zero is $\pgfmathprintnumber{1e-324}$. The FPU's relative precision is at least $\pgfmathprintnumber{1e-4}$ although operations like addition have a relative precision of $\pgfmathprintnumber{1e-6}$. - -Note that the library has not really been tested together with any drawing operations. It should be used to work with arbitrary input data which is then transformed somehow into \pgfname\ precision. This, in turn, can be processed by \pgfname. +The fpu provides a replacement set of math commands which can be +installed in isolated placed to achieve large data ranges at +reasonable accuracy. It provides at least\footnote{To be more precise, + the FPU's exponent is currently a 32 bit integer. That means it + supports a significantly larger data range than an IEEE double + precision number -- but if a future \TeX\ version may provide + lowlevel access to doubles, this may change.} the IEEE double +precision data range, $\pgfmathprintnumber{-1e+324}, \dotsc, +\pgfmathprintnumber{+1e324}$. The absolute smallest number bigger than +zero is $\pgfmathprintnumber{1e-324}$. The FPU's relative precision is +at least $\pgfmathprintnumber{1e-4}$ although operations like addition +have a relative precision of $\pgfmathprintnumber{1e-6}$. + +Note that the library has not really been tested together with any +drawing operations. It should be used to work with arbitrary input +data which is then transformed somehow into \pgfname\ precision. This, +in turn, can be processed by \pgfname. \subsection{Usage} \begin{key}{/pgf/fpu=\marg{boolean} (default true)} - This key installs or uninstalls the FPU. The installation exchanges any routines of the standard math parser with those of the FPU: |\pgfmathadd| will be replaced with |\pgfmathfloatadd| and so on. Furthermore, any number will be parsed with |\pgfmathfloatparsenumber|. + This key installs or uninstalls the FPU. The installation exchanges + any routines of the standard math parser with those of the FPU: + |\pgfmathadd| will be replaced with |\pgfmathfloatadd| and so + on. Furthermore, any number will be parsed with + |\pgfmathfloatparsenumber|. \begin{codeexample}[] \pgfkeys{/pgf/fpu} \pgfmathparse{1+1}\pgfmathresult \end{codeexample} -\noindent The FPU uses a lowlevel number representation consisting of flags, mantissa and exponent\footnote{Users should \emph{always} use high level routines to manipulate floating point numbers as the format may change in a future release.}. To avoid unnecessary format conversions, |\pgfmathresult| will usually contain such a cryptic number. Depending on the context, the result may need to be converted into something which is suitable for \pgfname\ processing (like coordinates) or may need to be typeset. The FPU provides such methods as well. + \noindent The FPU uses a lowlevel number representation consisting + of flags, mantissa and exponent\footnote{Users should \emph{always} + use high level routines to manipulate floating point numbers as + the format may change in a future release.}. To avoid unnecessary + format conversions, |\pgfmathresult| will usually contain such a + cryptic number. Depending on the context, the result may need to be + converted into something which is suitable for \pgfname\ processing + (like coordinates) or may need to be typeset. The FPU provides such + methods as well. %-------------------------------------------------- % \begin{codeexample}[] @@ -44,29 +74,40 @@ Note that the library has not really been tested together with any drawing opera % \end{codeexample} %-------------------------------------------------- - Use |fpu=false| to deactivate the FPU. This will restore any change. Please note that this is not necessary if the FPU is used inside of a \TeX\ group -- it will be deactivated afterwards anyway. + Use |fpu=false| to deactivate the FPU. This will restore any + change. Please note that this is not necessary if the FPU is used + inside of a \TeX\ group -- it will be deactivated afterwards + anyway. - It does not hurt to call |fpu=true| or |fpu=false| multiple times. + It does not hurt to call |fpu=true| or |fpu=false| multiple times. - Please note that if the |fixed point arithmetics| library of \pgfname\ will be activated after the FPU, the FPU will be deactivated automatically. + Please note that if the |fixed point arithmetics| library of + \pgfname\ will be activated after the FPU, the FPU will be + deactivated automatically. \end{key} \begin{key}{/pgf/fpu/output format=\mchoice{float,sci,fixed} (initially float)} - This key allows to change the number format in which the FPU assigns |\pgfmathresult|. - - The predefined choice |float| uses the low-level format used by the FPU. This is useful for further processing inside of any library. + This key allows to change the number format in which the FPU assigns + |\pgfmathresult|. + + The predefined choice |float| uses the low-level format used by the + FPU. This is useful for further processing inside of any library. \begin{codeexample}[] \pgfkeys{/pgf/fpu,/pgf/fpu/output format=float} \pgfmathparse{exp(50)*42}\pgfmathresult \end{codeexample} - The choice |sci| returns numbers in the format \meta{mantissa}|e|\meta{exponent}. It provides almost no computational overhead. + The choice |sci| returns numbers in the format + \meta{mantissa}|e|\meta{exponent}. It provides almost no + computational overhead. \begin{codeexample}[] \pgfkeys{/pgf/fpu,/pgf/fpu/output format=sci} \pgfmathparse{4.22e-8^-2}\pgfmathresult \end{codeexample} - The choice |fixed| returns normal fixed point numbers and provides the highest compatibility with the \pgfname\ engine. It is activated automatically in case the FPU scales results. + The choice |fixed| returns normal fixed point numbers and provides + the highest compatibility with the \pgfname\ engine. It is activated + automatically in case the FPU scales results. \begin{codeexample}[] \pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed} \pgfmathparse{sqrt(1e-12)}\pgfmathresult @@ -74,48 +115,77 @@ Note that the library has not really been tested together with any drawing opera \end{key} \begin{key}{/pgf/fpu/scale results=\marg{scale}} - A feature which allows semi--automatic result scaling. Setting this key has two effects: first, the output format for \emph{any} computation will be set to |fixed| (assuming results will be processed by \pgfname's kernel). Second, any expression which starts with a star, |*|, will be multiplied with \marg{scale}. + A feature which allows semi-automatic result scaling. Setting this + key has two effects: first, the output format for \emph{any} + computation will be set to |fixed| (assuming results will be + processed by \pgfname's kernel). Second, any expression which starts + with a star, |*|, will be multiplied with \meta{scale}. \end{key} \begin{keylist}{ - /pgf/fpu/scale file plot x=\marg{scale},% - /pgf/fpu/scale file plot y=\marg{scale},% - /pgf/fpu/scale file plot z=\marg{scale}}% - These keys will patch \pgfname's |plot file| command to automatically scale single coordinates by \marg{scale}. - - The initial setting does not scale |plot file|. + /pgf/fpu/scale file plot x=\marg{scale},% + /pgf/fpu/scale file plot y=\marg{scale},% + /pgf/fpu/scale file plot z=\marg{scale}}% + These keys will patch \pgfname's |plot file| command to + automatically scale single coordinates by \meta{scale}. + + The initial setting does not scale |plot file|. \end{keylist} \begin{command}{\pgflibraryfpuifactive\marg{true-code}\marg{false-code}} - This command can be used to execute dependent on whether the FPU has been activated or not. + This command can be used to execute either \meta{true-code} or + \meta{false-code}, depending on whether the FPU has been activated + or not. \end{command} \subsection{Comparison to the fixed point arithmetics library} -There are other ways to increase the data range and/or the precision of \pgfname's math parser. One of them is the |fp| package, preferable combined with \pgfname's |fixed point arithmetic| library. The differences between the FPU and |fp| are: +There are other ways to increase the data range and/or the precision +of \pgfname's math parser. One of them is the |fp| package, preferable +combined with \pgfname's |fixed point arithmetic| library. The +differences between the FPU and |fp| are: \begin{itemize} - \item The FPU supports at least the complete IEEE double precision number range, while |fp| covers only numbers of magnitude $\pm\pgfmathprintnumber{1e17}$. - \item The FPU has a uniform relative precision of about 4--5 correct digits. The fixed point library has an absolute precision which may perform good in many cases -- but will fail at the ends of the data range (as every fixed point routines does). - \item The FPU has potential to be faster than |fp| as it has access to fast mantissa operations using \pgfname's math capabilities (which use \TeX\ registers). +\item The FPU supports at least the complete IEEE double precision + number range, while |fp| covers only numbers of magnitude + $\pm\pgfmathprintnumber{1e17}$. +\item The FPU has a uniform relative precision of about 4--5 correct + digits. The fixed point library has an absolute precision which may + perform good in many cases -- but will fail at the ends of the data + range (as every fixed point routines does). +\item The FPU has potential to be faster than |fp| as it has access to + fast mantissa operations using \pgfname's math capabilities (which + use \TeX\ registers). \end{itemize} \subsection{Command Reference and Programmer's Manual} \subsubsection{Creating and Converting Floats} \begin{command}{\pgfmathfloatparsenumber\marg{x}} - Reads a number of arbitrary magnitude and precision and stores its result into |\pgfmathresult| as floating point number $m \cdot 10^e$ with mantissa and exponent base~$10$. + Reads a number of arbitrary magnitude and precision and stores its + result into |\pgfmathresult| as floating point number $m \cdot 10^e$ + with mantissa and exponent base~$10$. - The algorithm and the storage format is purely text-based. The number is stored as a triple of flags, a positive mantissa and an exponent, such as + The algorithm and the storage format is purely text-based. The + number is stored as a triple of flags, a positive mantissa and an + exponent, such as \begin{codeexample}[] \pgfmathfloatparsenumber{2} \pgfmathresult \end{codeexample} - Please do not rely on the low-level representation here, use |\pgfmathfloattomacro| (and its variants) and |\pgfmathfloatcreate| if you want to work with these components. + Please do not rely on the low-level representation here, use + |\pgfmathfloattomacro| (and its variants) and |\pgfmathfloatcreate| + if you want to work with these components. - The flags encoded in |\pgfmathresult| are represented as a digit where `$0$' stands for the number $\pm 0\cdot 10^0$, `$1$' stands for a positive sign, `$2$' means a negative sign, `$3$' stands for `not a number', `$4$' means $+\infty$ and `$5$' stands for $-\infty$. + The flags encoded in |\pgfmathresult| are represented as a digit + where `$0$' stands for the number $\pm 0\cdot 10^0$, `$1$' stands + for a positive sign, `$2$' means a negative sign, `$3$' stands for + `not a number', `$4$' means $+\infty$ and `$5$' stands for + $-\infty$. - The mantissa is a normalized real number $m \in \mathbb{R}$, $1 \le m < 10$. It always contains a period and at least one digit after the period. The exponent is an integer. + The mantissa is a normalized real number $m \in \mathbb{R}$, $1 \le + m < 10$. It always contains a period and at least one digit after + the period. The exponent is an integer. - Examples: + Examples: \begin{codeexample}[] \pgfmathfloatparsenumber{0} \pgfmathfloattomacro{\pgfmathresult}{\F}{\M}{\E} @@ -151,31 +221,47 @@ Flags: \F; Mantissa \M; Exponent \E. \pgfmathfloattomacro{\pgfmathresult}{\F}{\M}{\E} Flags: \F; Mantissa \M; Exponent \E. \end{codeexample} - The argument \marg{x} may be given in fixed point format or the scientific `e' (or `E') notation. The scientific notation does not necessarily need to be normalized. The supported exponent range is (currently) only limited by the \TeX-integer range (which uses 31 bit integer numbers). + The argument \meta{x} may be given in fixed point format or the + scientific ``e'' (or ``E'') notation. The scientific notation does not + necessarily need to be normalized. The supported exponent range is + (currently) only limited by the \TeX-integer range (which uses 31 + bit integer numbers). \end{command} \begin{key}{/pgf/fpu/handlers/empty number=\marg{input}\marg{unreadable part}} - This command key is invoked in case an empty string is parsed inside of |\pgfmathfloatparsenumber|. You can overwrite it to assign a replacement |\pgfmathresult| (in float!). + This command key is invoked in case an empty string is parsed inside + of |\pgfmathfloatparsenumber|. You can overwrite it to assign a + replacement |\pgfmathresult| (in float!). - The initial setting is to invoke |invalid number|, see below. + The initial setting is to invoke |invalid number|, see below. \end{key} \begin{key}{/pgf/fpu/handlers/invalid number=\marg{input}\marg{unreadable part}} - This command key is invoked in case an invalid string is parsed inside of |\pgfmathfloatparsenumber|. You can overwrite it to assign a replacement |\pgfmathresult| (in float!). + This command key is invoked in case an invalid string is parsed + inside of |\pgfmathfloatparsenumber|. You can overwrite it to assign + a replacement |\pgfmathresult| (in float!). - The initial setting is to generate an error message. + The initial setting is to generate an error message. \end{key} \begin{key}{/pgf/fpu/handlers/wrong lowlevel format=\marg{input}\marg{unreadable part}} - This command key is invoked whenever |\pgfmathfloattoregisters| or its variants encounter something which is no properly formatted lowlevel floating point number. As for |invalid number|, this key may assign a new |\pgfmathresult| (in floating point) which will be used instead of the offending \marg{input}. + This command key is invoked whenever |\pgfmathfloattoregisters| or + its variants encounter something which is not a properly formatted + lowlevel floating point number. As for |invalid number|, this key + may assign a new |\pgfmathresult| (in floating point) which will be + used instead of the offending \meta{input}. - The initial setting is to generate an error message. + The initial setting is to generate an error message. \end{key} \begin{command}{\pgfmathfloatqparsenumber\marg{x}} - The same as |\pgfmathfloatparsenumber|, but does not perform sanity checking. + The same as |\pgfmathfloatparsenumber|, but does not perform sanity checking. \end{command} \begin{command}{\pgfmathfloattofixed{\marg{x}}} - Converts a number in floating point representation to a fixed point number. It is a counterpart to |\pgfmathfloatparsenumber|. The algorithm is purely text based and defines |\pgfmathresult| as a string sequence which represents the floating point number \marg{x} as a fixed point number (of arbitrary precision). + Converts a number in floating point representation to a fixed point + number. It is a counterpart to |\pgfmathfloatparsenumber|. The + algorithm is purely text based and defines |\pgfmathresult| as a + string sequence which represents the floating point number \meta{x} + as a fixed point number (of arbitrary precision). \begin{codeexample}[] \pgfmathfloatparsenumber{0.00052} @@ -197,30 +283,35 @@ $\to$ \end{command} \begin{command}{\pgfmathfloattoint\marg{x}} - Converts a number from low-level floating point representation to an integer (by truncating the fractional part). + Converts a number from low-level floating point representation to an + integer (by truncating the fractional part). \begin{codeexample}[] \pgfmathfloatparsenumber{123456} \pgfmathfloattoint{\pgfmathresult} \pgfmathresult \end{codeexample} - See also |\pgfmathfloatint| which returns the result as float. +See also |\pgfmathfloatint| which returns the result as float. \end{command} \begin{command}{\pgfmathfloattosci\marg{float}} - Converts a number from low-level floating point representation to scientific format, $1.234e4$. The result will be assigned to the macro |\pgfmathresult|. + Converts a number from low-level floating point representation to + scientific format, $1.234e4$. The result will be assigned to the + macro |\pgfmathresult|. \end{command} + \begin{command}{\pgfmathfloatvalueof\marg{float}} - Expands a number from low-level floating point representation to scientific format, $1.234e4$. + Expands a number from low-level floating point representation to + scientific format, $1.234e4$. - Use |\pgfmathfloatvalueof| in contexts where only expandable macros are allowed. + Use |\pgfmathfloatvalueof| in contexts where only expandable macros are allowed. \end{command} \begin{command}{\pgfmathfloatcreate{\marg{flags}}{\marg{mantissa}}{\marg{exponent}}} - Defines |\pgfmathresult| as the floating point number encoded by - \marg{flags}, \marg{mantissa} and \marg{exponent}. + Defines |\pgfmathresult| as the floating point number encoded by + \meta{flags}, \meta{mantissa} and \meta{exponent}. - All arguments are characters and will be expanded using |\edef|. + All arguments are characters and will be expanded using |\edef|. \begin{codeexample}[] \pgfmathfloatcreate{1}{1.0}{327} \pgfmathfloattomacro{\pgfmathresult}{\F}{\M}{\E} @@ -229,19 +320,20 @@ Flags: \F; Mantissa \M; Exponent \E \end{command} \begin{command}{\pgfmathfloatifflags\marg{floating point number}\marg{flag}\marg{true-code}\marg{false-code}} - Invokes \marg{true-code} if the flag of \marg{floating point number} equals \marg{flag} and \marg{false-code} otherwise. - - The argument \marg{flag} can be one of - \begin{description} - \item[0] to test for zero, - \item[1] to test for positive numbers, - \item[+] to test for positive numbers, - \item[2] to test for negative numbers, - \item[-] to test for negative numbers, - \item[3] for ``not-a-number'', - \item[4] for $+\infty$, - \item[5] for $-\infty$. - \end{description} + Invokes \meta{true-code} if the flag of \meta{floating point number} + equals \meta{flag} and \meta{false-code} otherwise. + + The argument \meta{flag} can be one of + \begin{description} + \item[0] to test for zero, + \item[1] to test for positive numbers, + \item[+] to test for positive numbers, + \item[2] to test for negative numbers, + \item[-] to test for negative numbers, + \item[3] for ``not-a-number'', + \item[4] for $+\infty$, + \item[5] for $-\infty$. + \end{description} \begin{codeexample}[] \pgfmathfloatparsenumber{42} @@ -257,50 +349,73 @@ Flags: \F; Mantissa \M; Exponent \E \begin{command}{\pgfmathfloattomacro{\marg{x}}{\marg{flagsmacro}}{\marg{mantissamacro}}{\marg{exponentmacro}}} - Extracts the flags of a floating point number \marg{x} to \marg{flagsmacro}, the mantissa to \marg{mantissamacro} and the exponent to \marg{exponentmacro}. + Extracts the flags of a floating point number \meta{x} to + \meta{flagsmacro}, the mantissa to \meta{mantissamacro} and the + exponent to \meta{exponentmacro}. \end{command} \begin{command}{\pgfmathfloattoregisters{\marg{x}}{\marg{flagscount}}{\marg{mantissadimen}}{\marg{exponentcount}}} - Takes a floating point number \marg{x} as input and writes flags to count - register \marg{flagscount}, mantissa to dimen register \marg{mantissadimen} and exponent to count - register \marg{exponentcount}. + Takes a floating point number \meta{x} as input and writes flags to + count register \meta{flagscount}, mantissa to dimen register + \meta{mantissadimen} and exponent to count register \meta{exponentcount}. - Please note that this method rounds the mantissa to \TeX-precision. + Please note that this method rounds the mantissa to \TeX-precision. \end{command} \begin{command}{\pgfmathfloattoregisterstok{\marg{x}}{\marg{flagscount}}{\marg{mantissatoks}}{\marg{exponentcount}}} - A variant of |\pgfmathfloattoregisters| which writes the mantissa into a token register. It maintains the full input precision. + A variant of |\pgfmathfloattoregisters| which writes the + mantissa into a token register. It maintains the full input + precision. \end{command} \begin{command}{\pgfmathfloatgetflags{\marg{x}}{\marg{flagscount}}} - Extracts the flags of \marg{x} into the count register \marg{flagscount}. + Extracts the flags of \meta{x} into the count register + \meta{flagscount}. \end{command} -\begin{command}{\pgfmathfloatgetflagstomacro{\marg{x}}{\marg{\textbackslash macro}}} - Extracts the flags of \marg{x} into the macro \meta{\textbackslash macro}. +\begin{command}{\pgfmathfloatgetflagstomacro{\marg{x}}{\marg{macro}}} + Extracts the flags of \meta{x} into the macro \meta{macro}. \end{command} \begin{command}{\pgfmathfloatgetmantissa{\marg{x}}{\marg{mantissadimen}}} - Extracts the mantissa of \marg{x} into the dimen register \marg{mantissadimen}. + Extracts the mantissa of \meta{x} into the dimen register + \meta{mantissadimen}. \end{command} + \begin{command}{\pgfmathfloatgetmantissatok{\marg{x}}{\marg{mantissatoks}}} - Extracts the mantissa of \marg{x} into the token register \marg{mantissatoks}. + Extracts the mantissa of \meta{x} into the token register + \meta{mantissatoks}. \end{command} + \begin{command}{\pgfmathfloatgetexponent{\marg{x}}{\marg{exponentcount}}} - Extracts the exponent of \marg{x} into the count register \marg{exponentcount}. + Extracts the exponent of \meta{x} into the count register + \meta{exponentcount}. \end{command} \subsubsection{Symbolic Rounding Operations} -Commands in this section constitute the basic level implementations of the rounding routines. They work symbolically, i.e.\ they operate on text, not on numbers and allow arbitrarily large numbers. + +Commands in this section constitute the basic level implementations of +the rounding routines. They work symbolically, i.e.\ they operate on +text, not on numbers and allow arbitrarily large numbers. \begin{command}{\pgfmathroundto{\marg{x}}} - Rounds a fixed point number to prescribed precision and writes the result to |\pgfmathresult|. + Rounds a fixed point number to prescribed precision and writes the + result to |\pgfmathresult|. - The desired precision can be configured with |/pgf/number format/precision|, see section~\ref{pgfmath-numberprinting}. This section does also contain application examples. + The desired precision can be configured with + |/pgf/number format/precision|, see + section~\ref{pgfmath-numberprinting}. This section does also contain + application examples. - Any trailing zeros after the period are discarded. The algorithm is purely text based and allows to deal with precisions beyond \TeX's fixed point support. - - As a side effect, the global boolean |\ifpgfmathfloatroundhasperiod| will be set to true if and only if the resulting mantissa has a period. Furthermore, |\ifpgfmathfloatroundmayneedrenormalize| will be set to true if and only if the rounding result's floating point representation would have a larger exponent than \marg{x}. + Any trailing zeros after the period are discarded. The algorithm is + purely text based and allows to deal with precisions beyond \TeX's + fixed point support. + + As a side effect, the global boolean |\ifpgfmathfloatroundhasperiod| + will be set to true if and only if the resulting mantissa has a + period. Furthermore, |\ifpgfmathfloatroundmayneedrenormalize| will + be set to true if and only if the rounding result's floating point + representation would have a larger exponent than \meta{x}. \begin{codeexample}[] \pgfmathroundto{1} \pgfmathresult @@ -316,7 +431,8 @@ Commands in this section constitute the basic level implementations of the round \end{command} \begin{command}{\pgfmathroundtozerofill{\marg{x}}} - A variant of |\pgfmathroundto| which always uses a fixed number of digits behind the period. It fills missing digits with zeros. + A variant of |\pgfmathroundto| which always uses a fixed number of + digits behind the period. It fills missing digits with zeros. \begin{codeexample}[] \pgfmathroundtozerofill{1} \pgfmathresult @@ -332,13 +448,19 @@ Commands in this section constitute the basic level implementations of the round \end{command} \begin{command}{\pgfmathfloatround{\marg{x}}} - Rounds a normalized floating point number to a prescribed precision and writes the result to |\pgfmathresult|. + Rounds a normalized floating point number to a prescribed precision + and writes the result to |\pgfmathresult|. - The desired precision can be configured with |/pgf/number format/precision|, see section~\ref{pgfmath-numberprinting}. + The desired precision can be configured with + |/pgf/number format/precision|, see + section~\ref{pgfmath-numberprinting}. - This method employs |\pgfmathroundto| to round the mantissa and applies renormalization if necessary. + This method employs |\pgfmathroundto| to round the mantissa and + applies renormalization if necessary. - As a side effect, the global boolean |\ifpgfmathfloatroundhasperiod| will be set to true if and only if the resulting mantissa has a period. + As a side effect, the global boolean |\ifpgfmathfloatroundhasperiod| + will be set to true if and only if the resulting mantissa has a + period. \begin{codeexample}[] \pgfmathfloatparsenumber{52.5864} \pgfmathfloatround{\pgfmathresult} @@ -354,7 +476,8 @@ Commands in this section constitute the basic level implementations of the round \end{command} \begin{command}{\pgfmathfloatroundzerofill{\marg{x}}} - A variant of |\pgfmathfloatround| produces always the same number of digits after the period (it includes zeros if necessary). + A variant of |\pgfmathfloatround| produces always the same number of + digits after the period (it includes zeros if necessary). \begin{codeexample}[] \pgfmathfloatparsenumber{52.5864} \pgfmathfloatroundzerofill{\pgfmathresult} @@ -369,94 +492,139 @@ Commands in this section constitute the basic level implementations of the round \end{codeexample} \end{command} + + \subsubsection{Math Operations Commands} -This sections describes some of the replacement commands in more details. -Please note that these commands can be used even if the |fpu| as such has not been activated -- it is sufficient to load the library. +This section describes some of the replacement commands in more +detail. + +Please note that these commands can be used even if the |fpu| as such +has not been activated -- it is sufficient to load the library. \begin{command}{\pgfmathfloat\meta{op}} - Methods of this form constitute the replacement operations where \meta{op} can be any of the well--known math operations. + Methods of this form constitute the replacement operations where + \meta{op} can be any of the well-known math operations. - Thus, \declareandlabel{\pgfmathfloatadd} is the counterpart for |\pgfmathadd| and so on. The semantics and number of arguments is the same, but all input and output arguments are \emph{expected} to be floating point numbers. + Thus, \declareandlabel{\pgfmathfloatadd} is the counterpart + for |\pgfmathadd| and so on. The semantics and number of + arguments is the same, but all input and output arguments are + \emph{expected} to be floating point numbers. \end{command} \begin{command}{\pgfmathfloattoextentedprecision{\marg{x}}} -Renormalizes \marg{x} to extended precision mantissa, meaning -$100 \le m < 1000$ instead of $1 \le m < 10$. - -The `extended precision' means we have higher accuracy when we apply pgfmath operations to mantissas. - -The input argument is expected to be a normalized floating point number; the output argument is a non-normalized floating point number (well, normalized to extended precision). - -The operation is supposed to be very fast. + Renormalizes \meta{x} to extended precision mantissa, meaning + $100 \le m < 1000$ instead of $1 \le m < 10$. + + The ``extended precision'' means we have higher accuracy when we apply + pgfmath operations to mantissas. + + The input argument is expected to be a normalized floating point + number; the output argument is a non-normalized floating point number + (well, normalized to extended precision). + + The operation is supposed to be very fast. \end{command} \begin{command}{\pgfmathfloatsetextprecision\marg{shift}} - Sets the precision used inside of |\pgfmathfloattoextentedprecision| to \marg{shift}. - - The different choices are - - \begin{tabular}{llrll} - 0 & normalization to & $0$ & $\le m < 1$ & (disable extended precision)\\ - 1 & normalization to & $10$ & $\le m < 100$ \\ - 2 & normalization to & $100$ & $\le m < 1000$ & (default of |\pgfmathfloattoextentedprecision|)\\ - 3 & normalization to & $1000$ & $\le m < 10000$ \\ - \end{tabular} + Sets the precision used inside of |\pgfmathfloattoextentedprecision| to \meta{shift}. + + The different choices are + + \begin{tabular}{llrll} + 0 & normalization to & $0$ & $\le m < 1$ & (disable extended precision)\\ + 1 & normalization to & $10$ & $\le m < 100$ \\ + 2 & normalization to & $100$ & $\le m < 1000$ & (default of |\pgfmathfloattoextentedprecision|)\\ + 3 & normalization to & $1000$ & $\le m < 10000$ \\ + \end{tabular} \end{command} \begin{command}{\pgfmathfloatlessthan{\marg{x}}{\marg{y}}} - Defines |\pgfmathresult| as $1.0$ if $\meta{x} < \meta{y}$, but $0.0$ otherwise. It also sets the global \TeX-boolean |\pgfmathfloatcomparison| accordingly. The arguments \marg{x} and \marg{y} are expected to be numbers which have already been processed by |\pgfmathfloatparsenumber|. Arithmetics is carried out using \TeX-registers for exponent- and mantissa comparison. + Defines |\pgfmathresult| as $1.0$ if $\meta{x} < \meta{y}$, but + $0.0$ otherwise. It also sets the global \TeX-boolean + |\pgfmathfloatcomparison| accordingly. The arguments \meta{x} and + \meta{y} are expected to be numbers which have already been + processed by |\pgfmathfloatparsenumber|. Arithmetic is carried out + using \TeX-registers for exponent- and mantissa comparison. \end{command} \begin{command}{\pgfmathfloatmultiplyfixed\marg{float}\marg{fixed}} - Defines |\pgfmathresult| to be $\meta{float} \cdot \meta{fixed}$ where \meta{float} is a floating point number and \meta{fixed} is a fixed point number. The computation is performed in floating point arithmetics, that means we compute $m \cdot \meta{fixed}$ and renormalizes the result where $m$ is the mantissa of \meta{float}. + Defines |\pgfmathresult| to be $\meta{float} \cdot \meta{fixed}$ + where \meta{float} is a floating point number and \meta{fixed} is a + fixed point number. The computation is performed in floating point + arithmetics, that means we compute $m \cdot \meta{fixed}$ and + renormalize the result where $m$ is the mantissa of \meta{float}. - This operation renormalizes \meta{float} with |\pgfmathfloattoextentedprecision| before the operation, that means it is intended for relatively small arguments of \meta{fixed}. The result is a floating point number. + This operation renormalizes \meta{float} with + |\pgfmathfloattoextentedprecision| before the operation, that means + it is intended for relatively small arguments of \meta{fixed}. The + result is a floating point number. \end{command} \begin{command}{\pgfmathfloatifapproxequalrel\marg{a}\marg{b}\marg{true-code}\marg{false-code}} - Computes the relative error between \meta{a} and \meta{b} (assuming \meta{b}$\neq 0$) and - invokes \meta{true-code} if the relative error is below |/pgf/fpu/rel thresh| and - \meta{false-code} if that is not the case. + Computes the relative error between \meta{a} and \meta{b} (assuming + \meta{b}$\neq 0$) and invokes \meta{true-code} if the relative error + is below |/pgf/fpu/rel thresh| and \meta{false-code} if that is not + the case. - The input arguments will be parsed with |\pgfmathfloatparsenumber|. + The input arguments will be parsed with |\pgfmathfloatparsenumber|. - \begin{key}{/pgf/fpu/rel thresh=\marg{number} (initially 1e-4)} - A threshold used by |\pgfmathfloatifapproxequalrel| to decide whether numbers are approximately equal. - \end{key} + \begin{key}{/pgf/fpu/rel thresh=\marg{number} (initially 1e-4)} + A threshold used by |\pgfmathfloatifapproxequalrel| to decide + whether numbers are approximately equal. + \end{key} \end{command} \begin{command}{\pgfmathfloatshift{\marg{x}}{\marg{num}}} - Defines |\pgfmathresult| to be $\meta{x} \cdot 10^{\meta{num}}$. The operation is an arithmetic shift base ten and modifies only the exponent of \marg{x}. The argument \marg{num} is expected to be a (positive or negative) integer. + Defines |\pgfmathresult| to be $\meta{x} \cdot 10^{\meta{num}}$. The + operation is an arithmetic shift base ten and modifies only the + exponent of \meta{x}. The argument \meta{num} is expected to be a + (positive or negative) integer. \end{command} \begin{command}{\pgfmathfloatabserror\marg{x}\marg{y}} - Defines |\pgfmathresult| to be the absolute error between two floating point numbers $x$ and $y$, $\lvert x - y\rvert $ and returns the result as floating point number. + Defines |\pgfmathresult| to be the absolute error between two + floating point numbers $x$ and $y$, $\lvert x - y\rvert $ and + returns the result as floating point number. \end{command} \begin{command}{\pgfmathfloatrelerror\marg{x}\marg{y}} - Defines |\pgfmathresult| to be the relative error between two floating point numbers $x$ and $y$, $\lvert x - y\rvert / \lvert y \rvert $ and returns the result as floating point number. + Defines |\pgfmathresult| to be the relative error between two + floating point numbers $x$ and $y$, $\lvert x - y\rvert / \lvert y + \rvert $ and returns the result as floating point number. \end{command} \begin{command}{\pgfmathfloatint\marg{x}} -Returns the integer part of the floating point number \marg{x}, by truncating any digits after the period. This methods is applied to the absolute value $\rvert x \lvert$, so negative numbers are treated in the same way as positive ones. + Returns the integer part of the floating point number \meta{x}, by + truncating any digits after the period. This methods truncates the + absolute value $\rvert x \lvert$ to the next smaller integer and + restores the original sign afterwards. -The result is returned as floating point number as well. + The result is returned as floating point number as well. -See also |\pgfmathfloattoint| which returns the number in integer format. + See also |\pgfmathfloattoint| which returns the number in integer + format. \end{command} \begin{command}{\pgfmathlog{\marg{x}}} - Defines |\pgfmathresult| to be the natural logarithm of \marg{x}, $\ln(\meta{x})$. This method is logically the same as |\pgfmathln|, but it applies floating point arithmetics to read number \marg{x} and employs the logarithm identity - \[ \ln(m \cdot 10^e) = \ln(m) + e \cdot \ln(10) \] - to get the result. The factor $\ln(10)$ is a constant, so only $\ln(m)$ with $1 \le m < 10$ needs to be computed. This is done using standard pgf math operations. - - Please note that \marg{x} needs to be a number, expression parsing is not possible here. - - If \marg{x} is \emph{not} a bounded positive real number (for example $\meta{x} \le 0$), |\pgfmathresult| will be \emph{empty}, no error message will be generated. + Defines |\pgfmathresult| to be the natural logarithm of \meta{x}, + $\ln(\meta{x})$. This method is logically the same as |\pgfmathln|, + but it applies floating point arithmetics to read number \meta{x} + and employs the logarithm identity + \[ \ln(m \cdot 10^e) = \ln(m) + e \cdot \ln(10) \] + to get the result. The factor $\ln(10)$ is a constant, so only + $\ln(m)$ with $1 \le m < 10$ needs to be computed. This is done + using standard pgf math operations. + + Please note that \meta{x} needs to be a number, expression parsing + is not possible here. + + If \meta{x} is \emph{not} a bounded positive real number (for + example $\meta{x} \le 0$), |\pgfmathresult| will be \emph{empty}, no + error message will be generated. \begin{codeexample}[] \pgfmathlog{1.452e-7} \pgfmathresult @@ -468,10 +636,16 @@ See also |\pgfmathfloattoint| which returns the number in integer format. \end{command} \subsubsection{Accessing the Original Math Routines for Programmers} -As soon as the library is loaded, every private math routine will be copied to a new name. -This allows library and package authors to access the \TeX-register based math routines even if the FPU is activated. And, of course, it allows the FPU as such to perform its own mantissa computations. -The private implementations of \pgfname\ math commands, which are of the form |\pgfmath|\meta{name}|@|, will be available as|\pgfmath@basic@|\meta{name}|@| as soon as the library is loaded. +As soon as the library is loaded, every private math routine will be +copied to a new name. This allows library and package authors to +access the \TeX-register based math routines even if the FPU is +activated. And, of course, it allows the FPU as such to perform its +own mantissa computations. + +The private implementations of \pgfname\ math commands, which are of +the form |\pgfmath|\meta{name}|@|, will be available +as|\pgfmath@basic@|\meta{name}|@| as soon as the library is loaded. \endgroup diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-lsystems.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-lsystems.tex index 0aeb8113b01..75462b19720 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-lsystems.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-lsystems.tex @@ -126,13 +126,13 @@ only defined when the \meta{specification} argument is executed. The symbols |[| and |]| act like a stack: |[| pushes the state of the L-system on to the stack, and |]| pops a state off the stack. - When \meta{code} is executed the transformation matrix is set up + When \meta{code} is executed, the transformation matrix is set up so that the origin is at the current position and the positive x-axis ``points forward'', so |\pgfpathlineto{\pgfpoint{1cm}{0cm}}| draws a line 1cm forward. The following keys can alter the production of an L-system. However, -thy do not store values in themselves. +they do not store values in themselves. \begin{key}{/pgf/lindenmayer system/step=\meta{length} (initially 5pt)} How far the L-system moves forward if required. This key sets the @@ -161,7 +161,7 @@ thy do not store values in themselves. The value is stored in the \TeX{} macro |\pgflsystemrandomizeanglepercent|. \end{key} -For speed and convenience, when the code for a symbol is executed the +For speed and convenience, when the code for a symbol is executed, the following commands are available. \begin{command}{\pgflsystemcurrentstep} @@ -189,18 +189,18 @@ The following commands may be useful if you wish to define your own symbols. \begin{command}{\pgflsystemrandomizestep} - Randomizes the value in |\pgflsystemcurrentstep| according to the - value of the |randomize| |step| |percent| key. + Randomizes the value in |\pgflsystemcurrentstep| according to the + current value of the key |randomize step percent|. \end{command} \begin{command}{\pgflsystemrandomizeleftangle} Randomizes the value in |\pgflsystemcurrentleftangle| according to - the value of the |randomize| |angle| |percent| key. + the value of the |randomize angle percent| key. \end{command} \begin{command}{\pgflsystemrandomizerightangle} Randomizes the value in |\pgflsystemcurrentrightangle| according - to the value of the |randomize| |angle| key. + to the value of the |randomize angle| key. \end{command} \begin{command}{\pgflsystemdrawforward} @@ -252,17 +252,15 @@ symbols. need not have been declared using |\symbol| or exist as a default symbol (in fact, the more interesting L-systems depend on using symbols with no corresponding code, to control the ``growth'' of the - system). - \meta{body} consists of a string of symbols, which again need not - necessarily have any code associated with them. - + system). \meta{body} consists of a string of symbols, which again + need not necessarily have any code associated with them. \end{command} - As an example, the following shows an L-system that uses - some of these commands. This example illustrates the point - that some symbols, in this case |A| and |B|, do not have to - have code associated with them. They simply control the - growth of the system. +As an example, the following shows an L-system that uses +some of these commands. This example illustrates the point +that some symbols, in this case |A| and |B|, do not have to +have code associated with them. They simply control the +growth of the system. \begin{codeexample}[pre={\nullfont\expandafter\let\csname pgf@lsystem@Hilbert curve\endcsname=\relax}] \pgfdeclarelindenmayersystem{Hilbert curve}{ @@ -286,11 +284,11 @@ The following command is used to run an L-system in \pgfname: \begin{command}{\pgflindenmayersystem\marg{name}\marg{axiom}\marg{order}} Runs the L-system called \meta{name} using the input string \meta{axiom} for \meta{order} iterations. - In general, prior to calling this command the + In general, prior to calling this command, the transformation matrix should be set appropriately for shifting and rotating, and a move-to to the (transformed) origin should be executed. This origin will be where the L-system starts. - In addition the relevant keys should be set appropriately. + In addition, the relevant keys should be set appropriately. \begin{codeexample}[] \begin{tikzpicture} @@ -305,7 +303,7 @@ The following command is used to run an L-system in \pgfname: \end{tikzpicture} \end{codeexample} - Note that, it is perfectly feasible for an L-system to define + Note that it is perfectly feasible for an L-system to define special symbols which perform the move-to and use-path operations. @@ -346,9 +344,7 @@ The following command is used to run an L-system in \pgfname: This library adds some additional keys for specifying L-systems. These keys only work in \tikzname{} and all -have the same path, namely, |/pgf/lindenmayer| |system|, but so -you do not have to keep repeating this path the following keys are -provided: +have the same path, namely, |/pgf/lindenmayer| |system|, but the following keys are provided for convenience, so that you do not have to keep repeating this path: \begin{stylekey}{/pgf/lindenmayer system=\marg{keys}} \keyalias{tikz} @@ -362,15 +358,15 @@ A more compact version of the previous key. \end{stylekey} \begin{key}{/pgf/lindenmayer system/name=\marg{name}} - Set the name for the L-system. + Sets the name for the L-system. \end{key} \begin{key}{/pgf/lindenmayer system/axiom=\marg{string}} - Set the axiom (or input string) for the L-system. + Sets the axiom (or input string) for the L-system. \end{key} \begin{key}{/pgf/lindenmayer system/order=\marg{integer}} - Set the number of iterations the L-system will perform. + Sets the number of iterations the L-system will perform. \end{key} \begin{key}{/pgf/lindenmayer system/rule set=\marg{list}} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-math.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-math.tex new file mode 100644 index 00000000000..7d30a93c9d3 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-math.tex @@ -0,0 +1,547 @@ +% Copyright 2013 by Mark Wibrow +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + + +\section{Math Library} +\label{section-library-math} + +\begin{tikzlibrary}{math} + This library defines a simple mathematical language + to define simple functions and perform sequences of basic mathematical + operations. +\end{tikzlibrary} + + +\subsection{Overview} + + \pgfname\ and \tikzname\ both use the \pgfname\ mathematical engine + which provides many commands for parsing expressions. Unfortunately + the \pgfname\ math engine is somewhat cumbersome for long sequences + of mathematical + operations, particularly when assigning values to multiple variables. + The \tikzname\ |calc| library + provides some additional ``convenience'' operations for doing calculations + (particularly with coordinates), but this can only be used inside + \tikzname\ path commands. + + This |math| library provides a means to + perform sequences of mathematical operations in a more `user friendly' + manner than the \pgfname\ math engine. In addition, the coordinate calculations of the |calc| library + can be accessed (provided it is loaded). + % + However as the |math| library uses the \pgfname\ math engine -- which uses pure \TeX\ + to perform all its calculations -- it is subject to the same speed + and accuracy limitations. It is worth bearing this in mind, before + trying to implement algorithms requiring intensive and highly + accurate computation. You can, of course use the |fp| or the |fpu| + libraries to increase the accuracy (but not necessarily the speed) + of computations. + + For most purposes, the features provided by this library are accessed + using the following command: + +\begin{command}{\tikzmath\texttt{\{}\meta{statements}\texttt{\}}} + + This command process a series of \meta{statements} which can + represent assignments, function definitions, conditional evaluation, + and iterations. It provides, in effect, a miniature mathematical + language to perform basic mathematical operations. + Perhaps the most important thing to remember is that \emph{every + statement should end with a semi-colon}. This is + likely to be the most common reason why the |\tikzmath| command fails. + +\begin{codeexample}[] +\tikzmath{ + % Adapted from http://www.cs.northwestern.edu/academics/courses/110/html/fib_rec.html + function fibonacci(\n) { + if \n == 0 then { + return 0; + } else { + return fibonacci2(\n, 0, 1); + }; + }; + function fibonacci2(\n, \p, \q) { + if \n == 1 then { + return \q; + } else { + return fibonacci2(\n-1, \q, \p+\q); + }; + }; + int \f, \i; + for \i in {0,1,...,20}{ + \f = fibonacci(\i); + print {\f, }; + }; +} +\end{codeexample} + +\end{command} + +In addition to this command the following key is provided: + +\begin{key}{/tikz/evaluate={\meta{statements}}} + This key simply executes |\tikzmath{|\meta{statements}|}|. + +\begin{codeexample}[] +\tikz[x=0.25cm,y=0.25cm, + evaluate={ + int \i, \j; + for \i in {0,...,10}{ + for \j in {0,...,10}{ + \a{\i,\j} = (\i+\j)*5; + }; + }; + } +] +\foreach \i in {0,...,10} + \foreach \j in {0,...,10} + \fill [red!\a{\i,\j}!yellow] (\i,\j) rectangle ++(1, 1); + +\end{codeexample} + + +\end{key} + + + The following sections describe the miniature language that this + library provides and can be used in the |\tikzmath| command and the |evaluate| key. + The language consists only of simple keywords and expressions but + the mini-parser allows you to format code in a reasonably versatile + way (much like the |tikz| parser) except that + \emph{all the keywords must be followed by at least one space}. + This is the second most important thing to remember (after + remembering to insert semi-colons at the end of every statement). + + +\subsection{Assignment} + + In the simplest case, you will want to evaluate an expression + and assign it to a macro, or a \TeX\ count or dimension register. + In this case, use of the |math| library is straightforward: + +\begin{codeexample}[] +\newcount\mycount +\newdimen\mydimen +\tikzmath{ + \a = 4*5+6; + \b = sin(30)*4; + \mycount = log10(2048) / log10(2); + \mydimen = 15^2; +} +\a, \b, \the\mycount, \the\mydimen +\end{codeexample} + + + In addition, \TeX-macros (\emph{not} \TeX\ registers) + can be suffixed with an index, similar to + indices in mathematical notation, for example, $x_1$, $x_2$, $x_3$: + +\begin{codeexample}[] +\tikzmath{ + \x1 = 3+4; \x2 = 30+40; \x3 = 300+400; +} +\x1, \x2, \x3 +\end{codeexample} + + The index does not have to be a number. By using braces |{}|, + more sophisticated indices can be created: + +\begin{codeexample}[] +\tikzmath{ + \c{air} = 340; \c{water} = 1435; \c{steel} = 6100; +} +\foreach \medium in {air,steel}{The speed of sound in \medium\ is \c{\medium} m/s. } +\end{codeexample} + + You should not, however, try to mix indexed and non-indexed variables. Once + an assignment is made using an index, the |math| library expects + all instances of the variable on the right hand side of an assignment + to be followed by an index. This effect is reversed if you + subsequently make an assignment to the variable without an index: the |math| library + (or to be precise the \pgfname\ math-engine) + will then ignore any index following the variable on the right hand side + of an assignment. + + In some cases, you may wish to assign a value or expression to a variable + without evaluating it with the \pgfname\ math-engine. In this case, you + can use the following keyword: + +\begin{math-keyword}{{let} \meta{variable} \texttt{=} \meta{expression}\texttt{;}} + + This keyword assigns \meta{expression} to \meta{variable} + without evaluation. The \meta{expression} is however fully + expanded using |\edef|. Any spaces preceding \meta{expression} + are removed, but any trailing spaces (before the semi-colon) + are included. + +\begin{codeexample}[] +\tikzmath{ + let \x = (5*4)+1; + let \c1 = blue; +} +\x, ``\c1'' +\end{codeexample} +\end{math-keyword} + +\subsection{Integers, ``Real'' Numbers, and Coordinates} + + By default, assignments are made by evaluating expressions + using the \pgfname\ math-engine and + results are usually returned as number with a decimal point (unless you + are assigning to a count register or use the |int| function). + % + As this is not always desirable, the |math| library allows + variables -- which \emph{must} be \TeX\ macros -- to be `declared' + as being a particular `type'. The library recognizes three types: + integers (numbers without a decimal point), + real numbers (numbers with a decimal point\footnote{Strictly speaking, due to the + finite range and precision of \TeX\ numerical capabilities, the term ``real'' is + not correct.}), and coordinates. + + To declare a variable as being one of the three types, + you can use the keywords shown below. It is important to remember + that by telling the |math| library you want it to do a + particular assignment for a variable, it will also do the same + assignment when the variable is indexed. + +\begin{codeexample}[] +\tikzmath{ + integer \x; + \x1 = 3+4; \x2 = 30+40; \x3 = 300+400; +} +\x1, \x2, \x3 +\end{codeexample} + + +% But, if you want integer results without using a count register or the +% |int| function, you can use a keyword to indicate this: + +\begin{math-keyword}{{integer} \meta{variable}\opt{\texttt{,} +\meta{additional variables}}\texttt{;}} + + The |integer| keyword indicates that assignments to the \meta{variable} or + the comma separated list of \meta{additional variables} should be + truncated (not rounded) to integers. The variables should be ordinary + macros -- \emph{not} \TeX\ registers. In addition the variables + should \emph{not} be indexed. + +\begin{codeexample}[] +\tikzmath{ + integer \x, \y, \z; + \x = 4*5+6; + \y = sin(30)*4; + \z = log10(512) / log10(2); + print {$x=\x$, $y=\y$, $z=\z$}; +} +\end{codeexample} + +\end{math-keyword} + +\begin{math-keyword}{{int} \meta{variable}\opt{\texttt{,} +\meta{additional variables}}\texttt{;}} + Short version of the |integer| keyword. +\end{math-keyword} + + Having declared a variable as an integer, the |math| library will + continue to assign only integers to that variable within the + current \TeX\ scope. If you wish to assign non-integer (i.e., \emph{real}) + numbers to the same variable, the following keyword can be used. + +\begin{math-keyword}{{real} \meta{variable}\opt{\texttt{,} +\meta{additional variables}}\texttt{;}} + The |real| keyword ensures that assignments \meta{variable} + (and \meta{additional variables}) will not be truncated to integers. +\end{math-keyword} + + In order to take advantage of |math| library interface to the + |calc| library you must indicate that a variable is to be assigned + coordinates, using the following keyword. + +\begin{math-keyword}{{coordinate} +\meta{variable}\opt{\texttt{,} +\meta{additional variables}}\texttt{;}}% + + This keyword enables \tikzname-style coordinates such as |(2cm,3pt)| or + |(my node.east)| to be parsed and + assigned to \meta{variable} in the form $x,y$, which can then be used + in a |tikzpicture|: + +\begin{codeexample}[] +\tikzmath{ + coordinate \c; + \c = (45:10pt); +} +\tikz\draw (0,0) -- (\c); +\end{codeexample} + + If the \tikzname\ |calc| library is loaded, + coordinate calculations can be performed; + the coordinate expression does not have to be + surrounded by |($|\ldots|$)|. + +\begin{codeexample}[] +\tikzmath{ + coordinate \c, \d; + \c = (-1,2)+(1,-1); + \d = (4,1)-(2,-1); +} +\tikz\draw (\c) -- (\d); +\end{codeexample} + + In addition to assigning the $x$ and $y$ coordinates to \meta{variable} + (possibly with an optional index), two further + variables are defined. The first takes the name of \meta{variable} + (e.g., |\c|) suffixed with |x| (i.e., |\cx|) and is assigned the + $x$ coordinate of |\c|. + The second takes the name of \meta{variable} + suffixed with |y| (i.e., |\cy|) and is assigned the + $y$ coordinate of |\c|. + +\begin{codeexample}[] +\tikzmath{ + coordinate \c; + \c1 = (30:20pt); + \c2 = (210:20pt); +} +\tikz\draw (\cx1,\cy1) -- (\cx2,\cy1) -- (\cx2,\cy2) -- (\cx1,\cy2); +\end{codeexample} + +\end{math-keyword} + +%\begin{math-keyword}{{point} +%\meta{variable}\opt{\texttt{,} +%\meta{additional variables}}\texttt{;}}% +% +% The |point| keyword is a synonym for the |coordinate| keyword +% and performs the same function. +%\end{math-keyword} + + +\subsection{Repeating Things} + +\begin{math-keyword}{{for} \meta{variable} \texttt{in +\{}\meta{list}\texttt{\}\{}\meta{expressions}\texttt{\};}} + + This is a ``trimmed down'' version of the |\foreach| command available + as part of \pgfname\ and \tikzname, but cannot currently be used + outside of the |\tikzmath| command. + It is important to note the following: + +\begin{itemize} + +\item + Every value in \meta{list} is evaluated using the \pgfname\ mathematical + engine. However, if an item in \meta{list} contains a comma, it \emph{must} be + surrounded + by braces, for example, |{mod(5, 2)}|. + +\begin{codeexample}[] +\tikzmath{ + int \x, \v; + \v=1; + for \x in {1,...,{random(3,10)}}{ + \v=\v*2; + }; + print {$x=\x, v=\v$}; +} +\end{codeexample} + +\item + Because each item is evaluated, you cannot + use \tikzname\ coordinates in \meta{list}. + +\item + Only single variable assignment is supported. + +\item + The ``dots notation'' (e.\,g., |1,2,...,9|) can be used in \meta{list}, + but is not as sophisticated as the \pgfname\ |\foreach| command. + In particular, contextual replacement is not possible. + +\item + Assignments that occur in the loop body \emph{are not scoped}. + They last beyond the body of each iteration and the end of the |for| + statement. This includes the values assigned to the \meta{variable}. + +\begin{codeexample}[] +\tikzmath{ + int \x, \y; + \y = 0; + for \x1 in {1,...,5}{ + for \x2 in {10,20,...,50}{ + \y = \y+\x1*\x2; + }; + }; +} +$x_1=\x1, x_2=\x2, y=\y$ +\end{codeexample} + + + + + +\end{itemize} + +\end{math-keyword} + + + + + + + + +\subsection{Branching Statements} + + Sometimes you may wish to execute different statements + depending on the value of an expression. In this + case the following keyword can be used: + +\begin{math-keyword}{{if} \meta{condition} \texttt{then \{}\meta{if-non-zero-statements}\texttt{\};}} + + This keyword executes \meta{if-non-zero-statements} if the expression in \meta{condition} + evaluates to any value other than zero. + +\end{math-keyword} + +\begin{math-keyword}{{if} \meta{condition} \texttt{then \{}\meta{if-non-zero-statements}\texttt{\}} \texttt{else} \texttt{\{}\meta{if-zero-statements}\texttt{\}}\texttt{;}} + + This keyword executes \meta{if-non-zero-statements} if the expression in \meta{condition} + evaluates to any value other than zero and the \meta{if-zero-statements} are executed if + the expression in \meta{condition} evaluates to zero. + +\begin{codeexample}[] + \begin{tikzpicture} + \tikzmath{ + int \x; + for \k in {0,10,...,350}{ + if \k>260 then { let \c = orange; } else { + if \k>170 then { let \c = blue; } else { + if \k>80 then { let \c = red; } else { + let \c = green; }; }; }; + { + \path [fill=\c!50, draw=\c] (\k:0.5cm) -- (\k:1cm) -- + (\k+5:1cm) -- (\k+5:0.5cm) -- cycle; + }; + }; + } + \end{tikzpicture} +\end{codeexample} +\end{math-keyword} + +\subsection{Declaring Functions} + + You can add functions by using the following keywords: + +\begin{math-keyword}{{function} \meta{name}\texttt{(}\meta{arguments}\texttt{) \{} \meta{definition} \texttt{\};}} + + This keyword works much like the |declare function| provided by the + \pgfname\ math-engine. + The function \meta{name} can be any name that is not already a + function name in the current scope. The list of \meta{arguments} are + comma separated \TeX\ macros such as |\x|, or |\y| (it is not + possible to declare functions that take variable numbers of arguments). + If the function + takes no arguments then the parentheses need not be used. + It is very important to note that the arrays that the + \pgfname\ math engine supports + \emph{cannot currently be passed as arguments to functions}. + + + The function \meta{definition} should be a sequence of statements + that can be parsed by the |\tikzmath| command and + should use the commands specified in the \meta{arguments}. + The |return| keyword (described below) should be used to indicate + the value returned by the function. + % + Although \meta{definition} can take any statements accepted by + |\tikzmath|, it is not advisable try to define functions inside other + functions. + +\begin{codeexample}[] +\tikzmath{ + function product(\x,\y) { + return \x*\y; + }; + int \i, \i, \k; + \i = random(1,10); + \j = random(20, 40); + \k = product(\i, \j); + print { $\i\times \j = \k$ }; +} +\end{codeexample} + +\end{math-keyword} + +\begin{math-keyword}{{return} \meta{expression}\texttt{;}} + + This keyword should be used as the last executed statement + in a function definition to indicate the value that should be + returned. + +\end{math-keyword} + + +\subsection{Executing Code Outside the Parser} + + Sometimes you may wish to do ``something'' outside the parser, + perhaps display some intermediate result or execute some code. + In this case + you have two options. Firstly, the following keyword can be used: + +\begin{math-keyword}{{print} \texttt{\{}\meta{code}\texttt{\};}} + + Execute \meta{code} immediately. This is intended as convenience + keyword for displaying information in a document (analogous to + the |print| command in real programming languages). + The \meta{code} is executed inside a \TeX\ group. + +\begin{codeexample}[] +\tikzmath{ + int \x, \y, \z; + \x = random(2, 5); + for \y in {0,...,6}{ + \z = \x^\y; + print {$\x^\y=\z$, }; + }; +} +\end{codeexample} + +\end{math-keyword} + + Secondly, if a statement begins with a brace |{|, then + everything up to the closing brace |}| is collected + and executed (the closing brace \emph{must} + be followed by a semi-colon). + Like the |print| keyword, the contents of the braces + is executed inside a \TeX\ group. + Unlike the |print| keyword, the brace notation can be used in + functions so that |tikz| path commands can be safely executed + inside a |tikzpicture|. + +\begin{codeexample}[] +\begin{tikzpicture} +\draw [help lines] grid (3,2); +\tikzmath{ + coordinate \c; + for \x in {0,10,...,360}{ + \c = (1.5cm, 1cm) + (\x:1cm and 0.5cm); + { \fill (\c) circle [radius=1pt]; }; + }; +} +\end{tikzpicture} +\end{codeexample} + + + + + + +\endinput diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-matrices.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-matrices.tex index a50f1179d7b..2a697d768e7 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-matrices.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-matrices.tex @@ -11,7 +11,7 @@ \section{Matrix Library} \begin{tikzlibrary}{matrix} - This library packages defines additional styles and options for + This library package defines additional styles and options for creating matrices. \end{tikzlibrary} @@ -48,7 +48,7 @@ cell. The following key simplifies typesetting such matrices. be achieved in three ways. \begin{enumerate} \item You can modify, say, the - |row 2 column 5| style to pass special options to this particular + |row 2 column 3| style to pass special options to this particular cell. \begin{codeexample}[] @@ -98,7 +98,7 @@ cell. The following key simplifies typesetting such matrices. expands to |\path|, which includes |\draw|, |\node|, |\fill| and others, the |\node{| startup code and the |};| code are suppressed. This means that for this particular cell you can - provide a totally different contents. + provide totally different contents. \begin{codeexample}[] \begin{tikzpicture} @@ -132,7 +132,7 @@ cell. The following key simplifies typesetting such matrices. \end{key} \begin{key}{/tikz/nodes in empty cells=\meta{true or false} (default true)} - When set to |true|, a node (with an empty contents) is put in empty + When set to |true|, a node (with empty contents) is put in empty cells. Normally, empty cells are just, well, empty. The style can be used together with both a |matrix of nodes| and a |matrix of math nodes|. @@ -288,7 +288,7 @@ some after node magic. \begin{key}{/tikz/above delimiter=\meta{delimiter}} This option allows you to add a delimiter above the node. It is - implementing by rotating a left delimiter. + implemented by rotating a left delimiter. \begin{codeexample}[] \begin{tikzpicture} \matrix [matrix of math nodes,% diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-mindmaps.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-mindmaps.tex index 4a88719792c..0288319b757 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-mindmaps.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-mindmaps.tex @@ -65,7 +65,7 @@ Every mindmap should be put in a scope or a picture where the \end{codeexample} \end{stylekey} - \paragraph{Remark:} Note that |mindmap| re-defines |font| sizes and |sibling angle| depending on the current concept level (i.e. inside of |level 1 concept|, |level 2 concept| etc.). Thus, if you need to redefine these variables, use + \paragraph{Remark:} Note that |mindmap| redefines |font| sizes and |sibling angle| depending on the current concept level (i.e. inside of |level 1 concept|, |level 2 concept| etc.). Thus, if you need to redefine these variables, use |\tikzset{level 1 concept/.append style={font=\small}}| @@ -141,9 +141,9 @@ The following styles influence how isolated concepts are rendered: \begin{stylekey}{/tikz/extra concept} This style is intended for concepts that are not part of the ``mindmap tree,'' but stand beside it. Typically, they will have a - subdued color are be smaller. In order to have these concepts appear + subdued color or be smaller. In order to have these concepts appear in a uniform way and in order to indicate in the code that these - concepts are extra, you can use this style. + concepts are additional, you can use this style. \begin{codeexample}[] \begin{tikzpicture}[mindmap,concept color=blue!80] \node [concept] {Root concept}; @@ -158,7 +158,7 @@ The following styles influence how isolated concepts are rendered: \subsubsection{Concepts in Trees} -As pointed out earlier, \tikzname\ assumes that your mindmap is build +As pointed out earlier, \tikzname\ assumes that your mindmap is built using the |child| facilities of \tikzname. There are numerous options that influence how concepts are rendered at the different levels of a tree. @@ -199,7 +199,7 @@ tree. Works like |level 1 concept|. \end{stylekey} \begin{stylekey}{/tikz/level 4 concept} - Works like |level 1 concept|. Note that there are not fifth and + Works like |level 1 concept|. Note that there are no fifth and higher level styles, you need to modify |level 5| directly in such cases. \end{stylekey} @@ -222,8 +222,9 @@ tree. child[concept color=orange,grow=0] {node[concept] {Child concept}}; \end{codeexample} - In order to have all children of a certain level have a different - concept color, a tiny bit of magic is needed: + In order to have a concept color which changes with the hierarchy level, a tiny bit of magic is needed: + % FIXME : is this a bug in the software!? The root concept is + % black!? \begin{codeexample}[] \tikz[mindmap,text=white, root concept/.style={concept color=blue}, @@ -331,12 +332,12 @@ in the mindmap library: In the above example you may notice the small white line between the circles and the decorated path. This is due to rounding - errors. Unfortunately, for larger distances, there errors can + errors. Unfortunately, for larger distances, the errors can accumulate quite strongly, especially since \tikzname\ and \TeX\ are not very good at computing square roots. For this reason, it is a good idea to make the circles slightly larger to cover up such problems. When using nodes of shape |circle|, you can just add the - |draw| option with a |line width| or one or two points (for very + |draw| option with a |line width| of one or two points (for very large distances you may need line width up to 4pt). \begin{codeexample}[] \begin{tikzpicture} @@ -349,11 +350,12 @@ in the mindmap library: \end{tikzpicture} \end{codeexample} - Note the slightly strange |outer sep=0pt|. This is needed so that - the decorated path lies on the border of the filled circle, not on the - border of the stroked circle (which is slightly larger and this - slightly larger size is exactly what we wish to use to cover up the - rounding errors). + % FIXME : this paragraph appears to be deprecated: + %Note the slightly strange |outer sep=0pt|. This is needed so that + %the decorated path lies on the border of the filled circle, not on the + %border of the stroked circle (which is slightly larger and this + %slightly larger size is exactly what we wish to use to cover up the + %rounding errors). \end{decoration} @@ -363,7 +365,7 @@ in the mindmap library: The |circle connection bar| decoration is a bit complicated to use. Especially specifying the radii is quite bothersome (the amplitude and the angle can be set once and for all). For this reason, -the mindmap library defines a special to-path, that performs the +the mindmap library defines a special to-path that performs the necessary computations for you. \begin{stylekey}{/tikz/circle connection bar} @@ -392,7 +394,7 @@ necessary computations for you. \end{tikzpicture} \end{codeexample} Note that it is not a good idea to have more than one |to| operation - together this the option |circle connection bar| in a single + together with the option |circle connection bar| in a single |\path|. Use the |edge| operation, instead, for creating multiple connections and this operation creates a new scope for each edge. \end{stylekey} @@ -422,9 +424,8 @@ library provides a special option for facilitating this procedure. \subsubsection{Tree Edges} Most of the time, concepts in a mindmap are connected automatically -when the mindmap is build as a tree. The reason is that the |mindmap| -installs a |circle connection bar| path as the edge from parent -path. Also, the |mindmap| option takes care of things like setting the +when the mindmap is built as a tree. The reason is that the |mindmap| +installs a |circle connection bar| path as the |edge from parent path|. Also, the |mindmap| option takes care of things like setting the correct |draw| and |outer sep| settings and some other stuff. In detail, the |mindmap| option sets the |edge from parent path| to a @@ -436,7 +437,7 @@ set to the new (child's) concept color. This means that when you provide the |concept color| option to a |child| command, the color will change from the parent's concept color to the specified color. -Here is an example of a tree build in this way: +Here is an example of a tree built in this way: \begin{codeexample}[] \begin{tikzpicture} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-petri.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-petri.tex index befc36b9e0f..9807c3542d3 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-petri.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-petri.tex @@ -198,10 +198,10 @@ The Petri net library offers a solution to this problem: The \end{key} \end{stylekey} -The |children are tokens| options gives you a lot of flexibility, but +The |children are tokens| option gives you a lot of flexibility, but it is a bit cumbersome to use. For this reason there are some options that help in standard situations. They all use |children are tokens| -internally, so any change to, say, the |every tokens| style will +internally, so any change to, say, the |every token| style will affect how these options depict tokens. \begin{key}{/tikz/tokens=\meta{number}} @@ -236,15 +236,14 @@ affect how these options depict tokens. \begin{key}{/tikz/colored tokens=\meta{color list}} This option, which must also be given when a place node is being created, gets a list of colors as parameter. It will then add as - many tokens to the place are in this list, each colored with the - corresponding color in the list. + many tokens to the place as there are colors in this list, each filled correspondingly. \begin{codeexample}[] \tikz \node[place,colored tokens={black,black,red,blue}] {}; \end{codeexample} \end{key} \begin{key}{/tikz/structured tokens=\meta{token texts}} - This option, which must again be passed to a place, gets a list - texts for tokens. For each text, another token will be added to the place. + This option, which must again be passed to a place, gets a list of + texts for tokens. For each text, a new token will be added to the place. \begin{codeexample}[] \tikz \node[place,structured tokens={$x$,$y$,$z$}] {}; \end{codeexample} @@ -284,8 +283,8 @@ affect how these options depict tokens. \node[token] at (h1) {}; \node[transition] at (1.5,1.5) {} edge [pre] (p1) edge [post] (p2); - \node[transition] at (1.5,2.5) {} edge[pre] (p2) edge[pre] (m1f) - edge[post] (p3) edge[post] (m1t); + \node[transition] at (1.5,2.5) {} edge [pre] (p2) edge[pre] (m1f) + edge [post](p3) edge[post] (m1t); \node[transition] at (1.5,3.3) {} edge [pre] (p3) edge [post] (p4) edge [pre and post] (h1); \node[transition] at (1.5,3.7) {} edge [pre] (p3) edge [pre] (h2) diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-plot-handlers.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-plot-handlers.tex index fd58176b7a2..127aa229972 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-plot-handlers.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-plot-handlers.tex @@ -98,7 +98,7 @@ \end{command} \subsection{Constant Plot Handlers} -There are three plot handlers which produce piecewise constant interpolations between successive points. +There are several plot handlers which produce piecewise constant interpolations between successive points: \begin{command}{\pgfplothandlerconstantlineto} This handler works like the line-to plot handler, only it will @@ -134,6 +134,24 @@ the right line ends. \end{codeexample} \end{command} +\begin{command}{\pgfplothandlerconstantlinetomarkmid} +A variant of |\pgfplothandlerconstantlineto| which places its mark on +the center of the line. +\begin{codeexample}[] +\begin{tikzpicture} + \draw[gray] (0,0) node {x} (1,1) node {y} (2,.5) node {z}; + \pgfplothandlerconstantlinetomarkmid + \pgfplotstreamstart + \pgfplotstreampoint{\pgfpoint{0cm}{0cm}} + \pgfplotstreampoint{\pgfpoint{1cm}{1cm}} + \pgfplotstreampoint{\pgfpoint{2cm}{0.5cm}} + \pgfplotstreamend + \pgfusepath{stroke} +\end{tikzpicture} +\end{codeexample} + The plot handler always connects two data points by a horizontal line starting from the previous data points, followed by a vertical line in the middle between the two data points, followed by a horizontal line between the middle and the current data point. This results in a symmetric constant plot handler for constant mesh width. +\end{command} + \begin{command}{\pgfplothandlerjumpmarkleft} This handler works like the line-to plot handler, only it will produce a non-connected, piecewise constant path to connect the points. If there are any plot marks, they will be placed on the left open pieces. @@ -168,9 +186,27 @@ the right line ends. \end{codeexample} \end{command} +\begin{command}{\pgfplothandlerjumpmarkmid} + This handler works like the |\pgfplothandlerconstantlinetomarkmid|, but it will + produce a non-connected, piecewise constant path to connect the points. If there are any plot marks, they will be placed in the center of the horizontal line segment.. +\begin{codeexample}[] +\begin{tikzpicture} + \draw[gray] (0,0) node {x} (1,1) node {y} (2,.5) node {z}; + \pgfplothandlerjumpmarkmid + \pgfplotstreamstart + \pgfplotstreampoint{\pgfpoint{0cm}{0cm}} + \pgfplotstreampoint{\pgfpoint{1cm}{1cm}} + \pgfplotstreampoint{\pgfpoint{2cm}{0.5cm}} + \pgfplotstreamend + \pgfusepath{stroke} +\end{tikzpicture} +\end{codeexample} + See |\pgfplothandlerconstantlinetomarkmid| for details. +\end{command} + \subsection{Comb Plot Handlers} -There are three ``comb'' plot handlers. There name stems from the fact +There are three ``comb'' plot handlers. Their name stems from the fact that the plots they produce look like ``combs'' (more or less). \begin{command}{\pgfplothandlerxcomb} @@ -377,10 +413,10 @@ interval). The $y$~value of the last point will be ignored. \end{command} \label{key-bar-interval-shift}% -\begin{key}{/pgf/bar interval shift=\marg{shift} (initially 0.5)} +\begin{key}{/pgf/bar interval shift=\marg{factor} (initially 0.5)} \keyalias{tikz} Sets the \emph{relative} shift of |\pgfplothandlerxbarinterval| and - |\pgfplothandlerybarinterval| to \marg{shift}. As + |\pgfplothandlerybarinterval| to \meta{factor}. As |/pgf/bar interval width|, the argument is relative to the interval length of the input coordinates. @@ -428,6 +464,49 @@ interval). The $y$~value of the last point will be ignored. $0.25$ and $0.75$ instead of $0$ and $0.5$. \end{key} +\subsection{Gapped Plot Handlers} + +\label{section-plot-gapped} + + +\begin{command}{\pgfplothandlergaplineto} + This handler will connect the points of the plots by straight line + segments. However, at the start and the end of the lines there will + be a small gap, given by the following key: + \begin{key}{/pgf/gap around stream point=\meta{dimension} (initially 1.5pt)} + The \meta{dimension} by which the lines between consecutive stream + points are shortened at the beginning and end. + \end{key} +\begin{codeexample}[] +\begin{tikzpicture} + \pgfplothandlergaplineto + \pgfplotstreamstart + \pgfplotstreampoint{\pgfpoint{0cm}{0cm}} + \pgfplotstreampoint{\pgfpoint{1cm}{1cm}} + \pgfplotstreampoint{\pgfpoint{2cm}{0.5cm}} + \pgfplotstreamend + \pgfusepath{stroke} +\end{tikzpicture} +\end{codeexample} +\end{command} + + +\begin{command}{\pgfplothandlergapcycle} + Works like |\pgfplothandlergaplineto|, but the last point is + connected to the first in the same fashion: +\begin{codeexample}[] +\begin{tikzpicture} + \pgfplothandlergapcycle + \pgfplotstreamstart + \pgfplotstreampoint{\pgfpoint{0cm}{0cm}} + \pgfplotstreampoint{\pgfpoint{1cm}{1cm}} + \pgfplotstreampoint{\pgfpoint{2cm}{0.5cm}} + \pgfplotstreamend + \pgfusepath{stroke} +\end{tikzpicture} +\end{codeexample} +\end{command} + \subsection{Mark Plot Handler} \label{section-plot-marks} @@ -435,7 +514,7 @@ interval). The $y$~value of the last point will be ignored. \begin{command}{\pgfplothandlermark\marg{mark code}} This command will execute the \meta{mark code} for some points of the plot, but each time the coordinate transformation matrix will be - setup such that the origin is at the position of the point to be + set up such that the origin is at the position of the point to be plotted. This way, if the \meta{mark code} draws a little circle around the origin, little circles will be drawn at some point of the plot. @@ -500,7 +579,7 @@ interval). The $y$~value of the last point will be ignored. \begin{command}{\pgfuseplotmark\marg{plot mark name}} Draws the given \meta{plot mark name} at the origin. The \meta{plot - mark name} must previously have been declared using + mark name} must have been previously declared using |\pgfdeclareplotmark|. \begin{codeexample}[] diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-plot-marks.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-plot-marks.tex index b953be6a25e..8dbef923854 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-plot-marks.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-plot-marks.tex @@ -80,6 +80,11 @@ Note that each of the provided marks can be rotated freely by means of |mark opt There is no limitation about the number of characters or whatever. In fact, any \TeX\ material can be inserted as \marg{text}, including images. \end{key} +\begin{key}{/pgf/text mark as node=\marg{boolean} (initially false)} + Configures how |mark=text| will be drawn: either as |\node| or as |\pgftext|. + + The first choice is highly flexible and possibly slow, the second is very fast and usually enough. +\end{key} \begin{key}{/pgf/text mark style=\marg{options for \texttt{mark=text}}} Defines a set of options which control the appearance of |mark=text|. @@ -87,11 +92,6 @@ Note that each of the provided marks can be rotated freely by means of |mark opt If |/pgf/text mark as node=true|, \marg{options} is provided as argument to |\node|. This means you can provide a very powerful set of options including |anchor|, |scale|, |fill|, |draw|, |rounded corners| etc. \end{key} -\begin{key}{/pgf/text mark as node=\mchoice{true,false} (initially false)} - Configures how |mark=text| will be drawn: either as |\node| or as |\pgftext|. - - The first choice is highly flexible and possibly slow, the second is very fast and usually enough. -\end{key} } diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-profiler.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-profiler.tex index 74fbea14558..9bc9b6fd57f 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-profiler.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-profiler.tex @@ -13,7 +13,9 @@ \begin{pgflibrary}{profiler} A library to simplify the optimization of runtime speed of \TeX\ programs. - It relies on the |pdftex| primitive \declareandlabel{\pdfelapsedtime} to count (fractional) seconds and counts total time and self time for macro invocations. + It relies on the |pdftex| primitive + \declareandlabel{\pdfelapsedtime}\footnote{The primitive is + emulated in lua\TeX.} to count (fractional) seconds and counts total time and self time for macro invocations. \end{pgflibrary} \subsection{Overview} @@ -28,22 +30,23 @@ The work flow for the optimization is simple: the preamble contains configuratio \noindent and then, the time between |\begin{tikzpicture}| and |\end{tikzpicture}| and the time required to call |\pgfkeys| will be collected. At the end, a short usage summary like -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] pgflibraryprofiler(main job) {total time=1.07378sec; (100.0122%) self time=0.034sec; (3.1662%)} pgflibraryprofiler(<ENV>tikzpicture) {total time=1.03978sec; (96.84601%) self time=1.00415sec; (93.52722%)} pgflibraryprofiler(<CS>pgfkeys) {total time=0.03563sec; (3.31726%) self time=0.03563sec; (3.31726%)} \end{codeexample} \noindent will be provided in the log file, furthermore, the same information is available in a text table called |\jobname.profiler.|\meta{datetime}|.dat| which is of the form: -\begin{codeexample}[code only] +\begin{codeexample}[code only, tikz syntax=false] profilerentry totaltime[s] totaltime[percent] selftime[s] selftime[percent] main job 1.07378 100.0122 0.034 3.1662 <ENV>tikzpicture 1.03978 96.84601 1.00415 93.52722 <CS>pgfkeys 0.03563 3.31726 0.03563 3.31726 \end{codeexample} -Here, the |totaltime| means the time used for all invocations of the respective profiler entry (one row in the table). The |selftime| measures time which is not already counted for in another profiler entry which has been invoked within the current one. The example above is not very exiting: the main job consists only of several (quite complex) pictures and nothing else. Thus, its total time is large. However, the self time is very small because the |tikzpicture|s are counted separately, and they have been invoked within the |main job|. The |\pgfkeys| control sequence has been invoked within the |tikzpicture|, that's why the |selftime| for the |tikzpicture| is a little bit smaller than its |totaltime|. +Here, the |totaltime| means the time used for all invocations of the respective profiler entry (one row in the table). The |selftime| measures time which is not already counted for in another profiler entry which has been invoked within the current one. The example above is not very exciting: the main job consists only of several (quite complex) pictures and nothing else. Thus, its total time is large. However, the self time is very small because the |tikzpicture|s are counted separately, and they have been invoked within the |main job|. The |\pgfkeys| control sequence has been invoked within the |tikzpicture|, that's why the |selftime| for the |tikzpicture| is a little bit smaller than its |totaltime|. \subsection{Requirements} -The library doesn't work without |pdftex|. Furthermore, it requires a more or less recent version which supports the |\pdfelapsedtime| directive. +The library works with |pdftex| and |luatex|. Furthermore, it requires +a more or less recent version of |pdftex| which supports the |\pdfelapsedtime| directive. \subsection{Defining Profiler Entries} Unlike profilers for C/C++ or java, this library doesn't extract information about every \TeX\ macro automatically, nor does it collect information for each of them. Instead, every profiler entry needs to be defined explicitly. Only defined profiler entries will be processed. @@ -104,7 +107,7 @@ Note that |\pgfprofilenewforcommand| is a special case of |\pgfprofilenewforcomm \begin{command}{\pgfprofileshowinvocationsfor\marg{profiler entry name}} Enables verbose output for \emph{every} invocation of \meta{profiler entry name}. - This is only available for profiler entries for commands (those created by |\pgfprofilenewforcommand| for example). It will also show any arguments. + This is only available for profiler entries for commands (those created by |\pgfprofilenewforcommand| for example). It will also show all given arguments. \end{command} \begin{command}{\pgfprofileshowinvocationsexpandedfor\marg{profiler entry name}} A variant of |\pgfprofileshowinvocationsfor| which will expand all arguments for \meta{profiler entry name} before showing them. The invocation as such is not affected by this expansion. diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-shadings.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-shadings.tex index cf4a008aebe..2d7d9648ef5 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-shadings.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-shadings.tex @@ -32,7 +32,7 @@ even when this library is not used. bottom line is at the bottom of the path. \begin{key}{/tikz/top color=\meta{color}} - This option prescribes the color to be used at the top in an |axis| + This option sets the color to be used at the top in an |axis| shading. When this option is given, several things happen: \begin{enumerate} \item @@ -130,13 +130,13 @@ even when this library is not used. \end{key} \begin{key}{/tikz/upper left=\meta{color} (initially white)} - Like |lower left|. + Works like |lower left|. \end{key} \begin{key}{/tikz/upper right=\meta{color} (initially white)} - Like |lower left|. + Works like |lower left|. \end{key} - \begin{key}{/tikz/lower left=\meta{color} (initially white)} - Like |lower left|. + \begin{key}{/tikz/lower right=\meta{color} (initially white)} + Works like |lower left|. \end{key} \end{shading} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-shadows.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-shadows.tex index 2ca29e963f0..94e7487b1d7 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-shadows.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-shadows.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\section{Shadow Library} +\section{Shadows Library} \label{section-libs-shadows} \begin{pgflibrary}{shadows} @@ -19,7 +19,7 @@ \subsection{Overview} A \emph{shadow} is usually a black or gray area that is drawn behind a -path or a node, thereby adding visual depth to a picture. The shadows +path or a node, thereby adding visual depth to a picture. The |shadows| library defines options that make it easy to add shadows to paths. Internally, these options are based on using the |preaction| option to use a path twice: Once for drawing the shadow (slightly @@ -31,7 +31,7 @@ scopes. In addition to the general |shadow| option, there exist special options like |circular shadow|. These can only (sensibly) be used with a special kind of path (for |circular shadow|, a circle) and, thus, -there are not as general. The advantage is, however, that they are +they are not as general. The advantage is, however, that they are more visually pleasing since these shadows blend smoothly with the background. Note that these special shadows use fadings, which few printers will support. @@ -59,7 +59,7 @@ circumstances. \meta{shadow options} are used for painting this path. Typically, the \meta{shadow options} will contain options like |fill=black| to create, say, a black shadow. Furthermore, after the \meta{shadow - options} have been setup, the following extra canvas + options} have been set up, the following extra canvas transformations are applied to the path: It is scaled by |shadow scale| (with the origin of scaling at the path's center) and it is shifted by |shadow xshift| and |shadow yshift|. @@ -73,23 +73,23 @@ circumstances. \end{codeexample} \begin{key}{/tikz/shadow scale=\meta{factor} (initially 1)} - Shadows are scaled by this amount. + Shadows are scaled by \meta{factor}. \begin{codeexample}[] \tikz [even odd rule] \draw [general shadow={fill=red,shadow scale=1.25}] (0,0) circle (.5) (0.5,0) circle (.5); \end{codeexample} \end{key} - \begin{key}{/tikz/shadow xshift=\meta{factor} (initially 0pt)} - Shadows are shifted horizontally by this amount. + \begin{key}{/tikz/shadow xshift=\meta{dimension} (initially 0pt)} + Shadows are shifted horizontally by \meta{dimension}. \begin{codeexample}[] \tikz [even odd rule] \draw [general shadow={fill=red,shadow xshift=-5pt}] (0,0) circle (.5) (0.5,0) circle (.5); \end{codeexample} \end{key} - \begin{key}{/tikz/shadow yshift=\meta{factor} (initially 0pt)} - Shadows are shifted vertically by this amount. + \begin{key}{/tikz/shadow yshift=\meta{dimension} (initially 0pt)} + Shadows are shifted vertically by \meta{dimension}. \end{key} \end{key} @@ -100,9 +100,9 @@ circumstances. \subsubsection{Drop Shadows} \begin{key}{/tikz/drop shadow=\meta{shadow options} (default \normalfont empty)} - This option adds a drop shadow to a path or node. |\path| or a + This option adds a drop shadow to a |\path| or a |node|. It uses the |general shadow| and passes the \meta{shadow - options} to it plus, before them, the following extra options: + options} to it, plus, before them, the following extra options: \begin{codeexample}[code only] shadow scale=1, shadow xshift=.5ex, shadow yshift=-.5ex, opacity=.5, fill=black!50, every shadow @@ -122,11 +122,11 @@ circumstances. \begin{codeexample}[] \begin{tikzpicture} \draw [help lines] (0,0) grid (3,2); - \filldraw [drop shadow={opacity=0.25},fill=white] - (1,.5) circle (.5) (1.5,.5) circle (.5); - \filldraw [drop shadow={opacity=1},fill=white] (1,2) circle (.5) (1.5,2) circle (.5); + + \filldraw [drop shadow={opacity=0.25},fill=white] + (1,.5) circle (.5) (1.5,.5) circle (.5); \end{tikzpicture} \end{codeexample} \end{key} @@ -183,7 +183,7 @@ of the path/object present. \begin{key}{/tikz/double copy shadow=\meta{shadow options} (default \normalfont empty)} This shadow works like a |copy shadow|, only the shadow is added - twice, the first time with the double |xshift| and |yshift|. + twice, the second time with the double |xshift| and |yshift|. \begin{codeexample}[] \begin{tikzpicture} \node [double copy shadow,fill=blue!20,draw=blue,thick] {Hello World!}; diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-shapes.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-shapes.tex index 4c99d465083..3beaf544170 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-shapes.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-shapes.tex @@ -26,6 +26,18 @@ The appearance of shapes is influenced by numerous parameters like |minimum height| or |inner xsep|. These general parameters are documented in Section~\ref{section-shape-common-options} +In all of the examples presented in this section, the following +|shape example| style is used: +\begin{codeexample}[code only] +\tikzset{ + shape example/.style= {color = black!30, + draw, + fill = yellow!30, + line width = .5cm, + inner xsep = 2.5cm, + inner ysep = 0.5cm} +} +\end{codeexample} \subsection{Predefined Shapes} \label{section-predefined-shapes} @@ -163,9 +175,9 @@ shapes define a standard set of anchors. \begin{tikzpicture} \tikzstyle{every node}=[trapezium, draw] \node at (0,2) {A}; - \node[trapezium left angle=75, trapezium right angle=45pt] + \node[trapezium left angle=75, trapezium right angle=45] at (0,1) {B}; - \node[trapezium left angle=120, trapezium right angle=60pt] + \node[trapezium left angle=120, trapezium right angle=60] at (0,0) {C}; \end{tikzpicture} \end{codeexample} @@ -176,11 +188,11 @@ shapes define a standard set of anchors. To use these keys in \tikzname, simply remove the \declare{|/pgf/|} path. \begin{key}{/pgf/trapezium left angle=\meta{angle} (initially 60)} - Set the lower internal angle of the left side. + Sets the lower internal angle of the left side. \end{key} \begin{key}{/pgf/trapezium right angle=\meta{angle} (initially 60)} - Set the lower internal angle of the right side. + Sets the lower internal angle of the right side. \end{key} \begin{stylekey}{/pgf/trapezium angle=\meta{angle}} @@ -374,7 +386,7 @@ shapes define a standard set of anchors. Section~\ref{section-rotating-shape-borders}, but the border of the star is \emph{always} constructed using the incircle. - A star should be thought of as having an set of ``inner points'' + A star should be thought of as having a set of ``inner points'' and ``outer points''. The inner points of the border are based on the radius of the circle which tightly fits the node contents, and the outer points are based @@ -463,7 +475,7 @@ shapes define a standard set of anchors. To use these keys in \tikzname, simply remove the \declare{|/pgf/|} path. - \begin{key}{/pgf/isosceles triangle apex angle=\meta{angle} (initially 45)} + \begin{key}{/pgf/isosceles triangle apex angle=\meta{angle} (initially 30)} Sets the angle of the apex of the isosceles triangle. \end{key} @@ -545,11 +557,11 @@ shapes define a standard set of anchors. path. \begin{key}{/pgf/kite upper vertex angle=\meta{angle} (initially 120)} - Set the upper internal angle of the kite. + Sets the upper internal angle of the kite. \end{key} \begin{key}{/pgf/kite lower vertex angle=\meta{angle} (initially 60)} - Set the lower internal angle of the kite. + Sets the lower internal angle of the kite. \end{key} \begin{key}{/pgf/kite vertex angles=\meta{angle specification}} @@ -622,11 +634,11 @@ shapes define a standard set of anchors. \end{codeexample} \begin{key}{/pgf/dart tip angle=\meta{angle} (initially 45)} - Set the angle at the tip of the dart. + Sets the angle at the tip of the dart. \end{key} \begin{key}{/pgf/dart tail angle=\meta{angle} (initially 135)} - Set the angle between the tails of the dart. + Sets the angle between the tails of the dart. \end{key} The anchors for the |dart| shape are shown below (note that the @@ -678,7 +690,7 @@ shapes define a standard set of anchors. path. \begin{key}{/pgf/circular sector angle=\meta{angle} (initially 60)} - Set the central angle of the sector. + Sets the central angle of the sector. \end{key} The anchors for the circular sector shape are shown below. @@ -735,7 +747,7 @@ shapes define a standard set of anchors. width will stretch the curved ends. \begin{codeexample}[] -\begin{tikzpicture}[>=stealth, shape aspect=.5] +\begin{tikzpicture}[shape aspect=.5] \tikzset{every node/.style={cylinder, shape border rotate=90, draw}} \node [minimum height=1.5cm] {A}; \node [minimum width=1.5cm] at (1.5,0) {B}; @@ -751,7 +763,7 @@ shapes define a standard set of anchors. to some minimum width. \begin{codeexample}[] -\begin{tikzpicture}[>=stealth] +\begin{tikzpicture}[] \tikzset{every node/.style={cylinder, shape border rotate=90, draw}} \node [aspect=1.0] {A}; \node [aspect=0.5] at (1,0) {B}; @@ -771,22 +783,22 @@ shapes define a standard set of anchors. \end{key} \begin{codeexample}[] -\begin{tikzpicture}[>=stealth, aspect=0.5] +\begin{tikzpicture}[aspect=0.5] \node [cylinder, cylinder uses custom fill, cylinder end fill=red!50, cylinder body fill=red!25] {Cylinder}; \end{tikzpicture} \end{codeexample} \begin{key}{/pgf/cylinder end fill=\meta{color} (initially white)} - Set the color for the end of the cylinder. + Sets the color for the end of the cylinder. \end{key} \begin{key}{/pgf/cylinder body fill=\meta{color} (initially white)} - Set the color for the body of the cylinder. + Sets the color for the body of the cylinder. \end{key} - The anchors this shape are shown below (anchor |160| is an - example of a border anchor). Note the cylinder shape does not + The anchors of this shape are shown below (anchor |160| is an + example of a border anchor). Note that the cylinder shape does not distinguish between |outer xsep| and |outer ysep|. Only the larger of the two values is used for the shape. Note also the difference between the |center| and |shape center| anchors: |center| is the @@ -831,14 +843,28 @@ shapes define a standard set of anchors. -\begin{shape}{forbidden sign} +\begin{shape}{correct forbidden sign} This shape places the node inside a circle with a diagonal from the - lower left to the upper right added. The circle is part of the + upper left to the lower right added. The circle is part of the background, the diagonal line part of the foreground path; thus, the diagonal line is on top of the text. \begin{codeexample}[] \begin{tikzpicture} + \node [correct forbidden sign,line width=1ex,draw=red,fill=white] {Smoking}; +\end{tikzpicture} +\end{codeexample} + + The shape inherits all anchors from the |circle| shape. +\end{shape} + +\begin{shape}{forbidden sign} + This shape is like |correct forbidden sign|, only the line goes from + the lower left to the upper right. The strange naming of these + shapes is for historical reasons. + +\begin{codeexample}[] +\begin{tikzpicture} \node [forbidden sign,line width=1ex,draw=red,fill=white] {Smoking}; \end{tikzpicture} \end{codeexample} @@ -888,17 +914,17 @@ shapes define a standard set of anchors. \tikzname{}, simply remove the \declare{|/pgf/|} path). \begin{key}{/pgf/cloud puffs=\meta{integer} (initially 10)} - Set the number of puffs for the cloud. + Sets the number of puffs for the cloud. \end{key} \begin{key}{/pgf/cloud puff arc=\meta{angle} (initially 135)} - Set the length of the puff arc (in degrees). A shorter arc can + Sets the length of the puff arc (in degrees). A shorter arc can produce better looking joins between puffs for larger line widths. \end{key} Like the diamond shape, the cloud shape also uses the - \declare{|aspect|} key, to determine the ratio of the width and the - height of the cloud. However there may be circumstances where it may + \declare{|aspect|} key to determine the ratio of the width and the + height of the cloud. However, there may be circumstances where it may be undesirable to continually specify the |aspect| for the cloud. Therefore, the following key is implemented: @@ -961,7 +987,7 @@ shapes define a standard set of anchors. \begin{shape}{starburst} This shape is a randomly generated elliptical star, - which supports the rotating of the shape border as described in + which supports the rotation of the shape border as described in Section~\ref{section-rotating-shape-borders}. \begin{codeexample}[] \begin{tikzpicture} @@ -974,7 +1000,7 @@ shapes define a standard set of anchors. Using a specified `starburst point height' value, the outer points are generated randomly between this value and one quarter of this - value. For a given starburst shape the angle between each point is + value. For a given starburst shape, the angle between each point is fixed, and is determined by the number of points specified for the starburst. @@ -996,15 +1022,15 @@ shapes define a standard set of anchors. \declare{|/pgf/|} path. \begin{key}{/pgf/starburst points=\meta{integer} (initially 17)} - Set the number of points for the starburst. + Sets the number of outer points for the starburst. \end{key} \begin{key}{/pgf/starburst point height=\meta{length} (initially .5cm)} - Set the \emph{maximum} distance between the inner point radius + Sets the \emph{maximum} distance between the inner point radius and the outer point radius. \end{key} \begin{key}{/pgf/random starburst=\meta{integer} (initially 100)} - Set the seed for the random number generator for creating the + Sets the seed for the random number generator for creating the starburst. The maximum value for \meta{integer} is |16383|. If \meta{integer}|=0|, the random number generator will not be used, and the maximum point height will be used for all outer @@ -1056,13 +1082,13 @@ shapes define a standard set of anchors. keys in \tikzname{}, simply remove the \declare{|/pgf/|} path): \begin{key}{/pgf/signal pointer angle=\meta{angle} (initially 90)} - Set the angle for the pointed sides of the shape. This angle is + Sets the angle for the pointed sides of the shape. This angle is maintained when enforcing any minimum size requirements, so any adjustment to the width will affect the height, and vice versa. \end{key} \begin{key}{/pgf/signal from=\meta{direction}\space\opt{and \meta{opposite direction}} (initially nowhere)} - Set which sides take an inward pointer (i.e., that points towards the + Sets which sides take an inward pointer (i.e., that points towards the center of the shape). The possible values for \meta{direction} and \meta{opposite direction} are the compass point directions |north|, |south|, |east| and |west| (or |above|, |below|, |right| and |left|). @@ -1074,8 +1100,8 @@ shapes define a standard set of anchors. \end{key} \begin{key}{/pgf/signal to=\meta{direction}\space\opt{and \meta{opposite direction}} (initially east)} - Set which sides take an outward pointer (i.e., that points away from - the the shape). + Sets which sides take an outward pointer (i.e., that points away from + the shape). \end{key} Note that \pgfname{} will ignore any instruction to use directions @@ -1130,7 +1156,7 @@ shapes define a standard set of anchors. \declare{|/pgf/|} path): \begin{key}{/pgf/tape bend top=\meta{bend style} (initially in and out)} - Specify how the top side bends. The \meta{bend style} is either + Specifies how the top side bends. The \meta{bend style} is either |in and out|, |out and in| or |none| (i.e., a straight line). The bending sides are drawn in a clockwise direction, and using the bend style |in and out| will mean @@ -1164,11 +1190,11 @@ shapes define a standard set of anchors. \end{key} \begin{key}{/pgf/tape bend bottom=\meta{bend style} (initially in and out)} - Specify how the bottom side bends. + Specifies how the bottom side bends. \end{key}% \begin{key}{/pgf/tape bend height=\meta{length} (initially 5pt)} - Set the total height for a side with a bend. + Sets the total height for a side with a bend. \begin{codeexample}[] \begin{tikzpicture}[>=stealth] @@ -1207,6 +1233,74 @@ shapes define a standard set of anchors. +\begin{shape}{magnetic tape} + + This shape represents a `magnetic tape' or any sequential data store + that is sometimes used in flowcharts. It is essentially a circle with a + little tail: + +\begin{codeexample}[] +\tikz\node [magnetic tape, draw] (A) {A}; +\end{codeexample} + + The following keys can be used to customise the |magnetic tape| + shape: + + +\begin{key}{/pgf/magnetic tape tail extend=\meta{distance} (initially 0cm)} + + This key sets how far the tail extends beyond the radius of + the tape. Negative values will be ignored. + +\begin{codeexample}[] +\begin{tikzpicture}[every node/.style={magnetic tape, draw}] + \node [magnetic tape tail extend=0cm] at (0,0) {A}; + \node [magnetic tape tail extend=0.25cm] at (0,1) {B}; +\end{tikzpicture} +\end{codeexample} +\end{key} + + + +\begin{key}{/pgf/magnetic tape tail=\meta{proportion} (initially 0.15)} + + This key sets the thickness of the `tail' to be \meta{proportion} + times the radius of the shape. The \meta{proportion} should be + between |0.0| and |1.0|. + +\begin{codeexample}[] +\begin{tikzpicture}[every node/.style={magnetic tape, draw}] + \node [magnetic tape tail=0.5, magnetic tape tail extend=0.5cm] {A}; + \node [magnetic tape tail=0.25] at (0,1) {B}; +\end{tikzpicture} +\end{codeexample} +\end{key} + + + The following figure shows the anchors this shape defines; + the anchors 10 and 130 are example of border anchors. + +\begin{codeexample}[] +\Huge +\begin{tikzpicture} +\node[name=s,shape=magnetic tape,shape example,inner sep=0.75cm, +magnetic tape tail extend=0.5cm] + {Magnetic Tape\vrule width 1pt height 2cm}; +\foreach \anchor/\placement in + {north west/above left, north/above, north east/above right, + west/left, center/above, east/right, + mid west/right, mid/right, mid east/left, + base west/below, base/below, base east/right, + south west/below left, south/below, south east/left, + text/left, 10/right, 130/above, + tail east/right, tail south east/below, tail north east/above} + \draw[shift=(s.\anchor)] plot[mark=x] coordinates{(0,0)} + node[\placement] {\scriptsize\texttt{(s.\anchor)}}; +\end{tikzpicture} +\end{codeexample} +\end{shape} + + \subsection{Arrow Shapes} \begin{pgflibrary}{shapes.arrows} @@ -1217,11 +1311,11 @@ shapes define a standard set of anchors. \end{pgflibrary} \begin{shape}{single arrow} - This shape is an arrow, which tightly fits the note contents + This shape is an arrow, which tightly fits the node contents (including any |inner sep|). This shape supports the rotation of the shape border, as described in Section~\ref{section-rotating-shape-borders}. - The angle of rotation determines which direction the arrow + The angle of rotation determines in which direction the arrow points (provided no other rotational transformations are applied). \begin{codeexample}[] @@ -1255,7 +1349,7 @@ shapes define a standard set of anchors. path). \begin{key}{/pgf/single arrow tip angle=\meta{angle} (initially 90)} - Set the angle for the arrow tip. Enlarging the arrow to some + Sets the angle for the arrow tip. Enlarging the arrow to some minimum width may increase the height of the shape to maintain this angle. \end{key} @@ -1315,7 +1409,7 @@ shapes define a standard set of anchors. \begin{shape}{double arrow} - This shape is a double arrow, which tightly fits the note contents + This shape is a double arrow, which tightly fits the node contents (including any |inner sep|), and supports the rotation of the shape border, as described in Section~\ref{section-rotating-shape-borders}. @@ -1349,7 +1443,7 @@ shapes define a standard set of anchors. path). \begin{key}{/pgf/double arrow tip angle=\meta{angle} (initially 90)} - Set the angle for the arrow tip. Enlarging the arrow to some + Sets the angle for the arrow tip. Enlarging the arrow to some minimum width may increase the height of the shape to maintain this angle. \end{key} @@ -1429,25 +1523,25 @@ There are various \pgfname{} keys for drawing this shape (to use these keys in \tikzname, simply remove the \declare{/pgf/} path). \begin{key}{/pgf/arrow box tip angle=\meta{angle} (initially 90)} - Set the angle at the arrow tip for all four arrows. + Sets the angle at the arrow tip for all four arrows. \end{key} \begin{key}{/pgf/arrow box head extend=\meta{length} (initially .125cm)} - Set the distance the arrow head extends away from the shaft + Sets the distance the arrow head extends away from the shaft of the arrow. This applies to all arrows. \end{key} \begin{key}{/pgf/arrow box head indent=\meta{length} (initially 0cm)} - Move the point where the arrow head joins the shaft of the arrow + Moves the point where the arrow head joins the shaft of the arrow \emph{towards} the arrow tip. This applies to all arrows. \end{key} \begin{key}{/pgf/arrow box shaft width=\meta{length} (initially .125cm)} - Set the width of the shaft of all arrows. + Sets the width of the shaft of all arrows. \end{key} \begin{key}{/pgf/arrow box north arrow=\meta{distance} (initially .5cm)} - Set distance the north arrow extends from the node. By default this + Sets the distance the north arrow extends from the node. By default this is from the border of the shape, but by using the additional keyword |from center|, the distance will be measured from the center of the shape. If \meta{distance} is |0pt| or a negative distance, the arrow @@ -1455,19 +1549,19 @@ keys in \tikzname, simply remove the \declare{/pgf/} path). \end{key} \begin{key}{/pgf/arrow box south arrow=\meta{distance} (initially .5cm)} - Set distance the south arrow extends from the node. + Sets the distance the south arrow extends from the node. \end{key} \begin{key}{/pgf/arrow box east arrow=\meta{distance} (initially .5cm)} - Set distance the east arrow extends from the node. + Sets the distance the east arrow extends from the node. \end{key} \begin{key}{/pgf/arrow box west arrow=\meta{distance} (initially .5cm)} - Set distance the west arrow extends from the node. + Sets the distance the west arrow extends from the node. \end{key} \begin{key}{/pgf/arrow box arrows={\ttfamily\char`\{}\meta{list}{\ttfamily\char`\}}} - Set the distance that all arrows extend from the node. The + Sets the distance that all arrows extend from the node. The specification in \meta{list} consists of the four compass points |north|, |south|, |east| or |west|, separated by commas (so the list must be contained within braces). @@ -1479,7 +1573,7 @@ keys in \tikzname, simply remove the \declare{/pgf/} path). Any sides not specified will not be drawn with an arrow. \end{key} -The anchors for this shape are shown below (unfortunately due to its +The anchors for this shape are shown below (unfortunately, due to its size, this example must be rotated). Anchor |75| is an example of a border anchor. If a side is drawn without an arrow, the anchors for that arrow should @@ -1616,7 +1710,7 @@ to the center of the appropriate side. \begin{shape}{rectangle split} - This shape is a rectangle which can be either split horizontally + This shape is a rectangle which can be split either horizontally or vertically into several parts. \begin{codeexample}[] @@ -1652,15 +1746,15 @@ these extra boxes, the following key is provided: \begin{key}{/pgf/rectangle split allocate boxes=\meta{number}} This key checks if \meta{number} boxes have been allocated, and if - not allocates the required boxes using |\newbox| (some ``magic'' is + not, it allocates the required boxes using |\newbox| (some ``magic'' is performed to get around the fact that |\newbox| is declared |\outer| in plain \TeX). \end{key} - When split vertically, the rectangle split will observe any - |minimum width| requirements but any |minimum height| will be ignored. + When split vertically, the rectangle split will meet any + |minimum width| requirements, but any |minimum height| will be ignored. Conversely when split horizontally, |minimum height| requirements - will be observed, but any |minimum width| will be ignored. + will be met, but any |minimum width| will be ignored. In addition, |inner sep| is applied to every part that is used, so it cannot be specified independently for a particular part. @@ -1672,7 +1766,7 @@ these extra boxes, the following key is provided: \begin{key}{/pgf/rectangle split parts=\meta{number} (initially 4)} Split the rectangle into \meta{number} parts, which should be in the range |1| to |20|. If more than four parts - are need, the boxes should be allocated in advance as + are needed, the boxes should be allocated in advance as described above. \begin{codeexample}[] @@ -1711,25 +1805,25 @@ these extra boxes, the following key is provided: \end{key} % \begin{key}{/pgf/rectangle split empty part width=\meta{length} (initially 1ex)} - Set the default width for a node part box if it is empty and + Sets the default width for a node part box if it is empty and empty parts are not ignored. \end{key} \begin{key}{/pgf/rectangle split empty part height=\meta{length} (initially 1ex)} - Set the default height for a node part box if it is empty and + Sets the default height for a node part box if it is empty and empty parts are not ignored. \end{key} \begin{key}{/pgf/rectangle split empty part depth=\meta{length} (initially 0ex)} - Set the default depth for a node part box if it is empty and + Sets the default depth for a node part box if it is empty and empty parts are not ignored. \end{key} \begin{key}{/pgf/rectangle split part align={\ttfamily\char`\{}\meta{list}{\ttfamily\char`\}} (initially center)} - Set the alignment of the boxes inside the node parts. + Sets the alignment of the boxes inside the node parts. Each item in \meta{list} should be separated by commas (so if there is more than one item in - \meta{list} it must be surrounded by braces). + \meta{list}, it must be surrounded by braces). When the rectangle is split vertically, the entries in \meta{list} must be one of |left|, |right|, or |center|. If \meta{list} has less @@ -1752,7 +1846,7 @@ these extra boxes, the following key is provided: When the rectangle is split horizontally, the entries in \meta{list} must be one of |top|, |bottom|, |center| or |base|. Note that using - the value |base| will only makes sense if all the node part boxes are + the value |base| will only make sense if all the node part boxes are being aligned in this way. This is because the |base| value aligns the boxes in relation to each other, whereas the other values align the boxes in relation to the part of the shape they occupy. @@ -1774,7 +1868,7 @@ these extra boxes, the following key is provided: \end{key} \begin{key}{/pgf/rectangle split draw splits=\opt{\meta{boolean}} (default true)} - Set whether the line or lines between node parts will be drawn. + Sets whether the line or lines between node parts will be drawn. Internally, this sets the \TeX-if |\ifpgfrectanglesplitdrawsplits| appropriately. \end{key} @@ -1790,12 +1884,12 @@ these extra boxes, the following key is provided: \end{key} \begin{key}{/pgf/rectangle split part fill={\ttfamily\char`\{}\meta{list}{\ttfamily\char`\}} (initially white)} - Set the custom fill color for each node part shape. - Each item in \meta{list} should be separated by commas (so if - there is more than one item in \meta{list} it must be surrounded + Sets the custom fill color for each node part shape. + The items in \meta{list} should be separated by commas (so if + there is more than one item in \meta{list}, it must be surrounded by braces). If \meta{list} has less entries than node - parts then the remaining node parts use the color from + parts, then the remaining node parts use the color from the last entry in the list. This key will automatically set |/pgf/rectangle split use custom fill|. @@ -1813,7 +1907,7 @@ these extra boxes, the following key is provided: The anchors for the |rectangle split| shape split vertically into four, are shown below (anchor |70| is an example of a border angle). When a - node part is missing, the anchors prefixed with name of that node part + node part is missing, the anchors prefixed with the name of that node part should be considered unavailable. They are (unavoidably) defined, but default to other anchor positions. @@ -1859,7 +1953,7 @@ these extra boxes, the following key is provided: \end{pgflibrary} Callouts consist of a -main shape, and a pointer (which is part of the shape) which points +main shape and a pointer (which is part of the shape) which points to something in (or outside) the picture. The position on the border of the main shape to which the pointer is connected is determined automatically. However, the pointer is ignored when calculating the @@ -1903,14 +1997,14 @@ on whether they are being used in \pgfname{} or \tikzname{}. \begin{key}{/pgf/callout relative pointer=\meta{coordinate} (initially {\ttfamily\char`\\pgfpointpolar\char`\{315\char`\}\char`\{.5cm\char`\}})} - Set the vector of the callout pointer `relative' to the callout + Sets the vector of the callout pointer `relative' to the callout shape. \end{key} \begin{key}{/pgf/callout absolute pointer=\meta{coordinate}} - Set the vector of the callout pointer absolutely within the picture. + Sets the vector of the callout pointer absolutely within the picture. \end{key} @@ -1932,7 +2026,7 @@ on whether they are being used in \pgfname{} or \tikzname{}. the following key: \begin{key}{/pgf/callout pointer shorten=\meta{distance} (initially 0cm)} - Move the callout pointer towards the center of the callouts main + Moves the callout pointer towards the center of the callout's main shape by \meta{distance}. \begin{codeexample}[] @@ -1957,14 +2051,14 @@ on whether they are being used in \pgfname{} or \tikzname{}. \begin{key}{/pgf/callout pointer width=\meta{length} (initially .25cm)} - Set the width of the pointer at the border of the rectangle. + Sets the width of the pointer at the border of the rectangle. \end{key} The anchors for this shape are shown below (anchor |60| is an example of a border anchor). The pointer direction is ignored when placing anchors. Additionally, when using an absolute pointer, the |pointer| - anchor should not be used to used to position the shape as it is + anchor should not to be used to used to position the shape as it is calculated whilst the shape is being drawn. \begin{codeexample}[] @@ -1991,7 +2085,7 @@ on whether they are being used in \pgfname{} or \tikzname{}. \begin{shape}{ellipse callout}% - This shape is a callout whose main shape is a ellipse, which + This shape is a callout whose main shape is an ellipse, which tightly fits the node contents (including any |inner sep|). It uses the |absolute callout pointer|, |relative callout pointer| and |callout pointer shorten| keys, and @@ -1999,7 +2093,7 @@ on whether they are being used in \pgfname{} or \tikzname{}. \begin{key}{/pgf/callout pointer arc=\meta{angle} (initially 15)} - Set the width of pointer at the border of the ellipse according + Sets the width of the pointer at the border of the ellipse according to an arc of length \meta{angle}. \end{key} @@ -2053,7 +2147,7 @@ The main shape can be modified using the same keys as the |cloud| shape. The following keys are also supported: \begin{key}{/pgf/callout pointer start size=\meta{value} (initially .2 of callout)} - Set the size of the first segment in the pointer (i.e., the segment + Sets the size of the first segment in the pointer (i.e., the segment nearest the main cloud shape). There are three possible forms for \meta{value}: \begin{itemize} @@ -2072,11 +2166,11 @@ shape. The following keys are also supported: \end{key} \begin{key}{/pgf/callout pointer end size=\meta{value} (initially .1 of callout)} - Set the size of the last ellipse in the pointer. + Sets the size of the last ellipse in the pointer. \end{key} \begin{key}{/pgf/callout pointer segments=\meta{number} (initially 2)} - Set the number of segments in the pointer. Note that \pgfname{} will + Sets the number of segments in the pointer. Note that \pgfname{} will happily overlap segments if too many are specified. \end{key} @@ -2116,13 +2210,13 @@ of the last segment is drawn at the |pointer| anchor. \subsection{Miscellaneous Shapes} \begin{pgflibrary}{shapes.misc} - This library defines general-purpose shapes that do not fit in the + This library defines general-purpose shapes that do not fit into the previous categories. \end{pgflibrary} \begin{shape}{cross out} This shape ``crosses out'' the node. Its foreground path are simply - two diagonal lines that between the corners of the node's bounding + two diagonal lines between the corners of the node's bounding box. Here is an example: \begin{codeexample}[] @@ -2172,7 +2266,7 @@ Strike \tikz[baseline] \node [strike out,draw,anchor=text] {me}; out! \begin{shape}{rounded rectangle} - This shape is a rectangle which can be optionally round sides. + This shape is a rectangle which can have optionally rounded sides. \begin{codeexample}[] \begin{tikzpicture} @@ -2186,7 +2280,7 @@ Strike \tikz[baseline] \node [strike out,draw,anchor=text] {me}; out! \begin{key}{/pgf/rounded rectangle arc length=\meta{angle} (initially 180)} - Set the length of the arcs for the rounded ends. Recommended values + Sets the length of the arcs for the rounded ends. Recommended values for \meta{angle} are between |90| and |180|. \begin{codeexample}[] @@ -2201,7 +2295,7 @@ Strike \tikz[baseline] \node [strike out,draw,anchor=text] {me}; out! \end{key} \begin{key}{/pgf/rounded rectangle west arc=\meta{arc type} (initially convex)} - Set the style of the rounding for the left side. The permitted values + Sets the style of the rounding for the left side. The permitted values for \meta{arc type} are |concave|, |convex|, or |none|. \begin{codeexample}[] @@ -2219,7 +2313,7 @@ Strike \tikz[baseline] \node [strike out,draw,anchor=text] {me}; out! \end{stylekey} \begin{key}{/pgf/rounded rectangle east arc=\meta{arc type} (initially convex)} - Set the style of the rounding for the east side. + Sets the style of the rounding for the east side. \end{key} \begin{stylekey}{/pgf/rounded rectangle right arc=\meta{arc type}} @@ -2265,7 +2359,7 @@ Strike \tikz[baseline] \node [strike out,draw,anchor=text] {me}; out! these keys in \tikzname{} simply remove the \declare{|/pgf/|} path). \begin{key}{/pgf/chamfered rectangle angle=\meta{angle} (initially 45)} - Set the angle \emph{from the vertical} for the chamfer. + Sets the angle \emph{from the vertical} for the chamfer. \begin{codeexample}[] \begin{tikzpicture} @@ -2277,7 +2371,7 @@ Strike \tikz[baseline] \node [strike out,draw,anchor=text] {me}; out! \end{key} \begin{key}{/pgf/chamfered rectangle xsep=\meta{length} (initially .666ex)} - Set the distance that the chamfer extends horizontally beyond the node + Sets the distance that the chamfer extends horizontally beyond the node contents (which includes the |inner sep|). If \meta{length} is large, such that the top and bottom chamfered edges would cross, then @@ -2295,7 +2389,7 @@ Strike \tikz[baseline] \node [strike out,draw,anchor=text] {me}; out! \end{key} \begin{key}{/pgf/chamfered rectangle ysep=\meta{length} (initially .666ex)} - Set the distance that the chamfer extends vertically beyond the node + Sets the distance that the chamfer extends vertically beyond the node contents. If \meta{length} is large, such that the left and right chamfered edges would cross, then \meta{length} is ignored and the chamfered @@ -2303,11 +2397,11 @@ Strike \tikz[baseline] \node [strike out,draw,anchor=text] {me}; out! \end{key} \begin{key}{/pgf/chamfered rectangle sep=\meta{length} (initially .666ex)} - Set both the |xsep| and |ysep| simultaneously. + Sets both the |xsep| and |ysep| simultaneously. \end{key} \begin{key}{/pgf/chamfered rectangle corners=\meta{list} (initially chamfer all)} - Specify which corners are chamfered. The corners are identified by + Specifies which corners are chamfered. The corners are identified by their ``compass point'' directions (i.e. |north east|, |north west|, |south west|, and |south east|), and must be separated by commas (so if there is more than one corner in the list, it must be surrounded diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-spy.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-spy.tex index dc6f163929f..3f4aad69293 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-spy.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-spy.tex @@ -69,7 +69,7 @@ make this possible: implicitly set the |spy scope|. \item Inside this scope you may then use the command |\spy|, which is - only available inside such scopes (so there is no danger of your + only available inside such scopes (so there is no danger of you inadvertently using this command outside such a scope). This command has a special syntax and will (at some point) create two nodes: One node that shows the magnified picture (called the \emph{spy-in @@ -118,7 +118,7 @@ computed automatically. following effects: \begin{itemize} \item It resets a number of graphic state parameters, including the - color, line style, and other. This is necessary for technical + color, line style, and others. This is necessary for technical reasons. \item It tells \tikzname\ that the content of the scope should be saved internally in a special box. @@ -130,13 +130,13 @@ computed automatically. |\spy| is used, these \meta{options} will be used. \item Three keys are defined that provide useful shortcuts: \begin{key}{/tikz/size=\meta{dimension}} - Inside a |spy scope|, |size| this is a shortcut for |minimum size|. + Inside a |spy scope|, this is a shortcut for |minimum size|. \end{key} \begin{key}{/tikz/height=\meta{dimension}} - Inside a |spy scope|, |height| this is a shortcut for |minimum height|. + Inside a |spy scope|, this is a shortcut for |minimum height|. \end{key} \begin{key}{/tikz/width=\meta{dimension}} - Inside a |spy scope|, |width| this is a shortcut for |minimum width|. + Inside a |spy scope|, this is a shortcut for |minimum width|. \end{key} \end{itemize} It is permissible to nest |spy scopes|. In this case, all |\spy| @@ -172,7 +172,7 @@ computed automatically. \subsection{The Spy Command} \begin{command}{\spy \opt{\oarg{options}} |on| \meta{coordinate} - |in node| \meta{node options}|;|} + \texttt{in node} \meta{node options}|;|} This command can only be used inside a |spy scope|. Let us start with the syntax: \begin{itemize} \item The |\spy| command is not a special case of |\path|. Rather, @@ -207,7 +207,7 @@ computed automatically. To be precise, the picture of the |spy scope| is scaled by a certain factor, specified by the |lens| or |magnification| options - discussed below, and the shifted in such a way that the + discussed below, and is shifted in such a way that the \meta{coordinate} lies at the center of the spy-on node. \item The \emph{spy-on node} is a node that is centered on the \meta{coordinate} and whose size reflects exactly the area shown @@ -230,7 +230,7 @@ computed automatically. effect caused by the \meta{options} and the options of the |{spy scope}|. Additionally, the following style is used: \begin{stylekey}{/tikz/every spy in node} - This style is used with every spy in node. + This style is used with every spy-in node. \end{stylekey} The position of the node (the |at| option) is set to the \meta{coordinate} by default, so that it will cover the @@ -270,7 +270,7 @@ computed automatically. size. Note that the key |size| is an abbreviation for |minimum size| inside a spy scope. - You can name the spy on node in the usual ways. Additionally, the + You can name the spy-on node in the usual ways. Additionally, the node is (also) always named |tikzspyinnode|. Following the spy scope, you can use this node like any other node: \begin{codeexample}[] @@ -326,7 +326,7 @@ computed automatically. Like for the spy-in node, a style can be used to format the spy-on node: \begin{stylekey}{/tikz/every spy on node} - This style is used with every spy on node. + This style is used with every spy-on node. \end{stylekey} The spy-on node is named |tikzspyonnode| (but, as always, this node is only available after the spy scope). If you have multiple @@ -344,7 +344,7 @@ computed automatically. There are some predefined styles that make using the |spy| library easier. The following two styles can be used instead of |spy scope|, they pass their \meta{options} directly to |spy scope|. They -additionally setup the graphic styles to be used for the spy-in nodes +additionally set up the graphic styles to be used for the spy-in nodes and the spy-on nodes in some special way. \begin{key}{/tikz/spy using outlines=\meta{options} (default diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-svg-path.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-svg-path.tex index cafe102caad..ea6b2a73263 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-svg-path.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-svg-path.tex @@ -13,7 +13,7 @@ \begin{pgflibrary}{svg.path} This library defines a command that allows you to specify a path - using the svg-syntax. + using the \textsc{svg}-syntax. \end{pgflibrary} \begin{command}{\pgfpathsvg\marg{path}} @@ -24,16 +24,16 @@ In principle, the complete syntax is supported and the library just provides a parser and a mapping to basic layer commands. For instance, |M 0 10| is mapped to - |\pgfpathmoveto{\pgfpoint{0pt}{10pt}}|. There, however, a few things + |\pgfpathmoveto{\pgfpoint{0pt}{10pt}}|. There are, however, a few things to be aware of: \begin{itemize} \item The computation underlying the arc commands |A| and |a| are not numerically stable, which may result in quite imprecise arcs. B\'ezier curves, both quadratic and cubic, are not affected, - and also not arcs spanning degrees that are multiples of - $90^\circ$. + neither are arcs spanning degrees that are multiples of + $90^{\circ}$. \item The dimensionless units of \textsc{svg} are always interpreted - at points (|pt|). This is a problem with paths like |M 20000 0|, + as points (|pt|). This is a problem with paths like |M 20000 0|, which will raise an error message since \TeX\ cannot handle dimensions larger than about 16000 points. \item diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-trees.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-trees.tex index d95dd5e2106..7fd7974023c 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-trees.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-trees.tex @@ -22,8 +22,8 @@ The package |trees| defines two new growth functions. They are installed using the following options: -\begin{key}{/tikz/grow via three points=|one child at (|\meta{x}% - |) and two children at (|\meta{y}|) and (|\meta{z}|)|} +\begin{key}{/tikz/grow via three points=\texttt{one child at (}\meta{x}% + \texttt{) and two children at (}\meta{y}\texttt{) and (}\meta{z}|)|} This option installs a growth function that works as follows: If a parent node has just one child, this child is placed at \meta{x}. If the parent node has two children, these are placed at \meta{y} and @@ -82,7 +82,7 @@ functions. They are installed using the following options: \begin{key}{/tikz/grow cyclic} This style causes the children to be arranged ``on a circle.'' For this, the children are placed at distance |\tikzleveldistance| from - the parent node, but not on a straight line, but points on a + the parent node, but not on a straight line, but on points on a circle. Instead of a sibling distance, there is a |sibling angle| that denotes the angle between two given children. \begin{key}{/tikz/sibling angle=\meta{angle}} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-turtle.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-turtle.tex index ffb35b231d4..46198942e5a 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-turtle.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-library-turtle.tex @@ -28,7 +28,7 @@ Even though the |turtle| keys looks like an option, it uses the The basic drawing model behind the turtle graphics is very simple: There is a (virtual) \emph{turtle} that crawls around the page, thereby extending the path. The turtle always heads in a certain -direction. When you move the turtle forward you extend the path in +direction. When you move the turtle forward, you extend the path in that direction; turning the turtle just changes the direction, it does not cause anything to be drawn. @@ -63,7 +63,7 @@ independently of other path commands. the operation |to[turtle/how]| is used to extend the path to this point. \begin{stylekey}{/tikz/turtle/how (initially \normalfont empty)} - This style can setup the |to path| used by turtles. By setting + This style can set up the |to path| used by turtles. By setting this style you can change the to-path: \begin{codeexample}[] \tikz \draw [turtle={how/.style={bend left},home,forward,right,forward}]; diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-main-body.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-main-body.tex new file mode 100644 index 00000000000..1fdda1c63d9 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-main-body.tex @@ -0,0 +1,838 @@ +% Copyright 2006 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + +\begin{document} + +% The titlepage + +\newbox\mybox +{ + \parindent0pt + \null + \colorlet{mintgreen}{green!50!black!50} + + \thispagestyle{empty} + \vskip3cm + \vfill + \hfil + \begin{tikzpicture}[overlay] + \coordinate (front) at (0,0); + \coordinate (horizon) at (0,.31\paperheight); + \coordinate (bottom) at (0,-.6\paperheight); + \coordinate (sky) at (0,.57\paperheight); + \coordinate (left) at (-.51\paperwidth,0); + \coordinate (right) at (.51\paperwidth,0); + + \shade [bottom color=blue!30!black!10,top color=blue!30!black!50] + ([yshift=-5mm]horizon -| left) rectangle (sky -| right); + \shade [bottom color=black!70!green!25,top color=black!70!green!10] + (front -| left) -- (horizon -| left) + decorate [decoration=random steps] { -- (horizon -| right) } + -- (front -| right) -- cycle; + \shade [top color=black!70!green!25,bottom color=black!25] + ([yshift=-5mm-1pt]front -| left) rectangle ([yshift=1pt]front -| right); + \fill [black!25] (bottom -| left) rectangle ([yshift=-5mm]front -| right); + + \def\nodeshadowed[#1]#2;{\node[scale=2,above,#1]{\global\setbox\mybox=\hbox{#2}\copy\mybox}; + \node[scale=2,above,#1,yscale=-1,scope fading=south,opacity=0.4]{\box\mybox};} + + \nodeshadowed [at={(-5,5 )},yslant=0.05] {\Huge Ti\textcolor{orange}{\emph{k}}Z}; + \nodeshadowed [at={( 0,5.3)}] {\huge \textcolor{mintgreen}{\&}}; + \nodeshadowed [at={( 5,5 )},yslant=-0.05] {\Huge \textsc{PGF}}; + \nodeshadowed [at={( 0,2 )}] {Manual for Version \pgftypesetversion}; + + \foreach \where in {-9cm,9cm} + {\nodeshadowed [at={(\where,5cm)}] { + \tikz \draw [green!20!black, rotate=90] + [l-system={rule set={F -> FF-[-F+F]+[+F-F]}, axiom=F, order=4, + step=2pt, randomize step percent=50, angle=30, randomize angle percent=5}] + lindenmayer system;};} + + \foreach \i in {0.5,0.6,...,2} + \fill [white,decoration=Koch snowflake,opacity=.9] + [shift=(horizon),shift={(rand*11,rnd*7)},scale=\i] + [double copy shadow={opacity=0.2,shadow xshift=0pt,shadow + yshift=3*\i pt,fill=white,draw=none}] + decorate { + decorate { + decorate { + (0,0) -- ++(60:1) -- ++(-60:1) -- cycle + } + } + }; + + \node (left text) [text width=.5\paperwidth-2cm,below right,at={(-.5\paperwidth+1cm,-1.5cm)}] + { + \fontfamily{pcr} + \def\textbraceleft{\char`\{} + \def\textbraceright{\char`\}} + \def\textbackslash{\char`\\} + \begin{lstlisting}[basicstyle=\scriptsize\color{black}, + keywordstyle=\bfseries\color{white}, + identifierstyle=\bfseries\color{black}, + keywords={tikzpicture,shade,fill,draw,path,node}, + literate={-}{{-}}1] +\begin{tikzpicture} + \coordinate (front) at (0,0); + \coordinate (horizon) at (0,.31\paperheight); + \coordinate (bottom) at (0,-.6\paperheight); + \coordinate (sky) at (0,.57\paperheight); + \coordinate (left) at (-.51\paperwidth,0); + \coordinate (right) at (.51\paperwidth,0); + + \shade [bottom color=white, + top color=blue!30!black!50] + ([yshift=-5mm]horizon -| left) + rectangle (sky -| right); + + \shade [bottom color=black!70!green!25, + top color=black!70!green!10] + (front -| left) -- (horizon -| left) + decorate [decoration=random steps] { + -- (horizon -| right) } + -- (front -| right) -- cycle; + + \shade [top color=black!70!green!25, + bottom color=black!25] + ([yshift=-5mm-1pt]front -| left) + rectangle ([yshift=1pt]front -| right); + + \fill [black!25] + (bottom -| left) + rectangle ([yshift=-5mm]front -| right); + + \def\nodeshadowed[#1]#2;{ + \node[scale=2,above,#1]{ + \global\setbox\mybox=\hbox{#2} + \copy\mybox}; + \node[scale=2,above,#1,yscale=-1, + scope fading=south,opacity=0.4]{\box\mybox}; + } +\end{lstlisting} +}; + + \node (right text) [text width=.5\paperwidth-2cm,below right,at={(1cm,-1.5cm)}] + { + \fontfamily{pcr} + \def\textbraceleft{\char`\{} + \def\textbraceright{\char`\}} + \def\textbackslash{\char`\\} + \begin{lstlisting}[basicstyle=\scriptsize\color{black}, + keywordstyle=\bfseries\color{white}, + identifierstyle=\bfseries\color{black}, + keywords={tikzpicture,shade,fill,draw,path,node}, + literate={-}{{-}}1] + \nodeshadowed [at={(-5,8 )},yslant=0.05] + {\Huge Ti\textcolor{orange}{\emph{k}}Z}; + \nodeshadowed [at={( 0,8.3)}] + {\huge \textcolor{green!50!black!50}{\&}}; + \nodeshadowed [at={( 5,8 )},yslant=-0.05] + {\Huge \textsc{PGF}}; + \nodeshadowed [at={( 0,5 )}] + {Manual for Version \pgftypesetversion}; + + \foreach \where in {-9cm,9cm} { + \nodeshadowed [at={(\where,5cm)}] { \tikz + \draw [green!20!black, rotate=90, + l-system={rule set={F -> FF-[-F+F]+[+F-F]}, + axiom=F, order=4,step=2pt, + randomize step percent=50, angle=30, + randomize angle percent=5}] l-system; }} + + \foreach \i in {0.5,0.6,...,2} + \fill + [white,opacity=\i/2, + decoration=Koch snowflake, + shift=(horizon),shift={(rand*11,rnd*7)}, + scale=\i,double copy shadow={ + opacity=0.2,shadow xshift=0pt, + shadow yshift=3*\i pt,fill=white,draw=none}] + decorate { + decorate { + decorate { + (0,0)- ++(60:1) -- ++(-60:1) -- cycle + } } }; + + \node (left text) ... + \node (right text) ... + + \fill [decorate,decoration={footprints,foot of=gnome}, + opacity=.5,brown] (rand*8,-rnd*10) + to [out=rand*180,in=rand*180] (rand*8,-rnd*10); +\end{tikzpicture} + \end{lstlisting} + }; + + \fill [decorate,decoration=footprints, + decoration={footprints,foot of=gnome}, + opacity=.5,brown] (rand*8,-rnd*10) + to [out=rand*180,in=rand*180] (rand*8,-rnd*10); +\end{tikzpicture} +\vfill +\vbox{} +\clearpage +} + +{ + \vbox{} + \vskip0pt plus 1fill + F\"ur meinen Vater, damit er noch viele sch\"one \TeX-Graphiken + erschaffen kann. + \vskip1em + \hfill\emph{Till} + \vskip0pt plus 3fill + + \parindent=0pt + Copyright 2007 to 2013 by Till Tantau + + \medskip + Permission is granted to copy, distribute and/or modify \emph{the documentation} + under the terms of the \textsc{gnu} Free Documentation License, Version 1.2 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. + A copy of the license is included in the section entitled \textsc{gnu} + Free Documentation License. + + \medskip + Permission is granted to copy, distribute and/or modify \emph{the + code of the package} under the terms of the \textsc{gnu} Public License, Version 2 + or any later version published by the Free Software Foundation. + A copy of the license is included in the section entitled \textsc{gnu} + Public License. + + \medskip + Permission is also granted to distribute and/or modify \emph{both + the documentation and the code} 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 the license is included in + the section entitled \LaTeX\ Project Public License. + + \vbox{} + \clearpage +} + + +\title{\bfseries The \tikzname\ and {\Large PGF} Packages\\ + \large Manual for version \pgfversion\\[1mm] +\large\href{http://sourceforge.net/projects/pgf}{\texttt{http://sourceforge.net/projects/pgf}}} +\author{Till Tantau\footnote{Editor of this documentation. Parts of + this documentation have been written by other authors as indicated + in these parts or chapters and in Section~\ref{section-authors}.}\\ + \normalsize Institut f\"ur Theoretische Informatik\\[-1mm] + \normalsize Universit\"at zu L\"ubeck} + +\maketitle + +\tableofcontents + +\clearpage + + +\include{pgfmanual-en-introduction} + + +\part{Tutorials and Guidelines} + +{\Large \emph{by Till Tantau}} + +\bigskip +\noindent +To help you get started with \tikzname, instead of a long installation +and configuration section, this manual starts with tutorials. They +explain all the basic and some of the more advanced features of the +system, without going into all the details. This part also contains +some guidelines on how you should proceed when creating graphics using +\tikzname. + +\vskip3cm + +\begin{codeexample}[graphic=white,width=0pt] +\tikz \draw[thick,rounded corners=8pt] + (0,0) -- (0,2) -- (1,3.25) -- (2,2) -- (2,0) -- (0,2) -- (2,2) -- (0,0) -- (2,0); +\end{codeexample} + +\include{pgfmanual-en-tutorial} +\include{pgfmanual-en-tutorial-nodes} +\include{pgfmanual-en-tutorial-Euclid} +\include{pgfmanual-en-tutorial-chains} +\include{pgfmanual-en-tutorial-map} +\include{pgfmanual-en-guidelines} + + + +\part{Installation and Configuration} + +{\Large \emph{by Till Tantau}} + + +\bigskip +\noindent +This part explains how the system is installed. Typically, someone has +already done so for your system, so this part can be skipped; but if +this is not the case and you are the poor fellow who has to do the +installation, read the present part. + + +\vskip1cm + +\begin{codeexample}[graphic=white] +\begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=2.8cm,on grid,semithick, + every state/.style={fill=red,draw=none,circular drop shadow,text=white}] + + \node[initial,state] (A) {$q_a$}; + \node[state] (B) [above right=of A] {$q_b$}; + \node[state] (D) [below right=of A] {$q_d$}; + \node[state] (C) [below right=of B] {$q_c$}; + \node[state] (E) [below=of D] {$q_e$}; + + \path (A) edge node {0,1,L} (B) + edge node {1,1,R} (C) + (B) edge [loop above] node {1,1,L} (B) + edge node {0,1,L} (C) + (C) edge node {0,1,L} (D) + edge [bend left] node {1,0,R} (E) + (D) edge [loop below] node {1,1,R} (D) + edge node {0,1,R} (A) + (E) edge [bend left] node {1,0,R} (A); + + \node [right=1cm,text width=8cm] at (C) + { + The current candidate for the busy beaver for five states. It is + presumed that this Turing machine writes a maximum number of + $1$'s before halting among all Turing machines with five states + and the tape alphabet $\{0, 1\}$. Proving this conjecture is an + open research problem. + }; +\end{tikzpicture} +\end{codeexample} + +\include{pgfmanual-en-installation} +\include{pgfmanual-en-license} +\include{pgfmanual-en-drivers} + + +\part{Ti\emph{k}Z ist \emph{kein} Zeichenprogramm} +\label{part-tikz} + +{\Large \emph{by Till Tantau}} + + +\bigskip +\noindent +\vskip3cm +\begin{codeexample}[graphic=white] + +\begin{tikzpicture}[angle radius=.75cm] + + \node (A) at (-2,0) [red,left] {$A$}; + \node (B) at ( 3,.5) [red,right] {$B$}; + \node (C) at (-2,2) [blue,left] {$C$}; + \node (D) at ( 3,2.5) [blue,right] {$D$}; + \node (E) at (60:-5mm) [below] {$E$}; + \node (F) at (60:3.5cm) [above] {$F$}; + + \coordinate (X) at (intersection cs:first line={(A)--(B)}, second line={(E)--(F)}); + \coordinate (Y) at (intersection cs:first line={(C)--(D)}, second line={(E)--(F)}); + + \path + (A) edge [red, thick] (B) + (C) edge [blue, thick] (D) + (E) edge [thick] (F) + pic ["$\alpha$", draw, fill=yellow] {angle = F--X--A} + pic ["$\beta$", draw, fill=green!30] {angle = B--X--F} + pic ["$\gamma$", draw, fill=yellow] {angle = E--Y--D} + pic ["$\delta$", draw, fill=green!30] {angle = C--Y--E}; + + \node at ($ (D)!.5!(B) $) [right=1cm,text width=6cm,rounded corners,fill=red!20,inner sep=1ex] + { + When we assume that $\color{red}AB$ and $\color{blue}CD$ are + parallel, i.\,e., ${\color{red}AB} \mathbin{\|} \color{blue}CD$, + then $\alpha = \delta$ and $\beta = \gamma$. + }; +\end{tikzpicture} +\end{codeexample} + + + +\include{pgfmanual-en-tikz-design} +\include{pgfmanual-en-tikz-scopes} +\include{pgfmanual-en-tikz-coordinates} +\include{pgfmanual-en-tikz-paths} +\include{pgfmanual-en-tikz-actions} +\include{pgfmanual-en-tikz-arrows} +\include{pgfmanual-en-tikz-shapes} +\include{pgfmanual-en-tikz-pics} +\include{pgfmanual-en-tikz-graphs} +\include{pgfmanual-en-tikz-matrices} +\include{pgfmanual-en-tikz-trees} +\include{pgfmanual-en-tikz-plots} +\include{pgfmanual-en-tikz-transparency} +\include{pgfmanual-en-tikz-decorations} +\include{pgfmanual-en-tikz-transformations} + + +\part{Graph Drawing} +\label{part-gd} + +{\Large \emph{by Till Tantau et al.}} + +\bigskip +\noindent +\emph{Graph drawing algorithms} do the tough work of computing a +layout of a graph for you. \tikzname\ comes with powerful +such algorithms, but you can also implement new algorithms in the +Lua programming language. +\vskip1cm + +\ifluatex +\begin{codeexample}[graphic=white] +\tikz [nodes={text height=.7em, text depth=.2em, + draw=black!20, thick, fill=white, font=\footnotesize}, + >=spaced stealth', rounded corners, semithick] + \graph [layered layout, level distance=1cm, sibling sep=.5em, sibling distance=1cm] { + "5th Edition" -> { "6th Edition", "PWB 1.0" }; + "6th Edition" -> { "LSX" [>child anchor=45], "1 BSD", "Mini Unix", "Wollongong", "Interdata" }; + "Interdata" -> { "Unix/TS 3.0", "PWB 2.0", "7th Edition" }; + "7th Edition" -> { "8th Edition", "32V", "V7M", "Ultrix-11", "Xenix", "UniPlus+" }; + "V7M" -> "Ultrix-11"; + "8th Edition" -> "9th Edition"; + "1 BSD" -> "2 BSD" -> "2.8 BSD" -> { "Ultrix-11", "2.9 BSD" }; + "32V" -> "3 BSD" -> "4 BSD" -> "4.1 BSD" -> { "4.2 BSD", "2.8 BSD", "8th Edition" }; + "4.2 BSD" -> { "4.3 BSD", "Ultrix-32" }; + "PWB 1.0" -> { "PWB 1.2" -> "PWB 2.0", "USG 1.0" -> { "CB Unix 1", "USG 2.0" }}; + "CB Unix 1" -> "CB Unix 2" -> "CB Unix 3" -> { "Unix/TS++", "PDP-11 Sys V" }; + { "USG 2.0" -> "USG 3.0", "PWB 2.0", "Unix/TS 1.0" } -> "Unix/TS 3.0"; + { "Unix/TS++", "CB Unix 3", "Unix/TS 3.0" } -> "TS 4.0" -> "System V.0" -> "System V.2" -> "System V.3"; + }; +\end{codeexample} + +\else +You need to use Lua\TeX\ to typeset this part of the manual (and, +also, to use algorithmic graph drawing). +\fi + +\include{pgfmanual-en-gd-overview} +\include{pgfmanual-en-gd-usage-tikz} +\include{pgfmanual-en-gd-usage-pgf} +\include{pgfmanual-en-gd-trees} +\include{pgfmanual-en-gd-layered} +\include{pgfmanual-en-gd-force} +\include{pgfmanual-en-gd-circular} +\include{pgfmanual-en-gd-phylogenetics} +\include{pgfmanual-en-gd-ogdf} +\include{pgfmanual-en-gd-algorithm-layer} +\include{pgfmanual-en-gd-algorithms-in-c} +\include{pgfmanual-en-gd-display-layer} +\include{pgfmanual-en-gd-binding-layer} + + +\part{Libraries} +\label{part-libraries} + +{\Large \emph{by Till Tantau}} + + +\bigskip +\noindent +In this part the library packages are documented. They +provide additional predefined graphic objects like new arrow heads or +new plot marks, but sometimes also extensions of the basic \pgfname\ +or \tikzname\ system. The libraries are not loaded by default since +many users will not need them. + +\medskip +\noindent +\begin{codeexample}[graphic=white] +\tikzset{ + ld/.style={level distance=#1},lw/.style={line width=#1}, + level 1/.style={ld=4.5mm, trunk, lw=1ex ,sibling angle=60}, + level 2/.style={ld=3.5mm, trunk!80!leaf a,lw=.8ex,sibling angle=56}, + level 3/.style={ld=2.75mm,trunk!60!leaf a,lw=.6ex,sibling angle=52}, + level 4/.style={ld=2mm, trunk!40!leaf a,lw=.4ex,sibling angle=48}, + level 5/.style={ld=1mm, trunk!20!leaf a,lw=.3ex,sibling angle=44}, + level 6/.style={ld=1.75mm,leaf a, lw=.2ex,sibling angle=40}, +} +\pgfarrowsdeclare{leaf}{leaf} + {\pgfarrowsleftextend{-2pt} \pgfarrowsrightextend{1pt}} +{ + \pgfpathmoveto{\pgfpoint{-2pt}{0pt}} + \pgfpatharc{150}{30}{1.8pt} + \pgfpatharc{-30}{-150}{1.8pt} + \pgfusepathqfill +} + +\newcommand{\logo}[5] +{ + \colorlet{border}{#1} + \colorlet{trunk}{#2} + \colorlet{leaf a}{#3} + \colorlet{leaf b}{#4} + \begin{tikzpicture} + \scriptsize\scshape + \draw[border,line width=1ex,yshift=.3cm, + yscale=1.45,xscale=1.05,looseness=1.42] + (1,0) to [out=90, in=0] (0,1) to [out=180,in=90] (-1,0) + to [out=-90,in=-180] (0,-1) to [out=0, in=-90] (1,0) -- cycle; + + \coordinate (root) [grow cyclic,rotate=90] + child { + child [line cap=round] foreach \a in {0,1} { + child foreach \b in {0,1} { + child foreach \c in {0,1} { + child foreach \d in {0,1} { + child foreach \leafcolor in {leaf a,leaf b} + { edge from parent [color=\leafcolor,-#5] } + } } } + } edge from parent [shorten >=-1pt,serif cm-,line cap=butt] + }; + + \node [align=center,below] at (0pt,-.5ex) + { \textcolor{border}{T}heoretical \\ \textcolor{border}{C}omputer \\ + \textcolor{border}{S}cience }; + \end{tikzpicture} +} +\begin{minipage}{3cm} + \logo{green!80!black}{green!25!black}{green}{green!80}{leaf}\\ + \logo{green!50!black}{black}{green!80!black}{red!80!green}{leaf}\\ + \logo{red!75!black}{red!25!black}{red!75!black}{orange}{leaf}\\ + \logo{black!50}{black}{black!50}{black!25}{} +\end{minipage} +\end{codeexample} + +\include{pgfmanual-en-library-angles} +\include{pgfmanual-en-library-arrows} +\include{pgfmanual-en-library-automata} +\include{pgfmanual-en-library-babel} +\include{pgfmanual-en-library-backgrounds} +\include{pgfmanual-en-library-calc} +\include{pgfmanual-en-library-calendar} +\include{pgfmanual-en-library-chains} +\include{pgfmanual-en-library-circuits} +\include{pgfmanual-en-library-decorations} +\include{pgfmanual-en-library-er} +\include{pgfmanual-en-library-external} +\include{pgfmanual-en-library-fadings} +\include{pgfmanual-en-library-fit} +\include{pgfmanual-en-library-fixedpoint} +\include{pgfmanual-en-library-fpu} +\include{pgfmanual-en-library-lsystems} +\include{pgfmanual-en-library-math} +\include{pgfmanual-en-library-matrices} +\include{pgfmanual-en-library-mindmaps} +\include{pgfmanual-en-library-folding} +\include{pgfmanual-en-library-patterns} +\include{pgfmanual-en-library-petri} +\include{pgfmanual-en-library-plot-handlers} +\include{pgfmanual-en-library-plot-marks} +\include{pgfmanual-en-library-profiler} +\include{pgfmanual-en-library-shadings} +\include{pgfmanual-en-library-shadows} +\include{pgfmanual-en-library-shapes} +\include{pgfmanual-en-library-spy} +\include{pgfmanual-en-library-svg-path} +\include{pgfmanual-en-library-edges} +\include{pgfmanual-en-library-through} +\include{pgfmanual-en-library-trees} +\include{pgfmanual-en-library-turtle} + + +\part{Data Visualization} +\label{part-dv} + +{\Large \emph{by Till Tantau}} + +\bigskip +\noindent + +\begin{codeexample}[graphic=white] +\tikz \datavisualization [scientific axes=clean] +[ + visualize as smooth line=Gaussian, + Gaussian={pin in data={text={$e^{-x^2}$},when=x is 1}} +] +data [format=function] { + var x : interval [-7:7] samples 51; + func y = exp(-\value x*\value x); +} +[ + visualize as scatter, + legend={south east outside}, + scatter={ + style={mark=*,mark size=1.4pt}, + label in legend={text={ + $\sum_{i=1}^{10} x_i$, where $x_i \sim U(-1,1) $}}} +] +data [format=function] { + var i : interval [0:1] samples 20; + func y = 0; + func x = (rand + rand + rand + rand + rand + + rand + rand + rand + rand + rand); +}; +\end{codeexample} + +\include{pgfmanual-en-dv-introduction} +\include{pgfmanual-en-dv-main} +\include{pgfmanual-en-dv-formats} +\include{pgfmanual-en-dv-axes} +\include{pgfmanual-en-dv-visualizers} +\include{pgfmanual-en-dv-stylesheets} +\include{pgfmanual-en-dv-polar} +\include{pgfmanual-en-dv-backend} + + +\part{Utilities} +\label{part-utilities} + +{\Large \emph{by Till Tantau}} + + +\bigskip +\noindent +The utility packages are not directly involved in creating graphics, +but you may find them useful nonetheless. All of them either directly +depend on \pgfname\ or they are designed to work well together with +\pgfname\ even though they can be used in a stand-alone way. + +\vskip2cm +\medskip +\noindent +\begin{codeexample}[graphic=white] +\begin{tikzpicture}[scale=2] + \shade[top color=blue,bottom color=gray!50] (0,0) parabola (1.5,2.25) |- (0,0); + \draw (1.05cm,2pt) node[above] {$\displaystyle\int_0^{3/2} \!\!x^2\mathrm{d}x$}; + + \draw[help lines] (0,0) grid (3.9,3.9) + [step=0.25cm] (1,2) grid +(1,1); + + \draw[->] (-0.2,0) -- (4,0) node[right] {$x$}; + \draw[->] (0,-0.2) -- (0,4) node[above] {$f(x)$}; + + \foreach \x/\xtext in {1/1, 1.5/1\frac{1}{2}, 2/2, 3/3} + \draw[shift={(\x,0)}] (0pt,2pt) -- (0pt,-2pt) node[below] {$\xtext$}; + + \foreach \y/\ytext in {1/1, 2/2, 2.25/2\frac{1}{4}, 3/3} + \draw[shift={(0,\y)}] (2pt,0pt) -- (-2pt,0pt) node[left] {$\ytext$}; + + \draw (-.5,.25) parabola bend (0,0) (2,4) node[below right] {$x^2$}; +\end{tikzpicture} +\end{codeexample} + +\include{pgfmanual-en-pgfkeys} +\include{pgfmanual-en-pgffor} +\include{pgfmanual-en-pgfcalendar} +\include{pgfmanual-en-pages} +\include{pgfmanual-en-xxcolor} +\include{pgfmanual-en-module-parser} + + +\part{Mathematical and Object-Oriented Engines} + +{\Large \emph{by Mark Wibrow and Till Tantau}} + + +\bigskip +\noindent +\pgfname\ comes with two useful engines: One for doing mathematics, +one for doing object-oriented programming. Both engines can be used +independently of the main \pgfname. + +The job of the mathematical +engine is to support mathematical operations like addition, +subtraction, multiplication and division, using both integers and +non-integers, but also functions such as square-roots, sine, cosine, +and generate pseudo-random numbers. +Mostly, you will use the mathematical facilities of \pgfname\ +indirectly, namely when you write a coordinate like |(5cm*3,6cm/4)|, +but the mathematical engine can also be used independently of +\pgfname\ and \tikzname. + +The job of the object-oriented engine is to support simple +object-oriented programming in \TeX. It allows the definition of +\emph{classes} (without inheritance), \emph{methods}, +\emph{attributes} and \emph{objects}. + +\vskip1cm +\begin{codeexample}[graphic=white] +\pgfmathsetseed{1} +\foreach \col in {black,red,green,blue} +{ + \begin{tikzpicture}[x=10pt,y=10pt,ultra thick,baseline,line cap=round] + \coordinate (current point) at (0,0); + \coordinate (old velocity) at (0,0); + \coordinate (new velocity) at (rand,rand); + + \foreach \i in {0,1,...,100} + { + \draw[\col!\i] (current point) + .. controls ++([scale=-1]old velocity) and + ++(new velocity) .. ++(rand,rand) + coordinate (current point); + \coordinate (old velocity) at (new velocity); + \coordinate (new velocity) at (rand,rand); + } + \end{tikzpicture} +} +\end{codeexample} + +\include{pgfmanual-en-math-design} +\include{pgfmanual-en-math-parsing} +\include{pgfmanual-en-math-commands} +\include{pgfmanual-en-math-algorithms} +\include{pgfmanual-en-math-numberprinting} +\include{pgfmanual-en-oo} + + +\part{The Basic Layer} + +{\Large \emph{by Till Tantau}} + + +\bigskip +\noindent +\vskip1cm +\begin{codeexample}[graphic=white] +\begin{tikzpicture} + \draw[gray,very thin] (-1.9,-1.9) grid (2.9,3.9) + [step=0.25cm] (-1,-1) grid (1,1); + \draw[blue] (1,-2.1) -- (1,4.1); % asymptote + + \draw[->] (-2,0) -- (3,0) node[right] {$x(t)$}; + \draw[->] (0,-2) -- (0,4) node[above] {$y(t)$}; + + \foreach \pos in {-1,2} + \draw[shift={(\pos,0)}] (0pt,2pt) -- (0pt,-2pt) node[below] {$\pos$}; + + \foreach \pos in {-1,1,2,3} + \draw[shift={(0,\pos)}] (2pt,0pt) -- (-2pt,0pt) node[left] {$\pos$}; + + \fill (0,0) circle (0.064cm); + \draw[thick,parametric,domain=0.4:1.5,samples=200] + % The plot is reparameterised such that there are more samples + % near the center. + plot[id=asymptotic-example] function{(t*t*t)*sin(1/(t*t*t)),(t*t*t)*cos(1/(t*t*t))} + node[right] {$\bigl(x(t),y(t)\bigr) = (t\sin \frac{1}{t}, t\cos \frac{1}{t})$}; + + \fill[red] (0.63662,0) circle (2pt) + node [below right,fill=white,yshift=-4pt] {$(\frac{2}{\pi},0)$}; +\end{tikzpicture} +\end{codeexample} + + +\include{pgfmanual-en-base-design} +\include{pgfmanual-en-base-scopes} +\include{pgfmanual-en-base-points} +\include{pgfmanual-en-base-paths} +\include{pgfmanual-en-base-decorations} +\include{pgfmanual-en-base-actions} +\include{pgfmanual-en-base-arrows} +\include{pgfmanual-en-base-nodes} +\include{pgfmanual-en-base-matrices} +\include{pgfmanual-en-base-transformations} +\include{pgfmanual-en-base-patterns} +\include{pgfmanual-en-base-images} +\include{pgfmanual-en-base-external} +\include{pgfmanual-en-base-plots} +\include{pgfmanual-en-base-layers} +\include{pgfmanual-en-base-shadings} +\include{pgfmanual-en-base-transparency} +\include{pgfmanual-en-base-internalregisters} +\include{pgfmanual-en-base-quick} + + + + +\part{The System Layer} +\label{part-system} + +{\Large \emph{by Till Tantau}} + + +\bigskip +\noindent +This part describes the low-level interface of \pgfname, called the +\emph{system layer}. This interface provides a complete abstraction of +the internals of the underlying drivers. + +Unless you intend to port \pgfname\ to another driver or unless you intend +to write your own optimized frontend, you need not read this part. + +In the following it is assumed that you are familiar with the basic +workings of the |graphics| package and that you know what +\TeX-drivers are and how they work. + +\vskip1cm +\begin{codeexample}[graphic=white] +\begin{tikzpicture} + [shorten >=1pt,->, + vertex/.style={circle,fill=black!25,minimum size=17pt,inner sep=0pt}] + + \foreach \name/\x in {s/1, 2/2, 3/3, 4/4, 15/11, 16/12, 17/13, 18/14, 19/15, t/16} + \node[vertex] (G-\name) at (\x,0) {$\name$}; + + \foreach \name/\angle/\text in {P-1/234/5, P-2/162/6, P-3/90/7, P-4/18/8, P-5/-54/9} + \node[vertex,xshift=6cm,yshift=.5cm] (\name) at (\angle:1cm) {$\text$}; + + \foreach \name/\angle/\text in {Q-1/234/10, Q-2/162/11, Q-3/90/12, Q-4/18/13, Q-5/-54/14} + \node[vertex,xshift=9cm,yshift=.5cm] (\name) at (\angle:1cm) {$\text$}; + + \foreach \from/\to in {s/2,2/3,3/4,3/4,15/16,16/17,17/18,18/19,19/t} + \draw (G-\from) -- (G-\to); + + \foreach \from/\to in {1/2,2/3,3/4,4/5,5/1,1/3,2/4,3/5,4/1,5/2} + { \draw (P-\from) -- (P-\to); \draw (Q-\from) -- (Q-\to); } + + \draw (G-3) .. controls +(-30:2cm) and +(-150:1cm) .. (Q-1); + \draw (Q-5) -- (G-15); +\end{tikzpicture} +\end{codeexample} + +\include{pgfmanual-en-pgfsys-overview} +\include{pgfmanual-en-pgfsys-commands} +\include{pgfmanual-en-pgfsys-paths} +\include{pgfmanual-en-pgfsys-protocol} + + + +\part{References and Index} + +\vskip1cm +\begin{codeexample}[graphic=white] +\begin{tikzpicture} + \draw[line width=0.3cm,color=red!30,line cap=round,line join=round] (0,0)--(2,0)--(2,5); + \draw[help lines] (-2.5,-2.5) grid (5.5,7.5); + \draw[very thick] (1,-1)--(-1,-1)--(-1,1)--(0,1)--(0,0)-- + (1,0)--(1,-1)--(3,-1)--(3,2)--(2,2)--(2,3)--(3,3)-- + (3,5)--(1,5)--(1,4)--(0,4)--(0,6)--(1,6)--(1,5) + (3,3)--(4,3)--(4,5)--(3,5)--(3,6) + (3,-1)--(4,-1); + \draw[below left] (0,0) node(s){$s$}; + \draw[below left] (2,5) node(t){$t$}; + \fill (0,0) circle (0.06cm) (2,5) circle (0.06cm); + \draw[->,rounded corners=0.2cm,shorten >=2pt] + (1.5,0.5)-- ++(0,-1)-- ++(1,0)-- ++(0,2)-- ++(-1,0)-- ++(0,2)-- ++(1,0)-- + ++(0,1)-- ++(-1,0)-- ++(0,-1)-- ++(-2,0)-- ++(0,3)-- ++(2,0)-- ++(0,-1)-- + ++(1,0)-- ++(0,1)-- ++(1,0)-- ++(0,-1)-- ++(1,0)-- ++(0,-3)-- ++(-2,0)-- + ++(1,0)-- ++(0,-3)-- ++(1,0)-- ++(0,-1)-- ++(-6,0)-- ++(0,3)-- ++(2,0)-- + ++(0,-1)-- ++(1,0); +\end{tikzpicture} +\end{codeexample} + +\printindex + +%\typeout{Examples: \the\codeexamplecount}% +\end{document} + + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "~/pgf/doc/generic/pgf/version-for-luatex/en/pgfmanual" +%%% coding: iso-latin-1-unix +%%% End: diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-main-preamble.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-main-preamble.tex new file mode 100644 index 00000000000..9922ac79219 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-main-preamble.tex @@ -0,0 +1,223 @@ +% Copyright 2006 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + +% pgf version is defined in \pgfversion in file +% generic/pgf/utilities/pgfrcs.code.tex + +\def\xcolorversion{2.00} + +\usepackage[version=latest]{pgf} + +\usepackage{xkeyval,calc,listings,tikz,fp} + +\usepackage{hyperref} +\hypersetup{% + colorlinks=false, % use true to enable colors below: + linkcolor=blue,%red, + filecolor=blue,%magenta, + urlcolor=blue,%cyan, + citecolor=blue, + pdfborder=0 0 0, +} + +% We need lots of libraries... +\usetikzlibrary{ + arrows, + arrows.spaced, + arrows.meta, + bending, + babel, + calc, + fit, + patterns, + plotmarks, + shapes.geometric, + shapes.misc, + shapes.symbols, + shapes.arrows, + shapes.callouts, + shapes.multipart, + shapes.gates.logic.US, + shapes.gates.logic.IEC, + circuits.logic.US, + circuits.logic.IEC, + circuits.logic.CDH, + circuits.ee.IEC, + datavisualization, + datavisualization.polar, + datavisualization.formats.functions, + er, + automata, + backgrounds, + chains, + topaths, + trees, + petri, + mindmap, + matrix, + calendar, + folding, + fadings, + shadings, + spy, + through, + turtle, + positioning, + scopes, + decorations.fractals, + decorations.shapes, + decorations.text, + decorations.pathmorphing, + decorations.pathreplacing, + decorations.footprints, + decorations.markings, + shadows, + lindenmayersystems, + intersections, + fixedpointarithmetic, + fpu, + svg.path, + external, + graphs, + graphs.standard, + quotes, + math, + angles +} + +\usepackage{ifluatex} +\newif\ifgdccodebasic +\newif\ifgdccodeogdf + +\ifluatex + + \usetikzlibrary{graphdrawing} + \usegdlibrary{trees,circular,layered,examples,force,phylogenetics} + + % Test whether C code is available: + \directlua{ + if pcall(require,'pgf_gd_examples_c_SimpleDemoC') then + tex.print('\string\\gdccodebasictrue') + end + } + + \ifgdccodebasic + \usegdlibrary{pgf_gd_examples_c_SimpleDemoC,pgf_gd_examples_c_SimpleDemoCPlusPlus} + + % Test whether OGDF code is available: + \directlua{ + if pcall(require,'pgf_gd_ogdf_c_SimpleDemoOGDF') then + tex.print('\string\\gdccodeogdftrue') + end + } + + \ifgdccodeogdf + \usegdlibrary{pgf_gd_ogdf_c_SimpleDemoOGDF,ogdf} + \fi + + \fi + +\fi + +\def\LuaTeX{Lua\TeX}% + + + +\iffalse +%\iftrue + \tikzexternalize[ + mode=list only,export=true,% simply skips EVERY picture -> good for debugging the text. + ]{pgfmanual} + + \tikzifexternalizing{% + \pgfkeys{/pdflinks/codeexample links=false}% + }{}% +\fi + + +\usepackage[a4paper,left=2.25cm,right=2.25cm,top=2.5cm,bottom=2.5cm,nohead]{geometry} +\usepackage{amsmath,amssymb} +\usepackage{xxcolor} +\usepackage{pifont} +\usepackage{makeidx} + +\ifluatex +% \usepackage[no-math]{fontspec} +% \usepackage{luatextra} + + % TT: I have commented luatextra since it loads fontspec, which + % currently breaks "$\mathrm{\Omega}$" (nothing is + % shown). Also, fontspec loads so much stuff, I'm not really sure + % any of it is needed... + + % \filedescription is defined in expl3, required by fontspec, + % required by luatextra. Needs to be \relaxed since + % pgfmanual-en-macros.tex defines an environment named filedescription + \let\filedescription\relax + \usepackage[utf8]{luainputenc} +\else + \usepackage[utf8]{inputenc} +\fi +\usepackage{amsmath} + +\graphicspath{{../../images/}} % TODOsp: under windows this would go up 2 directories, but the file is only one directory up +\input{../../macros/pgfmanual-en-macros} % TODOsp: same here + +\makeindex + +\makeatletter +\renewcommand*\l@section[2]{% + \ifnum \c@tocdepth >\z@ + \addpenalty\@secpenalty + \addvspace{1.0em \@plus\p@}% + \setlength\@tempdima{2.5em}% + \begingroup + \parindent \z@ \rightskip \@pnumwidth + \parfillskip -\@pnumwidth + \leavevmode \bfseries + \advance\leftskip\@tempdima + \hskip -\leftskip + #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par + \endgroup + \fi} +\renewcommand*\l@subsection{\@dottedtocline{2}{2.5em}{3.3em}} +\renewcommand*\l@subsubsection{\@dottedtocline{3}{5.8em}{4.2em}} +\def\@pnumwidth{2.2em} +\makeatother + +%\includeonly{pgfmanual-en-library-profiler} + +% Global styles: +\tikzset{ + every plot/.style={prefix=plots/pgf-}, + shape example/.style={ + color=black!30, + draw, + fill=yellow!30, + line width=.5cm, + inner xsep=2.5cm, + inner ysep=0.5cm} +} + +\index{Options for graphics|see{Graphic options and styles}} +\index{Styles for graphics|see{Graphic options and styles}} +\index{Options for packages|see{Package options}} +\index{Handlers for keys|see{Key handlers}} +\index{File|see{Packages and files}} +\index{Layout|see{Page layout}} +\index{Node|see{Predefined node}} +\index{Data formats|see{Formats}} + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "~/pgf/doc/generic/pgf/version-for-luatex/en/pgfmanual" +%%% coding: iso-latin-1-unix +%%% End: diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-main.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-main.tex index 9b4ba330dd4..55df7111ae1 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-main.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-main.tex @@ -7,890 +7,9 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. - -% pgf version is defined in \pgfversion in file -% generic/pgf/utilities/pgfrcs.code.tex - -\def\xcolorversion{2.00} - -\usepackage[version=latest]{pgf} - -\usepackage{xkeyval,calc,listings,tikz,fp} - -\usepackage{hyperref} -\hypersetup{% - colorlinks=true, % use true to enable colors below: - linkcolor=blue,%red, - filecolor=blue,%magenta, - pagecolor=blue,%red, - urlcolor=blue,%cyan, - citecolor=blue, - pdfborder=0 0 0, -} - -% We need lots of libraries... -\usetikzlibrary{ - arrows, - calc, - fit, - patterns, - plotmarks, - shapes.geometric, - shapes.misc, - shapes.symbols, - shapes.arrows, - shapes.callouts, - shapes.multipart, - shapes.gates.logic.US, - shapes.gates.logic.IEC, - circuits.logic.US, - circuits.logic.IEC, - circuits.logic.CDH, - circuits.ee.IEC, - datavisualization, - datavisualization.formats.functions, - er, - automata, - backgrounds, - chains, - topaths, - trees, - petri, - mindmap, - matrix, - calendar, - folding, - fadings, - shadings, - spy, - through, - turtle, - positioning, - scopes, - decorations.fractals, - decorations.shapes, - decorations.text, - decorations.pathmorphing, - decorations.pathreplacing, - decorations.footprints, - decorations.markings, - shadows, - lindenmayersystems, - intersections, - fixedpointarithmetic, - fpu, - svg.path, - external, -} - -\iffalse -%\iftrue - \tikzexternalize[ - mode=list only,export=true,% simply skips EVERY picture -> good for debugging the text. - ] - {pgfmanual} - - \tikzifexternalizing{% - \pgfkeys{/pdflinks/codeexample links=false}% - }{}% -\fi - - -\usepackage[a4paper,left=2.25cm,right=2.25cm,top=2.5cm,bottom=2.5cm,nohead]{geometry} -\usepackage{amsmath,amssymb} -\usepackage{xxcolor} -\usepackage{pifont} -\usepackage{makeidx} -\usepackage[latin1]{inputenc} -\usepackage{amsmath} - -\graphicspath{{../../images/}} % TODOsp: under windows this would go up 2 directories, but the file is only one directory up -\input{../../macros/pgfmanual-en-macros} % TODOsp: same here - -\makeindex - -\makeatletter -\renewcommand*\l@subsection{\@dottedtocline{2}{1.5em}{2.8em}} -\renewcommand*\l@subsubsection{\@dottedtocline{3}{4.3em}{3.2em}} -\makeatother - -%\includeonly{pgfmanual-en-library-profiler} - -% Global styles: -\tikzset{ - every plot/.style={prefix=plots/pgf-}, - shape example/.style={ - color=black!30, - draw, - fill=yellow!30, - line width=.5cm, - inner xsep=2.5cm, - inner ysep=0.5cm} -} - -\index{Options for graphics|see{Graphic options and styles}} -\index{Styles for graphics|see{Graphic options and styles}} -\index{Options for packages|see{Package options}} -\index{Handlers for keys|see{Key handlers}} -\index{File|see{Packages and files}} -\index{Layout|see{Page layout}} -\index{Node|see{Predefined node}} -\index{Data formats|see{Formats}} - -\begin{document} - - -%\include{pgfmanual-en-dv-introduction} -%\include{pgfmanual-en-dv-main} -%\include{pgfmanual-en-dv-axes} -%\include{pgfmanual-en-dv-visualizers} -%\include{pgfmanual-en-dv-examples} -%\include{pgfmanual-en-dv-formats} -%\include{pgfmanual-en-dv-backend} - -%\end{document} - -% The titlepage - -\newbox\mybox -{ - \parindent0pt - \null - \colorlet{mintgreen}{green!50!black!50} - - \thispagestyle{empty} - \vskip3cm - \vfill - \hfil - \begin{tikzpicture}[overlay] - \coordinate (front) at (0,0); - \coordinate (horizon) at (0,.31\paperheight); - \coordinate (bottom) at (0,-.6\paperheight); - \coordinate (sky) at (0,.57\paperheight); - \coordinate (left) at (-.51\paperwidth,0); - \coordinate (right) at (.51\paperwidth,0); - - \shade [bottom color=blue!30!black!10,top color=blue!30!black!50] - ([yshift=-5mm]horizon -| left) rectangle (sky -| right); - \shade [bottom color=black!70!green!25,top color=black!70!green!10] - (front -| left) -- (horizon -| left) - decorate [decoration=random steps] { -- (horizon -| right) } - -- (front -| right) -- cycle; - \shade [top color=black!70!green!25,bottom color=black!25] - ([yshift=-5mm-1pt]front -| left) rectangle ([yshift=1pt]front -| right); - \fill [black!25] (bottom -| left) rectangle ([yshift=-5mm]front -| right); - - \def\nodeshadowed[#1]#2;{\node[scale=2,above,#1]{\global\setbox\mybox=\hbox{#2}\copy\mybox}; - \node[scale=2,above,#1,yscale=-1,scope fading=south,opacity=0.4]{\box\mybox};} - - \nodeshadowed [at={(-5,5 )},yslant=0.05] {\Huge Ti\textcolor{orange}{\emph{k}}Z}; - \nodeshadowed [at={( 0,5.3)}] {\huge \textcolor{mintgreen}{\&}}; - \nodeshadowed [at={( 5,5 )},yslant=-0.05] {\Huge \textsc{PGF}}; - \nodeshadowed [at={( 0,2 )}] {Manual for Version \pgftypesetversion}; - - \foreach \where in {-9cm,9cm} - {\nodeshadowed [at={(\where,5cm)}] { - \tikz \draw [green!20!black, rotate=90] - [l-system={rule set={F -> FF-[-F+F]+[+F-F]}, axiom=F, order=4, - step=2pt, randomize step percent=50, angle=30, randomize angle percent=5}] - lindenmayer system;};} - - \foreach \i in {0.5,0.6,...,2} - \fill [white,decoration=Koch snowflake,opacity=.9] - [shift=(horizon),shift={(rand*11,rnd*7)},scale=\i] - [double copy shadow={opacity=0.2,shadow xshift=0pt,shadow - yshift=3*\i pt,fill=white,draw=none}] - decorate { - decorate { - decorate { - (0,0) -- ++(60:1) -- ++(-60:1) -- cycle - } - } - }; - - \node (left text) [text width=.5\paperwidth-2cm,below right,at={(-.5\paperwidth+1cm,-1.5cm)}] - { - \fontfamily{pcr} - \def\textbraceleft{\char`\{} - \def\textbraceright{\char`\}} - \def\textbackslash{\char`\\} - \begin{lstlisting}[basicstyle=\scriptsize\color{black}, - keywordstyle=\bfseries\color{white}, - identifierstyle=\bfseries\color{black}, - keywords={tikzpicture,shade,fill,draw,path,node}, - literate={-}{{-}}1] -\begin{tikzpicture} - \coordinate (front) at (0,0); - \coordinate (horizon) at (0,.31\paperheight); - \coordinate (bottom) at (0,-.6\paperheight); - \coordinate (sky) at (0,.57\paperheight); - \coordinate (left) at (-.51\paperwidth,0); - \coordinate (right) at (.51\paperwidth,0); - - \shade [bottom color=white, - top color=blue!30!black!50] - ([yshift=-5mm]horizon -| left) - rectangle (sky -| right); - - \shade [bottom color=black!70!green!25, - top color=black!70!green!10] - (front -| left) -- (horizon -| left) - decorate [decoration=random steps] { - -- (horizon -| right) } - -- (front -| right) -- cycle; - - \shade [top color=black!70!green!25, - bottom color=black!25] - ([yshift=-5mm-1pt]front -| left) - rectangle ([yshift=1pt]front -| right); - - \fill [black!25] - (bottom -| left) - rectangle ([yshift=-5mm]front -| right); - - \def\nodeshadowed[#1]#2;{ - \node[scale=2,above,#1]{ - \global\setbox\mybox=\hbox{#2} - \copy\mybox}; - \node[scale=2,above,#1,yscale=-1, - scope fading=south,opacity=0.4]{\box\mybox}; - } -\end{lstlisting} -}; - - \node (right text) [text width=.5\paperwidth-2cm,below right,at={(1cm,-1.5cm)}] - { - \fontfamily{pcr} - \def\textbraceleft{\char`\{} - \def\textbraceright{\char`\}} - \def\textbackslash{\char`\\} - \begin{lstlisting}[basicstyle=\scriptsize\color{black}, - keywordstyle=\bfseries\color{white}, - identifierstyle=\bfseries\color{black}, - keywords={tikzpicture,shade,fill,draw,path,node}, - literate={-}{{-}}1] - \nodeshadowed [at={(-5,8 )},yslant=0.05] - {\Huge Ti\textcolor{orange}{\emph{k}}Z}; - \nodeshadowed [at={( 0,8.3)}] - {\huge \textcolor{green!50!black!50}{\&}}; - \nodeshadowed [at={( 5,8 )},yslant=-0.05] - {\Huge \textsc{PGF}}; - \nodeshadowed [at={( 0,5 )}] - {Manual for Version \pgftypesetversion}; - - \foreach \where in {-9cm,9cm} { - \nodeshadowed [at={(\where,5cm)}] { \tikz - \draw [green!20!black, rotate=90, - l-system={rule set={F -> FF-[-F+F]+[+F-F]}, - axiom=F, order=4,step=2pt, - randomize step percent=50, angle=30, - randomize angle percent=5}] l-system; }} - - \foreach \i in {0.5,0.6,...,2} - \fill - [white,opacity=\i/2, - decoration=Koch snowflake, - shift=(horizon),shift={(rand*11,rnd*7)}, - scale=\i,double copy shadow={ - opacity=0.2,shadow xshift=0pt, - shadow yshift=3*\i pt,fill=white,draw=none}] - decorate { - decorate { - decorate { - (0,0)- ++(60:1) -- ++(-60:1) -- cycle - } } }; - - \node (left text) ... - \node (right text) ... - - \fill [decorate,decoration={footprints,foot of=gnome}, - opacity=.5,brown] (rand*8,-rnd*10) - to [out=rand*180,in=rand*180] (rand*8,-rnd*10); -\end{tikzpicture} - \end{lstlisting} - }; - - \fill [decorate,decoration=footprints, - decoration={footprints,foot of=gnome}, - opacity=.5,brown] (rand*8,-rnd*10) - to [out=rand*180,in=rand*180] (rand*8,-rnd*10); -\end{tikzpicture} -\vfill -\vbox{} -\clearpage -} - -{ - \vbox{} - \vskip0pt plus 1fill - Für meinen Vater, damit er noch viele schöne \TeX-Graphiken - erschaffen kann. - \vskip1em - \hfill\emph{Till} - \vskip0pt plus 3fill - - \parindent=0pt - Copyright 2007 by Till Tantau - - \medskip - Permission is granted to copy, distribute and/or modify \emph{the documentation} - under the terms of the \textsc{gnu} Free Documentation License, Version 1.2 - or any later version published by the Free Software Foundation; - with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. - A copy of the license is included in the section entitled \textsc{gnu} - Free Documentation License. - - \medskip - Permission is granted to copy, distribute and/or modify \emph{the - code of the package} under the terms of the \textsc{gnu} Public License, Version 2 - or any later version published by the Free Software Foundation. - A copy of the license is included in the section entitled \textsc{gnu} - Public License. - - \medskip - Permission is also granted to distribute and/or modify \emph{both - the documentation and the code} 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 the license is included in - the section entitled \LaTeX\ Project Public License. - - \vbox{} - \clearpage -} - - -\title{\bfseries The \tikzname\ and {\Large PGF} Packages\\ - \large Manual for version \pgfversion\\[1mm] -\large\href{http://sourceforge.net/projects/pgf}{\texttt{http://sourceforge.net/projects/pgf}}} -\author{Till Tantau\footnote{Editor of this documentation. Parts of - this documentation have been written by other authors as indicated - in these parts or chapters and in Section~\ref{section-authors}.}\\ - \normalsize Institut f\"ur Theoretische Informatik\\[-1mm] - \normalsize Universit\"at zu L\"ubeck} - -\maketitle - -\tableofcontents - -\clearpage - - -\include{pgfmanual-en-introduction} - - -\part{Tutorials and Guidelines} - -{\Large \emph{by Till Tantau}} - -\bigskip -\noindent -To help you get started with \tikzname, instead of a long installation -and configuration section, this manual starts with tutorials. They -explain all the basic and some of the more advanced features of the -system, without going into all the details. This part also contains -some guidelines on how you should proceed when creating graphics using -\tikzname. - -\vskip3cm - -\begin{codeexample}[graphic=white,width=0pt] -\tikz \draw[thick,rounded corners=8pt] - (0,0) -- (0,2) -- (1,3.25) -- (2,2) -- (2,0) -- (0,2) -- (2,2) -- (0,0) -- (2,0); -\end{codeexample} - -\include{pgfmanual-en-tutorial} -\include{pgfmanual-en-tutorial-nodes} -\include{pgfmanual-en-tutorial-Euclid} -\include{pgfmanual-en-tutorial-chains} -\include{pgfmanual-en-tutorial-map} -\include{pgfmanual-en-guidelines} - - - -\part{Installation and Configuration} - -{\Large \emph{by Till Tantau}} - - -\bigskip -\noindent -This part explains how the system is installed. Typically, someone has -already done so for your system, so this part can be skipped; but if -this is not the case and you are the poor fellow who has to do the -installation, read the present part. - - -\vskip1cm - -\begin{codeexample}[graphic=white] -\begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=2.8cm,on grid,semithick, - every state/.style={fill=red,draw=none,circular drop shadow,text=white}] - - \node[initial,state] (A) {$q_a$}; - \node[state] (B) [above right=of A] {$q_b$}; - \node[state] (D) [below right=of A] {$q_d$}; - \node[state] (C) [below right=of B] {$q_c$}; - \node[state] (E) [below=of D] {$q_e$}; - - \path (A) edge node {0,1,L} (B) - edge node {1,1,R} (C) - (B) edge [loop above] node {1,1,L} (B) - edge node {0,1,L} (C) - (C) edge node {0,1,L} (D) - edge [bend left] node {1,0,R} (E) - (D) edge [loop below] node {1,1,R} (D) - edge node {0,1,R} (A) - (E) edge [bend left] node {1,0,R} (A); - - \node [right=1cm,text width=8cm] at (C) - { - The current candidate for the busy beaver for five states. It is - presumed that this Turing machine writes a maximum number of - $1$'s before halting among all Turing machines with five states - and the tape alphabet $\{0, 1\}$. Proving this conjecture is an - open research problem. - }; -\end{tikzpicture} -\end{codeexample} - -\include{pgfmanual-en-installation} -\include{pgfmanual-en-license} -\include{pgfmanual-en-drivers} - - -\part{Ti\emph{k}Z ist \emph{kein} Zeichenprogramm} -\label{part-tikz} - -{\Large \emph{by Till Tantau}} - - -\bigskip -\noindent -\vskip3cm -\begin{codeexample}[graphic=white] -\begin{tikzpicture} - \draw[fill=yellow] (0,0) -- (60:.75cm) arc (60:180:.75cm); - \draw(120:0.4cm) node {$\alpha$}; - - \draw[fill=green!30] (0,0) -- (right:.75cm) arc (0:60:.75cm); - \draw(30:0.5cm) node {$\beta$}; - - \begin{scope}[shift={(60:2cm)}] - \draw[fill=green!30] (0,0) -- (180:.75cm) arc (180:240:.75cm); - \draw (30:-0.5cm) node {$\gamma$}; - - \draw[fill=yellow] (0,0) -- (240:.75cm) arc (240:360:.75cm); - \draw (-60:0.4cm) node {$\delta$}; - \end{scope} - - \begin{scope}[thick] - \draw (60:-1cm) node[fill=white] {$E$} -- (60:3cm) node[fill=white] {$F$}; - \draw[red] (-2,0) node[left] {$A$} -- (3,0) node[right]{$B$}; - \draw[blue,shift={(60:2cm)}] (-3,0) node[left] {$C$} -- (2,0) node[right]{$D$}; - - \draw[shift={(60:1cm)},xshift=4cm] - node [right,text width=6cm,rounded corners,fill=red!20,inner sep=1ex] - { - When we assume that $\color{red}AB$ and $\color{blue}CD$ are - parallel, i.\,e., ${\color{red}AB} \mathbin{\|} \color{blue}CD$, - then $\alpha = \delta$ and $\beta = \gamma$. - }; - \end{scope} -\end{tikzpicture} -\end{codeexample} - - - -\include{pgfmanual-en-tikz-design} -\include{pgfmanual-en-tikz-scopes} -\include{pgfmanual-en-tikz-coordinates} -\include{pgfmanual-en-tikz-paths} -\include{pgfmanual-en-tikz-actions} -\include{pgfmanual-en-tikz-shapes} -\include{pgfmanual-en-tikz-matrices} -\include{pgfmanual-en-tikz-trees} -\include{pgfmanual-en-tikz-plots} -\include{pgfmanual-en-tikz-transparency} -\include{pgfmanual-en-tikz-decorations} -\include{pgfmanual-en-tikz-transformations} - - - -\part{Libraries} -\label{part-libraries} - -{\Large \emph{by Till Tantau}} - - -\bigskip -\noindent -In this part the library packages are documented. They -provide additional predefined graphic objects like new arrow heads or -new plot marks, but also sometimes extensions of the basic \pgfname\ -or \tikzname\ system. The libraries are not loaded by default since -many users will not need them. - -\medskip -\noindent -\begin{codeexample}[graphic=white] -\tikzset{ - ld/.style={level distance=#1},lw/.style={line width=#1}, - level 1/.style={ld=4.5mm, trunk, lw=1ex ,sibling angle=60}, - level 2/.style={ld=3.5mm, trunk!80!leaf a,lw=.8ex,sibling angle=56}, - level 3/.style={ld=2.75mm,trunk!60!leaf a,lw=.6ex,sibling angle=52}, - level 4/.style={ld=2mm, trunk!40!leaf a,lw=.4ex,sibling angle=48}, - level 5/.style={ld=1mm, trunk!20!leaf a,lw=.3ex,sibling angle=44}, - level 6/.style={ld=1.75mm,leaf a, lw=.2ex,sibling angle=40}, -} -\pgfarrowsdeclare{leaf}{leaf} - {\pgfarrowsleftextend{-2pt} \pgfarrowsrightextend{1pt}} -{ - \pgfpathmoveto{\pgfpoint{-2pt}{0pt}} - \pgfpatharc{150}{30}{1.8pt} - \pgfpatharc{-30}{-150}{1.8pt} - \pgfusepathqfill -} - -\newcommand{\logo}[5] -{ - \colorlet{border}{#1} - \colorlet{trunk}{#2} - \colorlet{leaf a}{#3} - \colorlet{leaf b}{#4} - \begin{tikzpicture} - \scriptsize\scshape - \draw[border,line width=1ex,yshift=.3cm, - yscale=1.45,xscale=1.05,looseness=1.42] - (1,0) to [out=90, in=0] (0,1) to [out=180,in=90] (-1,0) - to [out=-90,in=-180] (0,-1) to [out=0, in=-90] (1,0) -- cycle; - - \coordinate (root) [grow cyclic,rotate=90] - child { - child [line cap=round] foreach \a in {0,1} { - child foreach \b in {0,1} { - child foreach \c in {0,1} { - child foreach \d in {0,1} { - child foreach \leafcolor in {leaf a,leaf b} - { edge from parent [color=\leafcolor,-#5] } - } } } - } edge from parent [shorten >=-1pt,serif cm-,line cap=butt] - }; - - \node [align=center,below] at (0pt,-.5ex) - { \textcolor{border}{T}heoretical \\ \textcolor{border}{C}omputer \\ - \textcolor{border}{S}cience }; - \end{tikzpicture} -} -\begin{minipage}{3cm} - \logo{green!80!black}{green!25!black}{green}{green!80}{leaf}\\ - \logo{green!50!black}{black}{green!80!black}{red!80!green}{leaf}\\ - \logo{red!75!black}{red!25!black}{red!75!black}{orange}{leaf}\\ - \logo{black!50}{black}{black!50}{black!25}{} -\end{minipage} -\end{codeexample} - -\include{pgfmanual-en-library-arrows} -\include{pgfmanual-en-library-automata} -\include{pgfmanual-en-library-backgrounds} -\include{pgfmanual-en-library-calc} -\include{pgfmanual-en-library-calendar} -\include{pgfmanual-en-library-chains} -\include{pgfmanual-en-library-circuits} -\include{pgfmanual-en-library-decorations} -\include{pgfmanual-en-library-er} -\include{pgfmanual-en-library-external} -\include{pgfmanual-en-library-fadings} -\include{pgfmanual-en-library-fit} -\include{pgfmanual-en-library-fixedpoint} -\include{pgfmanual-en-library-fpu} -\include{pgfmanual-en-library-lsystems} -\include{pgfmanual-en-library-matrices} -\include{pgfmanual-en-library-mindmaps} -\include{pgfmanual-en-library-folding} -\include{pgfmanual-en-library-patterns} -\include{pgfmanual-en-library-petri} -\include{pgfmanual-en-library-plot-handlers} -\include{pgfmanual-en-library-plot-marks} -\include{pgfmanual-en-library-profiler} -\include{pgfmanual-en-library-shadings} -\include{pgfmanual-en-library-shadows} -\include{pgfmanual-en-library-shapes} -\include{pgfmanual-en-library-spy} -\include{pgfmanual-en-library-svg-path} -\include{pgfmanual-en-library-edges} -\include{pgfmanual-en-library-through} -\include{pgfmanual-en-library-trees} -\include{pgfmanual-en-library-turtle} - - - -\iffalse -\part{Data Visualization} -\label{part-dv} - -{\Large \emph{by Till Tantau}} - -\bigskip -\noindent -The documentation of the data visualization is still missing. This -stuff is still ``heavily under construction.'' - -\include{pgfmanual-en-dv-introduction} -\include{pgfmanual-en-dv-main} -\include{pgfmanual-en-dv-axes} -\include{pgfmanual-en-dv-visualizers} -\include{pgfmanual-en-dv-examples} -\include{pgfmanual-en-dv-formats} -\include{pgfmanual-en-dv-backend} - -\fi - - -\part{Utilities} -\label{part-utilities} - -{\Large \emph{by Till Tantau}} - - -\bigskip -\noindent -The utility packages are not directly involved in creating graphics, -but you may find them useful nonetheless. All of them either directly -depend on \pgfname\ or they are designed to work well together with -\pgfname\ even though they can be used in a stand-alone way. - -\vskip2cm -\medskip -\noindent -\begin{codeexample}[graphic=white] -\begin{tikzpicture}[scale=2] - \shade[top color=blue,bottom color=gray!50] (0,0) parabola (1.5,2.25) |- (0,0); - \draw (1.05cm,2pt) node[above] {$\displaystyle\int_0^{3/2} \!\!x^2\mathrm{d}x$}; - - \draw[help lines] (0,0) grid (3.9,3.9) - [step=0.25cm] (1,2) grid +(1,1); - - \draw[->] (-0.2,0) -- (4,0) node[right] {$x$}; - \draw[->] (0,-0.2) -- (0,4) node[above] {$f(x)$}; - - \foreach \x/\xtext in {1/1, 1.5/1\frac{1}{2}, 2/2, 3/3} - \draw[shift={(\x,0)}] (0pt,2pt) -- (0pt,-2pt) node[below] {$\xtext$}; - - \foreach \y/\ytext in {1/1, 2/2, 2.25/2\frac{1}{4}, 3/3} - \draw[shift={(0,\y)}] (2pt,0pt) -- (-2pt,0pt) node[left] {$\ytext$}; - - \draw (-.5,.25) parabola bend (0,0) (2,4) node[below right] {$x^2$}; -\end{tikzpicture} -\end{codeexample} - -\include{pgfmanual-en-pgfkeys} -\include{pgfmanual-en-pgffor} -\include{pgfmanual-en-pgfcalendar} -\include{pgfmanual-en-pages} -\include{pgfmanual-en-xxcolor} -\include{pgfmanual-en-module-parser} - - -\part{Mathematical and Object-Oriented Engines} - -{\Large \emph{by Mark Wibrow and Till Tantau}} - - -\bigskip -\noindent -\pgfname\ comes with two useful engines: One for doing mathematics, -one for doing object-oriented programming. Both engines can be used -independently of the main \pgfname. - -The job of the mathematical -engine is to support mathematical operations like addition, -subtraction, multiplication and division, using both integers and -non-integers, but also functions such as square-roots, sine, cosine, -and generate pseudo-random numbers. -Mostly, you will use the mathematical facilities of \pgfname\ -indirectly, namely when you write a coordinate like |(5cm*3,6cm/4)|, -but the mathematical engine can also be used independently of -\pgfname\ and \tikzname. - -The job of the object-oriented engine is to support simple -object-oriented programming in \TeX. It allows the definition of -\emph{classes} (without inheritance), \emph{methods}, -\emph{attributes} and \emph{objects}. - -\vskip1cm -\begin{codeexample}[graphic=white] -\pgfmathsetseed{1} -\foreach \col in {black,red,green,blue} -{ - \begin{tikzpicture}[x=10pt,y=10pt,ultra thick,baseline,line cap=round] - \coordinate (current point) at (0,0); - \coordinate (old velocity) at (0,0); - \coordinate (new velocity) at (rand,rand); - - \foreach \i in {0,1,...,100} - { - \draw[\col!\i] (current point) - .. controls ++([scale=-1]old velocity) and - ++(new velocity) .. ++(rand,rand) - coordinate (current point); - \coordinate (old velocity) at (new velocity); - \coordinate (new velocity) at (rand,rand); - } - \end{tikzpicture} -} -\end{codeexample} - -\include{pgfmanual-en-math-design} -\include{pgfmanual-en-math-parsing} -\include{pgfmanual-en-math-commands} -\include{pgfmanual-en-math-algorithms} -\include{pgfmanual-en-math-numberprinting} -\include{pgfmanual-en-oo} - - -\part{The Basic Layer} - -{\Large \emph{by Till Tantau}} - - -\bigskip -\noindent -\vskip1cm -\begin{codeexample}[graphic=white] -\begin{tikzpicture} - \draw[gray,very thin] (-1.9,-1.9) grid (2.9,3.9) - [step=0.25cm] (-1,-1) grid (1,1); - \draw[blue] (1,-2.1) -- (1,4.1); % asymptote - - \draw[->] (-2,0) -- (3,0) node[right] {$x(t)$}; - \draw[->] (0,-2) -- (0,4) node[above] {$y(t)$}; - - \foreach \pos in {-1,2} - \draw[shift={(\pos,0)}] (0pt,2pt) -- (0pt,-2pt) node[below] {$\pos$}; - - \foreach \pos in {-1,1,2,3} - \draw[shift={(0,\pos)}] (2pt,0pt) -- (-2pt,0pt) node[left] {$\pos$}; - - \fill (0,0) circle (0.064cm); - \draw[thick,parametric,domain=0.4:1.5,samples=200] - % The plot is reparameterised such that there are more samples - % near the center. - plot[id=asymptotic-example] function{(t*t*t)*sin(1/(t*t*t)),(t*t*t)*cos(1/(t*t*t))} - node[right] {$\bigl(x(t),y(t)\bigr) = (t\sin \frac{1}{t}, t\cos \frac{1}{t})$}; - - \fill[red] (0.63662,0) circle (2pt) - node [below right,fill=white,yshift=-4pt] {$(\frac{2}{\pi},0)$}; -\end{tikzpicture} -\end{codeexample} - - -\include{pgfmanual-en-base-design} -\include{pgfmanual-en-base-scopes} -\include{pgfmanual-en-base-points} -\include{pgfmanual-en-base-paths} -\include{pgfmanual-en-base-decorations} -\include{pgfmanual-en-base-actions} -\include{pgfmanual-en-base-arrows} -\include{pgfmanual-en-base-nodes} -\include{pgfmanual-en-base-matrices} -\include{pgfmanual-en-base-transformations} -\include{pgfmanual-en-base-patterns} -\include{pgfmanual-en-base-images} -\include{pgfmanual-en-base-external} -\include{pgfmanual-en-base-plots} -\include{pgfmanual-en-base-layers} -\include{pgfmanual-en-base-shadings} -\include{pgfmanual-en-base-transparency} -\include{pgfmanual-en-base-internalregisters} -\include{pgfmanual-en-base-quick} - - - - -\part{The System Layer} -\label{part-system} - -{\Large \emph{by Till Tantau}} - - -\bigskip -\noindent -This part describes the low-level interface of \pgfname, called the -\emph{system layer}. This interface provides a complete abstraction of -the internals of the underlying drivers. - -Unless you intend to port \pgfname\ to another driver or unless you intend -to write your own optimized frontend, you need not read this part. - -In the following it is assumed that you are familiar with the basic -workings of the |graphics| package and that you know what -\TeX-drivers are and how they work. - -\vskip1cm -\begin{codeexample}[graphic=white] -\begin{tikzpicture} - [shorten >=1pt,->, - vertex/.style={circle,fill=black!25,minimum size=17pt,inner sep=0pt}] - - \foreach \name/\x in {s/1, 2/2, 3/3, 4/4, 15/11, 16/12, 17/13, 18/14, 19/15, t/16} - \node[vertex] (G-\name) at (\x,0) {$\name$}; - - \foreach \name/\angle/\text in {P-1/234/5, P-2/162/6, P-3/90/7, P-4/18/8, P-5/-54/9} - \node[vertex,xshift=6cm,yshift=.5cm] (\name) at (\angle:1cm) {$\text$}; - - \foreach \name/\angle/\text in {Q-1/234/10, Q-2/162/11, Q-3/90/12, Q-4/18/13, Q-5/-54/14} - \node[vertex,xshift=9cm,yshift=.5cm] (\name) at (\angle:1cm) {$\text$}; - - \foreach \from/\to in {s/2,2/3,3/4,3/4,15/16,16/17,17/18,18/19,19/t} - \draw (G-\from) -- (G-\to); - - \foreach \from/\to in {1/2,2/3,3/4,4/5,5/1,1/3,2/4,3/5,4/1,5/2} - { \draw (P-\from) -- (P-\to); \draw (Q-\from) -- (Q-\to); } - - \draw (G-3) .. controls +(-30:2cm) and +(-150:1cm) .. (Q-1); - \draw (Q-5) -- (G-15); -\end{tikzpicture} -\end{codeexample} - -\include{pgfmanual-en-pgfsys-overview} -\include{pgfmanual-en-pgfsys-commands} -\include{pgfmanual-en-pgfsys-paths} -\include{pgfmanual-en-pgfsys-protocol} - - - -\part{References and Index} - -\vskip1cm -\begin{codeexample}[graphic=white] -\begin{tikzpicture} - \draw[line width=0.3cm,color=red!30,line cap=round,line join=round] (0,0)--(2,0)--(2,5); - \draw[help lines] (-2.5,-2.5) grid (5.5,7.5); - \draw[very thick] (1,-1)--(-1,-1)--(-1,1)--(0,1)--(0,0)-- - (1,0)--(1,-1)--(3,-1)--(3,2)--(2,2)--(2,3)--(3,3)-- - (3,5)--(1,5)--(1,4)--(0,4)--(0,6)--(1,6)--(1,5) - (3,3)--(4,3)--(4,5)--(3,5)--(3,6) - (3,-1)--(4,-1); - \draw[below left] (0,0) node(s){$s$}; - \draw[below left] (2,5) node(t){$t$}; - \fill (0,0) circle (0.06cm) (2,5) circle (0.06cm); - \draw[->,rounded corners=0.2cm,shorten >=2pt] - (1.5,0.5)-- ++(0,-1)-- ++(1,0)-- ++(0,2)-- ++(-1,0)-- ++(0,2)-- ++(1,0)-- - ++(0,1)-- ++(-1,0)-- ++(0,-1)-- ++(-2,0)-- ++(0,3)-- ++(2,0)-- ++(0,-1)-- - ++(1,0)-- ++(0,1)-- ++(1,0)-- ++(0,-1)-- ++(1,0)-- ++(0,-3)-- ++(-2,0)-- - ++(1,0)-- ++(0,-3)-- ++(1,0)-- ++(0,-1)-- ++(-6,0)-- ++(0,3)-- ++(2,0)-- - ++(0,-1)-- ++(1,0); -\end{tikzpicture} -\end{codeexample} - -\printindex - -%\typeout{Examples: \the\codeexamplecount}% -\end{document} - - +\input pgfmanual-en-main-preamble.tex +\input pgfmanual-en-main-body.tex %%% Local Variables: %%% mode: latex -%%% TeX-master: "~/texmf/tex/generic/pgf/doc/pgf/version-for-pdftex/en/pgfmanual" %%% End: diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-algorithms.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-algorithms.tex index 8f6f1639b0c..5441b9e101f 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-algorithms.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-algorithms.tex @@ -28,11 +28,11 @@ recommended for adventurous users. To add a new function to the math engine the following command can be used: -\begin{command}{\pgfmathdeclarefunction\marg{function name}\marg{number of arguments}\marg{code}} +\begin{command}{\pgfmathdeclarefunction\marg{name}\marg{number of arguments}\marg{code}} This will set up the parser to recognize a function called \meta{name}. The name of the function can consist of, uppercase or - lower case letters, numbers or the underscore |_|. In line with + lowercase letters, numbers or the underscore |_|. In line with many programming languages, a function name cannot begin with a number or contain any spaces. @@ -40,7 +40,7 @@ used: or the value |...|, which indicates a variable number of arguments. \pgfname{} treats constants, such as |pi| and |e|, as functions with zero arguments. Functions with more than nine - arguments or with variable arguments are a ``bit special'' and + arguments or with a variable number of arguments are a ``bit special'' and are discussed below. The effect of \meta{code} should be to set the macro @@ -85,7 +85,7 @@ used: \item |\pgfmath|\meta{function name} - This macro will provide ``public'' interface for the function + This macro will provide a ``public'' interface for the function \meta{function name} allowing the function to be called independently of the parser. All arguments passed to this macro are evaluated using |\pgfmathparse| and then passed on to the following @@ -94,11 +94,11 @@ used: \item |\pgfmath|\meta{function name}|@| - This macro is the ``private'' implementation of the functions + This macro is the ``private'' implementation of the function's algorithm (but note that, for speed, the parser calls this macro rather than the ``public'' one). Arguments passed to this macro are expected to be numbers without units. It is defined using - \meta{code}, but need not be self contained. + \meta{code}, but need not be self-contained. \end{itemize} @@ -123,7 +123,7 @@ used: This means that some ``extra work'' will be required to access each argument (although it is a fairly simple task). - Note, that there are, two exceptions to this arrangement: + Note that there are two exceptions to this arrangement: the public versions of the |min| and |max| functions still take two arguments for compatibility with older versions, but each of these arguments can take several comma separated values. @@ -147,7 +147,7 @@ used: \pgfname{} uses the last known definition of a function within the prevailing scope, so it is possible for a function to be redefined locally. You should also remember that any |.sty| or |.tex| file - containing any re-implementations should be loaded after pgf-Math. + containing any re-implementations should be loaded after |pgfmath|. In addition to the above commands, the following key is provided to quickly create simple ad hoc functions which can greatly improve @@ -171,13 +171,13 @@ used: Each definition in \meta{function definitions} takes the form \meta{name}|(|\meta{arguments}|)=|\meta{definition}|;| (note the semicolon at the end, this is very important). If multiple - functions are being defined the semicolon is used to separate + functions are being defined, the semicolon is used to separate them (\emph{not} a comma). The function \meta{name} can be any name that is not already a function name in the current scope. The list of \meta{arguments} are commands such as |\x|, or |\y| (it is not possible to declare functions that take variable numbers of arguments using this key). - If the function takes no arguments then the parentheses need not + If the function takes no arguments, then the parentheses need not be used. The \meta{definition} should be an expression that can be parsed by the mathematical engine and should use the commands diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-commands.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-commands.tex index b1be68267d7..fe42eacac4c 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-commands.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-commands.tex @@ -26,7 +26,7 @@ Section~\ref{pgfmath-functions-basic}, the following command is provided: \begin{command}{\pgfmathreciprocal\marg{x}} - Defines |\pgfmathresult| as $1\div\meta{x}$. This is provides + Defines |\pgfmathresult| as $1\div\meta{x}$. This provides greatest accuracy when \mvar{x} is small. \end{command} @@ -52,12 +52,12 @@ the following commands are provided: \begin{command}{\pgfmathgeneratepseudorandomnumber} Defines |\pgfmathresult| as a pseudo-random integer between 1 and $2^{31}-1$. This uses a linear congruency generator, based on ideas - due to Erich Janka. + of Erich Janka. \end{command} -\begin{command}{\pgfmathrandominteger\marg{macro}\marg{maximum}\marg{minimum}} +\begin{command}{\pgfmathrandominteger\marg{macro}\marg{minimum}\marg{maximum}} This defines \meta{macro} as a pseudo-randomly generated integer from - the range \meta{maximum} to \meta{minimum} (inclusive). + the range \meta{minimum} to \meta{maximum} (inclusive). \begin{codeexample}[] \begin{pgfpicture} @@ -99,7 +99,7 @@ the following commands are provided: \end{codeexample} \begin{command}{\pgfmathsetseed\marg{integer}} - Explicitly set seed for the pseudo-random number generator. By + Explicitly sets the seed for the pseudo-random number generator. By default it is set to the value of |\time|$\times$|\year|. \end{command} @@ -129,6 +129,8 @@ the following commands are provided: \begin{codeexample}[] \pgfmathbasetodec\mynumber{107f}{16} \mynumber \end{codeexample} + + \noindent Note that, as usual in \TeX, the braces around an argument can be omitted if the argument is just a single token (a macro name is a single token). \begin{codeexample}[] @@ -187,14 +189,62 @@ the following commands are provided: \begin{command}{\pgfmathsetbasenumberlength\marg{integer}} - Set the number of digits in the result of a base conversion to + Sets the number of digits in the result of a base conversion to \meta{integer}. If the result of a conversion has less digits - than this number it is prefixed with zeros. + than this number, it is prefixed with zeros. \begin{codeexample}[] \pgfmathsetbasenumberlength{8} \pgfmathdectobase\mynumber{15}{2} \mynumber \end{codeexample} +\end{command} + +\begin{command}{\pgfmathtodigitlist\marg{macro}\marg{number}} + + This command converts \meta{number} into a comma-separated + list of digits and stores the result in \meta{macro}. + The \marg{number} is \emph{not} parsed before processing. + +\begin{codeexample}[] +\pgfmathsetbasenumberlength{8} +\begin{tikzpicture}[x=0.25cm, y=0.25cm] + \foreach \n [count=\y] in {0, 60, 102, 102, 126, 102, 102, 102, 0}{ + \pgfmathdectobase{\binary}{\n}{2} + \pgfmathtodigitlist{\digitlist}{\binary} + \foreach \digit [count=\x, evaluate={\c=\digit*50+15;}] in \digitlist + \fill [fill=black!\c] (\x, -\y) rectangle ++(1,1); + } +\end{tikzpicture} +\end{codeexample} + +\end{command} + +\subsection{Angle Computations} + +Unlike the rest of the math engine, which is a ``standalone'' package, +the following commands only work in conjunction with the core of +\pgfname. + + + +\begin{command}{\pgfmathanglebetweenpoints\marg{p}\marg{q}} + Returns the angle of a line from \meta{p} to \meta{q} relative to a + line going straight right from \meta{p}. + +\begin{codeexample}[] +\pgfmathanglebetweenpoints{\pgfpoint{1cm}{3cm}}{\pgfpoint{2cm}{4cm}} +\pgfmathresult +\end{codeexample} \end{command} +\begin{command}{\pgfmathanglebetweenlines\marg{$p_1$}\marg{$q_1$}\marg{$p_2$}\marg{$q_2$}} + Returns the clockwise angle between a line going through $p_1$ and + $q_1$ and a line going through $p_2$ and $q_2$. + +\begin{codeexample}[] +\pgfmathanglebetweenlines{\pgfpoint{1cm}{3cm}}{\pgfpoint{2cm}{4cm}} + {\pgfpoint{0cm}{1cm}}{\pgfpoint{1cm}{0cm}} +\pgfmathresult +\end{codeexample} +\end{command} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-design.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-design.tex index e12380bd8ae..59295dc7c9d 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-design.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-design.tex @@ -47,7 +47,7 @@ not need \pgfname\ itself, you can load the following package: \begin{package}{pgfmath} This command will load the mathematical engine of \pgfname, but not - \pgfname itself. It defines commands like |\pgfmathparse|. + \pgfname{} itself. It defines commands like |\pgfmathparse|. \end{package} @@ -88,7 +88,7 @@ This poses some intriguing programming challenges as \TeX{} is a language for typesetting, rather than for general mathematics, and as with any programming language, there is a trade-off between accuracy and efficiency. -If you find the level of accuracy insufficient for you +If you find the level of accuracy insufficient for your purposes, you will have to replace the algorithms in the implementation layer. diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-numberprinting.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-numberprinting.tex index 9deedd2e504..f86b6f59187 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-numberprinting.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-numberprinting.tex @@ -9,17 +9,23 @@ \pgfname\ supports number printing in different styles and rounds to arbitrary precision. \begin{command}{\pgfmathprintnumber\marg{x}} -Generates pretty-printed output for the (real) number \marg{x}. The input number \marg{x} is parsed using |\pgfmathfloatparsenumber| which allows arbitrary precision. + Generates pretty-printed output for the (real) number \meta{x}. The + input number \meta{x} is parsed using |\pgfmathfloatparsenumber| + which allows arbitrary precision. -Numbers are typeset in math mode using the current set of number printing options, see below. Optional arguments can also be provided using |\pgfmathprintnumber[|\meta{options}|]|\marg{x}. + Numbers are typeset in math mode using the current set of number + printing options, see below. Optional arguments can also be provided + using |\pgfmathprintnumber[|\meta{options}|]|\meta{x}. \end{command} -\begin{command}{\pgfmathprintnumberto\marg{x}\marg{\textbackslash macro}} - Returns the resulting number into \marg{\textbackslash macro} instead of typesetting it directly. +\begin{command}{\pgfmathprintnumberto\marg{x}\marg{macro}} + Returns the resulting number into \meta{macro} + instead of typesetting it directly. \end{command} \begin{key}{/pgf/number format/fixed} -Configures |\pgfmathprintnumber| to round the number to a fixed number of digits after the period, discarding any trailing zeros. + Configures |\pgfmathprintnumber| to round the number to a fixed + number of digits after the period, discarding any trailing zeros. \begin{codeexample}[] \pgfkeys{/pgf/number format/.cd,fixed,precision=2} @@ -30,11 +36,13 @@ Configures |\pgfmathprintnumber| to round the number to a fixed number of digits \pgfmathprintnumber{123456.12345} \end{codeexample} -See section~\ref{sec:number:styles} for how to change the appearance. + See section~\ref{sec:number:styles} for how to change the + appearance. \end{key} \begin{key}{/pgf/number format/fixed zerofill=\marg{boolean} (default true)} -Enables or disables zero filling for any number drawn in fixed point format. + Enables or disables zero filling for any number drawn in fixed point + format. \begin{codeexample}[] \pgfkeys{/pgf/number format/.cd,fixed,fixed zerofill,precision=2} @@ -44,7 +52,8 @@ Enables or disables zero filling for any number drawn in fixed point format. \pgfmathprintnumber{24415.98123}\hspace{1em} \pgfmathprintnumber{123456.12345} \end{codeexample} -This key affects numbers drawn with |fixed| or |std| styles (the latter only if no scientific format is chosen). + This key affects numbers drawn with |fixed| or |std| styles (the + latter only if no scientific format is chosen). \begin{codeexample}[] \pgfkeys{/pgf/number format/.cd,std,fixed zerofill,precision=2} \pgfmathprintnumber{4.568}\hspace{1em} @@ -53,11 +62,15 @@ This key affects numbers drawn with |fixed| or |std| styles (the latter only if \pgfmathprintnumber{123456.12345} \end{codeexample} -See section~\ref{sec:number:styles} for how to change the appearance. + See section~\ref{sec:number:styles} for how to change the + appearance. \end{key} \begin{key}{/pgf/number format/sci} -Configures |\pgfmathprintnumber| to display numbers in scientific format, that means sign, mantissa and exponent (basis~$10$). The mantissa is rounded to the desired |precision| (or |sci precision|, see below). + Configures |\pgfmathprintnumber| to display numbers in scientific + format, that means sign, mantissa and exponent (basis~$10$). The + mantissa is rounded to the desired |precision| (or |sci precision|, + see below). \begin{codeexample}[] \pgfkeys{/pgf/number format/.cd,sci,precision=2} @@ -68,11 +81,13 @@ Configures |\pgfmathprintnumber| to display numbers in scientific format, that m \pgfmathprintnumber{123456.12345} \end{codeexample} -See section~\ref{sec:number:styles} for how to change the exponential display style. +See section~\ref{sec:number:styles} for how to change the exponential +display style. \end{key} \begin{key}{/pgf/number format/sci zerofill=\marg{boolean} (default true)} -Enables or disables zero filling for any number drawn in scientific format. + Enables or disables zero filling for any number drawn in scientific + format. \begin{codeexample}[] \pgfkeys{/pgf/number format/.cd,sci,sci zerofill,precision=2} @@ -82,19 +97,25 @@ Enables or disables zero filling for any number drawn in scientific format. \pgfmathprintnumber{24415.98123}\hspace{1em} \pgfmathprintnumber{123456.12345} \end{codeexample} -As with |fixed zerofill|, this option does only affect numbers drawn in |sci| format (or |std| if the scientific format is chosen). + As with |fixed zerofill|, this option does only affect numbers drawn + in |sci| format (or |std| if the scientific format is chosen). -See section~\ref{sec:number:styles} for how to change the exponential display style. + See section~\ref{sec:number:styles} for how to change the + exponential display style. \end{key} \begin{stylekey}{/pgf/number format/zerofill=\marg{boolean} (default true)} - Sets both, |fixed zerofill| and |sci zerofill| at once. + Sets both |fixed zerofill| and |sci zerofill| at once. \end{stylekey} \begin{keylist}{/pgf/number format/std,% /pgf/number format/std=\meta{lower e}, /pgf/number format/std=\meta{lower e}:\meta{upper e}} -Configures |\pgfmathprintnumber| to a standard algorithm. It chooses either |fixed| or |sci|, depending on the order of magnitude. Let $n=s \cdot m \cdot 10^e$ be the input number and $p$ the current precision. If $-p/2 \le e \le 4$, the number is displayed using |fixed| format. Otherwise, it is displayed using |sci| format. + Configures |\pgfmathprintnumber| to a standard algorithm. It chooses + either |fixed| or |sci|, depending on the order of magnitude. Let + $n=s \cdot m \cdot 10^e$ be the input number and $p$ the current + precision. If $-p/2 \le e \le 4$, the number is displayed using + |fixed| format. Otherwise, it is displayed using |sci| format. \begin{codeexample}[] \pgfkeys{/pgf/number format/.cd,std,precision=2} @@ -104,12 +125,168 @@ Configures |\pgfmathprintnumber| to a standard algorithm. It chooses either |fix \pgfmathprintnumber{24415.98123}\hspace{1em} \pgfmathprintnumber{123456.12345} \end{codeexample} -The parameters can be customized using the optional integer argument(s): if $\text{\meta{lower e}} \le e \le \text{\meta{upper e}}$, the number is displayed in |fixed| format, otherwise in |sci| format. Note that \meta{lower e} should be negative for useful results. The precision used for scientific format can be adjusted with |sci precision| if necessary. + The parameters can be customized using the optional integer + argument(s): if $\text{\meta{lower e}} \le e \le \text{\meta{upper + e}}$, the number is displayed in |fixed| format, otherwise in + |sci| format. Note that \meta{lower e} should be negative for useful + results. The precision used for the scientific format can be + adjusted with |sci precision| if necessary. +\end{keylist} + +\begin{keylist}{/pgf/number format/relative*=\meta{exponent base 10}} + Configures |\pgfmathprintnumber| to format numbers relative to an + order of magnitude, $10^r$, where $r$ is an integer number. + + This key addresses different use-cases. + + \paragraph{First use-case:} provide a unified format for a + \emph{sequence} of numbers. Consider the following test: +\begin{codeexample}[] +\pgfkeys{/pgf/number format/relative*={1}} +\pgfmathprintnumber{6.42e-16}\hspace{1em} +\pgfmathprintnumber{1.2}\hspace{1em} +\pgfmathprintnumber{6}\hspace{1em} +\pgfmathprintnumber{20.6}\hspace{1em} +\pgfmathprintnumber{87} +\end{codeexample} + \noindent With any other style, the |6.42e-16| would have been + formatted as an isolated number. Here, it is rounded to |0| because + when viewed relative to $10^1$ (the exponent $1$ is the argument for + |relative|), it has no significant digits. + +\begin{codeexample}[] +\pgfkeys{/pgf/number format/relative*={2}} +\pgfmathprintnumber{123.345}\hspace{1em} +\pgfmathprintnumber{0.0012}\hspace{1em} +\pgfmathprintnumber{0.0014}\hspace{1em} +\end{codeexample} + \noindent The example above applies the initial |precision=2| to + |123.345| -- relative to $100$. Two significant digits of |123.345| + relative to $100$ are |123|. Note that the ``$2$ significant digits + of |123.345|'' translates to ``round |1.2345| to $2$ digits'', which + would yield |1.2300|. Similarly, the other two numbers are |0| + compared to $100$ using the given |precision|. + +\begin{codeexample}[] +\pgfkeys{/pgf/number format/relative*={-3}} +\pgfmathprintnumber{123.345}\hspace{1em} +\pgfmathprintnumber{0.0012}\hspace{1em} +\pgfmathprintnumber{0.0014}\hspace{1em} +\end{codeexample} + + \paragraph{Second use-case:} improve rounding in the presence of + \emph{inaccurate} numbers. Let us suppose that some + limited-precision arithmetics resulted in the result |123456999| + (like the |fpu| of \pgfname). You know that its precision is about + five or six significant digits. And you want to provide a fixed + point output. In this case, the trailing digits |....999| are a + numerical artifact due to the limited precision. Use + |relative*=3,precision=0| to eliminate the artifacts: +\begin{codeexample}[] +\pgfkeys{/pgf/number format/.cd,relative*={3},precision=0} +\pgfmathprintnumber{123456999}\hspace{1em} +\pgfmathprintnumber{123456999.12} +\end{codeexample} + \noindent Here, |precision=0| means that we inspect |123456.999| and + round that number to $0$ digits. Finally, we move the period back to + its initial position. Adding |relative style=fixed| results in fixed + point output format: +\begin{codeexample}[] +\pgfkeys{/pgf/number format/.cd,relative*={3},precision=0,relative style=fixed} +\pgfmathprintnumber{123456999}\hspace{1em} +\pgfmathprintnumber{123456999.12} +\end{codeexample} + \noindent Note that there is another alternative for this use-case + which is discussed later: the |fixed relative| style. +\begin{codeexample}[] +\pgfkeys{/pgf/number format/.cd,fixed relative,precision=6} +\pgfmathprintnumber{123456999}\hspace{1em} +\pgfmathprintnumber{123456999.12} +\end{codeexample} + + You might wonder why there is an asterisk in the key's name. The + short answer is: there is also a \declareandlabel{/pgf/number + format/relative} number printer which does unexpected things. The + key |relative*| repairs this. Existing code will still use the old + behavior. + + Technically, the key works as follows: as already explained above, + |relative*=3| key applied to |123456999.12| moves the period by + three positions and analyzes |123456.99912|. Mathematically + speaking, we are given a number $x = \pm m \cdot 10^e$ and we + attempt to apply |relative*=|$r$. The method then rounds $x / 10^r$ + to |precision| digits. Afterwards, it multiplies the result by + $10^r$ and typesets it. +\end{keylist} + +\begin{stylekey}{/pgf/number format/every relative} + A style which configures how the |relative| method finally displays + its results. + + The initial configuration is +\begin{codeexample}[code only] +\pgfkeys{/pgf/number format/every relative/.style=std} +\end{codeexample} + + Note that rounding is turned off when the resulting style is being + evaluated (since |relative| already rounded the number). + + Although supported, I discourage from using |fixed zerofill| or + |sci zerofill| in this context -- it may lead to a suggestion of higher + precision than is actually used (because |fixed zerofill| might + simply add |.00| although there was a different information before + |relative| rounded the result). +\end{stylekey} + +\begin{key}{/pgf/number format/relative style=\marg{options}} + The same as |every relative/.append style=|\marg{options}. +\end{key} + +\begin{keylist}{/pgf/number format/fixed relative} + Configures |\pgfmathprintnumber| to format numbers in a similar way + to the |fixed| style, but the |precision| is interpreted relatively + to the number's exponent. + The motivation is to get the same rounding effect as for |sci|, but + to display the number in the |fixed| style: +\begin{codeexample}[] +\pgfkeys{/pgf/number format/.cd,fixed relative,precision=3} +\pgfmathprintnumber{1000.0123}\hspace{1em} +\pgfmathprintnumber{100.0567}\hspace{1em} +\pgfmathprintnumber{0.000010003452}\hspace{1em} +\pgfmathprintnumber{0.010073452}\hspace{1em} +\pgfmathprintnumber{1.23567}\hspace{1em} +\pgfmathprintnumber{1003.75}\hspace{1em} +\pgfmathprintnumber{1006.75}\hspace{1em} +\end{codeexample} + + The effect of |fixed relative| is that the number is rounded to + \emph{exactly} the first \meta{precision} non-zero digits, no matter + how many leading zeros the number might have. + + Use |fixed relative| if you want |fixed| and if you know that only + the first $n$ digits are correct. Use |sci| if you need a scientific + display style and only the first $n$ digits are correct. + + Note that |fixed relative| ignores the |fixed zerofill| flag. + + See also the |relative*| key. Note that the + |relative=|\marg{exponent} key explicitly moves the period to some + designated position before it attempts to round the + number. Afterwards, it ``rounds from the right'', i.e.\ it rounds to + that explicitly chosen digit position. In contrast to that, + |fixed relative| ``rounds from the left'': it takes the \emph{first} + non-zero digit, temporarily places the period after this digit, and + rounds that number. The rounding style |fixed| leaves the period + where it is, and rounds everything behind that digit. The |sci| + style is similar to |fixed relative|. \end{keylist} + \begin{key}{/pgf/number format/int detect} -Configures |\pgfmathprintnumber| to detect integers automatically. If the input number is an integer, no period is displayed at all. If not, the scientific format is chosen. + Configures |\pgfmathprintnumber| to detect integers + automatically. If the input number is an integer, no period is + displayed at all. If not, the scientific format is chosen. \begin{codeexample}[] \pgfkeys{/pgf/number format/.cd,int detect,precision=2} @@ -122,12 +299,15 @@ Configures |\pgfmathprintnumber| to detect integers automatically. If the input \end{key} \begin{command}{\pgfmathifisint\marg{number constant}\marg{true code}\marg{false code}} - A command which does the same check as |int detect|, but it invokes \meta{true code} if the \meta{number constant} actually is an integer and the \meta{false code} if not. - - As a side--effect, |\pgfretval| will contain the parsed number, either in integer format or as parsed floating point number. + A command which does the same check as |int detect|, but it invokes + \meta{true code} if the \meta{number constant} actually is an + integer and the \meta{false code} if not. + As a side-effect, |\pgfretval| will contain the parsed number, + either in integer format or as parsed floating point number. - The argument \meta{number constant} will be parsed with |\pgfmathfloatparsenumber|. + The argument \meta{number constant} will be parsed with + |\pgfmathfloatparsenumber|. \begin{codeexample}[] 15 \pgfmathifisint{15}{is an int: \pgfretval.}{is no int}\hspace{1em} 15.5 \pgfmathifisint{15.5}{is an int: \pgfretval.}{is no int} @@ -135,8 +315,8 @@ Configures |\pgfmathprintnumber| to detect integers automatically. If the input \end{command} \begin{key}{/pgf/number format/int trunc} -Truncates every number to integers (discards any digit after the period). - + Truncates every number to integers (discards any digit after the + period). \begin{codeexample}[] \pgfkeys{/pgf/number format/.cd,int trunc} \pgfmathprintnumber{4.568}\hspace{1em} @@ -148,7 +328,7 @@ Truncates every number to integers (discards any digit after the period). \end{key} \begin{key}{/pgf/number format/frac} -Displays numbers as fractionals. + Displays numbers as fractionals. \begin{codeexample}[width=3cm] \pgfkeys{/pgf/number format/frac} @@ -169,10 +349,12 @@ Displays numbers as fractionals. \end{codeexample} \begin{key}{/pgf/number format/frac TeX=\marg{\textbackslash macro} (initially \texttt{\textbackslash frac})} - Allows to use a different implementation for |\frac| inside of the |frac| display type. + Allows to use a different implementation for |\frac| inside of the + |frac| display type. \end{key} + \begin{key}{/pgf/number format/frac denom=\meta{int} (initially empty)} - Allows to provide a custom denominator for |frac|. + Allows to provide a custom denominator for |frac|. \begin{codeexample}[width=3cm] \pgfkeys{/pgf/number format/.cd,frac, frac denom=10} \pgfmathprintnumber{0.1}\hspace{1em} @@ -183,7 +365,9 @@ Displays numbers as fractionals. \end{codeexample} \end{key} \begin{key}{/pgf/number format/frac whole=\mchoice{true,false} (initially true)} - Configures whether complete integer parts shall be placed in front of the fractional part. In this case, the fractional part will be less then $1$. Use |frac whole=false| to avoid whole number parts. + Configures whether complete integer parts shall be placed in front + of the fractional part. In this case, the fractional part will be + less then $1$. Use |frac whole=false| to avoid whole number parts. \begin{codeexample}[width=3cm] \pgfkeys{/pgf/number format/.cd,frac, frac whole=false} \pgfmathprintnumber{20.1}\hspace{1em} @@ -194,41 +378,59 @@ Displays numbers as fractionals. \end{codeexample} \end{key} \begin{key}{/pgf/number format/frac shift=\marg{integer} (initially 4)} - In case you experience problems because of stability problems, try experimenting with a different |frac shift|. - Higher shift values $k$ yield higher sensitivity to inaccurate data or inaccurate arithmetics. + In case you experience problems because of stability problems, try + experimenting with a different |frac shift|. Higher shift values $k$ + yield higher sensitivity to inaccurate data or inaccurate + arithmetics. - Technically, the following happens. If $r < 1$ is the fractional part of the mantissa, then a scale $i = 1/r \cdot 10^k$ is computed where $k$ is the shift; fractional parts of $i$ are neglected. The value $1/r$ is computed internally, its error is amplified. + Technically, the following happens. If $r < 1$ is the fractional + part of the mantissa, then a scale $i = 1/r \cdot 10^k$ is computed + where $k$ is the shift; fractional parts of $i$ are neglected. The + value $1/r$ is computed internally, its error is amplified. - If you still experience stability problems, use |\usepackage{fp}| in your preamble. The |frac| style will then automatically employ the higher absolute precision of |fp| for the computation of $1/r$. + If you still experience stability problems, use |\usepackage{fp}| in + your preamble. The |frac| style will then automatically employ the + higher absolute precision of |fp| for the computation of $1/r$. \end{key} \end{key} \begin{key}{/pgf/number format/precision=\marg{number}} -Sets the desired rounding precision for any display operation. For scientific format, this affects the mantissa. + Sets the desired rounding precision for any display operation. For + scientific format, this affects the mantissa. \end{key} \begin{key}{/pgf/number format/sci precision=\meta{number or empty} (initially empty)} - Sets the desired rounding precision only for |sci| styles. + Sets the desired rounding precision only for |sci| styles. - Use |sci precision={}| to restore the initial configuration (which uses the argument provided to |precision| for all number styles). + Use |sci precision={}| to restore the initial configuration (which + uses the argument provided to |precision| for all number styles). \end{key} \subsection{Changing display styles}% \label{sec:number:styles}% -You can change the way how numbers are displayed. For example, if you use the `\texttt{fixed}' style, the input number is rounded to the desired precision and the current fixed point display style is used to typeset the number. The same is applied to any other format: first, rounding routines are used to get the correct digits, afterwards a display style generates proper \TeX-code. + +You can change the way how numbers are displayed. For example, if you +use the `\texttt{fixed}' style, the input number is rounded to the +desired precision and the current fixed point display style is used to +typeset the number. The same is applied to any other format: first, +rounding routines are used to get the correct digits, afterwards a +display style generates proper \TeX-code. \begin{key}{/pgf/number format/set decimal separator=\marg{text}} -Assigns \marg{text} as decimal separator for any fixed point numbers (including the mantissa in sci format). + Assigns \marg{text} as decimal separator for any fixed point numbers + (including the mantissa in sci format). -Use |\pgfkeysgetvalue{/pgf/number format/set decimal separator}\value| to get the current separator into |\value|. + Use |\pgfkeysgetvalue{/pgf/number format/set decimal separator}\value| + to get the current separator into |\value|. \end{key} \begin{stylekey}{/pgf/number format/dec sep=\marg{text}} - Just another name for |set decimal separator|. + Just another name for |set decimal separator|. \end{stylekey} \begin{key}{/pgf/number format/set thousands separator=\marg{text}} -Assigns \marg{text} as thousands separator for any fixed point numbers (including the mantissa in sci format). + Assigns \marg{text} as thousands separator for any fixed point + numbers (including the mantissa in sci format). \begin{codeexample}[] \pgfkeys{/pgf/number format/.cd, @@ -271,17 +473,48 @@ Assigns \marg{text} as thousands separator for any fixed point numbers (includin set thousands separator={{{,}}}} \pgfmathprintnumber{1234567890} \end{codeexample} -The last example employs commas and disables the default comma-spacing. + The last example employs commas and disables the default + comma-spacing. -Use |\pgfkeysgetvalue{/pgf/number format/set thousands separator}\value| to get the current separator into |\value|. + Use |\pgfkeysgetvalue{/pgf/number format/set thousands separator}\value| + to get the current separator into |\value|. \end{key} \begin{stylekey}{/pgf/number format/1000 sep=\marg{text}} - Just another name for |set thousands separator|. + Just another name for |set thousands separator|. \end{stylekey} +\begin{key}{/pgf/number format/1000 sep in fractionals=\marg{boolean} (initially false)} + Configures whether the fractional part should also be grouped into + groups of three digits. + + The value |true| will active the |1000 sep| for both, integer and + fractional parts. The value |false| will active |1000 sep| only for the integer part. +\begin{codeexample}[] +\pgfkeys{/pgf/number format/.cd, + fixed, + precision=999, + set thousands separator={\,}, + 1000 sep in fractionals, + } +\pgfmathprintnumber{1234.1234567} +\end{codeexample} +\begin{codeexample}[] +\pgfkeys{/pgf/number format/.cd, + fixed,fixed zerofill, + precision=9, + set thousands separator={\,}, + 1000 sep in fractionals, + } +\pgfmathprintnumber{1234.1234567} +\end{codeexample} +\end{key} + \begin{key}{/pgf/number format/min exponent for 1000 sep=\marg{number} (initially 0)} - Defines the smallest exponent in scientific notation which is required to draw thousand separators. The exponent is the number of digits minus one, so $\meta{number}=4$ will use thousand separators starting with $1e4 = 10000$. + Defines the smallest exponent in scientific notation which is + required to draw thousand separators. The exponent is the number of + digits minus one, so $\meta{number}=4$ will use thousand separators + starting with $1e4 = 10000$. \begin{codeexample}[] \pgfkeys{/pgf/number format/.cd, int detect, @@ -304,11 +537,14 @@ Use |\pgfkeysgetvalue{/pgf/number format/set thousands separator}\value| to get min exponent for 1000 sep=4} \pgfmathprintnumber{10000}; \pgfmathprintnumber{1000000} \end{codeexample} -\noindent A value of |0| disables this feature (negative values are ignored). + \noindent A value of |0| disables this feature (negative values are + ignored). \end{key} \begin{key}{/pgf/number format/use period} -A predefined style which installs periods `\texttt{.}' as decimal separators and commas `\texttt{,}' as thousands separators. This style is the default. + A predefined style which installs periods ``\texttt{.}'' as decimal + separators and commas ``\texttt{,}'' as thousands separators. This + style is the default. \begin{codeexample}[] \pgfkeys{/pgf/number format/.cd,fixed,precision=2,use period} @@ -321,7 +557,8 @@ A predefined style which installs periods `\texttt{.}' as decimal separators and \end{key} \begin{key}{/pgf/number format/use comma} -A predefined style which installs commas `\texttt{,}' as decimal separators and periods `\texttt{.}' as thousands separators. + A predefined style which installs commas ``\texttt{,}'' as decimal + separators and periods ``\texttt{.}'' as thousands separators. \begin{codeexample}[] \pgfkeys{/pgf/number format/.cd,fixed,precision=2,use comma} @@ -334,7 +571,8 @@ A predefined style which installs commas `\texttt{,}' as decimal separators and \end{key} \begin{key}{/pgf/number format/skip 0.=\marg{boolean} (initially false)} - Configures whether numbers like $0.1$ shall be typeset as $.1$ or not. + Configures whether numbers like $0.1$ shall be typeset as $.1$ or + not. \begin{codeexample}[] \pgfkeys{/pgf/number format/.cd, fixed, @@ -352,7 +590,8 @@ A predefined style which installs commas `\texttt{,}' as decimal separators and \end{key} \begin{key}{/pgf/number format/showpos=\marg{boolean} (initially false)} - Enables or disables display of plus signs for non-negative numbers. + Enables or disables the display of plus signs for non-negative + numbers. \begin{codeexample}[] \pgfkeys{/pgf/number format/showpos} \pgfmathprintnumber{12.345} @@ -370,11 +609,11 @@ A predefined style which installs commas `\texttt{,}' as decimal separators and \end{key} \begin{stylekey}{/pgf/number format/print sign=\marg{boolean}} - A style which is simply an alias for |showpos=|\marg{boolean}. + A style which is simply an alias for |showpos=|\marg{boolean}. \end{stylekey} \begin{key}{/pgf/number format/sci 10e} -Uses $m \cdot 10^e$ for any number displayed in scientific format. + Uses $m \cdot 10^e$ for any number displayed in scientific format. \begin{codeexample}[] \pgfkeys{/pgf/number format/.cd,sci,sci 10e} @@ -383,11 +622,12 @@ Uses $m \cdot 10^e$ for any number displayed in scientific format. \end{key} \begin{key}{/pgf/number format/sci 10\textasciicircum e} -The same as `|sci 10e|'. + The same as `|sci 10e|'. \end{key} \begin{key}{/pgf/number format/sci e} -Uses the `$1e{+}0$' format which is generated by common scientific tools for any number displayed in scientific format. + Uses the `$1e{+}0$' format which is generated by common scientific + tools for any number displayed in scientific format. \begin{codeexample}[] \pgfkeys{/pgf/number format/.cd,sci,sci e} @@ -396,7 +636,7 @@ Uses the `$1e{+}0$' format which is generated by common scientific tools for any \end{key} \begin{key}{/pgf/number format/sci E} -The same with an uppercase `\texttt{E}'. + The same with an uppercase `\texttt{E}'. \begin{codeexample}[] \pgfkeys{/pgf/number format/.cd,sci,sci E} @@ -405,7 +645,8 @@ The same with an uppercase `\texttt{E}'. \end{key} \begin{key}{/pgf/number format/sci subscript} -Typesets the exponent as subscript for any number displayed in scientific format. This style requires very few space. + Typesets the exponent as subscript for any number displayed in + scientific format. This style requires very little space. \begin{codeexample}[] \pgfkeys{/pgf/number format/.cd,sci,sci subscript} @@ -414,7 +655,8 @@ Typesets the exponent as subscript for any number displayed in scientific format \end{key} \begin{key}{/pgf/number format/sci superscript} -Typesets the exponent as superscript for any number displayed in scientific format. This style requires very few space. + Typesets the exponent as superscript for any number displayed in + scientific format. This style requires very little space. \begin{codeexample}[] \pgfkeys{/pgf/number format/.cd,sci,sci superscript} @@ -423,13 +665,17 @@ Typesets the exponent as superscript for any number displayed in scientific form \end{key} \begin{key}{/pgf/number format/sci generic=\marg{keys}} -Allows to define an own number style for the scientific format. Here, \meta{keys} can be one of the following choices (omit the long key prefix): + Allows to define an own number style for the scientific + format. Here, \meta{keys} can be one of the following choices (omit + the long key prefix): \begin{key}{/pgf/number format/sci generic/mantissa sep=\marg{text} (initially empty)} - Provides the separator between a mantissa and the exponent. It might be |\cdot|, for example, + Provides the separator between a mantissa and the exponent. It might + be |\cdot|, for example, \end{key} \begin{key}{/pgf/number format/sci generic/exponent=\marg{text} (initially empty)} - Provides text to format the exponent. The actual exponent is available as argument |#1| (see below). + Provides text to format the exponent. The actual exponent is + available as argument |#1| (see below). \end{key} \begin{codeexample}[] @@ -440,33 +686,50 @@ Allows to define an own number style for the scientific format. Here, \meta{keys \pgfmathprintnumber{12.345}; \pgfmathprintnumber{0.00012345} \end{codeexample} - The \meta{keys} can depend on three parameters, namely on |#1| which is the exponent, |#2| containing the flags entity of the floating point number and |#3| is the (unprocessed and unformatted) mantissa. + The \meta{keys} can depend on three parameters, namely on |#1| which + is the exponent, |#2| containing the flags entity of the floating + point number and |#3| is the (unprocessed and unformatted) + mantissa. - Note that |sci generic| is \emph{not} suitable to modify the appearance of fixed point numbers, nor can it be used to format the mantissa (which is typeset like fixed point numbers). Use |dec sep|, |1000 sep| and |print sign| to customize the mantissa. + Note that |sci generic| is \emph{not} suitable to modify the + appearance of fixed point numbers, nor can it be used to format the + mantissa (which is typeset like fixed point numbers). Use |dec sep|, + |1000 sep| and |print sign| to customize the mantissa. \end{key} -\begin{key}{/pgf/number format/@dec sep mark=\marg{text}} - Will be placed right before the place where a decimal separator belongs to. However, \marg{text} will be inserted even if there is no decimal separator. It is intended as place-holder for auxiliary routines to find alignment positions. +\begin{key}{/pgf/number format/\protect\atmarktext dec sep mark=\marg{text}} + Will be placed right before the place where a decimal separator + belongs to. However, \marg{text} will be inserted even if there is + no decimal separator. It is intended as place-holder for auxiliary + routines to find alignment positions. - This key should never be used to change the decimal separator! Use |dec sep| instead. + This key should never be used to change the decimal separator! + Use |dec sep| instead. \end{key} -\begin{key}{/pgf/number format/@sci exponent mark=\marg{text}} - Will be placed right before exponents in scientific notation. It is intended as place-holder for auxiliary routines to find alignment positions. +\begin{key}{/pgf/number format/\protect\atmarktext sci exponent mark=\marg{text}} + Will be placed right before exponents in scientific notation. It is + intended as place-holder for auxiliary routines to find alignment + positions. - This key should never be used to change the exponent! + This key should never be used to change the exponent! \end{key} \begin{key}{/pgf/number format/assume math mode=\marg{boolean} (default true)} - Set this to |true| if you don't want any checks for math mode. The initial setting checks whether math mode is active using |\pgfutilensuremath| for each final number. + Set this to |true| if you don't want any checks for math mode. The + initial setting checks whether math mode is active using + |\pgfutilensuremath| for each final number. - Use |assume math mode=true| if you know that math mode is active. In that case, the final number is typeset as-is, no further checking is performed. + Use |assume math mode=true| if you know that math mode is active. In + that case, the final number is typeset as-is, no further checking is + performed. \end{key} \begin{stylekey}{/pgf/number format/verbatim} - A style which configures the number printer to produce verbatim text output, i.e.\ it doesn't contain \TeX\ macros. + A style which configures the number printer to produce verbatim text + output, i.\,e., it doesn't contain \TeX\ macros. \begin{codeexample}[] \pgfkeys{ /pgf/fpu, @@ -478,9 +741,14 @@ Allows to define an own number style for the scientific format. Here, \meta{keys \pgfmathparse{exp(15)} \pgfmathprintnumber{\pgfmathresult} \end{codeexample} - The style resets |1000 sep|, |dec sep|, |print sign|, |skip 0.| and sets |assume math mode|. Furthermore, it installs a |sci generic| format for verbatim output of scientific numbers. + The style resets |1000 sep|, |dec sep|, |print sign|, |skip 0.| and + sets |assume math mode|. Furthermore, it installs a |sci generic| + format for verbatim output of scientific numbers. - However, it will still respect |precision|, |fixed zerofill|, |sci zerofill| and the overall styles |fixed|, |sci|, |int detect| (and their variants). It might be useful if you intent to write output files. + However, it will still respect |precision|, |fixed zerofill|, + |sci zerofill| and the overall styles |fixed|, |sci|, |int detect| + (and their variants). It might be useful if you intend to write + output files. \end{stylekey} %-------------------------------------------------- % \subsubsection{Defining own display styles} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-parsing.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-parsing.tex index 1d28cfa4fea..37df357e706 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-parsing.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-math-parsing.tex @@ -13,14 +13,14 @@ The easiest way of using \pgfname's mathematical engine is to provide a mathematical expression given in familiar infix notation, for example, |1cm+4*2cm/5.5| or |2*3+3*sin(30)|. This expression can be -parsed by the mathematical engine and the result be placed in a +parsed by the mathematical engine and the result can be placed in a dimension register, a counter, or a macro. It should be noted that all calculations must not exceed $\pm16383.99999$ at \emph{any} point, because the underlying computations rely on \TeX{} dimensions. This means that many of the underlying computations are necessarily -approximate and that in addition, are not very fast. \TeX{} is, +approximate and, in addition, not very fast. \TeX{} is, after all, a typesetting language and not ideally suited to relatively advanced mathematical operations. However, it is possible to change the computations as described in @@ -53,56 +53,77 @@ engine is the following: \begin{itemize} \item - The result stored in the macro |\pgfmathresult| is a decimal - \emph{without units}. This is true regardless of whether the - \meta{expression} contains any unit specification. All numbers - with units are converted to points first. - + The result stored in the macro |\pgfmathresult| is a decimal + \emph{without units}. This is true regardless of whether the + \meta{expression} contains any unit specification. All numbers + with units are converted to points first. + You can check whether an expression contained a unit using + the following \TeX-if. + {\let\ifpgfmathunitsdeclared\relax + \begin{command}{\ifpgfmathunitsdeclared} + After a call of |\pgfmathparse| this if will be true exactly if + some unit was encountered in the expression. It is always set + globally in each call. + \end{command} + } + + A special kind of units are \TeX's ``math units'' (|mu|). It will + be treated as if |pt| had been used, but you can + check whether an expression contained a math unit using the + following: + {\let\ifpgfmathmathunitsdeclared\relax + \begin{command}{\ifpgfmathmathunitsdeclared} + This \TeX-if is similar to |\ifpgfmathunitsdeclared|, but it + is only set when the unit |mu| is encountered at least + once. In this case, |\ifpgfmathunitsdeclared| will \emph{also} + be set to true. + \end{command} + } \item - You can check whether an expression contained a unit using - the \TeX-if |\||ifpgfmathunitsdeclared|. After a call - of |\pgfmathparse| this if will be true exactly if some unit was - encountered in the expression. - + The parser will recognize \TeX{} registers and box dimensions, + so |\mydimen|, |0.5\mydimen|, |\wd\mybox|, |0.5\dp\mybox|, + |\mycount\mydimen| and so on can be parsed. + \item - The parser can recognize \TeX{} registers and box dimensions, - so |\mydimen|, |0.5\mydimen|, |\wd\mybox|, |0.5\dp\mybox|, - |\mycount\mydimen| and so on can be parsed. - + The $\varepsilon$-TeX\ extensions |\dimexpr|, |\numexpr|, |\glueexpr|, and + |\muexpr| are recognized and evaluated. The values they + result in will be used in the further evaluation, as if you had + put |\the| before them. + \item - Parenthesis can be used to change the order of the evaluation. - + Parenthesis can be used to change the order of the evaluation. + \item - Various functions are recognized, so it is possible to parse - |sin(.5*pi r)*60|, which means ``the sine of $0.5$ times $\pi$ - radians, multiplied by 60''. The argument of functions can - be any expression. - + Various functions are recognized, so it is possible to parse + |sin(.5*pi r)*60|, which means ``the sine of $0.5$ times $\pi$ + radians, multiplied by 60''. The argument of functions can + be any expression. + \item - Scientific notation in the form |1.234e+4| is recognized (but - the restriction on the range of values still applies). The exponent - symbol can be upper or lower case (i.e., |E| or |e|). - + Scientific notation in the form |1.234e+4| is recognized (but + the restriction on the range of values still applies). The exponent + symbol can be upper or lower case (i.e., |E| or |e|). + \item - An integer with a zero-prefix (excluding, of course zero itself), - is interpreted as an octal number and is automatically converted - to base 10. - + An integer with a zero-prefix (excluding, of course zero itself), + is interpreted as an octal number and is automatically converted + to base 10. + \item - An integer with prefix |0x| or |0X| is interpreted as a hexadecimal - number and is automatically converted to base 10. Alphabetic digits - can be in uppercase or lowercase. - - \item - An integer with prefix |0b| or |0B| is interpreted as a binary - number and is automatically converted to base 10. - + An integer with prefix |0x| or |0X| is interpreted as a hexadecimal + number and is automatically converted to base 10. Alphabetic digits + can be in uppercase or lowercase. + \item - An expression (or part of an expression) surrounded with double - quotes (i.e., the character |"|) will not be evaluated. - Obviously this should be used with great care. - -\end{itemize} + An integer with prefix |0b| or |0B| is interpreted as a binary + number and is automatically converted to base 10. + + \item + An expression (or part of an expression) surrounded with double + quotes (i.e., the character |"|) will not be evaluated. + Obviously this should be used with great care. + + \end{itemize} \end{command} @@ -127,9 +148,9 @@ engine is the following: At the end of the parse this command is executed, allowing some custom action to be performed on the result of the parse. When this - command is executed the macro |\pgfmathresult| will hold the result - of the parse (as ever, without units). The result of the custom - action should be to redefined |\pgfmathresult| appropriately. + command is executed, the macro |\pgfmathresult| will hold the result + of the parse (as always, without units). The result of the custom + action should be used to redefine |\pgfmathresult| appropriately. By default, this command is equivalent to |\relax|. This differs from previous versions, where, if the parsed expression contained no units, the result of the parse was scaled according to the value @@ -143,7 +164,7 @@ engine is the following: \end{command} -Instead of the |\pgfmathparse| macro you can also wrapper commands, +Instead of the |\pgfmathparse| macro you can also use wrapper commands, whose usage is very similar to their cousins in the \calcname{} package. The only difference is that the expressions can be any expression that is handled by |\pgfmathparse|. @@ -152,15 +173,57 @@ For all of the following commands, if \meta{expression} starts with using normal \TeX\ assignments or increments. This will be orders of magnitude faster than calling the parser. -\begin{command}{\pgfmathsetlength\marg{dimension register}\marg{expression}} - Sets the length of the \TeX{} \meta{dimension register}, to the value - (in points) specified by \meta{expression}. The \meta{expression} - will be parsed using |\pgfmathparse|. +The effect of the following commands is always local to the current +\TeX\ scope. + +\begin{command}{\pgfmathsetlength\marg{register}\marg{expression}} + Basically, this command sets the length of the \TeX{} + \meta{register} to the value specified by + \meta{expression}. However, there is some fine print: + + First, in case \meta{expression} starts with a |+|, a simple \TeX\ + assignment is done. In particular, \meta{register} can be a glue + register and \meta{expression} be something like |+1pt plus 1fil| + and the \meta{register} will be assigned the expected value. + + Second, when the \meta{expected} does not start with |+|, it is + first parsed using |\pgfmathparse|, resulting in a (dimensionless) + value |\pgfmathresult|. Now, if the parser encountered the unit |mu| + somewhere in the expression, it assumes that \meta{register} is a + |\muskip| register and will try to assign to \meta{register} the + value |\pgfmathresult| followed by |mu|. Otherwise, in case |mu| was + not encountered, it is assumed that \meta{register} is a dimension + register or a glue register and we assign |\pgfmathresult| followed + by |pt| to it. + + The net effect of the above is that you can write things like +\begin{codeexample}[] + \muskipdef\mymuskip=0 + \pgfmathsetlength{\mymuskip}{1mu+3*4mu} \the\mymuskip +\end{codeexample} +\begin{codeexample}[] + \dimendef\mydimen=0 + \pgfmathsetlength{\mydimen}{1pt+3*4pt} \the\mydimen +\end{codeexample} +\begin{codeexample}[] + \skipdef\myskip=0 + \pgfmathsetlength{\myskip}{1pt+3*4pt} \the\myskip +\end{codeexample} + + One thing that will \emph{not} work is + |\pgfmathsetlength{\myskip}{1pt plus 1fil}| since the parser does + not support fill's. You can, however, use the |+| notation in this + case: +\begin{codeexample}[] + \skipdef\myskip=0 + \pgfmathsetlength{\myskip}{+1pt plus 1fil} \the\myskip +\end{codeexample} \end{command} -\begin{command}{\pgfmathaddtolength\marg{dimension register}\marg{expression}} - Adds the value (in points) of \meta{expression} to the \TeX{} - \meta{dimension register}. +\begin{command}{\pgfmathaddtolength\marg{register}\marg{expression}} + Adds the value of \meta{expression} to the \TeX{} + \meta{register}. All of the special consideration mentioned for + |\pgfmathsetlength| also apply here in the same way. \end{command} \begin{command}{\pgfmathsetcount\marg{count register}\marg{expression}} @@ -174,7 +237,7 @@ magnitude faster than calling the parser. \end{command} \begin{command}{\pgfmathsetcounter\marg{counter}\marg{expression}} - Sets the value of the \LaTeX{} \meta{counter}, to the \emph{truncated} + Sets the value of the \LaTeX{} \meta{counter} to the \emph{truncated} value specified by \meta{expression}. \end{command} @@ -190,7 +253,7 @@ magnitude faster than calling the parser. \begin{command}{\pgfmathsetlengthmacro\marg{macro}\marg{expression}} Defines \meta{macro} as the value of \meta{expression} - \LaTeX{}\emph{in points}. + \LaTeX{} \emph{in points}. \end{command} \begin{command}{\pgfmathtruncatemacro\marg{macro}\marg{expression}} @@ -242,7 +305,7 @@ magnitude faster than calling the parser. Raises \mvar{x} to the power \mvar{y}. \end{math-operator} -\begin{math-operator}{!}{postfix}{factorial} +\begin{math-operator}{\protect\exclamationmarktext}{postfix}{factorial} Calculates the factorial of \mvar{x}. \end{math-operator} @@ -272,7 +335,7 @@ magnitude faster than calling the parser. Returns |1| if \mvar{x}$<$\mvar{y}, |0| otherwise. \end{math-operator} -\begin{math-operator}{!=}{infix}{notequal} +\begin{math-operator}{\protect\exclamationmarktext=}{infix}{notequal} Returns |1| if \mvar{x}$\neq$\mvar{y}, |0| otherwise. \end{math-operator} @@ -301,7 +364,7 @@ magnitude faster than calling the parser. \end{math-operator} } -\begin{math-operator}{!}{prefix}{not} +\begin{math-operator}{\protect\exclamationmarktext}{prefix}{not} Returns |1| if \mvar{x} evaluates to zero, |0| otherwise. \end{math-operator} @@ -355,7 +418,7 @@ the array, an error will occur, and zero will be returned. \pgfmathparse{\myarray[3]} \pgfmathresult \end{codeexample} -If the array is defined to have multiple dimensions then the array +If the array is defined to have multiple dimensions, then the array access operators can be immediately repeated. \begin{codeexample}[] @@ -368,7 +431,7 @@ access operators can be immediately repeated. \end{math-operators} -\begin{math-operators}{"}{"}{group}{} +\begin{math-operators}{\char`\"}{\char`\"}{group}{} These operators are used to quote \mvar{x}. However, as every expression is expanded with |\edef| before it is parsed, macros @@ -403,18 +466,18 @@ The following functions are recognized: \foreach \f [count=\i from 0] in {abs,acos,add,and,array,asin,atan,atan2,bin,ceil,cos, cosec,cosh,cot,deg,depth,div,divide,e,equal,factorial, false, - floor,frac,greater,height,hex,Hex,int,ifthenelse, + floor,frac,gcd,greater,height,hex,Hex,int,ifthenelse,iseven,isodd,isprime, less,ln,log10,log2,max,min,mod,Mod,multiply, neg,not,notequal,notgreater,notless, oct,or,pi,pow,rad,rand,random,real,rnd,round, sec,sin,sinh,sqrt,subtract,tan,tanh,true, veclen,width} -\node [anchor=base west] at ({int(\i/11)*2.5cm},{-mod(\i,11)*1.1*\baselineskip}) {\mathlink{\f}}; +\node [anchor=base west] at ({int(\i/12)*2.5cm},{-mod(\i,12)*1.1*\baselineskip}) {\mathlink{\f}}; \end{tikzpicture} \bigskip Each function has a \pgfname{} command associated with it (which is -also shown with the function below). In general the command +also shown with the function below). In general, the command is simply the name of the function prefixed with |\pgfmath|, for example, |\pgfmathadd|, but there are some notable exceptions. @@ -512,9 +575,9 @@ example, |\pgfmathadd|, but there are some notable exceptions. \begin{math-function}{pow(\mvar{x},\mvar{y})} \mathcommand - Raises \mvar{x} to the power \mvar{y}. For greatest accuracy - \mvar{y} should be an integer. If \mvar{y} is not an integer - the actual calculation will be an approximation of $e^{yln(x)}$. + Raises \mvar{x} to the power \mvar{y}. For greatest accuracy, + \mvar{y} should be an integer. If \mvar{y} is not an integer, + the actual calculation will be an approximation of $e^{y\text{ln}(x)}$. \begin{codeexample}[] \pgfmathparse{pow(2,7)} \pgfmathresult @@ -563,7 +626,7 @@ example, |\pgfmathadd|, but there are some notable exceptions. \catcode`\^=7 An approximation for $\ln(\textrm{\mvar{x}})$. - This uses an algorithm due to Rouben Rostamian, and coefficients + This uses an algorithm of Rouben Rostamian, and coefficients suggested by Alain Matthes. } \begin{codeexample}[] @@ -654,7 +717,7 @@ example, |\pgfmathadd|, but there are some notable exceptions. Rounds \mvar{x} to the nearest integer. It uses ``asymmetric half-up'' rounding. So |1.5| is rounded to |2|, but |-1.5| is rounded to |-2| - (\emph{not} |1|). + (\emph{not} |-1|). \begin{codeexample}[] \pgfmathparse{round(32.5/17)} \pgfmathresult @@ -679,6 +742,9 @@ example, |\pgfmathadd|, but there are some notable exceptions. \pgfmathparse{floor(398/12)} \pgfmathresult \end{codeexample} +\begin{codeexample}[] +\pgfmathparse{floor(-398/12)} \pgfmathresult +\end{codeexample} \end{math-function} \begin{math-function}{ceil(\mvar{x})} @@ -694,6 +760,10 @@ example, |\pgfmathadd|, but there are some notable exceptions. \pgfmathparse{ceil(398/12)} \pgfmathresult \end{codeexample} +\begin{codeexample}[] +\pgfmathparse{ceil(-398/12)} \pgfmathresult +\end{codeexample} + \end{math-function} \begin{math-function}{int(\mvar{x})} @@ -730,6 +800,58 @@ example, |\pgfmathadd|, but there are some notable exceptions. \end{math-function} +\subsubsection{Integer arithmetics functions} + +\label{pgfmath-functions-integerarithmetics} + +\begin{math-function}{gcd(\mvar{x},\mvar{y})} +\mathcommand + + Computes the greatest common divider of \mvar{x} and \mvar{y}. + +\begin{codeexample}[] +\pgfmathparse{gcd(42,56)} \pgfmathresult +\end{codeexample} + +\end{math-function} + +\begin{math-function}{isodd(\mvar{x})} +\mathcommand + + Returns |1| if the integer part of \mvar{x} is odd. Otherwise, returns |0|. + +\begin{codeexample}[] +\pgfmathparse{isodd(2)} \pgfmathresult, +\pgfmathparse{isodd(3)} \pgfmathresult +\end{codeexample} + +\end{math-function} + +\begin{math-function}{iseven(\mvar{x})} +\mathcommand + + Returns |1| if the integer part of \mvar{x} is even. Otherwise, returns |0|. + +\begin{codeexample}[] +\pgfmathparse{iseven(2)} \pgfmathresult, +\pgfmathparse{iseven(3)} \pgfmathresult +\end{codeexample} + +\end{math-function} + +\begin{math-function}{isprime(\mvar{x})} +\mathcommand + + Returns |1| if the integer part of \mvar{x} is prime. Otherwise, returns |0|. + +\begin{codeexample}[] +\pgfmathparse{isprime(1)} \pgfmathresult, +\pgfmathparse{isprime(2)} \pgfmathresult, +\pgfmathparse{isprime(31)} \pgfmathresult, +\pgfmathparse{isprime(64)} \pgfmathresult +\end{codeexample} + +\end{math-function} \subsubsection{Trigonometric functions} @@ -891,8 +1013,8 @@ example, |\pgfmathadd|, but there are some notable exceptions. \end{math-function} -\begin{math-function}{atan2(\mvar{x},\mvar{y})} -\mathcommand[atantwo(\mvar{x},\mvar{y})] +\begin{math-function}{atan2(\mvar{y},\mvar{x})} +\mathcommand[atantwo(\mvar{y},\mvar{x})] Arctangent of $y\div x$ in degrees. This also takes into account the quadrants. @@ -1050,7 +1172,7 @@ example, |\pgfmathadd|, but there are some notable exceptions. \begin{math-function}{rnd} \mathcommand - Generates a pseudo-random number between 0 and 1. + Generates a pseudo-random number between $0$ and $1$ with a uniform distribution. \begin{codeexample}[] \foreach \x in {1,...,10}{\pgfmathparse{rnd}\pgfmathresult, } @@ -1061,7 +1183,7 @@ example, |\pgfmathadd|, but there are some notable exceptions. \begin{math-function}{rand} \mathcommand - Generates a pseudo-random number between -1 and 1. + Generates a pseudo-random number between $-1$ and $1$ with a uniform distribution. \begin{codeexample}[] \foreach \x in {1,...,10}{\pgfmathparse{rand}\pgfmathresult, } @@ -1072,11 +1194,11 @@ example, |\pgfmathadd|, but there are some notable exceptions. \begin{math-function}{random(\opt{\mvar{x},\mvar{y}})} \mathcommand This function takes zero, one or two arguments. If there are zero - arguments, a random number between 0 and 1 is generated. If there is - one argument \mvar{x}, a random integer between 1 and \mvar{x} is + arguments, a uniform random number between $0$ and $1$ is generated. If there is + one argument \mvar{x}, a random integer between $1$ and \mvar{x} is generated. Finally, if there are two arguments, a random integer between \mvar{x} and \mvar{y} is generated. If there are no - arguments the \pgfname{} command should be called as follows: + arguments, the \pgfname{} command should be called as follows: |\pgfmathrandom{}|. \begin{codeexample}[] @@ -1123,7 +1245,7 @@ example, |\pgfmathadd|, but there are some notable exceptions. \begin{math-function}{oct(\mvar{x})} \mathcommand - Convert \mvar{x}{} (assumed to be an integer in base 10) to a + Convert \mvar{x}{} (assumed to be an integer in base 10) to an octal representation. No further calculation should be attempted with the result, as the parser can only process numbers converted to base 10. @@ -1183,8 +1305,7 @@ example, |\pgfmathadd|, but there are some notable exceptions. \mathcommand Calculates $\sqrt{\left(\textrm{\mvar{x}}^2+\textrm{\mvar{y}}^2\right)}$. - This uses a polynomial approximation, based on ideas due - to Rouben Rostamian + This uses a polynomial approximation, based on ideas of Rouben Rostamian \begin{codeexample}[] \pgfmathparse{veclen(12,5)} \pgfmathresult \end{codeexample} @@ -1249,7 +1370,7 @@ suggested by Martin Heller: \mathcommand Return the width of a \TeX{} (horizontal) box containing \mvar{x}. - The quote characters are necessary to prevent \mvar{x}{} being + The quote characters are necessary to prevent \mvar{x}{} from being parsed. It is important to remember that any expression is expanded with |\edef| before being parsed, so any macros (e.g., font commands @@ -1259,6 +1380,8 @@ suggested by Martin Heller: \begin{codeexample}[] \pgfmathparse{width("Some Lovely Text")} \pgfmathresult \end{codeexample} + + Note that results of this method are provided in points. \end{math-function} \begin{math-function}{height("\mvar{x}")} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-module-parser.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-module-parser.tex index 8668d69ad24..f2ac87509d9 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-module-parser.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-module-parser.tex @@ -20,7 +20,7 @@ This module provides commands for defining a parser that scans some given text letter-by-letter. For each letter, some code is executed -and, possible, a state-switch occurs. The parsing process ends when a +and, possibly a state-switch occurs. The parsing process ends when a final state has been reached. \begin{command}{\pgfparserparse\marg{parser name}\meta{text}} @@ -73,7 +73,7 @@ There are \the\mycount\ a's. Inside the \meta{action} you can perform almost any kind of code. This code will not be surrounded by a scope, so its effect - persist after the parsing is done. However, each time after the + persists after the parsing is done. However, each time after the \meta{action} is executed, control goes back to the parser. You should not launch a parser inside the \meta{action} code, unless you put it in a scope. diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-oo.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-oo.tex index 5044c0bd183..7f11f1d06e0 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-oo.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-oo.tex @@ -42,8 +42,8 @@ for non-time-critical things. Basically, the oo-system supports \emph{classes} (in the object-oriented sense, this has nothing to do with \LaTeX-classes), \emph{methods}, \emph{constructors}, \emph{attributes}, -\emph{objects}, and \emph{object identities}. It (currently) does not -support either inheritance, overloading, destructors, or class nesting. +\emph{objects}, \emph{object identities}, and (thanks to Sa\v o \v +Zivanovi\'c) \emph{inheritance} and \emph{overloading.} The first step is to define a class, using the macro |\pgfooclass| (all normal macros in \pgfname's object-oriented system start with @@ -58,7 +58,7 @@ Once a class has been defined, you can create objects of this class. Objects are created using |\pgfoonew|. Such an object has many characteristics of objects in a normal object-oriented programming language: Each object has a \emph{unique identity}, so when you create -another object this object is completely distinct from all other +another object, this object is completely distinct from all other objects. Each object also has a set of private attributes, which may change over time. Suppose, for instance, that we have a |point| class. Then creating a new object (called an instance) of this class @@ -101,15 +101,16 @@ addition to \pgfname). We start with the definition of the |stamp| class. This is done using the |\pgfooclass| macro: -\begin{command}{\pgfooclass\marg{class name}\marg{body}} +\begin{command}{\pgfooclass\opt{|(|\meta{list of superclasses}|)|}\marg{class name}\marg{body}} This command defines a class named \meta{class name}. The name of the class can contain spaces and most other characters, but no periods. So, valid class names are |MyClass| or |my class| or - |Class_C++_emulation??1|. + |Class_C++_emulation??1|. The \meta{list of superclasses} is + optional just like the parenthesis around it. The \meta{body} is actually just executed, so any normal \TeX-code is permissible here. However, while the \meta{body} is - being executed, the macros |\method| and |\attribute| are setup so + being executed, the macros |\method| and |\attribute| are set up so that they can be used to define methods and attributes for this class (the original meanings are restored afterward). @@ -133,6 +134,17 @@ the |\pgfooclass| macro: % We can now create objects of type "stamp" \end{codeexample} + + Concerning the list of base classes, the Method Resolution Order + (\textsc{mro}) is computed using the C3 algorithm also used in Python, v2.3 + and higher. The linearization computed by the algorithm respects + both local precedence ordering and monotonicity. Resolution of both + methods and attributes depends on the \textsc{mro}: when a method method name + is called on an object of class $C$, the system invokes method + method name from the first class in the \textsc{mro} of $C$ which defines + method method name; when an object is created, each attribute |attr| + is initialized to the value specified in the first class in the \textsc{mro} + of $C$ which declares attribute |attr|. \end{command} The \meta{body} of a class usually just consists of calls to the macros @@ -173,7 +185,7 @@ peculiar syntax: The optional \meta{object handle or attribute} can either be an \meta{object handle} or an \meta{attribute}. When an \meta{object - handle} is give, it must be a normal \TeX\ macro name that will + handle} is given, it must be a normal \TeX\ macro name that will ``point'' to the object (handles are discussed in more detail in Section~\ref{section-identities}). You can use this macro to call methods of the object as discussed in the following section. When an @@ -217,20 +229,21 @@ command: names can contain spaces and other characters, so \meta{method names} like |put_stamp_here| or |put stamp here| are both legal. - Three method names are special: First, a method having the same name - as the class is called the \emph{constructor} of the class. The must be - such a method, even if its body is empty. There are (currently) no + Three method names are special: First, a method having either the + same name as the class or having the name |init| is called the + \emph{constructor} of the class. There are (currently) no destructors; objects simply become ``undefined'' at the end of the scope in which they have been created. The other two methods are called |get id| and |get handle|, which are always automatically defined and which you cannot redefine. They are discussed in Section~\ref{section-identities}. - Overloading of methods is not possible, that is, it is illegal to - have two methods inside a single class with the same name (despite - possibly different parameter lists). However, two different classes - may contain a method with the same name, that is, classes form - namespaces for methods. + Overloading of methods by differing numbers of parameters is not + possible, that is, it is illegal to have two methods inside a single + class with the same name (despite possibly different parameter + lists). However, two different classes may contain a method with the + same name, that is, classes form namespaces for methods. Also, a + class can (re)implement a method from a superclass. The \meta{method name} must be followed by a \meta{parameter list} in parentheses, which must be present even when the \meta{parameter @@ -244,8 +257,8 @@ command: When a method is called, the \meta{body} of the method will be executed. The main difference to a normal macro - is that while the \meta{body} is executed a special macro called - |\pgfoothis| is setup in such a way that it references that object + is that while the \meta{body} is executed, a special macro called + |\pgfoothis| is set up in such a way that it references the object for which the method is executed. \end{command} @@ -255,11 +268,18 @@ method for this object, a special syntax is used that is similar to Java or C++ syntax: \begin{pgfmanualentry} - \pgfmanualentryheadline{\meta{object handle}|.|\meta{method name}|(|\meta{parameters}|)|}% + \pgfmanualentryheadline{\meta{object handle}\opt{|.|\meta{super + class}}|.|\meta{method name}|(|\meta{parameters}|)|}% \pgfmanualbody This causes the method \meta{method name} to be called for the - object referenced by the \meta{object handle}. Naturally, the method - is the one defined in the class of the object. The \meta{parameters} + object referenced by the \meta{object handle}. The method is the one + defined in the class of the object or, if it is not defined there, + the method defined in the superclasses of the object's class (if + there are several superclasses that define the same method, the + method resolution order is used to determine which one gets + called). If the optional \meta{super class} is specified, the method + implementation of that class will be used rather than the + implementation in the object's class. The \meta{parameters} are matched against the parameters of the method and, then, the method body is executed. The execution of the method body is \emph{not} done inside a scope, so the effects of a method body @@ -320,6 +340,16 @@ Java or C++ syntax: \end{pgfmanualentry} +\begin{command}{\pgfoosuper|(|\meta{class},\meta{object + handle}|).|\meta{method name}|(|\meta{arguments}|)|} + This macro gives you finer control over which method gets invoked in + case of multiple inheritance. This macro calls \meta{method name} of + the object specified by \meta{object handle}, but which + implementation of the method is called is determined as follows: it + will be the implementation in the first class (in the method + resolution order) after \meta{class} that defines \meta{method + name}. +\end{command} \subsection{Attributes} @@ -495,7 +525,7 @@ a method of this name yourself. Different object that are alive (that are still within the scope in which they were created) will always have different ids, so you can use the id to test for equality of objects. However, after an object - has been destroyed because its scope has ended the same id may be + has been destroyed because its scope has ended, the same id may be used again for newly created objects. Here is a typical application where you need to call this method: @@ -511,7 +541,7 @@ a method of this name yourself. the |get id| method and store the resulting id, rather than the handle. \end{predefinedmethod} -There is a second predefined methods, called |get handle|, which is also +There is a second predefined method, called |get handle|, which is also used to create object handles. \begin{predefinedmethod}{get handle(\marg{macro name})} @@ -535,22 +565,41 @@ used to create object handles. +\subsection{The Object Class} + +\label{section-object} + +The object-oriented module predefines a basic class |object| that can +be used as a base class in different context. + +\begin{ooclass}{object} + This class current only implements one method: + + \begin{method}{copy(\meta{handle})} + Creates a new object and initializes the values of its (declared) + attributes to the values of the original. The method takes one + argument: a control sequence which receives the handle of the + copy. + \end{method} +\end{ooclass} + + \subsection{The Signal Class} \label{section-signals} -The object-oriented module predefines, in addition to the basic mechanism -for defining and using classes and object, one class: |signal|. This -class implements a so-called signal--slot mechanism. +In addition to the basic mechanism for defining and using classes and +object, the class |signal| is predefined. It implements a so-called +signal--slot mechanism. \begin{ooclass}{signal} This class is used to implement a simple signal--slot - mechanism. The idea is the following: Form time to time special + mechanism. The idea is the following: From time to time special things happen about which a number of objects need to be informed. Different things can happen and different object will be interested in these things. A |signal| object can be used to signal that such special things of a certain kind have happened. For - example, on signal object might be used to signal the event that ``a + example, one signal object might be used to signal the event that ``a page has been shipped out.'' Another signal might be used to signal that ``a figure is about to be typeset,'' and so on. @@ -648,6 +697,6 @@ implemented: value. This is done without scopes, so some tricky |\expandafter| magic is needed. Note that, because of this process, you cannot use commands like |\pgfutil@ifnextchar| at the end of a method. -\item An object handle contains just the code to setup and restore the +\item An object handle contains just the code to set up and restore the current object number to the number of the object being called. \end{itemize} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pages.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pages.tex index 57bf5b7cd98..452690a36d0 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pages.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pages.tex @@ -10,7 +10,7 @@ \section{Page Management} -This section describes the |pgfpages| packages. Although this package +This section describes the |pgfpages| package. Although this package is not concerned with creating pictures, its implementation relies so heavily on \pgfname\ that it is documented here. Currently, |pgfpages| only works with \LaTeX, but if you are adventurous, feel free to hack @@ -39,7 +39,7 @@ future. The internals of |pgfpages| are complex since the package can do all sorts of interesting tricks. For this reason, so-called \emph{layouts} -are predefined that setup all option in appropriate ways. +are predefined that set up all option in appropriate ways. You use a layout as follows: \begin{codeexample}[code only] @@ -170,8 +170,7 @@ printing on letter paper: This section explains the predefined layouts in more detail. You select a layout using the following command: \begin{command}{\pgfpagesuselayout\marg{layout}\oarg{options}} - Installs the specified \meta{layout} with the given \meta{options} - set. The predefined layouts and their permissible options are + Installs the specified \meta{layout} with the given \meta{options}. The predefined layouts and their permissible options are explained below. If this function is called multiple times, only the last call @@ -232,7 +231,7 @@ select a layout using the following command: landscape mode). When using this layout, it is advisable to use the |\nofiles| command, but this is not done automatically. - The same \meta{options} as for the |resize to| layout an be used, + The same \meta{options} as for the |resize to| layout can be used, plus the following option: \begin{itemize} \item @@ -244,11 +243,11 @@ select a layout using the following command: \begin{pgflayout}{4 on 1} Puts four logical pages on a single physical page. - The same \meta{options} as for the |resize to| layout an be used. + The same \meta{options} as for the |resize to| layout can be used. \end{pgflayout} \begin{pgflayout}{8 on 1} - Puts eight logical pages on a single physical page. As for |2 on 1|, + Puts eight logical pages on a single physical page. As for |2 on 1| and |4 on 1|, the orientation depends on whether the logical pages are in landscape mode or in portrait mode. \end{pgflayout} @@ -265,13 +264,13 @@ select a layout using the following command: page to the physical page size. Then four black rectangles are drawn in each corner. Next, a clipping region is set up that contains all of the logical page except for little rounded - corners. Finally, the logical page is draw, clipped against the + corners. Finally, the logical page is drawn and clipped against the clipping region. Note that every logical page should fill its background for this to work. - In addition to the \meta{options} that can be given to |resize to| + In addition to the \meta{options} that can be given to |resize to|, the following options may be given. \begin{itemize} \item \declare{|corner width=|\meta{size}} specifies the size of @@ -292,7 +291,7 @@ select a layout using the following command: This layout puts two logical pages alongside each other. The second page always shows what the main page showed on the previous physical page. Thus, the second page - ``lags behind'' the main page. This can be useful when you have to + ``lags behind'' the main page. This can be useful when you have two projectors attached to your computer and can show different parts of a physical page on different projectors. @@ -302,7 +301,7 @@ select a layout using the following command: main page. This will make the physical pages twice as wide as the logical pages, but it will retain the height. \item \declare{|second left|} puts the second page left, - otherwise it behave the same as |second right|. + otherwise it behaves the same as |second right|. \item \declare{|second bottom|} puts the second page below the main page. This make the physical pages twice as high as the logical ones. @@ -335,7 +334,7 @@ command: When |\pgfpagesuselayout|\marg{layout}\oarg{options} is called, the following happens: First, the \meta{before actions} are - executed. They can be used, for example, to setup default values for + executed. They can be used, for example, to set up default values for keys. Next, |\setkeys{pgfpagesuselayoutoption}|\marg{options} is executed. Finally, the \meta{after actions} are executed. @@ -392,7 +391,7 @@ send the physical page to the output file. In reality, things are slightly more complicated. First, once a physical page has been shipped out, the logical pages are usually voided, but this need not be the case. Instead, it is possible that -certain logical page just retain their contents after the physical +certain logical pages just retain their contents after the physical page has been shipped out and these pages need not be filled once more before a physical shipout can occur. However, the contents of these logical pages can still be changed using special commands. It is also @@ -404,7 +403,7 @@ physical page and which further modifications should be done. The following two commands are used to define the layout: \begin{command}{\pgfpagesphysicalpageoptions\marg{options}} - This command sets the characteristic of the ``physical'' page. For + This command sets the characteristics of the ``physical'' page. For example, it is used to specify how many logical pages there are and how many logical pages must be accumulated before a physical page is shipped out. How each individual logical page is typeset is @@ -469,7 +468,7 @@ following two commands are used to define the layout: \meta{current} has been filled, the internal counter is incremented normally as if the logical page \meta{current} had been ``reached'' normally. If you specify a \meta{current} larger - to \meta{last}, a physical shipout will occur after the logical + than \meta{last}, a physical shipout will occur after the logical page \meta{current} has been filled. \item \declare{|physical height=|\meta{height}} @@ -577,8 +576,8 @@ following two commands are used to define the layout: \end{codeexample} \item \declare{|border shrink|=\meta{size}} - specifies an addition reduction of the size to which the page is - page is scaled down. + specifies an additional reduction of the size to which the page is + page is scaled. \item \declare{|border code|=\meta{code}}. When this option is given, the \meta{code} is executed before the @@ -591,7 +590,7 @@ following two commands are used to define the layout: You can also call |\pgfdiscardpath| and add your own path construction code (for example to paint a rectangle with rounded - corners). The coordinate system is setup in such a way that a + corners). The coordinate system is set up in such a way that a rectangle starting at the origin and having the height and width of \TeX-box 0 will result in a rectangle filling exactly the logical page currently being put on the physical page. The logical @@ -614,13 +613,13 @@ following two commands are used to define the layout: \subsection{Creating Logical Pages} -Logical pages are created whenever a \TeX\ thinks that a page is full +Logical pages are created whenever \TeX\ thinks that a page is full and performs a |\shipout| command. This will cause |pgfpages| to store the box that was supposed to be shipped out internally until enough logical pages have been collected such that a physical shipout can occur. -Normally, whenever a logical shipout occurs that current page is +Normally, whenever a logical shipout occurs, that current page is stored in logical page number \meta{current logical page}. This counter is then incremented, until it is larger than \meta{last logical shipout}. You can, however, directly change the value of diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfcalendar.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfcalendar.tex index 318c01cf384..220955bc514 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfcalendar.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfcalendar.tex @@ -108,7 +108,7 @@ This section describes the package |pgfcalendar|. set to |01| for January. The \meta{day macro} gets assigned a two-digit number representing - the day of the month (again with a possible leading zero). + the day of the month (again, possibly with a leading zero). To convert a Julian day number to an ISO-date you use code like the following: @@ -130,7 +130,7 @@ This section describes the package |pgfcalendar|. \example |\pgfcalendarjuliantoweekday{2454115}{\mycount}| sets |\mycount| to - \pgfcalendarjuliantoweekday{2454115}{\mycount}\the\mycount. + \pgfcalendarjuliantoweekday{2454115}{\mycount}\the\mycount\ (it was a Sunday). \end{command} @@ -142,8 +142,8 @@ This section describes the package |pgfcalendar|. This command is used to execute code based on properties of \meta{date}. The \meta{date} must be a date in ISO-format. For this date, the \meta{tests} are checked (to be detailed later) - and if one of the tests applied, the \meta{code} is - executed. If none of the tests applies, the \meta{else code} is + and if one of the tests succeeds, the \meta{code} is + executed. If none of the tests succeeds, the \meta{else code} is executed. \example |\pgfcalendarifdate{2007-02-07}{Wednesday}{Is a Wednesday}{Is not a Wednesday}| @@ -164,7 +164,7 @@ This section describes the package |pgfcalendar|. \itemcalendaroption{Sunday} as above. \itemcalendaroption{workday} Passed by Mondays, Tuesdays, Wednesdays, Thursdays, and Fridays. - \itemcalendaroption{weekend} Passed Saturdays and Sundays. + \itemcalendaroption{weekend} Passed by Saturdays and Sundays. \itemcalendaroption{equals}|=|\meta{reference} The \meta{reference} can be in one of two forms: Either, it is a full ISO format date like |2007-01-01| or the year may be missing as in |12-31|. In the @@ -194,7 +194,7 @@ This section describes the package |pgfcalendar|. For another example, |between=05-01 and 05-07| is true for the days of the first week of May of any year. \itemcalendaroption{day of month}|=|\meta{number} Passed by the day - of month of the \meta{date} is \meta{number}. For example, the test + of month of the \meta{date} that is \meta{number}. For example, the test |day of month=1| is passed by every first of every month. \itemcalendaroption{end of month}\opt{|=|\meta{number}} Passed by the day of month of the \meta{date} that is \meta{number} from the @@ -205,9 +205,9 @@ This section describes the package |pgfcalendar|. \end{itemize} In addition to the above checks, you can also define new checks. To - do so, you must add a new key to the key-value group |pgfcalendar| - using |\define@key|. The job of the code of this new key is to - possibly set the \TeX-if |\ifpgfcalendarmatches| to true (if it is + do so, you must add a new key to the path |/pgf/calendar/| using + the |\pgfkeys| command. The job of the + code of this new key is to possibly set the \TeX-if |\ifpgfcalendarmatches| to true (if it is already true, no action should be taken) to indicate that the \meta{date} passes the test setup by this new key. @@ -229,17 +229,17 @@ This section describes the package |pgfcalendar|. \end{itemize} For example, let us define a new key that checks whether the - \meta{date} is a Workers day (first of May). This can be done as + \meta{date} is a Workers day (May 1st). This can be done as follows: \begin{verbatim} -\define@key{pgfcalendar}{workers day}[] +\pgfkeys{/pgf/calendar/workers day/.code=% { \ifnum\pgfcalendarifdatemonth=5\relax \ifnum\pgfcalendarifdateday=1\relax \pgfcalendarmatchestrue \fi \fi -} +}} \end{verbatim} \end{command} @@ -350,7 +350,7 @@ documentation of this package for more details. \item |\pgfcalendarendjulian| Julian day number of \meta{end date}. \item |\pgfcalendarcurrentjulian| This \TeX\ count holds the - Julian day number of day currently begin rendered. + Julian day number of the day currently being rendered. \item |\pgfcalendarcurrentweekday| The weekday (a number with zero representing Monday) of the current date. \item |\pgfcalendarcurrentyear| The year of the current date. diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgffor.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgffor.tex index 9c3ef4832a8..770f0c89dc3 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgffor.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgffor.tex @@ -148,7 +148,7 @@ automatically by \tikzname, but not by \pgfname: |\foreach \x in {9,...,3.5} {\x, }| yields \foreach \x in {9,...,3.5} {\x, } - There is a yet a further special case for the |...| statement, in that + There is a yet another special case for the |...| statement, in that it can indicate an alphabetic character sequence: |\foreach \x in {a,...,m} {\x, }| yields \foreach \x in {a,...,m} {\x, } @@ -185,22 +185,26 @@ automatically by \tikzname, but not by \pgfname: \medskip \textbf{Using the foreach-statement inside paths.} - \tikzname\ allows you to use a |\foreach| statement inside a path - construction. In such a case, the \meta{commands} must be path - construction commands. Here are two examples: + \tikzname\ allows you to use |foreach| and |\foreach| (both have the + same effect) inside a path construction. In such a case, the + \meta{commands} must be path construction commands. Here are two + examples: \begin{codeexample}[] \tikz \draw (0,0) - \foreach \x in {1,...,3} + foreach \x in {1,...,3} { -- (\x,1) -- (\x,0) } ; \end{codeexample} \begin{codeexample}[] -\tikz \draw \foreach \p in {1,...,3} {(\p,1)--(\p,3) (1,\p)--(3,\p)}; +\tikz \draw foreach \p in {1,...,3} {(\p,1)--(\p,3) (1,\p)--(3,\p)}; \end{codeexample} + Note that the |node| and |pic| path commands also support the + |foreach| statement in special ways. + \medskip \textbf{Multiple variables.} You will often wish to iterate over two variables at the same @@ -238,7 +242,7 @@ automatically by \tikzname, but not by \pgfname: \begin{codeexample}[] \begin{tikzpicture} % Define some coordinates: - \path[nodes={circle,fill=examplefill,draw}] + \path[nodes={circle,fill=yellow!80!black,draw}] (0,0) node(a) {a} (2,0.55) node(b) {b} (1,1.5) node(c) {c} @@ -264,7 +268,7 @@ automatically by \tikzname, but not by \pgfname: \begin{codeexample}[] \begin{tikzpicture}[line cap=round,line width=3pt] - \filldraw [fill=examplefill] (0,0) circle (2cm); + \filldraw [fill=yellow!80!black] (0,0) circle (2cm); \foreach \angle / \label in {0/3, 30/2, 60/1, 90/12, 120/11, 150/10, 180/9, @@ -295,7 +299,7 @@ automatically by \tikzname, but not by \pgfname: The keys described below can be used in the \meta{options} argument to the |\foreach| command. They all have the path |/pgf/foreach/|, however, the path is set automatically when \meta{options} are - parsed, so it does not have to explicitly stated. + parsed, so it does not have to be explicitly stated. \begin{key}{/pgf/foreach/var=\meta{variable}} This key provides an alternative way to specify variables: @@ -304,7 +308,7 @@ automatically by \tikzname, but not by \pgfname: \end{key} \begin{key}{/pgf/foreach/evaluate=\meta{variable}| |\opt{|as |\meta{macro}| using |\meta{formula}}} - By default list items are not evaluated: |1+2|, yields |1+2|, + By default, list items are not evaluated: |1+2|, yields |1+2|, not |3|. This key allows a variable to be evaluated using the mathematical engine. The variable must have been specified either using the |var| key or in the \meta{variables} argument of the diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfkeys.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfkeys.tex index 4ce292d380d..25825dc52c7 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfkeys.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfkeys.tex @@ -147,10 +147,10 @@ executed whenever the style is executed. Here is an example: \pgfkeys{/my style/.style={/a=foo,/b=bar,/a=#1}} \pgfkeys{/my style=wow} \end{codeexample} -As the above example shows, style can also be parametrized, just like +As the above example shows, styles can also be paramaterized, just like the normal code keys. -As a typical use of styles, suppose we wish to setup the key |/tikz| +As a typical use of styles, suppose we wish to set up the key |/tikz| so that it will change the default path to |/tikz|. This can be achieved as follows: \begin{codeexample}[code only] @@ -191,7 +191,7 @@ a slash, then the default path is automatically prefixed. Note that the default path is not the same as a search path. In particular, the default path is just a single path. When a partial key is given, only this single default path is prefixed; |pgfkeys| does -not try to lookup the key in different parts of a search path. It is, +not try to look up the key in different parts of a search path. It is, however, possible to emulate search paths, but a much more complicated mechanism must be used. @@ -222,7 +222,7 @@ continue with the next subsection. \end{command} \begin{command}{\pgfkeyslet\marg{full key}\marg{macro}} - Performs a |\let| statement so the the \meta{full key} pionts to the + Performs a |\let| statement so the \meta{full key} points to the contents of \meta{macro}. \begin{codeexample}[] \def\helloworld{Hello, world!} @@ -283,13 +283,13 @@ taken. This action can be one of the following: \item A command is executed whose argument(s) are \meta{value}. This command is stored in a special subkey of \meta{key}. \item The \meta{value} is stored in the \meta{key} itself. -\item If the key's name (the part after the last slahs) is a known +\item If the key's name (the part after the last slash) is a known \emph{handler}, then this handler will take care of the key. \item If the key is totally unknown, one of several possible \emph{unknown key handlers} is called. \end{enumerate} -Addtionally, if the \meta{value} is missing, a default value may or +Additionally, if the \meta{value} is missing, a default value may or may not be substituted. Before we plunge into all the details, let us have a quick look at the command itself. @@ -329,7 +329,7 @@ let us have a quick look at the command itself. \end{command} \begin{command}{\pgfkeysalso\marg{key list}} - This command has execatly the same effect as |\pgfkeys|, only the + This command has exactly the same effect as |\pgfkeys|, only the default path is not modified before or after the keys are being set. This command is mainly intended to be called by the code that is being processed for a key. @@ -344,6 +344,149 @@ let us have a quick look at the command itself. \end{command} +\subsubsection{First Char Syntax Detection} +\label{sec:pgf:first:char:syntax} + +Usually, keys are of the form \meta{key}|=|\meta{value} and how such +keys are handled is discussed in the rest of this section. However, it +is also possible to setup a different syntax for certain parts of the +input to |\pgfkeys|. Since this is a rather advanced option, most +readers may wish to skip the following discussion upon first reading; +it is discussed here because this special syntax detection is the very +first thing that is done when a key is processed, before any of the +following operations are performed. + +The |\pgfkeys| command and its variants decompose their input into a +list of \meta{string}s that are separated by commas. By default, each +such \meta{string} must either have the form \meta{key}|=|\meta{value} +or of the form \meta{key} with the value-part missing. However, you +might wish to interpret some of these strings differently. For +instance, when a \meta{string} has the form |"|\meta{text}|"|, you +might wish the \meta{string} to be interpreted as if one had written +|label text={|\meta{text}|}|. Then, people could write +\begin{codeexample}[code only] +\myset{red, "main valve", thick} +\end{codeexample} +instead of the more cumbersome +\begin{codeexample}[code only] +\myset{red, label text=main valve, thick} +\end{codeexample} +An example where such a syntax reinterpretation is done is the +|quotes| library, which allows you to write things like +\begin{codeexample}[] +\tikz \graph { a ->["1" red] b ->["0"] c }; +\end{codeexample} +\noindent instead of the somewhat longer +\begin{codeexample}[] +\tikz \graph { a ->[edge node={node[red,auto]{1}}] b ->[edge label=0] c }; +\end{codeexample} + +In order to detect whether a \meta{string} has a special syntax, you +can request that the \emph{first character} of \meta{string} is +analysed by the key parser. If this first character matches a +character that has been flagged as a special character, the +\meta{string} is not interpreted as a usual key--value pair. Instead, +\meta{string} is passed as a parameter to a special macro that should +take care of the \meta{string}. After this macro has finished, the +parsing continues with the \meta{next string} in the list. + +In order to setup a special syntax handling for \meta{strings} that +begin with a certain character, two things need to be done: +\begin{enumerate} +\item First, the whole first char syntax detection must be ``switched + on,'' since, by default, it is turned off for efficiency reasons + (the overhead is rather small, however). This is done by setting the + following key: + \begin{key}{/handlers/first char syntax=\opt{\meta{true or false}} + (default true, initially false)} + \end{key} +\item Second, in order to handle strings starting with a certain + \meta{character} in a special way, you need to store a macro in the + following key: + \begin{key}{/handlers/first char syntax/\meta{meaning of character}} + The \meta{meaning of character} should be the text that \TeX's + command |\meaning| returns for a macro that has been |\let| to the + \meta{character}. For instance, when strings starting with |"| + should be treated in a special way, the \meta{meaning of + character} would be the string |the character "| since this is + what \TeX\ writes when you say +\begin{codeexample}[] +\let\mycharacter=" +\meaning\mycharacter +\end{codeexample} + Now, the key |/handlers/first char syntax/|\meta{meaning of + character} should be setup (using |\pgfkeyssetvalue| or using + the |.initial| handler) to store a \meta{macro name}. + + If this is the case and if \meta{string} starts with the + \meta{character} (blanks at the beginning of \meta{string} are + deleted prior to this test), then \meta{macro name} is called with + \meta{string} as its argument. + \end{key} +\end{enumerate} + +Let us now have a look at an example. We install two handlers, one for +strings starting with |"| and one for strings starting with |<|. + +\begin{codeexample}[] +\pgfkeys{ + /handlers/first char syntax=true, + /handlers/first char syntax/the character "/.initial=\myquotemacro, + /handlers/first char syntax/the character </.initial=\mypointedmacro, +} + +\def\myquotemacro#1{Quoted: #1. } +\def\mypointedmacro#1{Pointed: #1. } + +\ttfamily \pgfkeys{"foo", <bar>} +\end{codeexample} + +Naturally, in the above examples, the two handling macros did not do +something particularly exciting. In the next example, we setup a more +elaborate macro that mimics a small part the behaviour of the |quotes| +library, only for single quotes: + +\begin{codeexample}[] +\pgfkeys{ + /handlers/first char syntax=true, + /handlers/first char syntax/the character '/.initial=\mysinglequotemacro +} + +\def\mysinglequotemacro#1{\pgfkeysalso{label={#1}}} + +\tikz \node [circle, 'foo', draw] {bar}; +\end{codeexample} + +Note that in the above example, the macro |\mysinglequotemacro| gets +passed the complete string, including the single quotes. It is the job +of the macro to get rid of them, if this is necessary. + +The first char syntax detection allows you to perform rather powerful +transformations on the syntax of keys -- provided you can ``pin down'' +the syntax on the first character. In the following example, you can +write expressions in parentheses in front of a key--value pair and the +pair will only be executed when the expression evaluates to true: + +\begin{codeexample}[] +\pgfkeys{ + /handlers/first char syntax=true, + /handlers/first char syntax/the character (/.initial=\myparamacro +} + +\def\myparamacro#1{\myparaparser#1\someendtext} +\def\myparaparser(#1)#2\someendtext{ + \pgfmathparse{#1} + \ifx\pgfmathresult\onetext + \pgfkeysalso{#2} + \fi +} +\def\onetext{1} + +\foreach \i in {1,...,4} + \tikz \node [draw, thick, rectangle, (pi>\i) circle, (pi>\i*2) draw=red] {x}; +\end{codeexample} + + \subsubsection{Default Arguments} The arguments of the |\pgfkeys| command can either be of the form @@ -356,7 +499,7 @@ value is defined, it will be used as if you had written In the following, the details of how default values are determined is described; however, you should normally use the handlers |/.default| and |/.value required| as described in -Section~\ref{section-default-handlers} and you can may wish to skip +Section~\ref{section-default-handlers} and you may wish to skip the following details. When |\pgfkeys| encounters a \meta{key} without an equal-sign, the @@ -391,7 +534,7 @@ following happens: After the transformation process described in the previous subsection, we arrive at a key of the form \meta{key}=\meta{value}, where \meta{key} is a full key. Different things can now happen, but always -the macro |\pgfkeyscurrentkey| will have been setup to expand to the +the macro |\pgfkeyscurrentkey| will have been set up to expand to the text of the \meta{key} that is currently being processed. The first things that is tested is whether the key \meta{key}|/.@cmd| @@ -426,7 +569,7 @@ handlers described in Section~\ref{section-code-handlers}. \begin{command}{\pgfkeysdef\marg{key}\marg{code}} This command temporarily defines a \TeX-macro with the argument list |#1\pgfeov| and then lets \meta{key}|/.@cmd| be equal to this - macro. The net effect of all this is that you have then setup code + macro. The net effect of all this is that you have then set up code for the key \meta{key} so that when you write |\pgfkeys{|\meta{key}|=|\meta{value}|}|, then the \meta{code} is executed with all occurrences of |#1| in \meta{code} being replaced @@ -517,9 +660,9 @@ key). It decomposed into two parts: detect for the reader. \end{enumerate} -(For efficiency reasons, these two macros are only setup at this point; +(For efficiency reasons, these two macros are only set up at this point; so when code is executed for a key in the ``usual'' manner then these -macros are not setup.) +macros are not set up.) The |\pgfkeys| command now checks whether the key |/handlers/|\meta{name}|/.@cmd| exists. If so, it should store a command @@ -527,7 +670,7 @@ and this command is executed exactly in the same manner as described in Section~\ref{section-key-code}. Thus, this code gets the \meta{value} that was originally intended for \meta{key} as its argument, followed by |\pgfeov|. -It is the job of the handlers to so something useful with the +It is the job of the handlers to do something useful with the \meta{value}. For an example, let us write a handler that will output the value @@ -550,10 +693,10 @@ this key and print it. \pgfkeys{/my key/.print to log} \end{codeexample} The above code will print |Hi!| in the log, provided the macro -|\writetolog| is setup appropriately. +|\writetolog| is set up appropriately. For a more interesting handler, let us program a handler that will -setup a key so that when the key is used some code is executed. This +set up a key so that when the key is used, some code is executed. This code is given as \meta{value}. All the handler must do is to call |\pgfkeysdef| for the path of the key (which misses the handler's name) and assign the parameter value to it. @@ -655,11 +798,13 @@ There are some parameters for handled keys which prove to be useful in some (pos key handler. \end{key} + + \subsubsection{Keys That Are Unknown} \label{sec:pgf:unknown:keys} -For some keys, neither the key is defined nor its |.@cmd| subkey nor -is a handler defined for this key. In this case, it is checked whether +For some keys, neither the key, nor its |.@cmd| subkey nor +a handler is defined. In this case, it is checked whether the key \meta{current path}|/.unknown/.@cmd| exists. Thus, when you try to use the key |/tikz/strange|, then it is checked whether |/tikz/.unknown/.@cmd| exists. If this key exists (which it does), it is @@ -668,13 +813,13 @@ instance, the handler for \tikzname\ will try to interpret the key's name as a color or as an arrow specification or as a \pgfname\ option. -You can setup unknown key handlers for your own keys by simply setting +You can set up unknown key handlers for your own keys by simply setting the code of the key \meta{my path prefix}|/.unknown|. This also allows -you to setup ``search paths.'' The idea is that you would like keys to +you to set up ``search paths.'' The idea is that you would like keys to be searched not only in a single default path, but in several. Suppose, for instance, that you would like keys to be searched -for in |/a|, |/b|, and |/b/c|. We setup a key |/my search path| for +for in |/a|, |/b|, and |/b/c|. We set up a key |/my search path| for this: \begin{codeexample}[code only] \pgfkeys{/my search path/.unknown/.code= @@ -780,125 +925,6 @@ also define new ones as described in Section~\ref{section-key-handlers}. |/.is family| handler is quicker. \end{handler} -\begin{handler}{{.search also}=\marg{path list}} - A style which installs a |/.unknown| handler into \meta{key}. This - |/.unknown| handler will then search for unknown keys in every path - provided in \marg{path list}. - -\begin{codeexample}[] -% define a key: -\pgfkeys{/secondary path/option/.code={Invoking /secondary path/option with `#1'}} - -% set up a search path: -\pgfkeys{/main path/.search also={/secondary path}} - -% try searching for `option=value' in '/main path': -% -> this finds `/secondary path/option'! -\pgfkeys{/main path/.cd,option=value} -\end{codeexample} - - The |/.search also| handler follows the strategy - \begin{enumerate} - \item If a user provides a fully qualified key which could not be - found, for example the full string |/main path/option|, it assume - that the user new what he is doing -- and does \emph{not} continue - searching for |an option| in \marg{path list}. - \item If a user provides only the key's name, for example |option| - and |option| can't be found in the current default path (which is - |/main path| in our example above), the current default path is - set to the next element in \marg{path list} (which is - |/secondary path| here) and |\pgfkeys| will be restarted. - - This will be iterated until either a match has been found or all - elements in \marg{path list} have been tested. - - \item If all elements in \marg{path list} have been checked and the - key is still unknown, the fall-back handler |/handlers/.unknown| - will be invoked. - \end{enumerate} -\begin{codeexample}[] -% define a key: -\pgfkeys{/secondary path/option/.code={Invoking /secondary path/option with `#1'}} - -% set up a search path: -\pgfkeys{/main path/.search also={/secondary path}} - -% try searching for `option=value' in '/main path': -% -> this finds `/secondary path/option'! -\pgfkeys{/main path/.cd,option=value} - -% negative example: -% try searching for fully qualified key /main path/option. -% This won't be handled by .search also. -\pgfkeys{/handlers/.unknown/.code={Found unknown option \pgfkeyscurrentkeyRAW={#1}!}}% -\pgfkeys{/main path/.cd,/main path/option=value} -\end{codeexample} - - Please note that the strategy of |/.search also| is different from - the first example provided in section~\ref{sec:pgf:unknown:keys} - ``Unknown Keys'' because |/.search also| only applies only for keys - which are not fully qualified. - - - For those who are familiar with |\pgfkeys|, the actual - implementation of |/.search also| might be interesting: - \begin{enumerate} - \item |\pgfkeys{/path/.search also={/tikz}}| is equivalent to -\begin{codeexample}[code only] -\pgfkeys{/path/.unknown/.code={% - \ifpgfkeysaddeddefaultpath - % only process keys for which no full path has been - % provided: - \pgfkeyssuccessfalse - \let\pgfkeys@searchalso@name =\pgfkeyscurrentkeyRAW - \ifpgfkeyssuccess - \else - % search with /tikz as default path: - \pgfqkeys{/tikz}{\pgfkeys@searchalso@name={#1}}% - \fi - \else - \def\pgfutilnext{\pgfkeysvalueof {/handlers/.unknown/.@cmd}#1\pgfeov}% - \pgfutilnext - \fi - } -} -\end{codeexample} - \item |\pgfkeys{/path/.search also={/tikz,/pgf}}| is equivalent to -\begin{codeexample}[code only] -\pgfkeys{/path/.unknown/.code={% - \ifpgfkeysaddeddefaultpath - \pgfkeyssuccessfalse - \let\pgfkeys@searchalso@name=\pgfkeyscurrentkeyRAW - \ifpgfkeyssuccess - \else - % step 1: search in /tikz with .try: - \pgfqkeys{/tikz}{\pgfkeys@searchalso@name/.try={#1}}% - \fi - \ifpgfkeyssuccess - \else - % step 2: search in /pgf (without .try!): - \pgfqkeys{/pgf}{\pgfkeys@searchalso@name={#1}}% - \fi - \else - \def\pgfutilnext{\pgfkeysvalueof {/handlers/.unknown/.@cmd}#1\pgfeov}% - \pgfutilnext - \fi - } -} -\end{codeexample} - \end{enumerate} - - To also enable searching for styles (or other handled keys), - consider changing the configuration for handled keys to - |/hander config=full or existing| when you use |/.search also|, - that is, use -\begin{codeexample}[code only] -\pgfkeys{ - /main path/.search also={/secondary path}, - /handler config=full or existing} -\end{codeexample} -\end{handler} - \subsubsection{Setting Defaults} @@ -1079,7 +1105,7 @@ key list. Thus, a style ``stands for'' a certain key value list. Styles can be parameterized just like normal code. \begin{handler}{{.style}|=|\meta{key list}} - This handler set things up so that whenever \meta{key}|=|\meta{value} is + This handler sets things up so that whenever \meta{key}|=|\meta{value} is encountered in a key list, then the \meta{key list}, with every occurrence of |#1| replaced by \meta{value}, is processed instead. As always, if no \meta{value} is given, the default @@ -1176,8 +1202,8 @@ For styles the corresponding handlers as for normal code exist: For some keys, the code that should be executed for them is rather ``specialized.'' For instance, it happens often that the code for a -key just sets a certain \TeX-if to true or false. For these case -predefine handlers make it easier to install the necessary code. +key just sets a certain \TeX-if to true or false. For these cases, +predefined handlers make it easier to install the necessary code. However, we start with some handlers that are used to manage the value that is directly stored in a key. @@ -1196,7 +1222,7 @@ that is directly stored in a key. % "/my key" now stores the value "blue" \end{codeexample} - Note that in the after the example, writing |\pgfkeys{/my key}| will not + Note that with this configuration, writing |\pgfkeys{/my key}| will not have the effect you might expect (namely that |blue| is inserted into the main text). Rather, |/my key| will be promoted to |/my key=\pgfkeysnovalue| and, thus, |\pgfkeysnovalue| will be @@ -1300,7 +1326,7 @@ The next handler deals with the problem when a handler is useful. \begin{handler}{{.is choice}} - This handler set things up so that writing \meta{key}|=|\meta{value} + This handler sets things up so that writing \meta{key}|=|\meta{value} will cause the subkey \meta{key}|/|\meta{value} to be executed. So, each of the different possible choices should be given by a subkey of \meta{key}. @@ -1327,7 +1353,7 @@ can even use things like |#1| or unbalanced \TeX-ifs inside expanded before it is used. For instance, \meta{value} might be a macro name like |\mymacro| and you do not want |\mymacro| to be used as the macro, but rather the \emph{contents} of |\mymacro|. Thus, -instead of using \meta{value} you wish to use whatever \meta{value} +instead of using \meta{value}, you wish to use whatever \meta{value} expands to. Instead of using some fancy |\expandafter| hackery, you can use the following handlers: @@ -1384,6 +1410,148 @@ Key 4:& \pgfkeys{/key4} \end{codeexample} \end{handler} + + +\subsubsection{Handlers for Forwarding} + +\begin{handler}{{.forward to}|=|\meta{another key}} + This handler causes the \meta{key} to ``forward'' its argument to + \meta{another key}. When the \meta{key} is used, its normal code + will be executed first. Then, the value is (additionally) passed to + \meta{another key}. If the \meta{key} has not yet been defined prior + to the use of |.forward to|, it will be defined then (and do nothing by + itself, expect for forwarding it to \meta{key name}). The + \meta{another key} must be a fully qualified key name. +\begin{codeexample}[] +\pgfkeys{ + /a/.code=(a:#1), + /b/.code=(b:#1), + /b/.forward to=/a, + /c/.forward to=/a +} +\pgfkeys{/b=1} \pgfkeys{/c=2} +\end{codeexample} +\end{handler} + + +\begin{handler}{{.search also}=\marg{path list}} + A style which installs a |/.unknown| handler into \meta{key}. This + |/.unknown| handler will then search for unknown keys in every path + provided in \marg{path list}. + +\begin{codeexample}[] +% define a key: +\pgfkeys{/secondary path/option/.code={Invoking /secondary path/option with `#1'}} + +% set up a search path: +\pgfkeys{/main path/.search also={/secondary path}} + +% try searching for `option=value' in '/main path': +% -> this finds `/secondary path/option'! +\pgfkeys{/main path/.cd,option=value} +\end{codeexample} + + The |/.search also| handler follows the strategy + \begin{enumerate} + \item If a user provides a fully qualified key which could not be + found, for example the full string |/main path/option|, it assume + that the user knew what she is doing -- and does \emph{not} continue + searching for |an option| in \marg{path list}. + \item If a user provides only the key's name, for example |option| + and |option| cannot be found in the current default path (which is + |/main path| in our example above), the current default path is + set to the next element in \marg{path list} (which is + |/secondary path| here) and |\pgfkeys| will be restarted. + + This will be iterated until either a match has been found or all + elements in \marg{path list} have been tested. + \item If all elements in \marg{path list} have been checked and the + key is still unknown, the fall-back handler |/handlers/.unknown| + will be invoked. + \end{enumerate} +\begin{codeexample}[] +% define a key: +\pgfkeys{/secondary path/option/.code={Invoking /secondary path/option with `#1'}} + +% set up a search path: +\pgfkeys{/main path/.search also={/secondary path}} + +% try searching for `option=value' in '/main path': +% -> this finds `/secondary path/option'! +\pgfkeys{/main path/.cd,option=value} + +% negative example: +% try searching for fully qualified key /main path/option. +% This won't be handled by .search also. +\pgfkeys{/handlers/.unknown/.code={Found unknown option \pgfkeyscurrentkeyRAW={#1}!}}% +\pgfkeys{/main path/.cd,/main path/option=value} +\end{codeexample} + + Please note that the strategy of |/.search also| is different from + the first example provided in section~\ref{sec:pgf:unknown:keys} + ``Unknown Keys'' because |/.search also| only applies to keys + that are not fully qualified. + + For those who are familiar with |\pgfkeys|, the actual + implementation of |/.search also| might be interesting: + \begin{enumerate} + \item |\pgfkeys{/path/.search also={/tikz}}| is equivalent to +\begin{codeexample}[code only] +\pgfkeys{/path/.unknown/.code={% + \ifpgfkeysaddeddefaultpath + % only process keys for which no full path has been + % provided: + \pgfkeyssuccessfalse + \let\pgfkeys@searchalso@name =\pgfkeyscurrentkeyRAW + \ifpgfkeyssuccess + \else + % search with /tikz as default path: + \pgfqkeys{/tikz}{\pgfkeys@searchalso@name={#1}}% + \fi + \else + \def\pgfutilnext{\pgfkeysvalueof {/handlers/.unknown/.@cmd}#1\pgfeov}% + \pgfutilnext + \fi + } +} +\end{codeexample} + \item |\pgfkeys{/path/.search also={/tikz,/pgf}}| is equivalent to +\begin{codeexample}[code only] +\pgfkeys{/path/.unknown/.code={% + \ifpgfkeysaddeddefaultpath + \pgfkeyssuccessfalse + \let\pgfkeys@searchalso@name=\pgfkeyscurrentkeyRAW + \ifpgfkeyssuccess + \else + % step 1: search in /tikz with .try: + \pgfqkeys{/tikz}{\pgfkeys@searchalso@name/.try={#1}}% + \fi + \ifpgfkeyssuccess + \else + % step 2: search in /pgf (without .try!): + \pgfqkeys{/pgf}{\pgfkeys@searchalso@name={#1}}% + \fi + \else + \def\pgfutilnext{\pgfkeysvalueof {/handlers/.unknown/.@cmd}#1\pgfeov}% + \pgfutilnext + \fi + } +} +\end{codeexample} + \end{enumerate} + + To also enable searching for styles (or other handled keys), + consider changing the configuration for handled keys to + |/hander config=full or existing| when you use |/.search also|, + that is, use +\begin{codeexample}[code only] +\pgfkeys{ + /main path/.search also={/secondary path}, + /handler config=full or existing} +\end{codeexample} +\end{handler} + + \subsubsection{Handlers for Testing Keys} \begin{handler}{{.try}|=|\meta{value}} @@ -1416,7 +1584,7 @@ Key 4:& \pgfkeys{/key4} \end{handler} \begin{handler}{{.lastretry}|=|\meta{value}} - This handler works like |/.retry|, only it will invoke the usual handlers for unknowns keys if |\||ifpgfkeyssuccess| is false. Thus, this handlers will only try to set a key if ``the last attempt failed''. Furthermore, this here is the last such attempt. + This handler works like |/.retry|, only it will invoke the usual handlers for unknowns keys if |\||ifpgfkeyssuccess| is false. Thus, this handler will only try to set a key if ``the last attempt failed''. Furthermore, this here is the last such attempt. \end{handler} @@ -1468,13 +1636,13 @@ language currently set so that users get a localized error message. \end{key} \begin{key}{/errors/boolean expected=\marg{offending key}\marg{value}} - This key is executed whenever a key setup using |/.is if| gets called + This key is executed whenever a key set up using |/.is if| gets called with a \meta{value} other than |true| or |false|. \end{key} \begin{key}{/errors/unknown choice value=\marg{offending key}\marg{value}} This key is executed whenever a choice is used as a \meta{value} for - a key setup using the |/.is choice| handler that is not defined. + a key set up using the |/.is choice| handler that is not defined. \end{key} \begin{key}{/errors/unknown key=\marg{offending key}\marg{value}} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfkeysfiltered.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfkeysfiltered.tex index b5c7e260432..be115418442 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfkeysfiltered.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfkeysfiltered.tex @@ -115,7 +115,7 @@ Remaining: `\remainingoptions'. \end{command} \begin{handler}{{.install key filter}|=|\meta{optional arguments}} - This handler install a key filter. A key filter is a command key which sets the \TeX-boolean |\ifpgfkeysfiltercontinue|, that means a key with existing `|/.@cmd|' suffix. A simple example is a key filter which returns always true: + This handler installs a key filter. A key filter is a command key which sets the \TeX-boolean |\ifpgfkeysfiltercontinue|, that means a key with existing `|/.@cmd|' suffix. A simple example is a key filter which returns always true: \begin{codeexample}[code only] \pgfkeys{/foo/bar/true key filter/.code={\pgfkeysfiltercontinuetrue}} \pgfkeys{/foo/bar/true key filter/.install key filter} @@ -126,7 +126,7 @@ Remaining: `\remainingoptions'. \pgfkeysfiltered{/my group/A1=a1, /my group/A2=a2, /my group/B=b, /my group/C=c, /tikz/color=blue, /my group/A3=a3} \end{codeexample} - If a key filter requires more than one argument, you need to provide the complete argument listing in braces like |{{first}{second}}|. + If a key filter requires more than one argument, you need to provide the complete argument list in braces like |{{first}{second}}|. You can also use |\pgfkeysinstallkeyfilter|\meta{full key}\meta{optional arguments}, it has the same effect. @@ -167,7 +167,7 @@ Remaining options: `\remainingoptions'. \subsubsection{Family Support} -\pgfname supports a family concept: every option can be associated with (at most) one family. Families form loose key groups which are independent of the key hierarchy. For example, |/my tree/key1| can belong to family |/tikz|. +\pgfname{} supports a family concept: every option can be associated with (at most) one family. Families form loose key groups which are independent of the key hierarchy. For example, |/my tree/key1| can belong to family |/tikz|. It is possible to `activate' or `deactivate' single families. Furthermore, it is possible to set only keys which belong to active families using appropriate key filter handlers. @@ -265,7 +265,7 @@ The family support is fast: if there are $N$ options in a key-value-list and the \subsubsection{Other Key Filters} There are some more key filters which have nothing to do with family handling. \begin{key}{/pgf/key filters/is descendant of=\marg{path}} - Install this key filter to process only options belonging to the key tree \marg{path}. It returns true for every key which has key path \marg{path}. It also returns true for any unknown key, that means unknown keys are processed using the standard unknown handlers of \pgfname. + Install this key filter to process only options belonging to the key tree \meta{path}. It returns true for every key whose key path is equal to \meta{path}. It also returns true for any unknown key, that means unknown keys are processed using the standard unknown handlers of \pgfname. \begin{codeexample}[] \pgfkeys{ /group 1/A/.code={(A:#1)}, @@ -326,7 +326,7 @@ There are some more key filters which have nothing to do with family handling. \subsubsection{Programmer Interface} \label{section-key-filter-api}% \begin{plainenvironment}{{pgfkeysinterruptkeyfilter}}% - Temporarily disables key filtering inside of the environment. If key filtering is not active, this has no effect at all. + Temporarily disables key filtering inside the environment. If key filtering is not active, this has no effect at all. Please note that no \TeX-group is introduced. \end{plainenvironment} @@ -351,11 +351,11 @@ switch the key filter. \end{command} \begin{command}{\pgfkeysdeactivatefamily\marg{family name}}% - Equivalent to |\pgfkeys{|\meta{family name}|/.dactivate family}|. + Equivalent to |\pgfkeys{|\meta{family name}|/.deactivate family}|. \end{command} \begin{command}{\pgfkeysactivatefamilies\marg{family list}\marg{deactivate macro name}}% - Activates each family in \meta{family list} and creates a macro \meta{deactivate macro name} which de-activates each family in \meta{family list}. + Activates each family in \meta{family list} and creates a macro \meta{deactivate macro name} which deactivates each family in \meta{family list}. \begin{codeexample}[code only] \pgfkeysactivatefamilies{/family 1,/family 2,/family 3}{\deactivatename} \pgfkeysfiltered{foo,bar} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-commands.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-commands.tex index 3739db4d83b..7030e1f96ac 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-commands.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-commands.tex @@ -12,6 +12,7 @@ \makeatletter + \subsection{Beginning and Ending a Stream of System Commands} A ``user'' of the \pgfname\ system layer (like the basic layer or a @@ -33,13 +34,13 @@ command. \begin{command}{\pgfsys@beginpicture} Called at the beginning of a |{pgfpicture}|. This command should - ``setup things.'' + ``set up things.'' Most drivers will need to implement this command. \end{command} \begin{command}{\pgfsys@endpicture} - Called at the end of a pgfpicture. + Called at the end of a |{pgfpicture}|. Most drivers will need to implement this command. \end{command} @@ -101,6 +102,19 @@ force. For this escaping, the following command is used: implementation, where a \TeX-translation makes no sense. \end{command} +\begin{command}{\pgfsys@pictureboxsynced\marg{box number}} + Basically, this should do the same as doing a (scoped) low level sync + followed by inserting the box \meta{box number} directly into the + output stream. However, the default implementation uses + |\pgfsys@hboxsynced| in conjunction with |\pgfsys@beginpicture| to + ensure that, if possible, hyperlinks survive in + \textsc{pdf}s. Drivers that are sensitive to picture-in-picture + scopes should replace this implementation by +\begin{codeexample}[code only] +\pgfsys@beginscope\pgflowlevelsynccm\box#1\pgfsys@endscope +\end{codeexample} +\end{command} + \subsection{Path Construction System Commands} @@ -139,7 +153,7 @@ force. For this escaping, the following command is used: \begin{command}{\pgfsys@curveto\marg{$x_1$}\marg{$y_1$}\marg{$x_2$}\marg{$y_2$}\marg{$x_3$}\marg{$y_3$}} Continue the current path to $(x_3,y_3)$ - with a Bézier curve that has the two control points $(x_1,y_1)$ and $(x_2,y_2)$. + with a B\'ezier curve that has the two control points $(x_1,y_1)$ and $(x_2,y_2)$. \example Draw a good approximation of a quarter circle: \begin{codeexample}[code only] @@ -429,14 +443,13 @@ force. For this escaping, the following command is used: \begin{command}{\pgfsys@setdash\marg{pattern}\marg{phase}} Sets the dashing patter. \meta{pattern} should be a list of \TeX\ - dimensions lengths separated by commas. \meta{phase} should be a + dimensions separated by commas. \meta{phase} should be a single dimension. \example |\pgfsys@setdash{3pt,3pt}{0pt}| The list of values in \meta{pattern} is used to determine the - lengths of the ``on'' phases of the dashing and of the ``off'' - phases. For example, if \meta{pattern} is |3bp,4bp|, then the dashing + lengths of the ``on'' and ``off'' phases of the dashing. For example, if \meta{pattern} is |3bp,4bp|, then the dashing pattern is ``3bp on followed by 4bp off, followed by 3bp on, followed by 4bp off, and so on.'' A pattern of |.5pt,4pt,3pt,1.5pt| means ``.5pt on, 4pt off, 3pt on, 1.5pt off, .5pt on, \dots'' If the @@ -508,20 +521,20 @@ whenever a stroking or a filling operation is done. \begin{command}{\pgfsys@color@cmyk\marg{cyan}\marg{magenta}\marg{yellow}\marg{black}} Sets the color used for stroking and filling operations to the given - cymk tuple (numbers between 0 and 1). + cmyk tuple (numbers between 0 and 1). This command is protocolled, see Section~\ref{section-protocols}. \end{command} \begin{command}{\pgfsys@color@cmyk@stroke\marg{cyan}\marg{magenta}\marg{yellow}\marg{black}} - Sets the color used for stroking operations to the given cymk tuple + Sets the color used for stroking operations to the given cmyk tuple (numbers between 0 and 1). This command is protocolled, see Section~\ref{section-protocols}. \end{command} \begin{command}{\pgfsys@color@cmyk@fill\marg{cyan}\marg{magenta}\marg{yellow}\marg{black}} - Sets the color used for filling operations to the given cymk tuple + Sets the color used for filling operations to the given cmyk tuple (numbers between 0 and 1). This command is protocolled, see Section~\ref{section-protocols}. @@ -529,20 +542,20 @@ whenever a stroking or a filling operation is done. \begin{command}{\pgfsys@color@cmy\marg{cyan}\marg{magenta}\marg{yellow}} Sets the color used for stroking and filling operations to the given - cymk tuple (numbers between 0 and 1). + cmy tuple (numbers between 0 and 1). This command is protocolled, see Section~\ref{section-protocols}. \end{command} \begin{command}{\pgfsys@color@cmy@stroke\marg{cyan}\marg{magenta}\marg{yellow}} - Sets the color used for stroking operations to the given cymk tuple + Sets the color used for stroking operations to the given cmy tuple (numbers between 0 and 1). This command is protocolled, see Section~\ref{section-protocols}. \end{command} \begin{command}{\pgfsys@color@cmy@fill\marg{cyan}\marg{magenta}\marg{yellow}} - Sets the color used for filling operations to the given cymk tuple + Sets the color used for filling operations to the given cmy tuple (numbers between 0 and 1). This command is protocolled, see Section~\ref{section-protocols}. @@ -718,7 +731,7 @@ The system layer provides some commands for image inclusion. If this macro and also the height macro are empty, the image should have its ``natural'' size. - If exactly only of them is specified, the undefined value the + If only one of them is specified, the undefined value the image is scaled so that the aspect ratio is kept. If both are set, the image is scaled in both directions @@ -743,7 +756,7 @@ The system layer provides some commands for image inclusion. interpolated in \pdf. \end{itemize} - The command should now setup the macro |\pgf@image| such that calling + The command should now set up the macro |\pgf@image| such that calling this macro will result in typesetting the image. Thus, |\pgf@image| is the ``return value'' of the command. @@ -784,7 +797,7 @@ The system layer provides some commands for image inclusion. \begin{command}{\pgfsys@radialshading\marg{name}\marg{starting point}\marg{specification}} Declares a radial shading. Like the previous macros, this command - should setup the macro |\@pgfshading|\meta{name}|!|, which upon + should set up the macro |\@pgfshading|\meta{name}|!|, which upon invocation should insert a radial shading whose size is implicit in \meta{specification}. @@ -797,22 +810,22 @@ The system layer provides some commands for image inclusion. corner}\meta{upper right corner}\marg{type 4 function}} Declares a shading using a PostScript-like function that provides a color for each point. Like the previous macros, this command - should setup the macro |\@pgfshading|\meta{name}|!| so that it will + should set up the macro |\@pgfshading|\meta{name}|!| so that it will produce a box containing the desired shading. Parameter \meta{name} is the name of the shading. Parameter \meta{type 4 function} is a Postscript-like function (type 4 function of the PDF specification) - as described in Section 3.9.4 of the PDF Specification version 1.7. + as described in Section 3.9.4 of the PDF specification version 1.7. Parameters \meta{lower left corner} and \meta{upper right corner} are \pgfname\ points that specifies the lower left and upper right - corners of the shading. + corners of the shading, respectively. When \meta{type 4 function} is evaluated, the coordinate of the current point will be on the (virtual) PostScript stack in bp units. After the function has been evaluated, the stack should consist of three numbers (not integers! -- the Apple PDF renderer is broken in this - regard, so add cvr's at the end if needed) that represent the red, + regard, so add cvrs at the end if needed) that represent the red, green, and blue components of the color. A buggy function will result is \emph{totally unpredictable chaos} during @@ -831,8 +844,13 @@ The system layer provides some commands for image inclusion. Sets the opacity of filling operations. \end{command} +\begin{command}{\pgfsys@blend@mode\marg{value}} + Sets the blend mode, see Section 7.2.4 of the \textsc{pdf} + Specification, Version 1.7. +\end{command} + \begin{command}{\pgfsys@transparencygroupfrombox\marg{box}} - This takes a TeX box and converts it into a transparency + This takes a \TeX\ box and converts it into a transparency group. This means that any transparency settings apply to the box as a whole. For instance, if a box contains two overlapping black circles and you draw the box and, thus, the two circles normally @@ -841,9 +859,29 @@ The system layer provides some commands for image inclusion. group, the overlap will get the same color as the rest. \end{command} +A transparency group can be \emph{isolated} and/or a \emph{knockout} +group (see Sections 7.3.4 and 7.3.5 of the \textsc{pdf} +Specification Version 1.7). Which of these is the case is dictated +by the current settings of the following two ifs, which must be set +before the above command is called: + +{\let\ifpgfsys@transparency@group@isolated=\relax +\begin{command}{\ifpgfsys@transparency@group@isolated} + Determines whether a transparency group should be isolated. +\end{command} +} + +{\let\ifpgfsys@transparency@group@knockout=\relax +\begin{command}{\ifpgfsys@transparency@group@knockout} + Determines whether a transparency group is a knockout group or not. +\end{command} +} + + + \begin{command}{\pgfsys@fadingfrombox\marg{name}\marg{box}} Declares the fading \meta{name}. The \meta{box} is a \TeX-box. Its - contents luminosity determines the opacity of the resulting + content's luminosity determines the opacity of the resulting fading. This means that the lighter a pixel inside the box, the more opaque the fading will be at this position. \end{command} @@ -950,11 +988,47 @@ commands do not open a graphics scope and can be opened and closed \end{command} + +\subsection{Page Size Commands} + +The following commands can be used to set the page size of a document +in a ``portable'' way. Note, however, that many packages also (try to) +set the page size. + +These commands are typically not given inside a |{pgfpicture}|, but on +the outer level of compilation. + +\begin{command}{\pgfsys@papersize\marg{width}\marg{height}} + Inserts the necessary |\special|s for the current driver into the + output stream to ``locally'' change the page size. Whether such a + ``local'' change is possible depends strongly on the driver. For + instance, |dvips| will honor the first call to this command that is + part of the shipped-out document and will ignore all other uses. In + contrast, |pdftex| will use the current value of the paper size for + each page and, additionally, setting the papersize is local to the + current \TeX\ group. +\end{command} + +\begin{command}{\pgfsys@global@papersize\marg{width}\marg{height}} + Like the previous command, only for drivers where setting the paper + size parameters is a \TeX-group-local operation, |\global| is + prefixed to the setting of the page sizes. +\end{command} + +\begin{command}{\pgfsys@thepageheight} + This macro expands to the current page's height, provided \LaTeX\ is + used, otherwise a best guess is returned (currently just |\the\vsize|). +\end{command} + +\begin{command}{\pgfsys@thepagewidth} + As above. +\end{command} + \subsection{Position Tracking Commands} The following commands are used to determine the position of text on a page. This is a rather complicated process in general since at the -moment when the text is read by \TeX\ the final position cannot be +moment when the text is read by \TeX, the final position cannot be determined, yet. For example, the text might be put in a box which is later put in the headline or perhaps in the footline or perhaps even on a different page. @@ -963,7 +1037,7 @@ For these reasons, position tracking is typically a two-stage process. In a first stage you indicate that a certain position is of interest by \emph{marking} it. This will (depending on the details of the backend driver) cause page coordinates or this position to be -written to a |.aux| file when the page is shipped. Possibly, the +written to an |.aux| file when the page is shipped. Possibly, the position might also be determined at an even later stage. Then, on a second run of \TeX, the position is read from the |.aux| file and can be used. @@ -981,7 +1055,7 @@ The value of $x$ is \pgfsys@markposition{here}important. \begin{command}{\pgfsys@getposition\marg{name}\marg{macro}} This command retrieves a position that has been marked on an earlier run of \TeX\ on the current file. The \meta{macro} must be a macro - name such as |\mymarco|. It will redefined such that it is + name such as |\mymacro|. It will be redefined such that it is \begin{itemize} \item either just |\relax| or \item a |\pgfpoint...| command. @@ -1002,7 +1076,7 @@ The value of $x$ is \pgfsys@markposition{here}important. |pgfpageorigin|. By shifting all positions by the amount returned by this call you can position things absolutely on a page. - \example Referencing a point or the page: + \example Referencing a point of the page: \begin{codeexample}[code only] The value of $x$ is \pgfsys@markposition{here}important. diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-overview.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-overview.tex index e2ec6f4e8ef..93951723868 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-overview.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-overview.tex @@ -25,7 +25,7 @@ higher layers should never use |\special| commands directly or even check whether |\pdfoutput| is defined. Instead, all drawing requests should be ``channeled'' through the system commands. -The system layer is loaded and setup by the following package: +The system layer is loaded and set up by the following package: \begin{package}{pgfsys} This file provides ``default implementations'' of all system @@ -36,8 +36,8 @@ The system layer is loaded and setup by the following package: called \emph{driver files} in the following. When |pgfsys.sty| is loaded, it will try to determine which driver - is used by loading |pgf.cfg|. This file should setup the macro - |\pgfsysdriver| appropriately. The, |pgfsys.sty| will input the + is used by loading |pgf.cfg|. This file should set up the macro + |\pgfsysdriver| appropriately. The |pgfsys.sty| will input the appropriate |pgfsys-|\meta{drivername}|.sty|. \end{package} @@ -50,7 +50,7 @@ The system layer is loaded and setup by the following package: \end{command} \begin{filedescription}{pgf.cfg} - This file should setup the command |\pgfsysdriver| correctly. If + This file should set up the command |\pgfsysdriver| correctly. If |\pgfsysdriver| is already set to some value, the driver normally should not change it. Otherwise, it should make a ``good guess'' at which driver will be appropriate. diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-paths.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-paths.tex index 8cf776ca3dd..a59b203b28d 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-paths.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-paths.tex @@ -28,7 +28,7 @@ the sense that they are not implemented in driver files, but rather directly by the \pgfname-system layer. For this reason, the commands for creating soft paths do not start with |\pgfsys@|, but rather with |\pgfsyssoftpath@|. On the other hand, as a user you will never use -these commands directly, so they are described as part of the +these commands directly, they are described as part of the low-level interface. @@ -48,7 +48,7 @@ quite a lot happens behind the scenes: \pgfusepath{stroke} \end{codeexample} \item - The |\pgfpathxxxx| command do \emph{not} directly call ``hard'' + The |\pgfpathxxxx| commands do \emph{not} directly call ``hard'' commands like |\pgfsys@xxxx|. Instead, the command |\pgfpathmoveto| invokes a special command called |\pgfsyssoftpath@moveto| and |\pgfpathlineto| invokes |\pgfsyssoftpath@lineto|. @@ -121,7 +121,7 @@ it. current soft path is \emph{not changed} by this command. Thus, in order to start a new soft path after the old one has been invoked and is no longer needed, you need to set the current soft path to be - empty. This may seems strange, but it is often useful to immediately + empty. This may seem strange, but it is often useful to immediately use the last soft path again. \end{command} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-protocol.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-protocol.tex index e46a31e0247..dcd21793278 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-protocol.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-protocol.tex @@ -40,7 +40,7 @@ require special |\special|'s and cannot be protocolled. \begin{command}{\pgfsysprotocol@literalbuffered\marg{literal text}} Adds the \meta{literal text} to the current protocol, after it has - been ``|\edef|ed.'' This command will always protocol. + been ``|\edef|ed.'' This command will always be protocolled. \end{command} \begin{command}{\pgfsysprotocol@literal\marg{literal text}} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-actions.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-actions.tex index c80846dcd85..bb201599575 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-actions.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-actions.tex @@ -55,8 +55,8 @@ all have the same effect: \filldraw (0,0) circle (1cm); \end{codeexample} -In the following subsection the different actions are explained that -can be performed on a path. The following commands are abbreviations for +In the following subsection the different actions that +can be performed on a path are explained. The following commands are abbreviations for certain sets of actions, but for many useful combinations there are no abbreviations: @@ -174,7 +174,7 @@ You can draw a path using the following option: Although this option is normally used on paths to indicate that the path should be drawn, it also makes sense to use the option with a |{scope}| or |{tikzpicture}| environment. However, this will - \emph{not} cause all path to drawn. Instead, this just sets the + \emph{not} cause all paths to be drawn. Instead, this just sets the \meta{color} to be used for drawing paths inside the environment. \begin{codeexample}[] @@ -187,7 +187,7 @@ You can draw a path using the following option: The following subsections list the different options that influence how a path is drawn. All of these options only have an effect if the -|draw| options is given (directly or indirectly). +|draw| option is given (directly or indirectly). \subsubsection{Graphic Parameters: Line Width, Line Cap, and Line Join} @@ -255,6 +255,8 @@ styles. \end{stylekey} +\label{section-line-cap} + \begin{key}{/tikz/line cap=\meta{type} (initially butt)} Specifies how lines ``end.'' Permissible \meta{type} are |round|, |rect|, and |butt|. They have the following effects: @@ -281,7 +283,7 @@ styles. \draw[line join=round] (0,0) -- ++(.5,1) -- ++(.5,-1); \draw[line join=bevel] (1.25,0) -- ++(.5,1) -- ++(.5,-1); \draw[line join=miter] (2.5,0) -- ++(.5,1) -- ++(.5,-1); - \useasboundingbox (0,1.5); % make bounding box bigger + \useasboundingbox (0,1.5); % enlarge bounding box \end{tikzpicture} \end{codeexample} @@ -389,52 +391,52 @@ dashing conveniently. \end{stylekey} -\begin{stylekey}{/tikz/dashdotted} +\begin{stylekey}{/tikz/dash dot} Shorthand for setting a dashed and dotted dash pattern. \begin{codeexample}[] -\tikz \draw[dashdotted] (0pt,0pt) -- (50pt,0pt); +\tikz \draw[dash dot] (0pt,0pt) -- (50pt,0pt); \end{codeexample} \end{stylekey} -\begin{stylekey}{/tikz/densely dashdotted} +\begin{stylekey}{/tikz/densely dash dot} Shorthand for setting a densely dashed and dotted dash pattern. \begin{codeexample}[] -\tikz \draw[densely dashdotted] (0pt,0pt) -- (50pt,0pt); +\tikz \draw[densely dash dot] (0pt,0pt) -- (50pt,0pt); \end{codeexample} \end{stylekey} -\begin{stylekey}{/tikz/loosely dashdotted} +\begin{stylekey}{/tikz/loosely dash dot} Shorthand for setting a loosely dashed and dotted dash pattern. \begin{codeexample}[] -\tikz \draw[loosely dashdotted] (0pt,0pt) -- (50pt,0pt); +\tikz \draw[loosely dash dot] (0pt,0pt) -- (50pt,0pt); \end{codeexample} \end{stylekey} -\begin{stylekey}{/tikz/dashdotdotted} +\begin{stylekey}{/tikz/dash dot dot} Shorthand for setting a dashed and dotted dash pattern with more dots. \begin{codeexample}[] -\tikz \draw[dashdotdotted] (0pt,0pt) -- (50pt,0pt); +\tikz \draw[dash dot dot] (0pt,0pt) -- (50pt,0pt); \end{codeexample} \end{stylekey} -\begin{stylekey}{/tikz/densely dashdotdotted} +\begin{stylekey}{/tikz/densely dash dot dot} Shorthand for setting a densely dashed and dotted dash pattern with more dots. \begin{codeexample}[] -\tikz \draw[densely dashdotdotted] (0pt,0pt) -- (50pt,0pt); +\tikz \draw[densely dash dot dot] (0pt,0pt) -- (50pt,0pt); \end{codeexample} \end{stylekey} -\begin{stylekey}{/tikz/loosely dashdotdotted} +\begin{stylekey}{/tikz/loosely dash dot dot} Shorthand for setting a loosely dashed and dotted dash pattern with more dots. \begin{codeexample}[] -\tikz \draw[loosely dashdotdotted] (0pt,0pt) -- (50pt,0pt); +\tikz \draw[loosely dash dot dot] (0pt,0pt) -- (50pt,0pt); \end{codeexample} \end{stylekey} @@ -442,130 +444,13 @@ dashing conveniently. \subsubsection{Graphic Parameters: Draw Opacity} When a line is drawn, it will normally ``obscure'' everything behind -it as if you has used perfectly opaque ink. It is also possible to ask +it as if you had used perfectly opaque ink. It is also possible to ask \tikzname\ to use an ink that is a little bit (or a big bit) transparent using the |draw opacity| option. This is explained in Section~\ref{section-tikz-transparency} on transparency in more detail. -\subsubsection{Graphic Parameters: Arrow Tips} - -When you draw a line, you can add arrow tips at the ends. It is -only possible to add one arrow tip at the start and one at the end. If -the path consists of several segments, only the last segment gets -arrow tips. The behavior for paths that are closed is not specified -and may change in the future. - -\begin{key}{/tikz/arrows=\meta{start arrow kind}|-|\meta{end arrow kind}} - This option sets the start and end arrow tips (an empty value as in |->| - indicates that no arrow tip should be drawn at the start).% - \indexoption{arrows} - - \emph{Note: Since the arrow option is so often used, you can leave - out the text |arrows=|.} What happens is that every option that - contains a |-| is interpreted as an arrow specification. - -\begin{codeexample}[] -\begin{tikzpicture} - \draw[->] (0,0) -- (1,0); - \draw[o-stealth] (0,0.3) -- (1,0.3); -\end{tikzpicture} -\end{codeexample} - - The permissible values are all predefined arrow tips, though - you can also define new arrow tip kinds as explained in - Section~\ref{section-arrows}. This is often necessary to obtain - ``double'' arrow tips and arrow tips that have a fixed size. You - need to load the |arrows| library if you need arrow tips other than - the default ones, see Section~\ref{section-library-arrows}. - - One arrow tip kind is special: |>| (and all arrow tip kinds containing the - arrow tip kind such as |<<| or \verb!>|!). This arrow tip type is not - fixed. Rather, you can redefine it using the |>=| option, see - below. - - \example You can also combine arrow tip types as in -\begin{codeexample}[] -\begin{tikzpicture}[thick] - \draw[to reversed-to] (0,0) .. controls +(.5,0) and +(-.5,-.5) .. +(1.5,1); - \draw[[-latex reversed] (1,0) .. controls +(.5,0) and +(-.5,-.5) .. +(1.5,1); - \draw[latex-)] (2,0) .. controls +(.5,0) and +(-.5,-.5) .. +(1.5,1); - \useasboundingbox (-.1,-.1) rectangle (3.1,1.1); % make bounding box bigger -\end{tikzpicture} -\end{codeexample} -\end{key} - -\begin{key}{/tikz/>=\meta{end arrow kind}} - This option can be used to redefine the ``standard'' arrow tip |>|. The - idea is that different people have different ideas what arrow tip kind - should normally be used. I prefer the arrow tip of \TeX's |\to| command - (which is used in things like $f\colon A \to B$). Other people will - prefer \LaTeX's standard arrow tip, which looks like this: \tikz - \draw[-latex] (0,0) -- (10pt,1ex);. Since the arrow tip kind |>| is - certainly the most ``natural'' one to use, it is kept free of any - predefined meaning. Instead, you can change it by saying |>=to| to - set the ``standard'' arrow tip kind to \TeX's arrow tip, whereas |>=latex| - will set it to \LaTeX's arrow tip and |>=stealth| will use a - \textsc{pstricks}-like arrow tip. - - Apart from redefining the arrow tip kind |>| (and |<| for the start), - this option also redefines the following arrow tip kinds: |>| and |<| as - the swapped version of \meta{end arrow kind}, |<<| and |>>| as - doubled versions, |>>| and |<<| as swapped doubled versions, %>> - and \verb!|<! and \verb!>|! as arrow tips ending with a vertical bar. - -\begin{codeexample}[] -\begin{tikzpicture}[scale=2] - \begin{scope}[>=latex] - \draw[->] (0pt,6ex) -- (1cm,6ex); - \draw[>->>] (0pt,5ex) -- (1cm,5ex); - \draw[|<->|] (0pt,4ex) -- (1cm,4ex); - \end{scope} - \begin{scope}[>=diamond] - \draw[->] (0pt,2ex) -- (1cm,2ex); - \draw[>->>] (0pt,1ex) -- (1cm,1ex); - \draw[|<->|] (0pt,0ex) -- (1cm,0ex); - \end{scope} -\end{tikzpicture} -\end{codeexample} -% << -\end{key} - -\begin{key}{/tikz/shorten >=\meta{dimension} (initially 0pt)} - This option will shorten the end of lines by the given - \meta{dimension}. If you specify an arrow tip, lines are already - shortened a bit such that the arrow tip touches the specified endpoint - and does not ``protrude over'' this point. Here is an example: - -\begin{codeexample}[] -\begin{tikzpicture}[line width=20pt] - \useasboundingbox (0,-1.5) rectangle (3.5,1.5); - \draw[red] (0,0) -- (3,0); - \draw[gray,->] (0,0) -- (3,0); -\end{tikzpicture} -\end{codeexample} - - The |shorten >| option allows you to shorten the end on the line - \emph{additionally} by the given distance. This option can also be - useful if you have not specified an arrow tip at all. - -\begin{codeexample}[] -\begin{tikzpicture}[line width=20pt] - \useasboundingbox (0,-1.5) rectangle (3.5,1.5); - \draw[red] (0,0) -- (3,0); - \draw[-to,shorten >=10pt,gray] (0,0) -- (3,0); -\end{tikzpicture} -\end{codeexample} -\end{key} - - -\begin{key}{/tikz/shorten <=\meta{dimension}} - Works like |shorten >|, but for the start. -\end{key} - - - \subsubsection{Graphic Parameters: Double Lines and Bordered Lines} \begin{key}{/tikz/double=\meta{core color} (default white)} @@ -612,7 +497,7 @@ and may change in the future. \begin{key}{/tikz/double distance between line centers=\meta{dimension}} This option works like |double distance|, only the distance is not - the distance between (inner) borders of the two main lines, ut + the distance between (inner) borders of the two main lines, but between their centers. Thus, the thickness the \emph{first} time the path is drawn is the normal line width plus the given \meta{dimension}, while the line width of the @@ -653,7 +538,35 @@ and may change in the future. +\subsection{Adding Arrow Tips to a Path} +\label{section-arrow-tip-action} + +In different situations, \tikzname\ will add arrow tips to the end of +a path. For this to happen, a number of different things need to be +specified: + +\begin{enumerate} +\item You must have used the |arrows| key, explained in detail in + Section~\ref{section-tikz-arrows}, to setup which kinds of arrow + tips you would like. +\item The path may not be closed (like a circle or a rectangle) and, + if it consists of several subpath, further restrictions apply as + explained in Section~\ref{section-tikz-arrows}. +\item The |tips| key must be set to an appropriate value, see + Section~\ref{section-tikz-arrows} once more. +\end{enumerate} +For the current section on paths, it is only important that when you +add the |tips| option to a path that is not drawn, arrow tips will +still be added at the beginning and at the end of the current +path. This is true even when ``only'' arrow tips get drawn for a path +without drawing the path itself. Here is an example: +\begin{codeexample}[width=2cm] +\tikz \path[tips, -{Latex[open,length=10pt,bend]}] (0,0) to[bend left] (1,0); +\end{codeexample} +\begin{codeexample}[width=2cm] +\tikz \draw[tips, -{Latex[open,length=10pt,bend]}] (0,0) to[bend left] (1,0); +\end{codeexample} \subsection{Filling a Path} @@ -692,7 +605,7 @@ To fill a path, use the following option: area because of the thickness of the ``pen.'' \begin{codeexample}[] -\begin{tikzpicture}[fill=examplefill,line width=5pt] +\begin{tikzpicture}[fill=yellow!80!black,line width=5pt] \filldraw (0,0) -- (1,1) -- (2,1); \filldraw (4,0) circle (.5cm) (4.5,0) circle (.5cm); \filldraw[even odd rule] (6,0) circle (.5cm) (6.5,0) circle (.5cm); @@ -722,7 +635,7 @@ is used the current \emph{pattern color} is used as its color. Patterns are not overly flexible. In particular, it is not possible to change the size or orientation of a pattern without declaring a new -pattern. For complicated case, it may be easier to use two nested +pattern. For complicated cases, it may be easier to use two nested |\foreach| statements to simulate a pattern, but patterns are rendered \emph{much} more quickly than simulated ones. @@ -788,7 +701,7 @@ should be determined: \begin{codeexample}[] \begin{tikzpicture} - \filldraw[fill=examplefill] + \filldraw[fill=yellow!80!black] % Clockwise rectangle (0,0) -- (0,1) -- (1,1) -- (1,0) -- cycle % Counter-clockwise rectangle @@ -800,7 +713,7 @@ should be determined: \draw[->] (0.5,0.5) -- +(0,1) node[above] {crossings: $-1+1 = 0$}; \begin{scope}[yshift=-3cm] - \filldraw[fill=examplefill] + \filldraw[fill=yellow!80!black] % Clockwise rectangle (0,0) -- (0,1) -- (1,1) -- (1,0) -- cycle % Clockwise rectangle @@ -829,7 +742,7 @@ should be determined: \begin{codeexample}[] \begin{tikzpicture} - \filldraw[fill=examplefill,even odd rule] + \filldraw[fill=yellow!80!black,even odd rule] (0,0) rectangle (1,1) (0.5,0.5) circle (0.4cm); \draw[->] (0.5,0.5) -- +(0,1) [above] node{crossings: $1+1 = 2$}; \end{tikzpicture} @@ -841,8 +754,7 @@ should be determined: \subsubsection{Graphic Parameters: Fill Opacity} \label{section-fill-opacity} -Analogously to the |draw opacity|, you can also set the filling -opacity. Please see Section~\ref{section-tikz-transparency} for more +Analogously to the |draw opacity|, you can also set the fill opacity. Please see Section~\ref{section-tikz-transparency} for more details. @@ -866,13 +778,10 @@ this process much easier: and, possibly, the path is stroked, provided the |draw| option has been given. - As with other keys like |fill| or |draw| this option needs to be - given on a path, setting the |path picture| outside a path has not - effect (the path picture is cleared at the beginning of each path). + As with other keys like |fill| or |draw| this option needs to be given on a path, setting the |path picture| outside a path has no effect (the path picture is cleared at the beginning of each path). The \meta{code} can be any normal \tikzname\ code like |\draw ...| - or |\node ...|. As always, when you include an external graphic you - need to put it inside a |\node|. + or |\node ...|. As always, when you include an external graphic, you need to put it inside a |\node|. Note that no special actions are taken to transform the origin in any way. This means that the coordinate |(0,0)| is still where is @@ -969,7 +878,7 @@ is drawn, scaled and shifted such that all parts of the path are filled. The default shading is a smooth transition from gray -to white and from above to bottom. However, other shadings are also +to white and from top to bottom. However, other shadings are also possible, for example a shading that will sweep a color from the center to the corners outward. To choose the shading, you can use the |shading=| option, which will also automatically invoke the |shade| @@ -991,7 +900,7 @@ needed, which are explained below. To change the color of a shading, special options are needed like |left color|, which sets the color of an axis shading from left to - right. These options implicitly also select the right shading type, + right. These options implicitly also select the correct shading type, see the following example \begin{codeexample}[] \tikz \shadedraw [left color=red,right color=blue] @@ -1066,7 +975,7 @@ right of picture. \end{codeexample} Note: If this option is used on a path inside a \TeX\ group (scope), - the effect ``lasts'' only till the end of the scope. Again, this + the effect ``lasts'' only until the end of the scope. Again, this behavior is the same as for clipping. @@ -1260,7 +1169,7 @@ with a color, then repaint the path with a pattern and then repaint it with yet another pattern. In such cases you can use the following two options: -\begin{key}{/tikz/preactions=\meta{options}} +\begin{key}{/tikz/preaction=\meta{options}} This option can be given to a |\path| command (or to derived commands like |\draw| which internally call |\path|). Similarly to options like |draw|, this option only has an effect when given to a @@ -1415,7 +1324,7 @@ options: Before a path is used, it is possible to first ``decorate'' and/or ``morph'' it. Morphing means that the path is replaced by another path -that slightly varied. Such morphings are a special case +that is slightly varied. Such morphings are a special case of the more general ``decorations'' described in detail in Section~\ref{section-tikz-decorations}. For instance, in the following example the path is drawn twice: Once normally and then in a morphed diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-arrows.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-arrows.tex new file mode 100644 index 00000000000..6e6f87da9c8 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-arrows.tex @@ -0,0 +1,2585 @@ +% Copyright 2006 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\section{Arrows} +\label{section-tikz-arrows} + + +\subsection{Overview} + +\tikzname\ allows you to add (multiple) arrow tips to the end of +lines as in \tikz [baseline] \draw [->>]%<< +(0,.5ex) -- (3ex,.5ex); or in \tikz [baseline] \draw [-{Latex[]}] +(0,.5ex) -- (3ex,.5ex);. It is possible to change which arrow tips are +used ``on-the-fly,'' you can have several arrow tips in a row, and you +can change the appearance of each of them individually using a special +syntax. The following example is a perhaps slightly ``excessive'' +demonstration of what you can do (you need to load the |arrows.meta| +library for it to work): +\begin{codeexample}[] +\tikz { + \node [circle,draw] (A) {A}; + \node [circle,draw] (B) [right=of A] {B}; + + \draw [draw = blue, thick, + arrows={ + Computer Modern Rightarrow [sep] + - Latex[blue!50,length=8pt,bend,line width=0pt] + Stealth[length=8pt,open,bend,sep]}] + (A) edge [bend left=45] (B) + (B) edge [in=-110, out=-70,looseness=8] (B); +} +\end{codeexample} + +There are a number of predefined generic arrow tip kinds whose +appearance you can modify in many ways using various options. It is +also possible to define completely new arrow tip kinds, see +Section~\ref{section-arrows}, but doing this is somewhat harder than +configuring an existing kind (it is like the difference between using +a font at different sizes or faces like italics, compared to +designing a new font yourself). + +In the present section, we go over the various ways in which you can +configure which particular arrow tips are \emph{used.} The glorious +details of how new arrow tips can be defined are explained in +Section~\ref{section-arrows}. + +At the end of the present section, Section~\ref{section-arrows-meta}, +you will find a description of the different predefined arrow tips +from the |arrows.meta| library. + +\emph{Remark:} Almost all of the features described in the following +were introduced in version 3.0 of \tikzname. For compatibility +reasons, the old arrow tips are still available. To differentiate +between the old and new arrow tips, the following rule is used: The +new, more powerful arrow tips start with an uppercase letter as in +|Latex|, compared to the old arrow tip |latex|. + +\emph{Remark:} The libraries |arrows| and |arrows.spaced| are +deprecated. Use |arrows.meta| instead/additionally, which allows you +to do all that the old libraries offered, plus much more. However, the +old libraries still work and you can even mix old and new arrow tips +(only, the old arrow tips cannot be configured in the ways described +in the rest of this section; saying |scale=2| for a |latex| arrow has +no effect for instance, while for |Latex| arrows it doubles their size +as one would expect.) + + +\subsection{Where and When Arrow Tips Are Placed} +\label{section-arrow-tips-where} + +In order to add arrow tips to the lines you draw, the following +conditions must be met: + +\begin{enumerate} +\item You have specified that arrow tips should be added to + lines, using the |arrows| key or its short form. +\item You set the |tips| key to some value that causes tips to be + drawn (to be explained later). +\item You do not use the |clip| key (directly or indirectly) with the + current path. +\item The path actually has two ``end points'' (it is not + ``closed''). +\end{enumerate} + +Let us start with an introduction to the basics of the |arrows| key: + +\begin{key}{/tikz/arrows=\meta{start arrow specification}|-|\meta{end + arrow specification}} + This option sets the arrow tip(s) to be used at the start and end of + lines. An empty value as in |->| for the start indicates that no + arrow tip should be drawn at the start.% + \indexoption{arrows} + + \emph{Note: Since the arrow option is so often used, you can leave + out the text |arrows=|.} What happens is that every (otherwise + unknown) option that contains a |-| is interpreted as an arrow specification. + +\begin{codeexample}[] +\begin{tikzpicture} + \draw[->] (0,0) -- (1,0); + \draw[>-Stealth] (0,0.3) -- (1,0.3); +\end{tikzpicture} +\end{codeexample} + + In the above example, the first start specification is empty and the + second is |>|. The end specifications are |>| for the first line and + |Stealth| for the second line. Note that it makes a difference + whether |>| is used in a start specification or in an end + specification: In an end specification it creates, as one would + expect, a pointed tip at the end of the line. In the start + specification, however, it creates a ``reversed'' version if this + arrow -- which happens to be what one would expect here. + + The above specifications are very simple and only select a single + arrow tip without any special configuration options, resulting in + the ``natural'' versions of these arrow tips. It is also possible to + ``configure'' arrow tips in many different ways, as explained in + detail in Section~\ref{section-arrow-config} below by adding options + in square brackets following the arrow tip kind: + +\begin{codeexample}[] +\begin{tikzpicture} + \draw[-{Stealth[red]}] (0,0) -- (1,0); +\end{tikzpicture} +\end{codeexample} + + Note that in the example I had to surround the end specification by + braces. This is necessary so that \tikzname\ does not mistake the + closing square bracket of the |Stealth| arrow tip's options for the + end of the options of the |\draw| command. In general, you often + need to add braces when specifying arrow tips except for simple case + like |->| or |<<->|, which are pretty frequent, though. When in + doubt, say |arrows={|\meta{start spec}|-|\meta{end spec}|}|, that + will always work. + + It is also possible to specify multiple (different) arrow tips in a + row inside a specification, see Section~\ref{section-arrow-spec} + below for details. +\end{key} + +As was pointed out earlier, to add arrow tips to a path, the path must +have ``end points'' and not be ``closed'' -- otherwise adding arrow +tips makes little sense, after all. However, a path can actually +consist of several subpath, which may be open or not and may even +consist of only a single point (a single move-to). In this case, it is +not immediately obvious, where arrow heads should be placed. The +actual rules that \tikzname\ uses are goverened by the setting of the +key |tips|: + +\begin{key}{/pgf/tips=\meta{value} (default true, initially on draw)} + \keyalias{tikz} + + This key governs in what situations arrow tips are added to a + path. The following \meta{values} are permissible: + \begin{itemize} + \item |true| (the value used when no \meta{value} is specified) + \item |proper| + \item |on draw| (the initial value, if the key has not yet been used + at all) + \item |on proper draw| + \item |never| or |false| (same effect) + \end{itemize} + + Firstly, there are a whole bunch of situations where the setting of + these (or other) options causes no arrow tips to be shown: + \begin{itemize} + \item If no arrow tips have been specified (for instance, by having + said |arrows=-|), no arrow tips are drawn. + \item If the |clip| option is set, no arrow tips are drawn. + \item If |tips| has been set to |never| or |false|, no arrow tips are drawn. + \item If |tips| has been set to |on draw| or |on proper draw|, but + the |draw| option is not set, no arrow tips are drawn. + \item If the path is empty (as in |\path ;|), no arrow tips are drawn. + \item If at least one of the subpaths of a path is closed (|cycle| is + used somewhere or something like |circle| or |rectangle|), arrow + tips are never drawn anywhere -- even if there are open subpaths. + \end{itemize} + + Now, if we pass all of the above tests, we must have a closer look + at the path. All its subpaths must now be open and there must be at + least one subpath. We conside the last one. Arrow tips will only be + added to this last subpath. + + \begin{enumerate} + \item If this last subpath not degenerate (all coordinates on the + subpath are the same as in a single ``move-to'' |\path (0,0);| or + in a ``move-to'' followed by a ``line-to'' to the same position as + in |\path (1,2) -- (1,2)|), arrow tips are added to this last + subpath now. + \item If the last subpath is degenerate, we add arrow tips pointing + upward at the single coordinate mentioned in the path, but only + for |tips| begin set to |true| or to |on draw| -- and not for + |proper| nor for |on proper draw|. In other words, ``proper'' + suppresses arrow tips on degenerate paths. + \end{enumerate} + +\begin{codeexample}[] +% No path, no arrow tips: +\tikz [<->] \draw; +\end{codeexample} +\begin{codeexample}[] +% Degenerate path, draw arrow tips (but no path, it is degenerate...) +\tikz [<->] \draw (0,0); +\end{codeexample} +\begin{codeexample}[] +% Degenerate path, tips=proper suppresses arrows +\tikz [<->] \draw [tips=proper] (0,0); +\end{codeexample} +\begin{codeexample}[] +% Normal case: +\tikz [<->] \draw (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[] +% Two subpaths, only second gets tips +\tikz [<->] \draw (0,0) -- (1,0) (2,0) -- (3,0); +\end{codeexample} +\begin{codeexample}[] +% Two subpaths, second degenerate, but still gets tips +\tikz [<->] \draw (0,0) -- (1,0) (2,0); +\end{codeexample} +\begin{codeexample}[] +% Two subpaths, second degenerate, proper suppresses them +\tikz [<->] \draw [tips=on proper draw] (0,0) -- (1,0) (2,0); +\end{codeexample} +\begin{codeexample}[] +% Two subpaths, but one is closed: No tips, even though last subpath is open +\tikz [<->] \draw (0,0) circle[radius=2pt] (2,0) -- (3,0); +\end{codeexample} +\end{key} + +One common pitfall when arrow tips are added to a path should be +addressed right here at the beginning: When \tikzname\ positions an +arrow tip at the start, for all its computations it only takes into +account the first segment of the subpath to which the arrow tip is +added. This ``first segment'' is the first line-to or curve-to operation (or arc +or parabola or a similar operation) of the path; but note that +decorations like |snake| will add many small line segments to +paths. The important point +is that if this first segment is very small, namely smaller that the +arrow tip itself, strange things may result. As will be explained in +Section~\ref{section-arrow-flex}, \tikzname\ will modify the path by +shortening the first segment and shortening a segment below its length +may result in strange effects. Similarly, for tips at the end of a +subpath, only the last segment is considered. + +The bottom line is that wherever an arrow tip is added to a path, the +line segment where it is added should be ``long enough.'' + + + + +\subsection{Arrow Keys: Configuring the Appearance of a Single Arrow Tip} +\label{section-arrow-config} + +For standard arrow tip kinds, like |Stealth| or |Latex| or |Bar|, +you can easily change their size, aspect ratio, color, and other +parameters. This is similar to selecting a font face from a font +family: \emph{``This text''} is not just typeset in the font +``Computer Modern,'' but rather in ``Computer Modern, italic face, +11pt size, medium weight, black color, no underline, \dots'' +Similarly, an arrow tip is not just a ``Stealth'' arrow tip, but +rather a ``Stealth arrow tip at its natural size, flexing, but not +bending along the path, miter line caps, draw and fill colors +identical to the path draw color, \dots'' + +Just as most programs make it easy to ``configure'' which font should +be used at a certain point in a text, \tikzname\ tries to make it easy +to specify which configuration of an arrow tip should be used. You use +\emph{arrow keys}, where a certain parameter like the |length| of an +arrow is set to a given value using the standard key--value +syntax. You can provide several arrow keys following an arrow tip kind +in an arrow tip specification as in +|Stealth[length=4pt,width=2pt]|. + +While selecting a font may be easy, \emph{designing} a new font is a +highly creative and difficult process and more often than not, not all +faces of a font are available on any given system. The difficulties +involved in designing a new arrow tip are somewhat similar to designing a new +letter for a font and, thus, it may also happen that not all +configuration options are actually implemented for a given arrow +tip. Naturally, for the standard arrow tips, all configuration options +are available -- but for special-purpose arrow tips it may well happen +that an arrow tip kind simply ``ignores'' some of the configurations +given by you. + +Some of the keys explained in the following are defined in the library +|arrows.meta|, others are always available. This has to do with the +question of whether the arrow key needs to be supported directly in the +\pgfname\ core or not. In general, the following explanations assume +that |arrows.meta| has been loaded. + + +\subsubsection{Size} + +The most important configuration parameter of an arrow tip is +undoubtedly its size. The following two keys are the main keys that +are important in this context: + +\begin{key}{/pgf/arrow keys/length=\meta{dimension}| |\opt{\meta{line width factor}}% + | |\opt{\meta{outer factor}}} + \label{length-arrow-key}% + This parameter is usually the most important parameter that governs + the size of an arrow tip: The \meta{dimension} that you provide + dictates the distance from the ``very tip'' of the arrow to its + ``back end'' along the line: +\begin{codeexample}[] +\tikz{ + \draw [-{Stealth[length=5mm]}] (0,0) -- (2,0); + \draw [|<->|] (1.5,.4) -- node[above=1mm] {5mm} (2,.4); +} +\end{codeexample} +\begin{codeexample}[] +\tikz{ + \draw [-{Latex[length=5mm]}] (0,0) -- (2,0); + \draw [|<->|] (1.5,.4) -- node[above=1mm] {5mm} (2,.4); +} +\end{codeexample} +\begin{codeexample}[] +\tikz{ + \draw [-{Classical TikZ Rightarrow[length=5mm]}] (0,0) -- (2,0); + \draw [|<->|] (1.5,.6) -- node[above=1mm] {5mm} (2,.6); +} +\end{codeexample} + + \medskip + \noindent \textbf{The Line Width Factors.} + Following the \meta{dimension}, you may put a space followed by a + \meta{line width factor}, which must be a plain number (no |pt| or + |cm| following). When you provide such a number, the size of the + arrow tip is not just \meta{dimension}, but rather $\meta{dimension} + + \meta{line width factor}\cdot w$ where + $w$ is the width of the to-be-drawn path. This + makes it easy to vary the size of an arrow tip in accordance with + the line width -- usually a very good idea since thicker lines will + need thicker arrow tips. + + As an example, when you write |length=0pt 5|, the length of the + arrow will be exactly five times the current line width. As another + example, the default length of a |Latex| arrow is + |length=3pt 4.5 0.8|. Let us ignore the 0.8 for a moment; the + |4pt 4.5| then means that for the standard line width of + |0.4pt|, the length of a |Latex| arrow will be exactly 4.8pt (3pt + plus 4.5 times |0.4pt|). + + Following the line width factor, you can additionally provide an + \meta{outer factor}, again preceded by a space (the |0.8| in the + above example). This factor is + taken into consideration only when the |double| option is used, that + is, when a so-called ``inner line width''. For a double line, we can + identify three different ``line widths'', namely the inner line + width $w_i$, the line width $w_o$ of the two outer lines, and the + ``total line width'' $w_t = w_i + 2w_o$. In the below examples, we + have $w_i = 3\mathrm{pt}$, $w_o=1\mathrm{pt}$, and $w_t = + 5\mathrm{pt}$. It is not immediately clear + which of these line widths should be considered as $w$ in the above + formula $\meta{dimension} + \meta{line width factor}\cdot w$ for the + computation of the length. One can argue both for $w_t$ and also for + $w_o$. Because of this, you use the \meta{outer factor} to + decide on one of them or even + mix them: \tikzname\ sets $w = \meta{outer factor} w_o + + (1-\meta{outer factor})w_t$. Thus, when the outer factor is $0$, as + in the first of the following examples and as is the default when it + is not specified, the computed $w$ will be the total + line width $w_t = 5\mathrm{pt}$. Since + $w=5\mathrm{pt}$, we get a total length of $15pt$ in the first + example (because of the factor |3|). In contrast, in the last + example, the outer factor is 1 and, thus, $w = w_o = \mathrm{1pt}$ and the + resulting length is 3pt. Finally, for the middle case, the ``middle'' between 5pt and + 1pt is 3pt, so the length is 9pt. +\begin{codeexample}[] +\tikz \draw [line width=1pt, double distance=3pt, + arrows = {-Latex[length=0pt 3 0]}] (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[] +\tikz \draw [line width=1pt, double distance=3pt, + arrows = {-Latex[length=0pt 3 .5]}] (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[] +\tikz \draw [line width=1pt, double distance=3pt, + arrows = {-Latex[length=0pt 3 1]} ] (0,0) -- (1,0); +\end{codeexample} + + \medskip + \noindent \textbf{The Exact Length.} + For an arrow tip kind that is just an outline that is filled with a + color, the specified length should \emph{exactly} equal the distance + from the tip to the back end. However, when the arrow tip is drawn + by stroking a line, it is no longer obvious whether the |length| + should refer to the extend of the stroked lines' path or of the + resulting pixels (which will be wider because of the thickness of + the stroking pen). The rules are as follows: + \begin{enumerate} + \item If the arrow tip consists of a closed path (like |Stealth| or + |Latex|), imagine the arrow tip drawn from left to right using a + miter line cap. Then the |length| should be the horizontal + distance from the first drawn ``pixel'' to the last drawn + ``pixel''. Thus, the thickness of the stroked line and also the + miter ends should be taken into account: +\begin{codeexample}[] +\tikz{ + \draw [line width=1mm, -{Stealth[length=10mm, open]}] + (0,0) -- (2,0); + \draw [|<->|] (2,.6) -- node[above=1mm] {10mm} ++(-10mm,0); +} +\end{codeexample} + \item If, in the above case, the arrow is drawn using a round line + join (see Section~\ref{section-arrow-key-caps} for details on how + to select this), the size of the arrow should still be the same as + in the first case (that is, as if a miter join were used). This + creates some ``visual consistency'' if the two modes are mixed or + if you later one change the mode. +\begin{codeexample}[] +\tikz{ + \draw [line width=1mm, -{Stealth[length=10mm, open, round]}] + (0,0) -- (2,0); + \draw [|<->|] (2,.6) -- node[above=1mm] {10mm} ++(-10mm,0); +} +\end{codeexample} + As the above example shows, however, a rounded arrow will still + exactly ``tip'' the point where the line should end (the point + |(2,0)| in the above case). It is only the scaling of the arrow + that is not affected. + \end{enumerate} +\end{key} + +\begin{key}{/pgf/arrow keys/width=\meta{dimension}| |\opt{\meta{line width factor}}% + | |\opt{\meta{outer factor}}} + This key works line the |length| key, only it specifies the + ``width'' of the arrow tip; so if width and length are identical, the + arrow will just touch the borders of a square. (An exception to this + rule are ``halved'' arrow tips, see + Section~\ref{section-arrow-key-harpoon}.) The meaning of the two + optional factor numbers following the \meta{dimension} is the same + as for the |length| key. +\begin{codeexample}[] +\tikz \draw [arrows = {-Latex[width=10pt, length=10pt]}] (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[] +\tikz \draw [arrows = {-Latex[width=0pt 10, length=10pt]}] (0,0) -- (1,0); +\end{codeexample} +\end{key} + +\begin{key}{/pgf/arrow keys/width'=\meta{dimension}| |\opt{\meta{length + factor}| |\opt{\meta{line width factor}}}} + The key (note the prime) has a similar effect as the |width| + key. The difference is that the second, still optional paraemter + \meta{length factor} specifies the width of the key not as a + multiple of the line width, but as a multiple of the arrow length. + + The idea is that if you write, say, |width'=0pt 0.5|, the width of + the arrow will be half its length. Indeed, for standard arrow tips + like |Stealth| the default width is specified in this way so that if + you change the length of an arrow tip, you also change the width in + such a way that the aspect ratio of the arrow tip is kept. The other + way round, if you modify the factor in |width'| without changing the + length, you change the aspect ratio of the arrow tip. + + Note that later changes of the length are taken into account for the + computation. For instance, if you write +\begin{codeexample}[code only] +length = 10pt, width'=5pt 2, length=7pt +\end{codeexample} + the resulting width will be $19\mathrm{pt} = 5\mathrm{pt} + 2\cdot + 7\mathrm{pt}$. + +\begin{codeexample}[] +\tikz \draw [arrows = {-Latex[width'=0pt .5, length=10pt]}] (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[] +\tikz \draw [arrows = {-Latex[width'=0pt .5, length=15pt]}] (0,0) -- (1,0); +\end{codeexample} + The third, also optional, parameter allows you to add a multiple of + the line width to the value computed in terms of the length. +\end{key} + + +\begin{key}{/pgf/arrow keys/inset=\meta{dimension}| |\opt{\meta{line width factor}}% + | |\opt{\meta{outer factor}}} + The key is relevant only for some arrow tips such as the |Stealth| + arrow tip. It specifies a distance by which something inside the + arrow tip is set inwards; for the |Stealth| arrow tip it is the + distance by which the back angle is moved inwards. + + The computation of the distance works in the same way as for + |length| and |width|: To the \meta{dimension} we add \meta{line + width factor} times that line width, where the line width is + computed based on the \meta{outer factor} as described for the + |length| key. +\begin{codeexample}[] +\tikz \draw [arrows = {-Stealth[length=10pt, inset=5pt]}] (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[] +\tikz \draw [arrows = {-Stealth[length=10pt, inset=2pt]}] (0,0) -- (1,0); +\end{codeexample} + + For most arrows for which there is no ``natural inset'' like, say, + |Latex|, this key has no effect. +\end{key} + + +\begin{key}{/pgf/arrow keys/inset'=\meta{dimension}| |\opt{\meta{length factor}}| |\opt{\meta{line width factor}}} + This key works like |inset|, only like |width'| the second parameter + is a factor of the arrow length rather than of the line width. For + instance, the |Stealth| arrow sets |inset'| to |0pt 0.325| to ensure + that the inset is always at $13/40$th of the arrow length if nothing + else is specified. +\end{key} + + + +\begin{key}{/pgf/arrow keys/angle=\meta{angle}|:|\meta{dimension}% + | |\opt{\meta{line width factor}}% + | |\opt{\meta{outer factor}}} + This key sets the |length| and the |width| of an arrow tip at the + same time. The lenght will be the cosine of \meta{angle}, while the + width will be twice the sine of half the \meta{angle} (this slightly + awkward rule ensures that a |Stealth| arrow will have an opening + angle of \meta{angle} at its tip if this option is used). As for the + |length| key, if the optional factors are given, they add a certain + multiple of the line width to the \meta{dimension} before the sine + and cosines are computed. +\begin{codeexample}[] +\tikz \draw [arrows = {-Stealth[inset=0pt, angle=90:10pt]}] (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[] +\tikz \draw [arrows = {-Stealth[inset=0pt, angle=30:10pt]}] (0,0) -- (1,0); +\end{codeexample} +\end{key} + + +\begin{key}{/pgf/arrow keys/angle'=\meta{angle}} + Sets the width of the arrow to twice the tangent of $\meta{angle}/2$ + times the arrow length. This results in an arrow tip with an opening + angle of \meta{angle} at its tip and with the specified |length| + unchanged. +\begin{codeexample}[] +\tikz \draw [arrows = {-Stealth[inset=0pt, length=10pt, angle'=90]}] + (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[] +\tikz \draw [arrows = {-Stealth[inset=0pt, length=10pt, angle'=30]}] + (0,0) -- (1,0); +\end{codeexample} +\end{key} + + +\subsubsection{Scaling} + +In the previous section we saw that there are many options for getting +``fine control'' overt the length and width of arrow tips. However, in +some cases, you do not really care whether the arrow tip is 4pt long +or 4.2pt long, you ``just want it to be a little bit larger than +usual.'' In such cases, the following keys are useful: + +\begin{key}{/pgf/arrows keys/scale=\meta{factor} (initially 1)} + After all the other options listed in the previous (and also the + following sections) have been processed, \tikzname\ applies a + \emph{scaling} to the computed length, inset, and width of the arrow + tip (and, possibly, to other size parameters defined by + special-purpose arrow tip kinds). Everything is simply scaled by the + given \meta{factor}. +\begin{codeexample}[] +\tikz { + \draw [arrows = {-Stealth[]}] (0,1) -- (1,1); + \draw [arrows = {-Stealth[scale=1.5]}] (0,0.5) -- (1,0.5); + \draw [arrows = {-Stealth[scale=2]}] (0,0) -- (1,0); +} +\end{codeexample} + Note that scaling has \emph{no} effect on the line width (as usual) + and also not on the arrow padding (the |sep|). +\end{key} + +You can get even more fine-grained control over scaling using the +following keys (the |scale| key is just a shorthand for setting both +of the following keys simultaneously): + +\begin{key}{/pgf/arrows keys/scale length=\meta{factor} (initially 1)} + This factor works like |scale|, only it is applied only to + dimensions ``along the axis of the arrow,'' that is, to the length + and to the inset, but not to the width. +\begin{codeexample}[] +\tikz { + \draw [arrows = {-Stealth[]}] (0,1) -- (1,1); + \draw [arrows = {-Stealth[scale length=1.5]}] (0,0.5) -- (1,0.5); + \draw [arrows = {-Stealth[scale length=2]}] (0,0) -- (1,0); +} +\end{codeexample} +\end{key} + +\begin{key}{/pgf/arrows keys/scale width=\meta{factor} (initially 1)} + Like |scale length|, but for dimensions related to the width. +\begin{codeexample}[] +\tikz { + \draw [arrows = {-Stealth[]}] (0,1) -- (1,1); + \draw [arrows = {-Stealth[scale width=1.5]}] (0,0.5) -- (1,0.5); + \draw [arrows = {-Stealth[scale width=2]}] (0,0) -- (1,0); +} +\end{codeexample} +\end{key} + + +\subsubsection{Arc Angles} + +A few arrow tips consist mainly of arcs, whose length can be +specified. For these arrow tips, you use the following key: + +\begin{key}{/pgf/arrow keys/arc=\meta{degrees} (initially 180)} + Sets the angle of arcs in arrows to \meta{degrees}. Note that this key + is quite different from the |angle| key, which is ``just a + fancy way of setting the length and width.'' In contrast, the |arc| + key is used to set the degrees of arcs that are part of an arrow + tip: +\begin{codeexample}[] +\tikz [ultra thick] { + \draw [arrows = {-Hooks[]}] (0,1) -- (1,1); + \draw [arrows = {-Hooks[arc=90]}] (0,0.5) -- (1,0.5); + \draw [arrows = {-Hooks[arc=270]}] (0,0) -- (1,0); +} +\end{codeexample} +\end{key} + + +\subsubsection{Slanting} + +You can ``slant'' arrow tips using the following key: + +\begin{key}{/pgf/arrow keys/slant=\meta{factor} (initially 0)} + Slanting is used to create an ``italics'' effect for arrow tips: All + arrow tips get ``slanted'' a little bit relative to the axis of the + arrow: +\begin{codeexample}[] +\tikz { + \draw [arrows = {->[]}] (0,1) -- (1,1); + \draw [arrows = {->[slant=.5]}] (0,0.5) -- (1,0.5); + \draw [arrows = {->[slant=1]}] (0,0) -- (1,0); +} +\end{codeexample} + There is one thing to note about slanting: Slanting is done using a + so-called ``canvas transformation'' and has no effect on + positioning of the arrow tip. In particular, if an arrow tip gets + slanted so strongly that it starts to protrude over the arrow tip + end, this does not change the positioning of the arrow tip. + + Here is another example where slanting is used to match italic text: +\begin{codeexample}[] +\tikz [>={[slant=.3] To[] To[]}] + \graph [math nodes] { A -> B <-> C }; +\end{codeexample} +\end{key} + + + +\subsubsection{Reversing, Halving, Swapping} +\label{section-arrow-key-harpoon} + +\begin{key}{/pgf/arrow keys/reverse} + Adding this key to an arrow tip will ``reverse its direction'' so + that is points in the opposite direction (but is still at that end of the + line where the non-reversed arrow tip would have been drawn; so only + the tip is reversed). For most arrow tips, this just results in an + internal flip of a coordinate system, but some arrow tips actually + use a slightly different version of the tip for reversed arrow tips + (namely when the joining of the tip with the line would look + strange). All of this happens automatically, so you do not need to + worry about this. + + If you apply this key twice, the effect cancels, which is useful for + the definition of shorthands (which will be discussed later). +\begin{codeexample}[width=3cm] +\tikz [ultra thick] \draw [arrows = {-Stealth[reversed]}] (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[width=3cm] +\tikz [ultra thick] \draw [arrows = {-Stealth[reversed, reversed]}] (0,0) -- (1,0); +\end{codeexample} +\end{key} + +\begin{key}{/pgf/arrow keys/harpoon} + The key requests that only the ``left half'' of the arrow tip should + drawn: +\begin{codeexample}[width=3cm] +\tikz [ultra thick] \draw [arrows = {-Stealth[harpoon]}] (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[width=3cm] +\tikz [ultra thick] \draw [arrows = {->[harpoon]}] (0,0) -- (1,0); +\end{codeexample} + Unlike the |reverse| key, which all arrows tip kinds support at + least in a basic way, designers of arrow tips really need to take + this key into account in their arrow tip code and often a lot of + special attention needs to do be paid to this key in the + implementation. For this reason, only some arrow tips will support + it. +\end{key} + +\begin{key}{/pgf/arrow keys/swap} + This key flips that arrow tip along the axis of the line. It makes + sense only for asymmetric arrow tips like the harpoons created using + the |harpoon| option. +\begin{codeexample}[width=3cm] +\tikz [ultra thick] \draw [arrows = {-Stealth[harpoon]}] (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[width=3cm] +\tikz [ultra thick] \draw [arrows = {-Stealth[harpoon,swap]}] (0,0) -- (1,0); +\end{codeexample} + Swapping is always possible, no special code is needed on behalf of + an arrow tip implementer. +\end{key} + +\begin{key}{/pgf/arrow keys/left} + A shorthand for |harpoon|. +\end{key} + +\begin{key}{/pgf/arrow keys/right} + A shorthand for |harpoon, swap|. +\begin{codeexample}[width=3cm] +\tikz [ultra thick] \draw [arrows = {-Stealth[left]}] (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[width=3cm] +\tikz [ultra thick] \draw [arrows = {-Stealth[right]}] (0,0) -- (1,0); +\end{codeexample} +\end{key} + + +\subsubsection{Coloring} + +Arrow tips are drawn using the same basic mechanisms as normal paths, +so arrow tips can be stroked (drawn) and/or filled. However, we +usually want the color of arrow tips to be identical to the color used +to draw the path, even if a different color is used for filling the +path. On the other hand, we may also sometimes wish to use a special +color for the arrow tips that is different from both the line and fill +colors of the main path. + +The following options allow you to configure how arrow tips are +colored: + +\begin{key}{/pgf/arrow keys/color=\meta{color or empty} (initially + \normalfont empty)} + Normally, an arrow tip gets the same color as the path to which it + is attached. More precisely, it will get the current ``draw color'', + also known as ``stroke color,'' which you can set using + |draw=|\meta{some color}. By adding the option |color=| to an arrow + tip (note that an ``empty'' color is specified in this way), you ask + that the arrow tip gets this default draw color of the path. Since + this is the default behaviour, you usually do not need to specify + anything: +\begin{codeexample}[width=3cm] +\tikz [ultra thick] \draw [red, arrows = {-Stealth}] (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[width=3cm] +\tikz [ultra thick] \draw [blue, arrows = {-Stealth}] (0,0) -- (1,0); +\end{codeexample} + + Now, when you provide a \meta{color} with this option, you request + that the arrow tip should get this color \emph{instead} of the color + of the main path: +\begin{codeexample}[width=3cm] +\tikz [ultra thick] \draw [red, arrows = {-Stealth[color=blue]}] (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[width=3cm] +\tikz [ultra thick] \draw [red, arrows = {-Stealth[color=black]}] (0,0) -- (1,0); +\end{codeexample} + + Similar to the |color| option used in normal \tikzname\ options, you + may omit the |color=| part of the option. Whenever an \meta{arrow key} + is encountered that \tikzname\ does not recognize, it will test whether + the key is the name of a color and, if so, execute + |color=|\meta{arrow key}. So, the first of the above examples can be + rewritten as follows: +\begin{codeexample}[width=3cm] +\tikz [ultra thick] \draw [red, arrows = {-Stealth[blue]}] (0,0) -- (1,0); +\end{codeexample} + + The \meta{color} will apply both to any drawing and filling + operations used to construct the path. For instance, even though the + |Stealth| arrow tips looks like a filled quadrilateral, it is + actually constructed by drawing a quadrilateral and then filling it + in the same color as the drawing (see the |fill| option below to + see the difference). + + When |color| is set to an empty text, the drawing color is + always used to fill the arrow tips, even if a different color is + specified for filling the path: +\begin{codeexample}[width=3cm] +\tikz [ultra thick] \draw [draw=red, fill=red!50, arrows = {-Stealth[length=10pt]}] + (0,0) -- (1,1) -- (2,0); +\end{codeexample} + As you can see in the above example, the filled area is not quite + what you might have expected. The reason is that the path was + actually internally shortened a bit so that the end of the ``fat + line'' as inside the arrow tip and we get a ``clear'' arrow tip. + + In general, it is a good idea not to add arrow tips to paths that + are filled. +\end{key} + +\begin{key}{/pgf/arrow keys/fill=\meta{color or |none|}} + Use this key to explicitly set the color used for filling the arrow + tips. This color can be different from the color used to draw + (stroke) the arrow tip: +\begin{codeexample}[width=3cm] +\tikz { + \draw [help lines] (0,-.5) grid [step=1mm] (1,.5); + \draw [thick, red, arrows = {-Stealth[fill=white,length=15pt]}] (0,0) -- (1,0); +} +\end{codeexample} + You can also specify the special ``color'' |none|. In this case, the + arrow tip is not filled at all (not even with white): +\begin{codeexample}[width=3cm] +\tikz { + \draw [help lines] (0,-.5) grid [step=1mm] (1,.5); + \draw [thick, red, arrows = {-Stealth[fill=none,length=15pt]}] (0,0) -- (1,0); +} +\end{codeexample} + Note that such ``open'' arrow tips are a bit difficult to draw in + some case: The problem is that the line must be shortened by just + the right amount so that it ends exactly on the back end of the + arrow tip. In some cases, especially when double lines are used, + this will not be possible. + + \begin{key}{/pgf/arrow keys/open} + A shorthand for |fill=none|. + \end{key} + + When you use both the |color| and |fill| option, the |color| option + must come first since it will reset the filling to the color + specified for drawing. +\begin{codeexample}[width=3cm] +\tikz { + \draw [help lines] (0,-.5) grid [step=1mm] (1,.5); + \draw [thick, red, arrows = {-Stealth[color=blue, fill=white, length=15pt]}] + (0,0) -- (1,0); +} +\end{codeexample} + + Note that by setting |fill| to the special color |pgffillcolor|, you + can cause the arrow tips to be filled using the color used to fill + the main path. (This special color is always available and always + set to the current filling color of the graphic state.): +\begin{codeexample}[width=3cm] +\tikz [ultra thick] \draw [draw=red, fill=red!50, + arrows = {-Stealth[length=15pt, fill=pgffillcolor]}] + (0,0) -- (1,1) -- (2,0); +\end{codeexample} +\end{key} + + +\subsubsection{Line Styling} +\label{section-arrow-key-caps} + +Arrow tips are created by drawing and possibly filling a path that +makes up the arrow tip. When \tikzname\ draws a path, there are +different ways in which such a path can be drawn (such as +dashing). Three particularly important parameters are the line join, +the line cap, see Section~\ref{section-line-cap} for an introduction, +and the line width (thickness) + +\tikzname\ resets the line cap and line join each time it draws an +arrow tip since you usually do not want their settings to ``spill +over'' to the way the arrow tips are drawn. You can, however, change +there values explicitly for an arrow tip: + +\begin{key}{/pgf/arrow keys/line cap=\meta{|round| or |butt|}} + Sets the line cap of all lines that are drawn in the arrow to a + round cap or a butt cap. (Unlike for normal lines, the |rect| cap is + not allowed.) Naturally, this key has no effect for arrows whose + paths are closed. + + Each arrow tip has a default value for the line cap, which can + be overruled using this option. + + Changing the cap should have no effect on the size of the + arrow. However, it will have an effect on where the exact ``tip'' of + the arrow is since this will always be exactly at the end of the + arrow: +\begin{codeexample}[width=3cm] +\tikz [line width=2mm] + \draw [arrows = {-Computer Modern Rightarrow[line cap=butt]}] + (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[width=3cm] +\tikz [line width=2mm] + \draw [arrows = {-Computer Modern Rightarrow[line cap=round]}] + (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[width=3cm] +\tikz [line width=2mm] + \draw [arrows = {-Bracket[reversed,line cap=butt]}] + (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[width=3cm] +\tikz [line width=2mm] + \draw [arrows = {-Bracket[reversed,line cap=round]}] + (0,0) -- (1,0); +\end{codeexample} +\end{key} + +\begin{key}{/pgf/arrow keys/line join=\meta{|round| or |miter|}} + Sets the line join to round or miter (|bevel| is not allowed). This + time, the key only has an effect on paths that have ``corners'' in + them. The same rules as for |line cap| apply: the size is not + affects, but the tip end is: + \begin{codeexample}[width=3cm] +\tikz [line width=2mm] + \draw [arrows = {-Computer Modern Rightarrow[line join=miter]}] + (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[width=3cm] +\tikz [line width=2mm] + \draw [arrows = {-Computer Modern Rightarrow[line join=round]}] + (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[width=3cm] +\tikz [line width=2mm] + \draw [arrows = {-Bracket[reversed,line join=miter]}] + (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[width=3cm] +\tikz [line width=2mm] + \draw [arrows = {-Bracket[reversed,line join=round]}] + (0,0) -- (1,0); +\end{codeexample} +\end{key} + +The following keys set both of the above: +\begin{key}{/pgf/arrow keys/round} + A shorthand for |line cap=round, line join=round|, resulting in + ``rounded'' arrow heads. + \begin{codeexample}[width=3cm] +\tikz [line width=2mm] + \draw [arrows = {-Computer Modern Rightarrow[round]}] (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[width=3cm] +\tikz [line width=2mm] + \draw [arrows = {-Bracket[reversed,round]}] (0,0) -- (1,0); +\end{codeexample} +\end{key} + +\begin{key}{/pgf/arrow keys/sharp} + A shorthand for |line cap=butt, line join=miter|, resulting in + ``sharp'' or ``pointed'' arrow heads. + \begin{codeexample}[width=3cm] +\tikz [line width=2mm] + \draw [arrows = {-Computer Modern Rightarrow[sharp]}] (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[width=3cm] +\tikz [line width=2mm] + \draw [arrows = {-Bracket[reversed,sharp]}] (0,0) -- (1,0); +\end{codeexample} +\end{key} + + +You can also set the width of lines used inside arrow tips: + +\begin{key}{/pgf/arrow keys/line width=\meta{dimension}| |\opt{\meta{line width factor}}% + | |\opt{\meta{outer factor}}} + This key sets the line width inside an arrow tip for drawing + (out)lines of the arrow tip. When you set this width to |0pt|, which + makes sense only for closed tips, the arrow tip is only filled. This + can result in better rendering of some small arrow tips and in case + of bend arrow tips (because the line joins will also be bend and not + ``mitered''.) + + The meaning of the factors is as usual the same as for |length| or |width|. + +\begin{codeexample}[width=2cm] +\tikz \draw [arrows = {-Latex[line width=0.1pt, fill=white, length=10pt]}] (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[width=2cm] +\tikz \draw [arrows = {-Latex[line width=1pt, fill=white, length=10pt]}] (0,0) -- (1,0); +\end{codeexample} +\end{key} + + +\begin{key}{/pgf/arrow keys/line width'=\meta{dimension}| |\opt{\meta{length factor}}} + Works like |line width| only the factor is with respect to the |length|. +\end{key} + +\subsubsection{Bending and Flexing} + +\label{section-arrow-flex} + +Up to now, we have only added arrow tip to the end of straight lines, +which is in some sense ``easy.'' Things get far more difficult, if the +line to which we wish to end an arrow tip is curved. In the following, +we have a look at the different actions that can be taken and how they +can be configured. + +To get a feeling for the difficulties involved, consider the following +situation: We have a ``gray wall'' at the $x$-coordinate of and a +red line that ends in its middle. + +\begin{codeexample}[] +\def\wall{ \fill [fill=black!50] (1,-.5) rectangle (2,.5); + \pattern [pattern=bricks] (1,-.5) rectangle (2,.5); + \draw [line width=1pt] (1cm+.5pt,-.5) -- ++(0,1); } +\begin{tikzpicture} + \wall + % The "line" + \draw [red,line width=1mm] (-1,0) -- (1,0); +\end{tikzpicture} +\end{codeexample} + +Now we wish to add a blue open arrow tip the red line like, say, +|Stealth[length=1cm,open,blue]|: + +\def\wall{ \fill [fill=black!50] (1,-.5) rectangle (2,.5); + \pattern [pattern=bricks] (1,-.5) rectangle (2,.5); + \draw [line width=1pt] (1cm+.5pt,-.5) -- ++(0,1); } +\begin{codeexample}[] +\begin{tikzpicture} + \wall + \draw [red,line width=1mm,-{Stealth[length=1cm,open,blue]}] + (-1,0) -- (1,0); +\end{tikzpicture} +\end{codeexample} + +There are several noteworthy things about the blue arrow tip: +\begin{enumerate} +\item Notice that the red line no longer goes all the way to the + wall. Indeed, the red line ends more or less exactly where it meets + the blue line, leaving the arrow tip empty. Now, recall that the red + line was supposed to be the path |(-2,0)--(1,0)|; however, this path + has obviously become much shorter (by 6.25mm to be precise). This + effect is called \emph{path shortening} in \tikzname. +\item The very tip of the arrow just ``touches'' the wall, even we + zoom out a lot. This point, where the original path ended and where + the arrow tip should now lie, is called the \emph{tip end} in + \tikzname. +\item Finally, the point where the red line touches the blue line is + the point where the original path ``visually ends.'' Notice that + this is not the same as the point that lies at a distance of the + arrow's |length| from the wall -- rather it lies at a distance of + |length| minus the |inset|. Let us call this point the \emph{visual + end} of the arrow. +\end{enumerate} + +As pointed out earlier, for straight lines, shortening the path and +rotating and shifting the arrow tip so that it ends precisely at the +tip end and the visual end lies on a line from the tip end to the +start of the line is relatively easy. + +For curved lines, things are much more difficult and \tikzname\ copes +with the difficulties in different ways, depending on which options +you add to arrows. Here is now a curved red line to which we wish to +add our arrow tip (the original straight red line is shown in light red): + +\begin{codeexample}[] +\begin{tikzpicture} + \wall + \draw [red!25,line width=1mm] (-1,0) -- (1,0); + \draw [red,line width=1mm] (-1,-.5) .. controls (0,-.5) and (0,0) .. (1,0); +\end{tikzpicture} +\end{codeexample} + +The first way of dealing with curved lines is dubbed the ``quick +and dirty'' way (although the option for selecting this option is +politely just called ``|quick|'' \dots): + +\begin{key}{/pgf/arrow keys/quick} + Recall that curves in \tikzname\ are actually B\'ezier curves, which + means that they start and end at certain points and we specify two + vectors, one for the start and one for the end, that provide + tangents to the curve at these points. In particular, for the end of + the curve, there is a point called the \emph{second support point} + of the curve such that a tangent to the curve at the end goes + through this point. In our above example, the second support point + is at the middle of the light red line and, indeed, a tangent to the + red line at the point touching the wall is perfectly horizontal. + + In order to add our arrow tip to the curved path, our first + objective is to ``shorten'' the path by 6.25mm. Unfortunately, this + is now much more difficult than for a straight path. When the + |quick| option is added to an arrow tip (it is also + the default if no special libraries are loaded), we cheat somewhat: + Instead of really moving along 6.25mm along the path, we simply + shift the end of the curve by 6.25mm \emph{along the tangent} (which + is easy to compute). We also have to shift the second support point + by the same amount to ensure that the line still has the same + tangent at the end. This will result in the following: + +\begin{codeexample}[] +\begin{tikzpicture} + \wall + \draw [red!25,line width=1mm] (-1,0) -- (1,0); + \draw [red,line width=1mm,-{Stealth[length=1cm,open,blue,quick]}] + (-1,-.5) .. controls (0,-.5) and (0,0) .. (1,0); +\end{tikzpicture} +\end{codeexample} + + They main problem with the above picture is that the red line is no + longer equal to the original red line (notice much sharper curvature + near its end). In our example this is not such a bad thing, but it + certainly ``not a nice thing'' that adding arrow tips to a curve + changes the overall shape of the curves. This is especially + bothersome if there are several similar curves that have different + arrow heads. In this case, the similar curves now suddenly look + different. + + Another big problem with the above approach is that it works only + well if there is only a single arrow tip. When there are multiple + ones, simply shifting them along the tangent as the |quick| option + does produces less-than-satisfactory results: +\begin{codeexample}[] +\begin{tikzpicture} + \wall + \draw [red!25,line width=1mm] (-1,0) -- (1,0); + \draw [red,line width=1mm,-{[quick,sep]>>>}] + (-1,-.5) .. controls (0,-.5) and (0,0) .. (1,0); +\end{tikzpicture} +\end{codeexample} + Note that the third arrow tip does not really lie on the curve any + more. +\end{key} + +Because of the shortcomings of the |quick| key, more powerful +mechanisms for shortening lines and rotating arrows tips have been +implemented. To use them, you need to load the following library: + +\begin{tikzlibrary}{bending} + Load this library to use the |flex|, |flex'|, or |bending| arrow + keys. When this library is loaded, |flex| becomes the default mode + that is used with all paths, unless |quick| is explicitly selected + for the arrow tip. +\end{tikzlibrary} + +\begin{key}{/pgf/arrow keys/flex=\opt{\meta{factor}} (default 1)} + When the |bending| library is loaded, this key is applied + to all arrow tips by default. It has the following effect: + \begin{enumerate} + \item Instead of simply shifting the visual end of the arrow along + the tangent of the curve's end, we really move it along the curve + by the necessary distance. This operation is more expensive than + the |quick| operation -- but not \emph{that} expensive, only + expensive enough so that it is not selected by default for all + arrow tips. Indeed, some compromises are made in the + implementation where accuracy was traded for speed, so the + distance by which the line end is shifted is not necessarily + \emph{exactly} 6.25mm; only something reasonably close. + \item The supports of the line are updated accordingly so that the + shortened line will still follow \emph{exactly} the original + line. This means that the curve deformation effect caused by the + |quick| command does not happen here. + \item Next, the arrow tip is rotated and shifted as follows: First, + we shift it so that its tip is exactly at the tip end, where the + original line ended. Then, the arrow is rotated so the \emph{the + visual end lies on the line}: +\begin{codeexample}[] +\begin{tikzpicture} + \wall + \draw [red!25,line width=1mm] (-1,0) -- (1,0); + \draw [red,line width=1mm,-{Stealth[length=1cm,open,blue,flex]}] + (-1,-.5) .. controls (0,-.5) and (0,0) .. (1,0); +\end{tikzpicture} +\end{codeexample} + \end{enumerate} + + As can be seen in the example, the |flex| option gives a result that + is visually pleasing and does not deform the path. + + There is, however, one possible problem with the |flex| option: The + arrow tip no longer points along the tangent of the end of the + path. This may or may not be a problem, put especially for larger + arrow tips readers will use the orientation of the arrow head to + gauge the direction of the tangent of the line. If this tangent is + important (for example, if it should be horizontal), then it may be + necessary to enforce that the arrow tip ``really points in the + direction of the tangent. + + To achieve this, the |flex| option takes an optional \meta{factor} + parameter, which defaults to |1|. This factor specifies how much the + arrow tip should be rotated: If set to |0|, the arrow points exactly + along a tangent to curve at its tip. If set to |1|, the arrow point + exactly along a line from the visual end point on the curve to the + tip. For values in the middle, we interpolate the rotation between + these two extremes; so |flex=.5| will rotate the arrow's visual end + ``halfway away from the tangent towards the actual position on the + line.'' +\begin{codeexample}[] +\begin{tikzpicture} + \wall + \draw [red!25,line width=1mm] (-1,0) -- (1,0); + \draw [red,line width=1mm,-{Stealth[length=1cm,open,blue,flex=0]}] + (-1,-.5) .. controls (0,-.5) and (0,0) .. (1,0); +\end{tikzpicture} +\end{codeexample} +\begin{codeexample}[] +\begin{tikzpicture} + \wall + \draw [red!25,line width=1mm] (-1,0) -- (1,0); + \draw [red,line width=1mm,-{Stealth[length=1cm,open,blue,flex=.5]}] + (-1,-.5) .. controls (0,-.5) and (0,0) .. (1,0); +\end{tikzpicture} +\end{codeexample} + Note how in the above examples the red line is visible inside the + open arrow tip. Open arrow tips do not go well with a flex value + other than~|1|. Here is a more realistic use of the |flex=0| key: +\begin{codeexample}[] +\begin{tikzpicture} + \wall + \draw [red!25,line width=1mm] (-1,0) -- (1,0); + \draw [red,line width=1mm,-{Stealth[length=1cm,flex=0]}] + (-1,-.5) .. controls (0,-.5) and (0,0) .. (1,0); +\end{tikzpicture} +\end{codeexample} + If there are several arrow tips on a path, the |flex| option + positions them independently, so that each of them lies optimally on + the path: +\begin{codeexample}[] +\begin{tikzpicture} + \wall + \draw [red!25,line width=1mm] (-1,0) -- (1,0); + \draw [red,line width=1mm,-{[flex,sep]>>>}] + (-1,-.5) .. controls (0,-.5) and (0,0) .. (1,0); +\end{tikzpicture} +\end{codeexample} +\end{key} + + +\begin{key}{/pgf/arrow keys/flex'=\opt{\meta{factor}} (default 1)} + The |flex'| key is almost identical to the |flex| key. The only + difference is that a factor of |1| corresponds to rotating the arrow + tip so that the instead of the visual end, the ``ultimate back end'' + of the arrow tip lies on the red path. In the example instead of + having the arrow tip at a distance of |6.25mm| from the tip lie on + the path, we have the point at a distance of |1cm| from the tip lie + on the path: +\begin{codeexample}[] +\begin{tikzpicture} + \wall + \draw [red!25,line width=1mm] (-1,0) -- (1,0); + \draw [red,line width=1mm,-{Stealth[length=1cm,open,blue,flex']}] + (-1,-.5) .. controls (0,-.5) and (0,0) .. (1,0); +\end{tikzpicture} +\end{codeexample} + Otherwise, the factor works as for |flex| and, indeed |flex=0| and + |flex'=0| have the same effect. + + The main use of this option is not so much with an arrow tip like + |Stealth| but rather with tips like the standard |>| in the context + of a strongly curved line: +\begin{codeexample}[] +\begin{tikzpicture} + \wall + \draw [red!25,line width=1mm] (-1,0) -- (1,0); + \draw [red,line width=1mm,-{Computer Modern Rightarrow[flex]}] + (0,-.5) .. controls (1,-.5) and (0.5,0) .. (1,0); +\end{tikzpicture} +\end{codeexample} + In the example, the |flex| option does not really flex the arrow + since for a tip like the Computer Modern arrow, the visual end is + the same as the arrow tip -- after all, the red line does, indeed, end + almost exactly where it used to end. + + Nevertheless, you may feel that the arrow tip looks ``wrong'' in the sense that it + should be rotated. This is exactly what the |flex'| option does + since it allows us to align the ``back end'' of the tip with the red line: +\begin{codeexample}[] +\begin{tikzpicture} + \wall + \draw [red!25,line width=1mm] (-1,0) -- (1,0); + \draw [red,line width=1mm,-{Computer Modern Rightarrow[flex'=.75]}] + (0,-.5) .. controls (1,-.5) and (0.5,0) .. (1,0); +\end{tikzpicture} +\end{codeexample} + In the example, I used |flex'=.75| so as not to overpronounce the + effect. Usually, you will have to fiddle with it sometime to get the + ``perfectly aligned arrow tip,'' but a value of |.75| is usually a + good start. +\end{key} + + + +\begin{key}{/pgf/arrow keys/bend} + \emph{Bending} an arrow tip is a radical solution to the problem of + positioning arrow tips on a curved line: The arrow tip is no longer + ``rigid'' but the drawing itself will now bend along the curve. This + has the advantage that all the problems of flexing with wrong + tangents and overflexing disappear. The downsides are longer + computation times (bending an arrow is \emph{much} more expensive + that flexing it, let alone than quick mode) and also the fact that + excessive bending can lead to ugly arrow tips. On the other hand, + for most arrow tips their bend version are visually quite pleasing + and create a sophisticated look: +\begin{codeexample}[] +\begin{tikzpicture} + \wall + \draw [red!25,line width=1mm] (-1,0) -- (1,0); + \draw [red,line width=1mm,-{Stealth[length=20pt,bend]}] + (-1,-.5) .. controls (0,-.5) and (0,0) .. (1,0); +\end{tikzpicture} +\end{codeexample} +\begin{codeexample}[] +\begin{tikzpicture} + \wall + \draw [red!25,line width=1mm] (-1,0) -- (1,0); + \draw [red,line width=1mm,-{[bend,sep]>>>}] + (-1,-.5) .. controls (0,-.5) and (0,0) .. (1,0); +\end{tikzpicture} +\end{codeexample} +\begin{codeexample}[] +\begin{tikzpicture} + \wall + \draw [red!25,line width=1mm] (-1,0) -- (1,0); + \draw [red,line width=1mm,-{Stealth[bend,round,length=20pt]}] + (0,-.5) .. controls (1,-.5) and (0.25,0) .. (1,0); +\end{tikzpicture} +\end{codeexample} +\end{key} + + + + + + +\subsection{Arrow Tip Specifications} +\label{section-arrow-spec} + +\subsubsection{Syntax} + +When you select the arrow tips for the start and the end of a path, +you can specify a whole sequence of arrow tips, each having its own +local options. At the beginning of this section, it was pointed out +that the syntax for selecting the start and end arrow tips is the +following: + +\begin{quote} + \meta{start specification}|-|\meta{end specification} +\end{quote} + +We now have a closer look at what these specifications may look +like. The general syntax of the \meta{start specification} is as +follows: +\begin{quote} + \opt{|[|\meta{options for all tips}|]|} \meta{first arrow tip spec} + \meta{second arrow tip spec} \meta{third arrow tip spec} \dots +\end{quote} +As can be seen, an arrow tip specification may start with some options +in brackets. If this is the case, the \meta{options for all tips} +will, indeed, be applied to all arrow tips that follow. (We will see, +in a moment, that there are even more places where options may be +specified and a list of the ordering in which the options are applied +will be given later.) + +The main part of a specification is taken up by a sequence of +individual arrow tip specifications. Such a specification can be of +three kinds: + +\begin{enumerate} +\item It can be of the form \meta{arrow tip kind name}|[|\meta{options}|]|. +\item It can be of the form \meta{shorthand}|[|\meta{options}|]|. +\item It can be of the form \meta{single char shorthand}\opt{|[|\meta{options}|]|}. Note that only for this form the + brackets are optional. +\end{enumerate} + +The easiest kind is the first one: This adds an arrow tip of the kind +\meta{arrow tip kind name} to the sequence of arrow tips with the +\meta{options} applied to it at the start (for the \meta{start + specification}) or at the end (for the \meta{end + specification}). Note that for the \meta{start specification} the +first arrow tip specified in this way will be at the very start of the +curve, while for the \meta{end specification} the ordering is +reversed: The last arrow tip specified will be at the very end of the +curve. This implies that a specification like +\begin{quote} +|Stealth[] Latex[] - Latex[] Stealth[]| +\end{quote} +will give perfectly symmetric arrow tips on a line (as one would +expect). + +It is important that even if there are no \meta{options} for an arrow +tip, the square brackets still need to be written to indicate the end +of the arrow tip's name. Indeed, the opening brackets are used to +divide the arrow tip specification into names. + +Instead of a \meta{arrow tip kind name}, you may also provide the name +of a so-called \emph{shorthand}. Shorthands look like normal arrow tip +kind names and, indeed, you will often be using shorthands without +noticing that you do. The idea is that instead of, say, +|Computer Modern Rightarrow| you might wish to just write |Rightarrow| +or perhaps just |To| or even just |>|. For this, you can create a +shorthand that tells \tikzname\ that whenever this shorthand is used, +another arrow tip kind is meant. (Actually, shorthands are somewhat +more powerful, we have a detailed look at them in +Section~\ref{section-arrow-tip-macro}.) For shorthands, the same rules +apply as for normal arrow tip kinds: You \emph{need} to provide +brackets so that \tikzname\ can find the end of the name inside a +longer specification. + +The third kind of arrow tip specifications consist of just a single +letter like |>| or |)| or |*| or even |o| or |x| (but you may not use +|[|, |]|, or |-| since they will confuse the parser). These single +letter arrow specifications will invariably be shorthands that select +some ``real'' arrow tip instead. An important feature of single letter +arrow tips is that they do \emph{not} need to be followed by options +(but they may). + +Now, since we can use any letter for single letter shorthands, how can +\tikzname\ tell whether by |foo[]| we mean an arrow tip kind |foo| +without any options or whether we mean an arrow tip called |f|, +followed by two arrow tips called |o|? Or perhaps an arrow tip called +|f| followed by an arrow tip called |oo|? To solve this problem, the +following rule is used to determine which of the three possible +specifications listed above applies: First, we check whether +everything from the current position up to the next opening bracket +(or up to the end) is the name of an arrow tip or of a shorthand. In +our case, |foo| would first be tested under this rule. Only if |foo| +is neither the name of an arrow tip kind nor of a shorthand does +\tikzname\ consider the first letter of the specification, |f| in our +case. If this is not the name of a shorthand, an error is +raised. Otherwise the arrow tip corresponding to |f| is added to the +list of arrow tips and the process restarts with the rest. Thus, we +would next text whether |oo| is the name of an arrow tip or shorthand +and, if not, whether |o| is such a name. + +All of the above rules mean that you can rather easily specify arrow +tip sequences if they either mostly consist of single letter names or +of longer names. Here are some examples: + +\begin{itemize} +\item |->>>| is interpreted as three times the |>| shorthand since + |>>>| is not the name of any arrow tip kind (and neither is |>>|). +\item |->[]>>| has the same effect as the above. +\item |-[]>>>| also has the same effect.%>> +\item |->[]>[]>[]| so does this. +\item |->Stealth| yields an arrow tip |>| followed by a |Stealth| + arrow at the end. +\item |-Stealth>| is illegal since there is no arrow tip |Stealth>| + and since |S| is also not the name of any arrow tip. +\item |-Stealth[] >| is legal and does what was presumably meant in the previous item. +\item |< Stealth-| is legal and is the counterpart to |-Stealth[] >|. +\item |-Stealth[length=5pt] Stealth[length=6pt]| selects two stealth + arrow tips, but at slightly different sizes for the end of lines. +\end{itemize} + + +An interesting question concerns how flexing and bending interact with +multiple arrow tips: After all, flexing and quick mode use different +ways of shortening the path so we cannot really mix them. The +following rule is used: We check, independently for the start and the +end specifications, whether at least one arrow tip in them uses one of +the options |flex|, |flex'|, or |bend|. If so, all |quick| settings in +the other arrow tips are ignored and treated as if |flex| had been +selected for them, too. + + +\subsubsection{Specifying Paddings} + +When you provide several arrow tips in a row, all of them are added to +the start or end of the line: +\begin{codeexample}[] +\tikz \draw [<<<->>>>] (0,0) -- (2,0); +\end{codeexample} +The question is now what will be distance between them? For this, the +following arrow key is important: +\begin{key}{/pgf/arrow keys/sep=\meta{dimension}| |\opt{\meta{line + width factor}}| |\opt{\meta{outer factor}} (default 0.88pt .3 1)} + When a sequence of arrow tips is specified in an arrow tip + specification for the end of the line, the arrow tips are normally + arranged in such a way that the tip of each arrow ends exactly at + the ``back end'' of the next arrow tip (for start specifications, + the ordering is inverted, of course). Now, when the |sep| option is + set, instead of exactly touching the back end of the next arrow, the + specified \meta{dimension} is added as additional space (the + distance may also be negative, resulting in an overlap of the arrow + tips). The optional factors have the same meaning as for the + |length| key, see that key for details. + + Let us now have a look at some examples. First, we use two arrow + tips with different separations between them: +\begin{codeexample}[] +\tikz { + \draw [-{>[sep=1pt]>[sep= 2pt]>}] (0,1.0) -- (1,1.0); + \draw [-{>[sep=1pt]>[sep=-2pt]>}] (0,0.5) -- (1,0.5); + \draw [-{> >[sep] >}] (0,0.0) -- (1,0.0); +} +\end{codeexample} + + You can also specify a |sep| for the last arrow tip in the sequence + (for end specifications, otherwise for the first arrow tip). In this + case, this first arrow tip will not exactly ``touch'' the point + where the path ends, but will rather leave the specified amount of + space. This is usually quite desirable. +\begin{codeexample}[] +\tikz { + \node [draw] (A) {A}; + \node [draw] (B) [right=of A] {B}; + + \draw [-{>>[sep=2pt]}] (A) to [bend left=45] (B); + \draw [- >> ] (A) to [bend right=45] (B); +} +\end{codeexample} + Indeed, adding a |sep| to an arrow tip is \emph{very} desirable, so + you will usually write something like |>={To[sep]}| somewhere near + the start of your files. + + One arrow tip kind can be quite useful in this context: The arrow + tip kind |_|. It draws nothing and has zero length, \emph{but} + it has |sep| set as a default option. Since it is a single letter + shorthand, you can write short and clean ``code'' in this way: +\begin{codeexample}[] +\tikz \draw [->_>] (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[] +\tikz \draw [->__>] (0,0) -- (1,0); +\end{codeexample} + However, using the |sep| option will be faster than using the |_| + arrow tip and it also allows you to specify the desired length + directly. +\end{key} + + + +\subsubsection{Specifying the Line End} + +In the previous examples of sequences of arrow tips, the line of the +path always ended at the last of the arrow tips (for end +specifications) or at the first of the arrow tips (for start +specifications). Often, this is what you may want, but not +always. Fortunately, it is quite easy to specify the desired end of +the line: The special single char shorthand |.| is reserved to +indicate that last arrow that is still part of the line; in other +words, the line will stop at the last arrow before |.| is encountered +(for end specifications) are at the first arrow following |.| (for +start specifications). +%>> +\begin{codeexample}[] +\tikz [very thick] \draw [<<<->>>] (0,0) -- (2,0); +\end{codeexample} +\begin{codeexample}[] +\tikz [very thick] \draw [<.<<->.>>] (0,0) -- (2,0); +\end{codeexample} +\begin{codeexample}[] +\tikz [very thick] \draw [<<.<-.>>>] (0,0) -- (2,0); +\end{codeexample} +\begin{codeexample}[] +\tikz [very thick] \draw [<<.<->.>>] (0,0) to [bend left] (2,0); +\end{codeexample} + +It is permissible that there are several dots in a specification, in +this case the first one ``wins'' (for end specifications, otherwise +the last one). + +Note that |.| is parsed as any other shorthand. In particular, if you +wish to add a dot after a normal arrow tip kind name, you need to add +brackets: +\begin{codeexample}[] +\tikz [very thick] \draw [-{Stealth[] . Stealth[] Stealth[]}] (0,0) -- (2,0); +\end{codeexample} +Adding options to |.| is permissible, but they have no effect. In +particular, |sep| has no effect since a dot is not an arrow. + + + + +\subsubsection{Defining Shorthands} +\label{section-arrow-tip-macro} + +It is often desirable to create ``shorthands'' for the names of arrow +tips that you are going to use very often. Indeed, in most documents +you will only need a single arrow tip kind and it would be useful that +you could refer to it just as |>| in your arrow tip specifications. As +another example, you might constantly wish to switch between a filled +and a non-filled circle as arrow tips and would like to use |*| and +|o| are shorthands for these case. Finally, you might just like to +shorten a long name like |Computer Modern Rightarrow| down to just, +say |To| or something similar. + +All of these case can be addressed by defining appropriate +shorthands. This is done using the following handler: + +\begin{handler}{{.tip}{=\meta{end specification}}} + Defined the \meta{key} as a name that can be used inside arrow tip + specifications. If the \meta{key} has a path before it, this path is + ignored (so there is only one ``namespace'' for arrow + tips). Whenever it is used, it will be replaced by the \meta{end + specification}. Note that you must \emph{always} provide + (only) an end specification; when the \meta{key} is used inside a + start specification, the ordering and the meaning of the keys inside + the \meta{end specification} are translated automatically. + +\begin{codeexample}[] +\tikz [foo /.tip = {Stealth[sep]. >>}] + \draw [-foo] (0,0) -- (2,0); +\end{codeexample} +\begin{codeexample}[] +\tikz [foo /.tip = {Stealth[sep] Latex[sep]}, + bar /.tip = {Stealth[length=10pt,open]}] + \draw [-{foo[red] . bar}] (0,0) -- (2,0); +\end{codeexample} + + In the last of the examples, we used |foo[red]| to make the arrows + red. Any options given to a shorthand upon use will be passed on to + the actual arrows tip for which the shorthand stands. Thus, we could + also have written |Stealth[sep,red]| |Latex[sep,red]| instead of + |foo[red]|. In other words, the ``replacement'' of a shorthand by + its ``meaning'' is a semantic replacement rather than a syntactic + replacement. In particular, the \meta{end specification} will be + parsed immediately when the shorthand is being defined. However, + this applies only to the options inside the specification, whose + values are evaluated immediately. In contrast, which actual arrow + tip kind is meant by a given shorthand used inside the \meta{end + specification} is resolved only up each use of the shorthand. This + means that when you write + \begin{quote} + |dup /.tip = >>| + \end{quote} + and then later write + \begin{quote} + |> /.tip = whatever| + \end{quote} + then |dup| will have the effect as if you had written + |whatever[]whatever[]|. You will find that this behaviour is + what one would expect. + + There is one problem we have not yet addressed: The asymmetry of + single letter arrow tips like |>| or |)|. When someone writes +\begin{codeexample}[] +\tikz \draw [<->] (0,0) -- (1,0); +\end{codeexample} + we rightfully expect one arrow tip pointing left at the left end and + an arrow tip pointing right at the right end. However, compare +\begin{codeexample}[] +\tikz \draw [>->] (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[] +\tikz \draw [Stealth-Stealth] (0,0) -- (1,0); +\end{codeexample} + In both cases, we have \emph{identical} text in the start and end + specifications, but in the first case we rightfully expect the left + arrow to be flipped. + + The solution to this problem is that it is possible to define + two names for the same arrow tip, namely one that is used inside + start specifications and one for end specifications. Now, we can + decree that the ``name of |>|'' inside start specifications is + simply |<| and the above problems disappear. + + To specify different names for a shorthand in start and end + specifications, use the following syntax: Instead of \meta{key}, you + use \meta{name in start specifications}|-|\meta{name in end + specifications}. Thus, to set the |>| key correctly, you actually + need to write +\begin{codeexample}[] +\tikz [<-> /.tip = Stealth] \draw [<->>] (0,0) -- (1,0); +\end{codeexample} +\begin{codeexample}[] +\tikz [<-> /.tip = Latex] \draw [>-<] (0,0) -- (1,0); +\end{codeexample} + + Note that the above also works even though we have not set |<| as an + arrow tip name for end specifications! The reason this works is that + the \tikzname\ (more precisely, \pgfname) actually uses the + following definition internally: + \begin{quote} + |>-< /.tip = >[reversed]| + \end{quote} + Translation: ``When |<| is used in an end specification, please + replace it by |>|, but reversed. Also, when |>| is used in a start + specification, we also mean this inverted |>|.'' + + By default, |>| is a shorthand for |To| and |To| is a shorthand for + |to| (an arrow from the old libraries) when |arrows.meta| is not + loaded library. When |arrow.meta| is loaded, |To| is redefined to + mean the same as + |Computer Modern Rightarrow|. +\end{handler} + +\begin{key}{/tikz/>=\meta{end arrow specification}} + This is a short way of saying |<->/.tip=|\meta{end arrow specification}. +\begin{codeexample}[] +\begin{tikzpicture}[scale=2,ultra thick] + \begin{scope}[>=Latex] + \draw[>->] (0pt,3ex) -- (1cm,3ex); + \draw[|<->>|] (0pt,2ex) -- (1cm,2ex); + \end{scope} + \begin{scope}[>=Stealth] + \draw[>->] (0pt,1ex) -- (1cm,1ex); + \draw[|<<.<->|] (0pt,0ex) -- (1cm,0ex); + \end{scope} +\end{tikzpicture} +\end{codeexample} + +\end{key} + + + +\subsubsection{Scoping of Arrow Keys} +\label{section-arrow-scopes} + +There are numerous places where you can specify keys for an arrow +tip. There is, however, one final place that we have not yet +mentioned: + +\begin{key}{/tikz/arrows=|[|\meta{arrow keys}|]|} + The |arrows| key, which is normally used to set the arrow tips for + the current scope, can also be used to set some arrow keys for the + current scope. When the argument to |arrows| starts with an opening + bracket and only otherwise contains one further closing bracket at + the very end, this semantic of the |arrow| key is assumed. + + The \meta{arrow keys} will be set for the rest of current + scope. This is useful for generally setting some design parameters + or for generally switching on, say, bending as in: +\begin{codeexample}[code only] +\tikz [arrows={[bend]}] ... % Bend all arrows +\end{codeexample} +\end{key} + +We can now summarize which arrow keys are applied in what order when +an arrow tip is used: +\begin{enumerate} +\item First, the so-called \emph{defaults} are applied, which are + values for the different parameters of a key. They are fixed in the + definition of the key and cannot be changed. Since they are executed + first, they are only the ultimate fallback. +\item The \meta{keys} from the use of |arrows=[|\meta{keys}|]| in all + enclosing scopes. +\item Recursively, the \meta{keys} provided with the arrow + tip inside shorthands. +\item The keys provided at the beginning of an arrow tip specification + in brackets. +\item The keys provided directly next to the arrow tip inside the + specification. +\end{enumerate} + + + + +\subsection{Reference: Arrow Tips} +\label{section-arrows-meta} + +\begin{pgflibrary}{arrows.meta} + This library defines a large number of standard ``meta'' arrow + tips. ``Meta'' means that you can configure these arrow tips in many + different ways like changing their size or their line caps and joins + and many other details. + + The only reason this library is not loaded by default is for + compatibility with older versions of \tikzname. You can, however, + safely load and use this library alongside the older libraries + |arrows| and |arrows.spaced|. +\end{pgflibrary} + + +The different arrow tip kinds defined in the |arrows.meta| library can +be classified in different groups: +\begin{itemize} +\item \emph{Barbed} arrow tips consist mainly of lines that ``point + backward'' from the tip of the arrow and which are not filled. For + them, filling has no effect. A typical example is \tikz [baseline] + \draw (0,.5ex) -- (1.5em,.5ex) [-Straight Barb];. Here is the list + of defined arrow tips: + + \begin{arrowexamples} + \arrowexample Arc Barb[] + \arrowexample Bar[] + \arrowexample Bracket[] + \arrowexample Hooks[] + \arrowexample Parenthesis[] + \arrowexample Straight Barb[] + \arrowexample Tee Barb[] + \end{arrowexamples} + + All of these arrow tips can be configured and resized in many + different ways as described in the following. Above, they are shown at + their ``natural'' sizes, which are chosen in such a way that for a + line width of 0.4pt their width matches the height + of a letter ``x'' in Computer Modern at 11pt (with some + ``overshooting'' to create visual consistency). +\item \emph{Mathematical} arrow tips are actually a subclass of the + barbed arrow tips, but we list them separately. They contain arrow + tips that look exactly like the tips of arrows used in mathematical + fonts such as the |\to|-symbol $\to$ from standard \TeX. + \begin{arrowexamples} + \arrowexample Classical TikZ Rightarrow[] + \arrowexample Computer Modern Rightarrow[] + \arrowexampledouble Implies[] + \arrowexample To[] + \end{arrowexamples} + The |To| arrow tip is a shorthand for |Computer Modern Rightarrow| + when |arrows.meta| is loaded. +\item \emph{Geometric} arrow tips consist of a filled shape like a + kite or a circle or a ``stealth-fighter-like'' shape. A typical + example is \tikz [baseline] \draw (0,.5ex) -- (1.5em,.5ex) + [-Stealth];. These arrow tips can also be used in an ``open'' + variant as in \tikz [baseline] \draw (0,.5ex) -- (1.5em,.5ex) + [-{Stealth[open]}];. + + \begin{arrowexamples} + \arrowexample Circle[] + \arrowexample Diamond[] + \arrowexample Ellipse[] + \arrowexample Kite[] + \arrowexample Latex[] + \arrowexample Latex[round] + \arrowexample Rectangle[] + \arrowexample Square[] + \arrowexample Stealth[] + \arrowexample Stealth[round] + \arrowexample Triangle[] + \arrowexample Turned Square[] + \end{arrowexamples} + + Here are the ``open'' variants: + + \begin{arrowexamples} + \arrowexample Circle[open] + \arrowexample Diamond[open] + \arrowexample Ellipse[open] + \arrowexample Kite[open] + \arrowexample Latex[open] + \arrowexample Latex[round,open] + \arrowexample Rectangle[open] + \arrowexample Square[open] + \arrowexample Stealth[open] + \arrowexample Stealth[round,open] + \arrowexample Triangle[open] + \arrowexample Turned Square[open] + \end{arrowexamples} + + Note that ``open'' arrow tips are not the same as ``filled with + white,'' which is also available (just say |fill=white|). The + difference is that the background will ``shine through'' an open + arrow, while a filled arrow always obscures the background: + +\begin{codeexample}[] +\tikz { + \shade [left color=white, right color=red!50] (0,0) rectangle (4,1); + + \draw [ultra thick,-{Triangle[open]}] (0,2/3) -- ++ (3,0); + \draw [ultra thick,-{Triangle[fill=white]}] (0,1/3) -- ++ (3,0); +} +\end{codeexample} + +\item \emph{Cap} arrow tips are used to add a ``cap'' to the end of a + line. The graphic languages underlying \tikzname\ (\textsc{pdf}, + \textsc{postscript} or \textsc{svg}) all support three basic types + of line caps on a very low level: round, rectangular, and ``butt.'' + Using cap arrow tips, you can add new caps to lines and use + different caps for the end and the start. An example is the line + \tikz [baseline] \draw [line width=1ex, {Round + Cap[reversed]}-{Triangle Cap[] . Fast Triangle[] Fast Triangle[]}] + (0,0.5ex) -- (2em,0.5ex);. + \begin{arrowcapexamples} + \arrowcapexample Butt Cap[] + \arrowcapexample Fast Round[] + \arrowcapexample Fast Triangle[] + \arrowcapexample Round Cap[] + \arrowcapexample Triangle Cap[] + \end{arrowcapexamples} +\item \emph{Special} arrow tips are used for some specific purpose and + do not fit into the above categories. + \begin{arrowexamples} + \arrowexample Rays[] + \arrowexample Rays[n=8] + \end{arrowexamples} +\end{itemize} + +\subsubsection{Barbed Arrow Tips} + +\begin{arrowtip}{Arc Barb} + { + This arrow tip attaches an arc to the end of the line whose angle + is given by the |arc| option. The + |length| and |width| parameters refer to the size of the arrow tip + for |arc| set to 180 degrees, which is why in the example for + |arc=210| the actual length is larger than the specified + |length|. The line width is taken into account + for the computation of the length and width. Use the |round| + option to add round caps to the end of the arcs. + } + {length=1.5cm,arc=210} + {length=1.5cm,width=3cm} + + \begin{arrowexamples} + \arrowexample[] + \arrowexampledup[sep] + \arrowexampledupdot[sep] + \arrowexample[arc=120] + \arrowexample[arc=270] + \arrowexample[length=2pt] + \arrowexample[length=2pt,width=5pt] + \arrowexample[line width=2pt] + \arrowexample[reversed] + \arrowexample[round] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[harpoon,reversed] + \arrowexample[red] + \end{arrowexamples} + The following options have no effect: |open|, |fill|. + + On |double| lines, the arrow tip will not look correct. +\end{arrowtip} + + +\begin{arrowtipsimple}{Bar} + A simple bar. This is a simple instance of |Tee Barb| for length zero. +\end{arrowtipsimple} + +\begin{arrowtip}{Bracket} + { + This is an instance of the |Tee Barb| arrow tip that results in + something resembling a bracket. Just like the |Parenthesis| arrow + tip, a |Bracket| is not modelled from a text square bracket, but + rather its size has been chosen so that it fits with the other + arrow tips. + } + {} + {} + + \begin{arrowexamples} + \arrowexample[] + \arrowexampledup[sep] + \arrowexampledupdot[sep] + \arrowexample[reversed] + \arrowexample[round] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[harpoon,reversed] + \arrowexample[red] + \end{arrowexamples} + The following options have no effect: |open|, |fill|. + + On |double| lines, the arrow tip will not look correct. +\end{arrowtip} + +\begin{arrowtip}{Hooks} + { + This arrow tip attaches two ``hooks'' to the end of the line. The + |length| and |width| parameters refer to the size of the arrow tip + if both arcs are 180 degrees; in the example the arc is 210 + degrees and, thus, the arrow is actually longer that the |length| + dictates. The line width is taken into account for the computation + of the length and width. The |arc| option is used to specify the + angle of the arcs. Use the |round| option to add round caps to the + end of the arcs. + } + {length=1cm,width=3.5cm,arc=210} + {length=1cm,width=3.5cm} + + \begin{arrowexamples} + \arrowexample[] + \arrowexampledup[sep] + \arrowexampledupdot[sep] + \arrowexample[arc=120] + \arrowexample[arc=270] + \arrowexample[length=2pt] + \arrowexample[length=2pt,width=5pt] + \arrowexample[line width=2pt] + \arrowexample[reversed] + \arrowexample[round] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[harpoon,reversed] + \arrowexample[red] + \end{arrowexamples} + The following options have no effect: |open|, |fill|. + + On |double| lines, the arrow tip will not look correct. +\end{arrowtip} + + +\begin{arrowtip}{Parenthesis} + { + This arrow tip is an instantiation of the |Arc Barb| so that it + resembles a parenthesis. However, the idea is not to recreate a + ``real'' parenthesis as it is used in text, but rather a ``bow'' + at a size that harmonizes with the other arrow tips at their + default sizes. + } + {} + {} + + \begin{arrowexamples} + \arrowexample[] + \arrowexampledup[sep] + \arrowexampledupdot[sep] + \arrowexample[reversed] + \arrowexample[round] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[harpoon,reversed] + \arrowexample[red] + \end{arrowexamples} + The following options have no effect: |open|, |fill|. + + On |double| lines, the arrow tip will not look correct. +\end{arrowtip} + +\begin{arrowtip}{Straight Barb} + { + This is the ``archetypal'' arrow head, consisting of just two + straight lines. The |length| and |width| parameters refer to the + horizontal and vertical distances between the points on the path + making up the arrow tip. As can be seen, the line width of the + arrow tip's path is not taken into account. + The |angle| option is particularly useful to set + the opening angle at the tip of the arrow head. The |round| option + gives a ``softer'' or ``rounder'' version of the arrow tip. + } + {length=2cm,width=3cm} + {length=2cm/-4mm,width=3cm} + + \begin{arrowexamples} + \arrowexample[] +% \arrowexampledouble[] + \arrowexampledup[] + \arrowexampledupdot[] + \arrowexample[length=5pt] + \arrowexample[length=5pt,width=5pt] + \arrowexample[line width=2pt] + \arrowexample[reversed] + \arrowexample[angle=60:2pt 3] + \arrowexample[round] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[harpoon,reversed] + \arrowexample[red] + \end{arrowexamples} + The following options have no effect: |open|, |fill|. + + On |double| lines, the arrow tip will not look correct. +\end{arrowtip} + + +\begin{arrowtip}{Tee Barb} + { + This arrow tip attaches a little ``T'' on both sides of the + tip. The arrow |inset| dictates the distance from the back end to + the middle of the stem of the T. When the inset is equal to the + length, the arrow tip is drawn as a single line, not as three + lines (this is important for the ``round'' version since, then, + the corners get rounded). + } + {length=1.5cm,width=3cm,inset=1cm} + {length=1.5cm,width=3cm,inset=1cm} + + \begin{arrowexamples} + \arrowexample[] + \arrowexampledup[sep] + \arrowexampledupdot[sep] + \arrowexample[inset=0pt] + \arrowexample[inset'=0pt 1] + \arrowexample[line width=2pt] + \arrowexample[round] + \arrowexample[round,inset'=0pt 1] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[harpoon,reversed] + \arrowexample[red] + \end{arrowexamples} + The following options have no effect: |open|, |fill|. + + On |double| lines, the arrow tip will not look correct. +\end{arrowtip} + + + +\subsubsection{Mathematical Barbed Arrow Tips} + + +\begin{arrowtip}{Classical TikZ Rightarrow} + { + This arrow tip is the ``old'' or ``classical'' arrow tip that used + to be the standard in \tikzname\ in earlier versions. It was + modelled on an old version of the tip of \texttt{\string\rightarrow} + ($\rightarrow$) of the Computer Modern fonts. However, this ``old + version'' was really old, Donald + Knuth (the designer of both \TeX\ and of the Computer Modern + fonts) replaced the arrow tip of the mathematical fonts + in~1992. + } + {length=1cm,width=2cm} + {length=1cm,width=2cm} + The main problem with this arrow tip is that it is ``too small'' + at its natural size. I recommend using the new \texttt{Computer Modern + Rightarrow} arrow tip instead, which matches the current + $\to$. This new version is also the default used as |>| and as + |To|, now. + + \begin{arrowexamples} + \arrowexample[] + \arrowexampledup[sep] + \arrowexampledupdot[sep] + \arrowexample[length=3pt] + \arrowexample[sharp] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[harpoon,reversed] + \arrowexample[red] + \end{arrowexamples} + The following options have no effect: |open|, |fill|. + + On |double| lines, the arrow tip will not look correct. +\end{arrowtip} + +\begin{arrowtip}{Computer Modern Rightarrow} + { + For a line width of 0.4pt (the default), this arrow tip looks very + much like \texttt{\string\rightarrow} ($\to$) of the Computer Modern math + fonts. However, it is not a ``perfect'' match: the line caps and + joins of the ``real'' $\to$ are rounded differently from this + arrow tip; but it takes a keen eye to notice the difference. When + the |arrow.meta| library is loaded, this arrow tip becomes the + default of |To| and, thus, is used whenever |>| is used (unless, + of course, you redefined |>|). + } + {length=1cm,width=2cm} + {length=1cm,width=2cm} + + \begin{arrowexamples} + \arrowexample[] + \arrowexampledup[sep] + \arrowexampledupdot[sep] + \arrowexample[length=3pt] + \arrowexample[sharp] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[harpoon,reversed] + \arrowexample[red] + \end{arrowexamples} + The following options have no effect: |open|, |fill|. + + On |double| lines, the arrow tip will not look correct. +\end{arrowtip} + + + +\begin{arrowtipsimple}{Implies} + This arrow tip makes only sense in conjunction with the |double| + option. The idea is that you attach it to a double line to get + something that looks like \TeX's \texttt{\string\implies} arrow + ($\implies$). A typical use of this arrow tip is +\begin{codeexample}[] +\tikz \graph [clockwise=3, math nodes, + edges = {double equal sign distance, -Implies}] { + "\alpha", "\beta", "\gamma"; + "\alpha" -> "\beta" -> "\gamma" -> "\alpha" +}; +\end{codeexample} + \begin{arrowexamples} + \arrowexampledouble[] + \arrowexampledouble[red] + \end{arrowexamples} +\end{arrowtipsimple} + +\begin{arrowtipsimple}{To} + This is a shorthand for |Computer Modern Rightarrow| when the + |arrow.meta| library is loaded. Otherwise, it is a shorthand for the + classical \tikzname\ rightarrow. +\end{arrowtipsimple} + + + + +\subsubsection{Geometric Arrow Tips} + + + +\begin{arrowtip}{Circle} + { + Although this tip is called ``circle,'' you can also use it to + draw ellipses if you set the length and width to different + values. Neither |round| nor |reversed| has any effect on this + arrow tip. + } + {length=2cm,width=2cm} + {length=2cm,width=2cm} + + \begin{arrowexamples} + \arrowexample[] + \arrowexampledup[sep] + \arrowexampledupdot[sep] + \arrowexample[open] + \arrowexample[length=3pt] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[red] + \end{arrowexamples} +\end{arrowtip} + +\begin{arrowtipsimple}{Diamond} + This is an instance of |Kite| where the length is larger than the + width. + + \begin{arrowexamples} + \arrowexample[] + \arrowexampledup[] + \arrowexampledupdot[] + \arrowexample[open] + \arrowexample[length=10pt] + \arrowexample[round] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[red] + \arrowexample[fill=red!50] + \end{arrowexamples} +\end{arrowtipsimple} + +\begin{arrowtipsimple}{Ellipse} + This is a shorthand for a ``circle'' that is twice as wide as high. + + \begin{arrowexamples} + \arrowexample[] + \arrowexampledup[sep] + \arrowexampledupdot[sep] + \arrowexample[open] + \arrowexample[length=10pt] + \arrowexample[round] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[red] + \arrowexample[fill=red!50] + \end{arrowexamples} +\end{arrowtipsimple} + + +\begin{arrowtip}{Kite} + { + This arrow tip consists of four lines that form a ``kite.'' The + |inset| prescribed how far the width-axis of the kite is removed + from the back end. Note that the inset cannot be negative, use a + |Stealth| arrow tip for this. + } + {length=3cm,width=2cm,inset=1cm} + {length=3cm,width=2cm,inset=1cm} + + \begin{arrowexamples} + \arrowexample[] + \arrowexampledup[sep] + \arrowexampledupdot[sep] + \arrowexample[open] + \arrowexample[length=6pt,width=4pt] + \arrowexample[length=6pt,width=4pt,inset=1.5pt] + \arrowexample[round] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[red] + \end{arrowexamples} +\end{arrowtip} + + +\begin{arrowtip}{Latex} + { + This arrow tip is the same as the arrow tip used in \LaTeX's + standard pictures (via the \texttt{\string\vec} command), if you + set the length to 4pt. The default size for this arrow tip was set + slightly larger so that it fits better with the other geometric + arrow tips. + } + {length=3cm,width=2cm} + {length=3cm,width=2cm} + + \begin{arrowexamples} + \arrowexample[] + \arrowexampledup[sep] + \arrowexampledupdot[sep] + \arrowexample[open] + \arrowexample[length=4pt] + \arrowexample[round] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[red] + \end{arrowexamples} +\end{arrowtip} + +\begin{arrowtipsimple}{LaTeX} + Another spelling for the |Latex| arrow tip. +\end{arrowtipsimple} + + + +\begin{arrowtip}{Rectangle} + { + A rectangular arrow tip. By default, it is twice as long as high. + } + {length=3cm,width=2cm} + {length=3cm,width=2cm} + + \begin{arrowexamples} + \arrowexample[] + \arrowexampledup[sep] + \arrowexampledupdot[sep] + \arrowexample[open] + \arrowexample[length=4pt] + \arrowexample[round] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[red] + \end{arrowexamples} +\end{arrowtip} + + +\begin{arrowtipsimple}{Square} + An instance of the |Rectangle| whose width is identical to the length. + + \begin{arrowexamples} + \arrowexample[] + \arrowexampledup[sep] + \arrowexampledupdot[sep] + \arrowexample[open] + \arrowexample[length=4pt] + \arrowexample[round] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[red] + \end{arrowexamples} +\end{arrowtipsimple} + + + +\begin{arrowtip}{Stealth} + { + This arrow tip is similar to a |Kite|, only the |inset| now counts + ``inwards.'' Because of that sharp angles, for this arrow tip is + makes quite a difference, visually, if use the |round| + option. Also, using the |harpoon| option (or |left| or |right|) + will \emph{lengthen} the arrow tip because of the even sharper + corner at the tip. + } + {length=3cm,width=2cm,inset=1cm} + {length=3cm,width=2cm,inset=1cm} + + \begin{arrowexamples} + \arrowexample[] + \arrowexampledup[sep] + \arrowexampledupdot[sep] + \arrowexample[open] + \arrowexample[length=6pt,width=4pt] + \arrowexample[length=6pt,width=4pt,inset=1.5pt] + \arrowexample[round] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[red] + \end{arrowexamples} +\end{arrowtip} + + +\begin{arrowtipsimple}{Triangle} + An instance of a |Kite| with zero inset. + + \begin{arrowexamples} + \arrowexample[] + \arrowexampledup[sep] + \arrowexampledupdot[sep] + \arrowexample[open] + \arrowexample[length=4pt] + \arrowexample[angle=45:1pt 3] + \arrowexample[angle=60:1pt 3] + \arrowexample[angle=90:1pt 3] + \arrowexample[round] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[red] + \end{arrowexamples} +\end{arrowtipsimple} + +\begin{arrowtipsimple}{Turned Square} + An instance of a |Kite| with identical width and height and mid-inset. + + \begin{arrowexamples} + \arrowexample[] + \arrowexampledup[sep] + \arrowexampledupdot[sep] + \arrowexample[open] + \arrowexample[length=4pt] + \arrowexample[round] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[red] + \end{arrowexamples} +\end{arrowtipsimple} + + + +\subsubsection{Caps} + +Recall that a \emph{cap} is a way of ending a line. The graphic +languages underlying \tikzname\ (\textsc{pdf}, \textsc{postscript} or +\textsc{svg}) all support three basic types of line caps on a very low +level: round, rectangular, and ``butt.'' Using cap arrow tips, you can +add new caps to lines and use different caps for the end and the +start. + + +\begin{arrowtipsimple}{Butt Cap} + This arrow tip ends the line ``in the normal way'' with a straight + end. This arrow tip is only need to ``cover up'' the actual line + cap, if this happens to differ from the normal cap. In the following + example, the line cap is ``round'', but, nevertheless, the right end + is a ``butt'' cap: + +\begin{codeexample}[] +\tikz \draw [line width=1ex, line cap=round, -Butt Cap] (0,0) -- (1,0); +\end{codeexample} +\end{arrowtipsimple} + + +\begin{arrowcap}{Fast Round} + { + This arrow tip is not really a cap, you use it in conjunction with + (typically) the |Round Cap|. The idea is that you end your line + using the round cap and then add several \texttt{Fast + Round}s. As for |Round Cap|, the |length| parameter + dictates the length is the length of the ``main part,'' the + inset sets the length of a line that comes before this tip. + } + {length=5mm,inset=1cm} + {length=5mm,inset=-1cm} + {-15mm} + +\begin{codeexample}[] +\tikz \draw [line width=1ex, + -{Round Cap []. Fast Round[] Fast Round[]}] + (0,0) -- (1,0); +\end{codeexample} + Note that in conjunction with the |bend| option, this works even + quite well for curves: +\begin{codeexample}[] +\tikz [f/.tip = Fast Round] % shorthand + \draw [line width=1ex, -{[bend] Round Cap[] . f f f}] + (0,0) to [bend left] (1,0); +\end{codeexample} + + \begin{arrowcapexamples} + \arrowcapexample[] + \arrowcapexample[reversed] + \arrowcapexample[cap angle=60] + \arrowcapexample[cap angle=60,inset=5pt] + \arrowcapexample[length=.5ex] + \arrowcapexample[slant=.3] + \end{arrowcapexamples} +\end{arrowcap} + + +\begin{arrowcap}{Fast Triangle} + { + This arrow tip works like |Fast Round|, only for triangular caps. + } + {length=5mm,inset=1cm} + {length=5mm,inset=-1cm} + {-15mm} + +\begin{codeexample}[] +\tikz \draw [line width=1ex, + -{Triangle Cap []. Fast Triangle[] Fast Triangle[]}] + (0,0) -- (1,0); +\end{codeexample} + Again, this tip works well for curves: +\begin{codeexample}[] +\tikz [f/.tip = Fast Triangle] % shorthand + \draw [line width=1ex, -{[bend] Triangle Cap[] . f f f}] + (0,0) to [bend left] (1,0); +\end{codeexample} + + \begin{arrowcapexamples} + \arrowcapexample[] + \arrowcapexample[reversed] + \arrowcapexample[cap angle=60] + \arrowcapexample[cap angle=60,inset=5pt] + \arrowcapexample[length=.5ex] + \arrowcapexample[slant=.3] + \end{arrowcapexamples} +\end{arrowcap} + + + +\begin{arrowcap}{Round Cap} + { + This arrow tip ends the line using a half circle or, if the length + has been modified, a half-ellipse. + } + {length=5mm} + {length=5mm} + {-5mm} + \begin{arrowcapexamples} + \arrowcapexample[] + \arrowcapexample[reversed] + \arrowcapexample[length=.5ex] + \arrowcapexample[slant=.3] + \end{arrowcapexamples} +\end{arrowcap} + + + +\begin{arrowcap}{Triangle Cap} + { + This arrow tip ends the line using a triangle whose length is + given by the |length| option. + } + {length=5mm} + {length=5mm} + {-5mm} + + You can get any angle you want at the tip by specifying a length + that is an appropriate multiple of the line width. The following + options does this computation for you: + \begin{key}{/pgf/arrow keys/cap angle=\meta{angle}} + Sets |length| to an appropriate multiple of the line width so that + the angle of a |Triangle Cap| is exactly \meta{angle} at the tip. + \end{key} + + \begin{arrowcapexamples} + \arrowcapexample[] + \arrowcapexample[reversed] + \arrowcapexample[cap angle=60] + \arrowcapexample[cap angle=60,reversed] + \arrowcapexample[length=.5ex] + \arrowcapexample[slant=.3] + \end{arrowcapexamples} +\end{arrowcap} + + +\subsubsection{Special Arrow Tips} + +\begin{arrowtip}{Rays} + { + This arrow tip attaches a ``bundle of rays'' to the tip. The + number of evenly spaced rays is given by the |n| arrow key (see + below). When the number is even, the rays will lie to the left and + to the right of the direction of the arrow; when the number is + odd, the rays are rotated in such a way that one of them points + perpendicular to the direction of the arrow (this is to ensure + that no ray points in the direction of the line, which would look + strange). The |length| and |width| describe the length and width + of an ellipse into which the rays fit. + } + {length=3cm,width=3cm,n=6} + {length=3cm,width=3cm} + + \begin{arrowexamples} + \arrowexample[] + \arrowexampledup[sep] + \arrowexampledupdot[sep] + \arrowexample[width'=0pt 2] + \arrowexample[round] + \arrowexample[n=2] + \arrowexample[n=3] + \arrowexample[n=4] + \arrowexample[n=5] + \arrowexample[n=6] + \arrowexample[n=7] + \arrowexample[n=8] + \arrowexample[n=9] + \arrowexample[slant=.3] + \arrowexample[left] + \arrowexample[right] + \arrowexample[left,n=5] + \arrowexample[right,n=5] + \arrowexample[red] + \end{arrowexamples} +\end{arrowtip} +\begin{key}{/pgf/arrow keys/n=\meta{number} (initially 4)} + Sets the number of rays in a |Rays| arrow tip. +\end{key} + + +\endinput + + diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-coordinates.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-coordinates.tex index 1847b27bc92..d23d81efb3e 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-coordinates.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-coordinates.tex @@ -18,7 +18,7 @@ coordinates. Coordinates are always put in round brackets. The general syntax is \declare{|(|\opt{|[|\meta{options}|]|}\meta{coordinate specification}|)|}. -The \meta{coordinate specification} specified coordinates using one of +The \meta{coordinate specification} specifies coordinates using one of many different possible \emph{coordinate systems}. Examples are the Cartesian coordinate system or polar coordinates or spherical coordinates. No matter which coordinate system is used, in the end, a @@ -185,7 +185,7 @@ by interpreting them as |pt|. So, |2+3cm| is the same dimension as polar coordinates. You provide an angle using the |angle=| option and a radius using the |radius=| option. This yields the point on the canvas that is at the given radius distance from the origin at - the given degree. A degree of zero points to the right, a degree of + the given degree. An angle of zero degrees to the right, a degree of 90 upward. \begin{key}{/tikz/cs/angle=\meta{degrees}} The angle of the coordinate. @@ -238,7 +238,7 @@ by interpreting them as |pt|. So, |2+3cm| is the same dimension as point that lies at a given angle on this ellipse, where an angle of zero is the same as the $x$-vector and an angle of 90 is the $y$-vector. Finally, multiply the resulting vector by the given - radius factor. Voilà. + radius factor. Voil\`a. \begin{key}{/tikz/cs/angle=\meta{degrees}} The angle of the coordinate interpreted in the ellipse whose axes are the $x$-vector and the @@ -359,8 +359,8 @@ you use the following coordinate system: You can use three options to specify which coordinate you mean: \begin{key}{/tikz/cs/name=\meta{node name}} - Specifies the node in which you which to specify a coordinate. The - \meta{node name} is + Specifies the node that you wish to use to specify a coordinate. + The \meta{node name} is the name that was previously used to name the node using the |name=|\meta{node name} option or the special node name syntax. \end{key} @@ -375,7 +375,8 @@ you use the following coordinate system: \draw (node cs:name=circle,anchor=north) |- (0,1); \draw (node cs:name=ellipse,anchor=north) |- (0,1); - \draw[-open triangle 90] (node cs:name=rect,anchor=north) + \draw [arrows = -{Triangle[open, angle=60:3mm]}] + (node cs:name=rect,anchor=north) |- (0,1) -| (node cs:name=shape,anchor=south); \end{tikzpicture} \end{codeexample} @@ -700,7 +701,7 @@ coordinate system. \declare{|(|\meta{q}\verb! -| !\meta{p}|)|}. For example, \verb!(2,1 |- 3,4)! and \verb!(3,4 -| 2,1)! both yield - the same as \verb!(2,4)! (provided the $xy$-coordinate system has not + the same as \verb!(2,4)! (provided the $xy$-co\-or\-di\-nate system has not been modified). The most useful application of the syntax is to draw a line up to some @@ -719,6 +720,30 @@ coordinate system. \draw[->] (p2) -- (p2 -| yline); \end{tikzpicture} \end{codeexample} + + Note that in \declare{|(|\meta{c}\verb! |- !\meta{d}|)|} the + coordinates \meta{c} and \meta{d} are \emph{not} surrounded by + parentheses. If they need to be complicated expressions (like a + computation using the |$|-syntax), %$ + you must surround them with braces; parentheses will then be added + around them. + + As an example, let us specify a point that lies horizontally at the + middle of the line from $A$ to~$B$ and vertically at the middle of + the line from $C$ to~$D$: +\begin{codeexample}[] +\begin{tikzpicture} + \node (A) at (0,1) {A}; + \node (B) at (1,1.5) {B}; + \node (C) at (2,0) {C}; + \node (D) at (2.5,-2) {D}; + + \draw (A) -- (B) node [midway] {x}; + \draw (C) -- (D) node [midway] {x}; + + \node at ({$(A)!.5!(B)$} -| {$(C)!.5!(D)$}) {X}; +\end{tikzpicture} +\end{codeexample} \end{coordinatesystem} @@ -728,7 +753,7 @@ coordinate system. This library enables the calculation of intersections of two arbitrary paths. However, due to the low accuracy of \TeX, the paths should not be ``too complicated''. - In particular, you should not try to intersect paths consisting + In particular, you should not try to intersect paths consisting of lots of very small segments such as plots or decorated paths. \end{tikzlibrary} @@ -787,7 +812,7 @@ The following keys can be used in \meta{options}: \end{key} \begin{key}{/tikz/intersection/total=\meta{macro}} - This key will mean than the total number of intersections found + This key means that the total number of intersections found will be stored in \meta{macro}. \end{key} @@ -908,14 +933,14 @@ notation to specify numerous points, all relative to the same There is a special situation, where relative coordinates are interpreted differently. If you use a relative coordinate as a control -point of a Bézier curve, the following rule applies: First, a relative +point of a B\'ezier curve, the following rule applies: First, a relative first control point is taken relative to the beginning of the curve. Second, a relative second control point is taken relative to the end of the curve. Third, a relative end point of a curve is taken relative to the start of the curve. This special behavior makes it easy to specify that a curve should -``leave or arrives from a certain direction'' at the start or end. In +``leave or arrive from a certain direction'' at the start or end. In the following example, the curve ``leaves'' at $30^\circ$ and ``arrives'' at $60^\circ$: @@ -928,6 +953,55 @@ the following example, the curve ``leaves'' at $30^\circ$ and \end{codeexample} +\subsubsection{Rotational Relative Coordinates} + +You may sometimes wish to specify points relative not only to the +previous point, but additionally relative to the tangent entering the +previous point. For this, the following key is useful: + +\begin{key}{/tikz/turn} + This key can be given as an option to a \meta{coordinate} as in the + following example: +\begin{codeexample}[] +\tikz \draw (0,0) -- (1,1) -- ([turn]-45:1cm) -- ([turn]-30:1cm); +\end{codeexample} + The effect of this key is to locally shift the coordinate system so + that the last point reached is at the origin and the coordinate + system is ``turned'' so that the $x$-axis points in the direction of + a tangent entering the last point. This means, in effect, that when + you use polar coordinates of the form \meta{relative + angle}|:|\meta{distance} together with the |turn| option, you + specify a point that lies at \meta{distance} from the last point in + the direction of the last tangent entering the last point, but with + a rotation of \meta{relative angle}. + + This key also works with curves \dots +\begin{codeexample}[] +\tikz [delta angle=30, radius=1cm] + \draw (0,0) arc [start angle=0] -- ([turn]0:1cm) + arc [start angle=30] -- ([turn]0:1cm) + arc [start angle=60] -- ([turn]30:1cm); +\end{codeexample} +\begin{codeexample}[] +\tikz \draw (0,0) to [bend left] (2,1) -- ([turn]0:1cm); +\end{codeexample} + + \dots and with plots \dots +\begin{codeexample}[] +\tikz \draw plot coordinates {(0,0) (1,1) (2,0) (3,0) } -- ([turn]30:1cm); +\end{codeexample} + + Although the above examples use polar coordinates with |turn|, you + can also use any normal coordinate. For instance, |([turn]1,1)| will + append a line of length $\sqrt 2$ that is turns by $45^\circ$ + relative to the tangent to the last point. +\begin{codeexample}[] +\tikz \draw (0.5,0.5) -| (2,1) -- ([turn]1,1) + .. controls ([turn]0:1cm) .. ([turn]-90:1cm); +\end{codeexample} +\end{key} + + \subsubsection{Relative Coordinates and Scopes} \label{section-scopes-relative} An interesting question is, how do relative coordinates behave in the @@ -984,7 +1058,7 @@ decide which you need. It is possible to do some basic calculations that involve coordinates. In essence, you can add and subtract coordinates, scale them, compute midpoints, and do projections. For instance, -|($(a) + 1/3*(1cm,0)$)| is the coordinate that is $1/3$cm to the right +|($(a) + 1/3*(1cm,0)$)| is the coordinate that is $1/3 \text{cm}$ to the right of the point |a|: \begin{codeexample}[] \begin{tikzpicture} @@ -1050,7 +1124,7 @@ following rule is used: Once it has been determined, that a everything up to the next occurrence of |*(|. Note that there is no space between the asterisk and the parenthesis. -It is permissible to put the \meta{factor} is curly braces. This can +It is permissible to put the \meta{factor} in curly braces. This can be used whenever it is unclear where the \meta{factor} would end. Here are some examples of coordinate specifications that consist of @@ -1089,7 +1163,7 @@ $(1-\meta{number})\meta{coordinate x} + \meta{number} \meta{coordinate \meta{number} is interpreted in the |xcolor| package: First, you use a factor between $0$ and $1$, not a percentage, and, second, as the \meta{number} approaches $1$, we approach the second coordinate, not -the first. It is permissible to use \meta{numbers} that are smaller +the first. It is permissible to use a \meta{number} that is smaller than $0$ or larger than $1$. The \meta{number} is evaluated using the |\pgfmathparse| command and, thus, it can involve complicated computations. @@ -1223,7 +1297,7 @@ Here is an example: \end{codeexample} The effect is the following: We project the \meta{projection - coordinate} orthogonally onto to the line from \meta{coordinate} to + coordinate} orthogonally onto the line from \meta{coordinate} to \meta{second coordinate}. This makes it easy to compute projected points: \begin{codeexample}[] diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-decorations.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-decorations.tex index a00c1df01ad..5c1276b02cb 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-decorations.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-decorations.tex @@ -166,7 +166,7 @@ typeset and they can be inaccurate. The reason is that \pgfname\ has to a \emph{lot} of rather difficult computations in the background and \TeX\ is not very good at doing math. Decorations are fastest when applied to straight line segments, but even then they are much slower -than other alternative. For instance, the |ticks| decoration can be +than other alternatives. For instance, the |ticks| decoration can be simulated by clever use of a dashing pattern and the dashing pattern will literally be thousands of times faster to typeset. However, for most decorations there are no real alternatives. @@ -225,7 +225,7 @@ command. \begin{key}{/pgf/decoration=\meta{decoration options}} \keyalias{tikz} This option is used to specify which decoration is used and how it - will look like. Note that his key will \emph{not} cause any + will look like. Note that this key will \emph{not} cause any decorations to be applied, immediately. It takes the |decorate| path command or the |decorate| option to actually decorate a path. The |decoration| option is only used to specify which decoration should @@ -244,7 +244,7 @@ command. The \meta{decoration options} are special options (which have the path prefix |/pgf/decoration/|) that determine the properties of the decoration. Which options are appropriate for a - decoration depend strongly on the decoration, you will have to look + decoration strongly depend on the decoration, you will have to look up the appropriate options in the documentation of the decoration, see Section~\ref{section-library-decorations}. @@ -319,7 +319,7 @@ command. You may sometimes wish to decorate a path over whose construction you have no control. For instance, the path of the background of a node is -created without your having a chance to issue a |decorate| path +created without having a chance to issue a |decorate| path command. In such cases you can use the following option, which allows you to decorate a path ``after the fact.'' @@ -334,7 +334,7 @@ you to decorate a path ``after the fact.'' \end{enumerate} The main use or the |decorate| option is the you can also use it with the nodes. It then causes the background path of the node to be - decorated. Note that you decorate a background path only once in + decorated. Note that you can decorate a background path only once in this manner. That is, in contrast to the |decorate| path command you cannot apply this option twice (this would just set it to |true|, once more). @@ -367,8 +367,8 @@ you to decorate a path ``after the fact.'' \end{codeexample} Here is more useful example, where a postaction is used to add the path after the main path has been drawn. +% \catcode`\|12 % !? \begin{codeexample}[] -\catcode`\|12 \begin{tikzpicture} \draw [help lines] grid (3,2); \fill [draw=red,fill=red!20, @@ -506,7 +506,7 @@ not with meta-decorations. \begin{key}{/pgf/decoration/pre length=\meta{dimension} (initially 0pt)} This key sets the distance along which the pre-decoration should be used. If you do not need/wish a pre-decoration, set this key to - |0pt| (exactly this string, not just to something that evaluated to + |0pt| (exactly this string, not just to something that evaluates to the same things such as |0cm|). \end{key} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-design.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-design.tex index b3e19fdefd6..48a2f06a467 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-design.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-design.tex @@ -21,9 +21,9 @@ The commands and syntax of \tikzname\ were influenced by several sources. The basic command names and the notion of path operations is taken from \textsc{metafont}, the option mechanism comes from \textsc{pstricks}, the notion of styles is reminiscent of -\textsc{svg}. To make it all work together, some compromises were -necessary. I also added some ideas of my own, like coordinate -transformations. +\textsc{svg}, the graph syntax is taken from \textsc{graphviz}. To make it +all work together, some compromises were necessary. I also added some +ideas of my own, like coordinate transformations. The following basic design principles underlie \tikzname: \begin{enumerate} @@ -33,6 +33,7 @@ The following basic design principles underlie \tikzname: \item Key-value syntax for graphic parameters. \item Special syntax for nodes. \item Special syntax for trees. +\item Special syntax for graphs. \item Grouping of graphic parameters. \item Coordinate transformation system. \end{enumerate} @@ -118,7 +119,7 @@ stroking. \subsection{Key-Value Syntax for Graphic Parameters} Whenever \tikzname\ draws or fills a path, a large number of graphic -parameters influenced the rendering. Examples include the colors +parameters influences the rendering. Examples include the colors used, the dashing pattern, the clipping area, the line width, and many others. In \tikzname, all these options are specified as lists of so called key-value pairs, as in |color=red|, that are @@ -137,8 +138,8 @@ in the following example: \tikz \draw (1,1) node {text} -- (2,2); \end{codeexample} Nodes are inserted at the current position of -the path, but only \emph{after} the path has been rendered. When -special options are given, as in +the path, but either \emph{after} (the default) or \emph{before} the +complete path is rendered. When special options are given, as in |\draw (1,1) node[circle,draw] {text};|, the text is not just put at the current position. Rather, it is surrounded by a circle and this circle is ``drawn.'' @@ -152,12 +153,10 @@ it is possible (though a bit challenging) to define new shapes. \subsection{Special Syntax for Specifying Trees} -In addition to the ``node syntax,'' \tikzname\ also introduces a -special syntax for drawing trees. The syntax is intergraded with the -special node syntax and only few new commands need to be remembered. -In essence, a |node| can be followed by any number of children, each -introduced by the keyword |child|. The children are nodes themselves, -each of which may have children in turn. +The ``node syntax'' can also be used to draw tress: A |node| can be +followed by any number of children, each introduced by the keyword +|child|. The children are nodes themselves, each of which may have +children in turn. \begin{codeexample}[] \begin{tikzpicture} @@ -176,7 +175,7 @@ redrawn with different options: \begin{codeexample}[] \begin{tikzpicture} - [edge from parent fork down, + [edge from parent fork down, sibling distance=15mm, level distance=15mm, every node/.style={fill=red!30,rounded corners}, edge from parent/.style={red,-o,thick,draw}] \node {root} @@ -191,6 +190,7 @@ redrawn with different options: \begin{codeexample}[] \begin{tikzpicture} [parent anchor=east,child anchor=west,grow=east, + sibling distance=15mm, level distance=15mm, every node/.style={ball color=red,circle,text=white}, edge from parent/.style={draw,dashed,thick,red}] \node {root} @@ -202,6 +202,31 @@ redrawn with different options: \end{tikzpicture} \end{codeexample} + + +\subsection{Special Syntax for Graphs} + +The |\node| command gives you fine control over where nodes should be +placed, what text they should use, and what they should look +like. However, when you draw a graph, you typically need to create +numerous fairly similar nodes that only differ with respect to the +name they show. In these cases, the |graph| syntax can be used, which +is another syntax layer build ``on top'' of the node syntax. + +\begin{codeexample}[] +\tikz \graph [grow down, branch right] { + root -> { left, right -> {child, child} } +}; +\end{codeexample} +The syntax of the |graph| command extends the so-called +\textsc{dot}-notation used in the popular \textsc{graphviz} program. + +Depending on the version of \TeX\ you use (it must allow you to call +Lua code, which is the case for Lua\TeX), you can also ask \tikzname\ +to do automatically compute good positions for the nodes of a graph +using one of several integrated \emph{graph drawing algorithms}. + + \subsection{Grouping of Graphic Parameters} Graphic parameters should often apply to several path drawing or @@ -244,11 +269,11 @@ transformations, a more low-level transformation system. (For details on the difference between coordinate transformations and canvas transformations see Section~\ref{section-design-transformations}.) -The syntax is setup in such a way that is harder to use canvas +The syntax is set up in such a way that it is harder to use canvas transformations than coordinate transformations. There are two reasons for this: First, the canvas transformation must be used with great care and often results in ``bad'' graphics with changing line width -and text in wrong sizes. Second, \pgfname\ looses track of where nodes +and text in wrong sizes. Second, \pgfname\ loses track of where nodes and shapes are positioned when canvas transformations are used. So, in almost all circumstances, you should use coordinate transformations rather than canvas transformations. diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-graphs.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-graphs.tex new file mode 100644 index 00000000000..91aebaa1b0d --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-graphs.tex @@ -0,0 +1,3515 @@ +% Copyright 2010 by Till Tantau +% Copyright 2011 by Jannis Pohlmann +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\section{Specifying Graphs} +\label{section-library-graphs} + + +\subsection{Overview} + +\tikzname\ offers a powerful path command for specifying how the nodes +in a graph are connected by edges and arcs: The |graph| path +command, which becomes available when you load the |graphs| library. + +\begin{tikzlibrary}{graphs} + The package must be loaded to use the |graph| path command. +\end{tikzlibrary} + +In this section, by \emph{graph} we refer to a set of nodes together +with some edges (sometimes also called arcs, in case they are +directed) such as the following: + +\begin{codeexample}[] +\tikz \graph { a -> {b, c} -> d }; +\end{codeexample} + +\begin{codeexample}[] +\tikz \graph { + subgraph I_nm [V={a, b, c}, W={1,...,4}]; + + a -> { 1, 2, 3 }; + b -> { 1, 4 }; + c -> { 2 [>green!75!black], 3, 4 [>red]} +}; +\end{codeexample} + +\begin{codeexample}[] +\tikz + \graph [nodes={draw, circle}, clockwise, radius=.5cm, empty nodes, n=5] { + subgraph I_n [name=inner] --[complete bipartite] + subgraph I_n [name=outer] + }; +\end{codeexample} + +\begin{codeexample}[] +\tikz + \graph [nodes={draw, circle}, clockwise, radius=.75cm, empty nodes, n=8] { + subgraph C_n [name=inner] <->[shorten <=1pt, shorten >=1pt] + subgraph C_n [name=outer] + }; +\end{codeexample} + +\begin{codeexample}[width=6.6cm] +\tikz [>={To[sep]}, rotate=90, xscale=-1, + mark/.style={fill=black!50}, mark/.default=] + \graph [trie, simple, + nodes={circle,draw}, + edges={nodes={ + inner sep=1pt, anchor=mid, + fill=graphicbackground}}, % yellowish background + put node text on incoming edges] + { + root[mark] -> { + a -> n -> { + g [mark], + f -> a -> n -> g [mark] + }, + f -> a -> n -> g [mark], + g[mark], + n -> { + g[mark], + f -> a -> n -> g[mark] + } + }, + { [edges=red] % highlight one path + root -> f -> a -> n + } + }; +\end{codeexample} + +The nodes of a graph are normal \tikzname\ nodes, the edges are +normal lines drawn between nodes. There is nothing in the |graph| +library that you cannot do using the normal |\node| and the |edge| +commands. Rather, its purpose is to offer a concise and powerful way of +\emph{specifying} which nodes are present +and how they are connected. The |graph| library only offers simple +methods for specifying \emph{where} the nodes should be shown, its +main strength is in specifying which nodes and edges are present in +principle. The problem of finding ``good positions on the canvas'' for +the nodes of a graph is left to \emph{graph drawing algorithms}, which +are covered in Part~\ref{part-gd} of this manual and which +are not part of the |graphs| library; indeed, these algorithms can be +used also with graphs specified using |node| and |edge| +commands. \ifluatex +As an example, consider the above drawing of a trie, which is drawn +without using the graph drawing libraries. Its layout can be +somewhat improved by loading the |layered| graph drawing library, +saying |\tikz[layered layout,...|, and then using Lua\TeX, resulting +in the following drawing of the same graph: +\medskip + +\tikz [layered layout, >={To[sep]}, rotate=90, xscale=-1, + mark/.style={fill=black!50}, mark/.default=] + \graph [trie, simple, sibling distance=8mm, + nodes={circle,draw}, + edges={nodes={ + inner sep=1pt, anchor=mid, fill=white}}, + put node text on incoming edges] + { + root[mark] -> { + a -> n -> { + g [mark], + f -> a -> n -> g [mark] + }, + f -> a -> n -> g [mark], + g[mark], + n -> { + g[mark], + f -> a -> n -> g[mark] + } + }, + { [edges=red] % highlight one path + root -> f -> a -> n + } + }; +\medskip +\fi + +The |graph| library uses a syntax that is quite different from the +normal \tikzname\ syntax for specifying nodes. The reason for this is +that for many medium-sized graphs it can become quite cumbersome to +specify all the nodes using |\node| repeatedly and then using a great +number of |edge| command; possibly with complicated |\foreach| +statements. Instead, the syntax of the |graph| library is loosely +inspired by the \textsc{dot} format, which is quite useful for +specifying medium-sized graphs, with some extensions on top. + + + +\subsection{Concepts} + +The present section aims at giving a quick overview of the main +concepts behind the |graph| command. The exact syntax is explained in +more detail in later sections. + + +\subsubsection{Concept: Node Chains} + +The basic way of specifying a graph is to write down a \emph{node + chain} as in the following example: + +\begin{codeexample}[] +\tikz [every node/.style = draw] + \graph { foo -> bar -> blub }; +\end{codeexample} + +As can be seen, the text |foo -> bar -> my node| creates three nodes, +one with the text |foo|, one with |bar| and one with the text +|blub|. These nodes are connected by arrows, which are caused by +the |->| between the node texts. Such a sequence of node texts and +arrows between them is called a \emph{chain} in the following. + +Inside a graph there can be more than one chain: + +\begin{codeexample}[] +\tikz \graph { + a -> b -> c; + d -> e -> f; + g -> f; +}; +\end{codeexample} + +Multiple chains are separated by a semicolon or a comma (both have +exactly the same effect). As the example shows, when a node text is +seen for the second time, instead of creating a new node, a connection +is created to the already existing node. + +When a node like |f| is created, both the node name and the node text +are identical by default. This is not always desirable and can be +changed by using the |as| key or by providing another text after +a slash: + +\begin{codeexample}[] +\tikz \graph { + x1/$x_1$ -> x2 [as=$x_2$, red] -> x34/{$x_3,x_4$}; + x1 -> [bend left] x34; +}; +\end{codeexample} + +When you wish to use a node name that contains special symbols like +commas or dashes, you must surround the node name by quotes. This +allows you to use quite arbitrary text as a ``node name'': +\begin{codeexample}[] +\tikz \graph { + "$x_1$" -> "$x_2$"[red] -> "$x_3,x_4$"; + "$x_1$" ->[bend left] "$x_3,x_4$"; +}; +\end{codeexample} + + +\subsubsection{Concept: Chain Groups} + +Multiple chains that are separated by a semicolon or a comma and that +are surrounded by curly braces form what will be called a \emph{chain + group} or just a \emph{group}. A group in itself has no special +effect. However, things get interesting when you write down a node or +even a whole group and connect it to another group. In this case, the +``exit points'' of the first node or group get connected to the +``entry points'' of the second node or group: + +\begin{codeexample}[] +\tikz \graph { + a -> { + b -> c, + d -> e + } -> f +}; +\end{codeexample} + +Chain groups make it easy to create tree structures: + +\begin{codeexample}[width=10cm] +\tikz + \graph [grow down, + branch right=2.5cm] { + root -> { + child 1, + child 2 -> { + grand child 1, + grand child 2 + }, + child 3 -> { + grand child 3 + } + } +}; +\end{codeexample} + +As can be seen, the placement is not particularly nice by default, use +the algorithms from the graph drawing libraries to get a better +layout. For instance, adding |tree layout| to the above code results in the +following somewhat more pleasing rendering: +\ifluatex +\medskip + +\tikz \graph [grow down, branch right=2.5cm, tree layout] { + root -> { + child 1, + child 2 -> { + grand child 1, + grand child 2 + }, + child 3 -> { + grand child 3 + } + } +}; +\else +(You need to use Lua\TeX\ to typeset this graphic.) +\fi + +\subsubsection{Concept: Edge Labels and Styles} + +When connectors like |->| or |--| are used to connect nodes or whole +chain groups, one or more edges will typically be created. These edges +can be styles easily by providing options in square brackets directly +after these connectors: + +\begin{codeexample}[] +\tikz \graph { + a ->[red] b --[thick] {c, d}; +}; +\end{codeexample} + +Using the quotes syntax, see Section~\ref{section-label-quotes}, +you can even add labels to the edges easily by putting the labels in +quotes: + +\begin{codeexample}[] +\tikz \graph { + a ->[red, "foo"] b --[thick, "bar"] {c, d}; +}; +\end{codeexample} + +For the first edge, the effect is as desired, however +between |b| and the group |{c,d}| two edges are inserted and the +options |thick| and the label option |"bar"| is applied to both of +them. While this is the correct and consistent behaviour, we typically +might wish to specify different labels for the edge going from |b| to +|c| and the edge going from |b| to |d|. To achieve this effect, we can +no longer specify the label as part of the options of |--|. Rather, we +must pass the desired label to the nodes |c| and |d|, but we must +somehow also indicate that these options actually ``belong'' to the +edge ``leading to'' to nodes. This is achieved by preceding the +options with a greater-than sign: + +\begin{codeexample}[] +\tikz \graph { + a -> b -- {c [> "foo"], d [> "bar"']}; +}; +\end{codeexample} + +Symmetrically, preceding the options by |<| causes the options and +labels to apply to the ``outgoing'' edges of the node: + +\begin{codeexample}[] +\tikz \graph { + a [< red] -> b -- {c [> blue], d [> "bar"']}; +}; +\end{codeexample} + +This syntax allows you to easily create trees with special edge +labels as in the following example of a treap: + +\begin{codeexample}[] +\tikz + \graph [edge quotes={fill=white,inner sep=1pt}, + grow down, branch right, nodes={circle,draw}] { + "" -> h [>"9"] -> { + c [>"4"] -> { + a [>"2"], + e [>"0"] + }, + j [>"7"] + } + }; +\end{codeexample} + + + +\subsubsection{Concept: Node Sets} + +When you write down some node text inside a |graph| command, a new +node is created by default unless this node has already been created +inside the same |graph| command. In particular, if a node has +already been declared outside of the current |graph| command, a new +node of the same name gets created. + +This is not always the desired behaviour. Often, you may wish to make +nodes part of a graph than have already been defined prior to the use +of the |graph| command. For this, simply surround a node name by +parentheses. This will cause a reference to be created to an already +existing node: + +\begin{codeexample}[] +\tikz { + \node (a) at (0,0) {A}; + \node (b) at (1,0) {B}; + \node (c) at (2,0) {C}; + + \graph { (a) -> (b) -> (c) }; +} +\end{codeexample} + +You can even go a step further: A whole collection of nodes can all be +flagged to belong to a \emph{node set} by adding the option +|set=|\meta{node set name}. Then, inside a |graph| command, you can +collectively refer to these nodes by surrounding the node set name in +parentheses: + +\begin{codeexample}[] +\tikz [new set=my nodes] { + \node [set=my nodes, circle, draw] at (1,1) {A}; + \node [set=my nodes, rectangle, draw] at (1.5,0) {B}; + \node [set=my nodes, diamond, draw] at (1,-1) {C}; + \node (d) [star, draw] at (3,0) {D}; + + \graph { X -> (my nodes) -> (d) }; +} +\end{codeexample} + + +\subsubsection{Concept: Graph Macros} + +Often, a graph will consist -- at least in parts -- of standard +parts. For instance, a graph might contain a cycle of certain size or +a path or a clique. To facilitate specifying such graphs, you can +define a \emph{graph macro}. Once a graph macro has been defined, you +can use the name of the graph to make a copy of the graph part of the +graph currently being specified: + +\begin{codeexample}[] +\tikz \graph { subgraph K_n [n=6, clockwise] }; +\end{codeexample} + +\begin{codeexample}[] +\tikz \graph { subgraph C_n [n=5, clockwise] -> mid }; +\end{codeexample} + +The library |graphs.standard| defines a number of such graphs, +including the complete clique $K_n$ on $n$ nodes, the complete +bipartite graph $K_{n,m}$ with shores sized $n$ and $m$, the cycle +$C_n$ on $n$ nodes, the path $P_n$ on $n$ nodes, and the independent +set $I_n$ on $n$ nodes. + + +\subsubsection{Concept: Graph Expressions and Color Classes} + +When a graph is being constructed using the |graph| command, it is +constructed recursively by uniting smaller graphs to larger +graphs. During this recursive union process the nodes +of the graph get implicitly \emph{colored} (conceptually) and you can +also explicitly assign colors to individual nodes and even change the +colors as the graph is being specified. All nodes having the same +color form what is called a \emph{color class}. + +The power of color class is that special \emph{connector operators} +allow you to add edges between nodes having certain colors. For instance, +saying |clique=red| at the beginning of a group will +cause all nodes that have been flagged as being (conceptually) ``red'' +to be connected as a clique. Similarly, saying +|complete bipartite={red}{green}| will cause edges to be added +between all red and all green nodes. More advanced connectors, like +the |butterfly| connector, allow you to add edges between color +classes in a fancy manner. + +\begin{codeexample}[] +\tikz [x=8mm, y=6mm, circle] + \graph [nodes={fill=blue!70}, empty nodes, n=8] { + subgraph I_n [name=A] --[butterfly={level=4}] + subgraph I_n [name=B] --[butterfly={level=2}] + subgraph I_n [name=C] --[butterfly] + subgraph I_n [name=D] -- + subgraph I_n [name=E] + }; +\end{codeexample} + + + +\subsection{Syntax of the Graph Path Command} + +\subsubsection{The Graph Command} + +In order to construct a graph, you should use the |graph| path +command, which can be used anywhere on a path at any place where +you could also use a command like, say, |plot| or |--|. + +\begin{command}{\graph} + Inside a |{tikzpicture}| this is an abbreviation for |\path graph|. +\end{command} + +\begin{pathoperation}{graph}{\opt{\oarg{options}}\meta{group specification}} + When this command is encountered on a path, the construction of the + current path is suspended (similarly to an |edge| command or a + |node| command). In a local scope, the \meta{options} are first + executed with the key path |/tikz/graphs| using the following + command: + \begin{command}{\tikzgraphsset\marg{options}} + Executes the \meta{options} with the path prefix |/tikz/graphs|. + \end{command} + Apart from the keys explained in the following, further permissible + keys will be listed during the course of the rest of this section. + + \begin{stylekey}{/tikz/graphs/every graph} + This style is executed at the beginning of every |graph| path + command prior to the \meta{options}. + \end{stylekey} + + Once the scope has been set up and once the \meta{options} have been + executed, a parser starts to parse the \meta{group + specification}. The exact syntax of such a group specification + in explained in detail in + Section~\ref{section-library-graphs-group-spec}. Basically, a group + specification is a list of chain specifications, separated by commas + or semicolons. + + Depending on the content of the \meta{group specification}, two + things will happen: + \begin{enumerate} + \item A number of new nodes may be created. These will be inserted + into the picture in the same order as if they had been created + using multiple |node| path commands at the place where the |graph| + path command was used. In other words, all nodes created in a + |graph| path command will be painted on top of any nodes created + earlier in the path and behind any nodes created later in the + path. Like normal nodes, the newly created nodes always lie on top + of the path that is currently being created (which is often + empty, for instance when the |\graph| command is used). + \item Edges between the nodes may be added. They are added in the + same order as if the |edge| command had been used at the position + where the |graph| command is being used. + \end{enumerate} + + Let us now have a look at some common keys that may be used inside + the \meta{options}: + \begin{key}{/tikz/graphs/nodes=\meta{options}} + This option causes the \meta{options} to be applied to each newly + created node inside the \meta{group specification}. + \begin{codeexample}[] +\tikz \graph [nodes=red] { a -> b -> c }; + \end{codeexample} + Multiple uses of this key accumulate. + \end{key} + \begin{key}{/tikz/graphs/edges=\meta{options}} + This option causes the \meta{options} to be applied to each newly + created edge inside the \meta{group specification}. + \begin{codeexample}[] +\tikz \graph [edges={red,thick}] { a -> b -> c }; + \end{codeexample} + Again, multiple uses of this key accumulate. + \end{key} + \begin{key}{/tikz/graphs/edge=\meta{options}} + This is an alias for |edges|. + \end{key} + + \begin{key}{/tikz/graphs/edge node=\meta{node specification}} + This key specifies that the \meta{node specification} should be + added to each newly created edge as an implicitly placed node. + \begin{codeexample}[] +\tikz \graph [edge node={node [red, near end] {X}}] { a -> b -> c }; + \end{codeexample} + Again, multiple uses of this key accumulate. + \begin{codeexample}[] +\tikz \graph [edge node={node [near end] {X}}, + edge node={node [near start] {Y}}] { a -> b -> c }; + \end{codeexample} + \end{key} + + \begin{key}{/tikz/graphs/edge label=\meta{text}} + This key is an abbreviation for + |edge node=node[auto]{|\meta{text}|}|. The net effect is that the + |text| is placed next to the newly created edges. + \begin{codeexample}[] +\tikz \graph [edge label=x] { a -> b -> {c,d} }; + \end{codeexample} + \end{key} + + \begin{key}{/tikz/graphs/edge label'=\meta{text}} + This key is an abbreviation for + |edge node=node[auto,swap]{|\meta{text}|}|. + \begin{codeexample}[] +\tikz \graph [edge label=out, edge label'=in] + { subgraph C_n [clockwise, n=5] }; + \end{codeexample} + \end{key} +\end{pathoperation} + + +\subsubsection{Syntax of Group Specifications} +\label{section-library-graphs-group-spec} + +A \meta{group specification} inside a |graph| path command has the +following syntax: +\begin{quote} + |{|\opt{\oarg{options}}\meta{list of chain specifications}|}| +\end{quote} +The \meta{chain specifications} must contain chain specifications, +whose syntax is detailed in the next section, separated by either +commas or semicolons; you can freely mix them. +It is permissible to use empty lines (which are mapped to |\par| +commands internally) to structure the chains visually, they are simply +ignored by the parser. + +In the following example, the group specification consists of three +chain specifications, namely of |a -> b|, then |c| alone, and finally +|d -> e -> f|: +\begin{codeexample}[] +\tikz \graph { + a -> b, + c; + + d -> e -> f +}; +\end{codeexample} +The above has the same effect as the more compact group specification +|{a->b,c,d->e->f}|. + +Commas are used to detect where chain specifications end. However, you +will often wish to use a comma also inside the options of a single +node like in the following example: + +\begin{codeexample}[] +\tikz \graph { + a [red, draw] -> b [blue, draw], + c [brown, draw, circle] +}; +\end{codeexample} + +Note that the above example works as expected: The first comma inside +the option list of |a| is \emph{not} interpreted as the end of the +chain specification ``|a [red|''. Rather, commas inside square +brackets are ``protected'' against being interpreted as separators of +group specifications. + +The \meta{options} that can be given at the beginning of a group +specification are local to the group. They are executed with the path +prefix |/tikz/graphs|. Note that for the outermost group specification +of a graph it makes no difference whether the options are passed to +the |graph| command or whether they are given at the beginning of this +group. However, for groups nested inside other groups, it does make a +difference: + +\begin{codeexample}[] +\tikz \graph { + a -> { [nodes=red] % the option is local to these nodes: + b, c + } -> + d +}; +\end{codeexample} + +\medskip +\textbf{Using foreach.} +There is special support for the |\foreach| statement inside groups: +You may use the statement inside a group +specification at any place where a \meta{chain specification} would +normally go. In this case, the |\foreach| statement is executed and +for each iteration the content of the statement's body is treated and +parsed as a new chain specification. + +\begin{codeexample}[] +\tikz \graph [math nodes, branch down=5mm] { + a -> { + \foreach \i in {1,2,3} { + a_\i -> { x_\i, y_\i } + }, + b + } +}; +\end{codeexample} + +\medskip +\textbf{Using macros.} +In some cases you may wish to use macros and \TeX\ code to compute +which nodes and edges are present in a group. You cannot use macros in +the normal way inside a graph specification since the parser does not +expand macros as it scans for the start and end of groups and node +names. Rather, only after commas, semicolons, and hyphens have already +been detected and only after all other parsing decisions have been +made will macros be expanded. At this point, when a macro expands to, +say |a,b|, this will not result in two nodes to be created since the +parsing is already done. For these reasons, a special key is needed to +make it possible to ``compute'' which nodes should be present in a +group. + +\begin{key}{/tikz/graph/parse=\meta{text}} + This key can only be used inside the \meta{options} of a \meta{group + specification}. Its effect is that the \meta{text} is inserted at + the beginning of the current group as if you had entered it there. + Naturally, it makes little sense to just write down some static + \meta{text} since you could just as well directly place it at the + beginning of the group. The real power of this command stems from + the fact that the keys mechanism allows you to say, for instance, + |parse/.expand once| to insert the text stored in some macro into + the group. +\begin{codeexample}[] +\def\mychain{ a -> b -> c; } +\tikz \graph { [parse/.expand once=\mychain] d -> e }; +\end{codeexample} + In the following, more fancy example we use a loop to create a chain + of dynamic length. +\begin{codeexample}[] +\def\mychain#1{ + \def\mytext{1} + \foreach \i in {2,...,#1} { + \xdef\mytext{\mytext -> \i} + } +} +\tikzgraphsset{my chain/.style={ + /utils/exec=\mychain{#1}, + parse/.expand once=\mytext} +} +\tikz \graph { [my chain=4] }; +\end{codeexample} + Multiple uses of this key accumulate, that is, all the \text{text}s + given in the different uses is inserted in the order it is given. +\end{key} + + +\subsubsection{Syntax of Chain Specifications} + +A \meta{chain specification} has the following syntax: It consists of +a sequence of \meta{node specifications}, where subsequent node +specifications are separated by \meta{edge specifications}. Node +specifications, which typically consist of some text, are discussed in +the next section in more detail. They normally represent a single node +that is either newly created or exists already, but they may also +specify a whole set of nodes. + +An \meta{edge specification} specifies \emph{which} of the node(s) to +the left of the edge specification should be connected to which +node(s) to the right of it and it also specifies in which direction +the connections go. In the following, we only discuss how the +direction is chosen, the powerful mechanism behind choosing which +nodes should be connect is detailed in +Section~\ref{section-library-graphs-color-classes}. + +The syntax of an edge specification is always one of the following +five possibilities: + +\begin{quote} + |->| \opt{\oarg{options}}\\ + |--| \opt{\oarg{options}}\\ + |<-| \opt{\oarg{options}}\\ + |<->| \opt{\oarg{options}}\\ + |-!-| \opt{\oarg{options}} +\end{quote} + +The first four correspond to a directed edge, an undirected edge, a +``backward'' directed edge, and a bidirected edge, respectively. The +fifth edge specification means that there should be no edge (this +specification can be used together with the |simple| option to remove +edges that have previously been added, see +Section~\ref{section-library-graphs-simple}). + +Suppose the nodes \meta{left nodes} are to the left of the \meta{edge + specification} and \meta{right nodes} are to the right and suppose +we have written |->| between them. Then the following happens: +\begin{enumerate} +\item The \meta{options} are executed (inside a local scope) with the + path |/tikz/graphs|. These options may setup the connector algorithm + (see below) and may also use keys like |edge| or |edge label| to + specify how the edge should look like. As a convenience, whenever an + unknown key is encountered for the path |/tikz/graphs|, the key is + passed to the |edge| key. This means that you can directly use + options like |thick| or |red| inside the \meta{options} and they + will apply to the edge as expected. +\item The chosen connector algorithm, see + Section~\ref{section-library-graphs-color-classes}, is used to + compute from which of the \meta{left nodes} an edge should lead to + which of the \meta{right nodes}. Suppose that $(l_1,r_1)$, \dots, + $(l_n,r_n)$ is the list of node pairs that result (so there should + be an edge between $l_1$ and $r_1$ and another edge between $l_2$ + and $r_2$ and so on). +\item For each pair $(l_i,r_i)$ an edge is created. This is done by + calling the following key (for the edge specification |->|, other + keys are executed for the other kinds of specifications): + \begin{key}{/tikz/graphs/new ->=\marg{left node}\marg{right node}\marg{edge options}\marg{edge nodes}} + This key will be called for a |->| edge specification with the + following four parameters: + \begin{enumerate} + \item \meta{left node} is the name of the ``left'' node, that is, + the name of $l_i$. + \item \meta{right node} is the name of the right node. + \item \meta{edge options} are the accumulated options from all + calls of |/tikz/graph/edges| in groups that surround the edge + specification. + \item \meta{edge nodes} is text like |node {A} node {B}| that + specifies some nodes that should be put as labels on the edge + using \tikzname's implicit positioning mechanism. + \end{enumerate} + By default, the key executes the following code: + \begin{quote} + |\path [->,every new ->]|\\ + \hbox{}\quad|(|\meta{left node}|\tikzgraphleftanchor) edge [|% + \meta{edge options}|]| \meta{edge nodes}||\\ + \hbox{}\quad|(|\meta{right node}|\tikzgraphrightanchor);| + \end{quote} + You are welcome to change the code underlying the key. + \begin{stylekey}{/tikz/every new ->} + This key gets executed by default for a |new ->|. + \end{stylekey} + \end{key} + \begin{key}{/tikz/graphs/left anchor=\meta{anchor}} + This anchor is used for the node that is to the left of an edge + specification. Setting this anchor to the empty string means that + no special anchor is used (which is the default). The + \meta{anchor} is stored in the macro |\tikzgraphleftanchor| with a + leading dot. + \begin{codeexample}[] +\tikz \graph { + {a,b,c} -> [complete bipartite] {e,f,g} +}; + \end{codeexample} + \begin{codeexample}[] +\tikz \graph [left anchor=east, right anchor=west] { + {a,b,c} -- [complete bipartite] {e,f,g} +}; + \end{codeexample} + \end{key} + \begin{key}{/tikz/graphs/right anchor=\meta{anchor}} + Works like |left anchor|, only for |\tikzgraphrightanchor|. + \end{key} + For the other three kinds of edge specifications, the following keys + will be called: + \begin{key}{/tikz/graphs/new --=\marg{left node}\marg{right node}\marg{edge options}\marg{edge nodes}} + This key is called for |--| with the same parameters as above. The + only difference in the definition is that in the |\path| command + the |->| gets replaced by |-|. + \begin{stylekey}{/tikz/every new --} + \end{stylekey} + \end{key} + \begin{key}{/tikz/graphs/new <->=\marg{left node}\marg{right node}\marg{edge options}\marg{edge nodes}} + Called for |<->| with the same parameters as above. The |->| is + replaced by |<-| + \begin{stylekey}{/tikz/every new <->} + \end{stylekey} + \end{key} + \begin{key}{/tikz/graphs/new <-=\marg{left node}\marg{right node}\marg{edge options}\marg{edge nodes}} + Called for |<-| with the same parameters as above.% + \footnote{You might + wonder why this key is needed: It seems more logical at first + sight to just call |new edge directed| with swapped first + parameters. However, a positioning + algorithm might wish to take the fact into account that an edge is + ``backward'' rather than ``forward'' in order to + improve the layout. Also, different arrow heads might be used.} + \begin{stylekey}{/tikz/every new <-} + \end{stylekey} + \end{key} + \begin{key}{/tikz/graphs/new -\protect\exclamationmarktext-=\marg{left node}\marg{right node}\marg{edge options}\marg{edge nodes}} + Called for |-!-| with the same parameters as above. Does nothing + by default. + \end{key} +\end{enumerate} + +Here is an example that shows the default rendering of the different +edge specifications: + +\begin{codeexample}[] +\tikz \graph [branch down=5mm] { + a -> b; + c -- d; + e <- f; + g <-> h; + i -!- j; +}; +\end{codeexample} + + + +\subsubsection{Syntax of Node Specifications} + +\label{section-library-graphs-node-spec} + +Node specifications are the basic building blocks of a graph +specification. There are three different possible kinds of node +specifications, each of which has a different syntax: + +\begin{description} +\item[Direct Node Specification] + \ \\ + \opt{|"|}\meta{node name}\opt{|"|}\opt{|/|\opt{|"|}\meta{text}\opt{|"|}} \opt{\oarg{options}}\\ + (note that the quotation marks are optional and only needed when the + \meta{node name} contains special symbols) +\item[Reference Node Specification] + \ \\ + |(|\meta{node name or node set name}|)| +\item[Group Node Specification] + \ \\ + \meta{group specification} +\end{description} + +The rule for determining which of the possible kinds is meant is +as follows: If the node specification starts with an opening +parenthesis, a reference node specification is meant; if it starts +with an opening curly brace, a group specification is meant; and in +all other cases a direct node specification is meant. + +\medskip +\textbf{Direct Node Specifications.} If after reading the first symbol +of a node specification is has been detected to be \emph{direct}, +\tikzname\ will collect all text up to the next edge +specification and store it as the \meta{node name}; however, square +brackets are used to indicate options and a slash ends the \meta{node + name} and start a special \meta{text} that is used as a +rendering text instead of the original \meta{node name}. + +Due to the way the parsing works and due to the restrictions on node +names, most special characters are forbidding inside the \meta{node + name}, including commas, semicolons, hyphens, braces, dots, +parentheses, slashes, dashes, and more (but spaces, single +underscores, and the hat character \emph{are} allowed). To use special +characters in the name of a node, you can optionally surround the +\meta{node name} and/or the \meta{text} by quotation marks. In this +case, you can use all of the special symbols once more. The details +of what happens, exactly, when the \meta{node name} is surrounded by +quotation marks is explained later; surrounding the \meta{text} by +quotation marks has essentially the same effect as surrounding it by +curly braces. + +Once the node name has been determined, it is checked whether the same +node name was already used inside the current graph. If this is the +case, then we say that the already existing node is \emph{referenced}; +otherwise we say that the node is \emph{fresh}. + +\begin{codeexample}[] +\tikz \graph { + a -> b; % both are fresh + c -> a; % only c is fresh, a is referenced +}; +\end{codeexample} + +This behaviour of deciding whether a node is fresh or referenced can, +however, be modified by using the following keys: +\begin{key}{/tikz/graphs/use existing node=\opt{\meta{true or + false}} (default true)} + When this key is set to |true|, all nodes will be considered to the + referenced, no node will be fresh. This option is useful if you have + already created all the nodes of a graph prior to using the |graph| + command and you now only wish to connect the nodes. +\end{key} +\begin{key}{/tikz/graphs/fresh nodes=\opt{\meta{true or + false}} (default true)} + When this key is set to |true|, all nodes will be considered to be + fresh. This option is useful when you create for instance a tree + with many identical nodes. + + When a node name is encountered that was already used previously, + a new name is chosen is follows: An apostrophe (|'|) is appended + repeatedly until a node name is found that has not yet been + used: +\begin{codeexample}[] +\tikz \graph [branch down=5mm] { + { [fresh nodes] + a -> { + b -> {c, c}, + b -> {c, c}, + b -> {c, c}, + } + }, + b' -- b'' +}; +\end{codeexample} +\end{key} + +When a fresh node has been detected, a new node is created in the +inside a protecting scope. For this, the current +placement strategy is asked to compute a default position for the +node, see Section~\ref{section-library-graphs-placement} for +details. Then, the command +\begin{quote} + |\node (|\meta{full node name}|) [|\meta{node options}|] {|\meta{text}|};| +\end{quote} +is called. The different parameters are as follows: +\begin{itemize} +\item + The \meta{full node name} is normally the \meta{node name} that has + been determined as described before. However, there are two exceptions: + + First, if the \meta{node name} is empty (which happens when there + is no \meta{node name} before the slash), then a fresh internal node + name is created and used as + \meta{full node name}. This name is guaranteed to be different from all + node names used in this or any other graph. Thus, a direct node + starting with a slash represents an anonymous fresh node. + + Second, you can use the following key to prefix the \meta{node name} + inside the \meta{full node name}: + + \begin{key}{/tikz/graphs/name=\meta{text}} + This key prepends the \meta{text}, followed by a separating symbol + (a space by default), to all + \meta{node name}s inside a \meta{full node name}. Repeated calls + of this key accumulate, leading to ever-longer ``name paths'': +\begin{codeexample}[] +\begin{tikzpicture} + \graph { + { [name=first] 1, 2, 3} -- + { [name=second] 1, 2, 3} + }; + \draw [red] (second 1) circle [radius=3mm]; +\end{tikzpicture} +\end{codeexample} + Note that, indeed, in the above example six nodes are created even + though the first and second set of nodes have the same \meta{node + name}. The reason is that the full names of the six nodes are + all different. Also note that only the \meta{node name} is used as + the node text, not the full name. This can be changed as described + later on. + + This key can be used repeatedly, leading to ever longer node names. + \end{key} + + \begin{key}{/tikz/graphs/name separator=\meta{symbols} (initially \string\space)} + Changes the symbol that is used to separate the \meta{text} from + the \meta{node name}. The default is |\space|, resulting in a + space. +\begin{codeexample}[] +\begin{tikzpicture} + \graph [name separator=] { % no separator + { [name=first] 1, 2, 3} -- + { [name=second] 1, 2, 3} + }; + \draw [red] (second1) circle [radius=3mm]; +\end{tikzpicture} +\end{codeexample} +\begin{codeexample}[] +\begin{tikzpicture} + \graph [name separator=-] { + { [name=first] 1, 2, 3} -- + { [name=second] 1, 2, 3} + }; + \draw [red] (second-1) circle [radius=3mm]; +\end{tikzpicture} +\end{codeexample} + \end{key} +\item + The \meta{node options} are + \begin{enumerate} + \item The options that have accumulated in calls to |nodes| from + the surrounding scopes. + \item The local \meta{options}. + \end{enumerate} + The options are executed with the path prefix |/tikz/graphs|, but + any unknown key is executed with the prefix |/tikz|. This means, in + essence, that some esoteric keys are more difficult to use inside + the options and that any key with the prefix |/tikz/graphs| will + take precedence over a key with the prefix |/tikz|. +\item The \meta{text} that is passed to the |\node| command is + computed as follows: First, you can use the following key to + directly set the \meta{text}: + \begin{key}{/tikz/graphs/as=\meta{text}} + The \meta{text} is used as the text of the node. This allows you + to provide a text for the node that differs arbitrarily from the + name of the node. + \begin{codeexample}[] +\tikz \graph { a [as=$x$] -- b [as=$y_5$] -> c [red, as={a--b}] }; + \end{codeexample} + This key always takes precedence over all of the mechanisms + described below. + \end{key} + In case the |as| key is not used, a default text + is chosen as follows: First, when a direct node specification + contains a slash (or, for historical reasons, a double underscore), + the text to the right of the slash (or double underscore) is stored + in the macro |\tikzgraphnodetext|; if + there is no slash, the \meta{node name} is stored in + |\tikzgraphnodetext|, instead. Then, the current value of the + following key is used as \meta{text}: + \begin{key}{/tikz/graphs/typeset=\meta{code}} + The macro or code stored in this key is used as the + \meta{text} if the node. Inside the \meta{code}, the following + macros are available: + \begin{command}{\tikzgraphnodetext} + This macro expands to the \meta{text} to the right of the double + underscore or slash in a direct node specification or, if there + is no slash, to the \meta{node name}. + \end{command} + \begin{command}{\tikzgraphnodename} + This macro expands to the name of the current node with the + path. + \end{command} + \begin{command}{\tikzgraphnodepath} + This macro expands to the current path of the node. These + paths result from the use of the |name| key as described above. + \end{command} + \begin{command}{\tikzgraphnodefullname} + This macro contains the concatenation of the above two. + \end{command} + \end{key} + By default, the typesetter is just set to |\tikzgraphnodetext|, + which means that the default text of a node is its name. However, + it may be useful to change this: For instance, you might wish that + the text of all graph nodes is, say, surrounded by parentheses: + \begin{codeexample}[] +\tikz \graph [typeset=(\tikzgraphnodetext)] + { a -> b -> c }; + \end{codeexample} + A more advanced macro might take apart the node text and render it + differently: + \begin{codeexample}[] +\def\mytypesetter{\expandafter\myparser\tikzgraphnodetext\relax} +\def\myparser#1 #2 #3\relax{% + $#1_{#2,\dots,#3}$ +} +\tikz \graph [typeset=\mytypesetter, grow down] + { a 1 n -> b 2 m -> c 4 nm }; + \end{codeexample} + The following styles install useful predefined typesetting macros: + \begin{key}{/tikz/graphs/empty nodes} + Just sets |typeset| to nothing, which causes all nodes to have an + empty text (unless, of course, the |as| option is used): + \begin{codeexample}[] +\tikz \graph [empty nodes, nodes={circle, draw}] { a -> {b, c} }; + \end{codeexample} + \end{key} + \begin{key}{/tikz/graphs/math nodes} + Sets |typeset| to |$\tikzgraphnodetext$|, which causes all nodes + names to be typeset in math mode: + \begin{codeexample}[] +\tikz \graph [math nodes, nodes={circle, draw}] { a_1 -> {b^2, c_3^n} }; + \end{codeexample} + \end{key} +\end{itemize} + +If a node is referenced instead of fresh, then this node becomes the +node that will be connected by the preceding or following edge +specification to other +nodes. The \meta{options} are executed even for a referenced node, but +they cannot be used to change the appearance of the node (because the +node exists already). Rather, the \meta{options} can only be used to +change the logical coloring of the node, see +Section~\ref{section-library-graphs-color-classes} for details. + +\medskip +\textbf{Quoted Node Names.} When the \meta{node name} and/or the +\meta{text} of a node is surrounded by quotation marks, you can use +all sorts of special symbols as part of the text that are +normally forbidden: +\begin{codeexample}[] +\begin{tikzpicture} + \graph [grow right=2cm] { + "Hi, World!" -> "It's \emph{important}!"[red,rotate=-45]; + "name"/actual text -> "It's \emph{important}!"; + }; + \draw (name) circle [radius=3pt]; +\end{tikzpicture} +\end{codeexample} + +In detail, for the following happens when qutation marks are +encountered at the beginning of a node name or its text: +\begin{itemize} +\item Everything following the quotation mark up to the next single + quotation mark is collected into a macro \meta{collected}. All sorts + of special characters, including commas, square brackets, dashes, + and even backslashes are allowed here. Basically, the only + restriction is that braces must be balanced. +\item A double quotation mark (|""|) does not count as the ``next + single quotation mark.'' Rather, it is replaced by a single + quotation mark. For instance, |"He said, ""Hello world."""| would be + stored inside \meta{collected} as |He said, "Hello world."| + However, this rule applies only on the outer-most level of + braces. Thus, in +\begin{codeexample}[code only] +"He {said, ""Hello world.""}" +\end{codeexample} + we would get |He {said, ""Hello world.""}| as \meta{collected}. +\item ``The next single quotation mark'' refers to the next + quotation mark on the current level of braces, so in + |"hello {"} world"|, the next quotation mark would be the one + following |world|. +\end{itemize} + +Now, once the \meta{collected} text has been gather, it is used as +follows: When used as \meta{text} (what is actually displayed), it is +just used ``as is''. When it is used as \meta{node name}, however, the +following happens: Every ``special character'' in \meta{collected} is +replaced by its Unicode name, surrounded by |@|-signs. For instance, +if \meta{collected} is |Hello, world!|, the \meta{node name} is the +somewhat longer text |Hello@COMMA@ world@EXCLAMATION MARK@|. Admittedly, +referencing such a node from outside the graph is +cumbersome, but when you use exactly the same \meta{collected} text +once more, the same \meta{node name} will result. The +following characters are considered ``special'': +\begin{quote} + \texttt{\char`\|}|$&^~_[](){}/.-,+*'`!":;<=>?@#%\{}|%$ +\end{quote} +These are exactly the Unicode character with a decimal code number +between 33 and 126 that are neither digits nor letters. + + +\medskip +\textbf{Reference Node Specifications.} A reference node specification +is a node specification that starts with an opening parenthesis. In +this case, parentheses must surround a \meta{name} as in |(foo)|, +where |foo| is the \meta{name}. The following will now happen: + +\begin{enumerate} +\item It is tested whether \meta{name} is the name of a currently + active \emph{node set}. This case will be discussed in a moment. +\item Otherwise, the \meta{name} is interpreted and treated as a + referenced node, but independently of whether the node has already + been fresh in the current graph or not. In other words, the node + must have been defined either already inside the graph (in which + case the parenthesis are more or less superfluous) or it must have + been defined outside the current picture. + + The way the referenced node is handled is the same way as for a + direct node that is a referenced node. + + If the node does not already exist, an error message is printed. +\end{enumerate} + +Let us now have a look at node sets. Inside a |{tikzpicture}| you can +locally define a \emph{node set} by using the following key: +\begin{key}{/tikz/new set=\meta{set name}} + This will setup a node set named \meta{set name} within the current + scope. Inside the scope, you can add nodes to the node set using the + |set| key. If a node set of the same name already exists in the + current scope, it will be reset and made empty for the current + scope. + + Note that this command has the path |/tikz| and is normally used + \emph{outside} the |graph| command. +\end{key} +\begin{key}{/tikz/set=\meta{set name}} + This key can be used as an option with a |node| command. The + \meta{set name} must be the name of a node set that has previously + been created inside some enclosing scope via the |new set| key. The + effect is that the current node is added to the node set. +\end{key} + +When you use a |graph| command inside a scope where some node set +called \meta{set name} is defined, then inside this |graph| command +you use |(|\meta{set name}|)| to reference \emph{all} of the nodes in +the node set. The effect is the same as if instead of the reference to +the set name you had created a group specification containing a list +of references to all the nodes that are part of the node set. + +\begin{codeexample}[] +\begin{tikzpicture}[new set=red, new set=green, shorten >=2pt] + \foreach \i in {1,2,3} { + \node [draw, red!80, set=red] (r\i) at (\i,1) {$r_\i$}; + \node [draw, green!50!black, set=green] (g\i) at (\i,2) {$g_\i$}; + } + \graph { + root [xshift=2cm] -> + (red) -> [complete bipartite, right anchor=south] + (green) + }; +\end{tikzpicture} +\end{codeexample} + +There is an interesting caveat with referencing node sets: Suppose +that at the beginning of a graph you just say |(foo);| where |foo| is +a set name. Unless you have specified special options, this will cause +the following to happen: A group is created whose members are all the +nodes of the node set |foo|. These nodes become referenced nodes, but +otherwise nothing happens since, by default, the nodes of a group are +not connected automatically. However, the referenced nodes have now +been referenced inside the graph, you can thus subsequently access +them as if they had been defined inside the graph. Here is an example +showing how you can create nodes outside a |graph| command and then +connect them inside as if they had been declared inside: + +\begin{codeexample}[] +\begin{tikzpicture}[new set=import nodes] + \begin{scope}[nodes={set=import nodes}] % make all nodes part of this set + \node [red] (a) at (0,1) {$a$}; + \node [red] (b) at (1,1) {$b$}; + \node [red] (d) at (2,1) {$d$}; + \end{scope} + + \graph { + (import nodes); % "import" the nodes + + a -> b -> c -> d -> e; % only c and e are new + }; +\end{tikzpicture} +\end{codeexample} + + +\medskip +\textbf{Group Node Specifications.} +At a place where a node specification should go, you can also instead +provide a group specification. Since nodes specifications are part of +chain specifications, which in turn are part of group specifications, +this is a recursive definition. + +\begin{codeexample}[] +\tikz \graph { a -> {b,c,d} -> {e -> {f,g}, h} }; +\end{codeexample} + +As can be seen in the above example, when two groups of nodes are +connected via an edge specification, it is not immediately obvious +which connecting edges are added. This is detailed in +Section~\ref{section-library-graphs-color-classes}. + + + +\subsubsection{Specifying Tries} + +In computer science, a \emph{trie} is a special kind of tree, where +for each node and each symbol of an alphabet, there is at most one +child of the node labeled with this symbol. + +The |trie| key is useful for drawing tries, but it can also be used in +other situations. What it does, essentially, is to prepend the node +names of all nodes \emph{before} the current node of the current chain +to the node's name. This will often make it easier or more natural to +specify graphs in which several nodes have the same label. + +\begin{key}{/tikz/graphs/trie=\opt{\meta{true or false}} (default true, initially false)} + If this key is set to |true|, after a node has been created on a + chain, the |name| key is executed with the node's \meta{node + name}. Thus, all nodes later on this chain have the ``path'' of + nodes leading to this node as their name. This means, in particular, + that + \begin{enumerate} + \item two nodes of the same name but in different parts of a chain + will be different, + \item while if another chain starts with the same nodes, no new + nodes get created. + \end{enumerate} + In total, this is exactly the behaviour you would expect of a trie: +\begin{codeexample}[] +\tikz \graph [trie] { + a -> { + a, + c -> {a, b}, + b + } +}; +\end{codeexample} + You can even ``reiterate'' over a path in conjunction with the + |simple| option. However, in this case, the default placement + strategies will not work and you will need options like + |layered layout| from the graph drawing libraries, which need + Lua\TeX. +\ifluatex +\begin{codeexample}[] +\tikz \graph [trie, simple, layered layout] { + a -> b -> a, + a -> b -> c, + a -> {d,a} +}; +\end{codeexample} + In the following example, we setup the |typeset| key so that it + shows the complete names of the nodes: +\begin{codeexample}[] +\tikz \graph [trie, simple, layered layout, + typeset=\tikzgraphnodefullname] { + a -> b -> a, + a -> b -> c, + a -> {d,a} +}; +\end{codeexample} +\fi + You can also use the |trie| key locally and later reference nodes + using their full name: +\begin{codeexample}[] +\tikz \graph { + { [trie, simple] + a -> { + b, + c -> a + } + }, + a b ->[red] a c a +}; +\end{codeexample} +\end{key} + + +\subsection{Quick Graphs} + +\label{section-library-graphs-quick} + +The graph syntax is powerful, but this power comes at a price: parsing +the graph syntax, which is done by \TeX, can take some time. Normally, +the parsing is fast enough that you will not notice it, but it can be +bothersome when you have graphs with hundreds of nodes as happens +frequently when nodes are generated algorithmically by some other +program. Fortunately, when another program generated a graph +specification, we typically do not need the full power of the graph +syntax. Rather, a small subset of the graph syntax would suffice that +allows to specify nodes and edges. For these reasons, the is a special +``quick'' version of the graph syntax. + +Note, however, that using this syntax will usually at most halve the +time needed to parse a graph. Thus, it really mostly makes sense in +conjunction with large, algorithmically generated graphs. + +\begin{key}{/tikz/graphs/quick} + When you provide this key with a graph, the syntax of graph + specifications gets restricted. You are no longer allowed to use + certain features of the graph syntax; but all features that are + still allowed are also allowed in the same way when you do not + provide the |quick| option. Thus, leaving out the |quick| option + will never hurt. + + Since the syntax is so severely restricted, it is easier to explain + which aspects of the graph syntax \emph{will} still work: + + \begin{enumerate} + \item + A quick graph consists of a sequence of either nodes, edges sequences, or + groups. These are separated by commas or semicolons. + \item + Every node is of the form + + \begin{quote} + |"|\meta{node name}|"|\opt{|/"|\meta{node text}|"[|\meta{options}|]|} + \end{quote} + + The quotation marks are mandatory. The part |/"|\meta{node + text}|"| may be missing, in which case the node name is used as + the node text. The \meta{options} may also be missing. The + \meta{node name} may not contain any ``funny'' characters (unlike + in the normal graph command). + \item + Every chain is of the form + + \begin{quote} + \meta{node spec} \meta{connector} \meta{node spec} + \meta{connector} \dots \meta{connector} \meta{node spec}|;| + \end{quote} + + Here, the \meta{node spec} are node specifications as described + above, the \meta{connector} is one of the four connectors |->|, + |<-|, |--|, and |<->| (the connector |-!-| is not allowed since + the |simple| option is also not allowed). Each connector may be + followed by options in square brackets. The semicolon may be + replaced by a comma. + \item + Every group is of the form + + \begin{quote} + |{ [|\meta{options}|]| \meta{chains and groups} |};| + \end{quote} + The \meta{options} are compulsory. The semicolon can, again, be + replaced by a comma. + \end{enumerate} + + Here is a typical way this syntax might be used: +\begin{codeexample}[] +\tikz \graph [quick] { "a" --["foo"] "b"[x=1] }; +\end{codeexample} + +\begin{codeexample}[] +\tikz \graph [quick] { + "a"/"$a$" -- "b"[x=1] --[red] "c"[x=2]; + { [nodes=blue] "a" -- "d"[y=1]; }; +}; +\end{codeexample} + + Let us now have a look at the most important things that will + \emph{not} work when the |quick| option is used: + + \begin{itemize} + \item Connecting a node and a group as in |a->{b,c}|. + \item Node names without quotation marks as in |a--b|. + \item Everything described in subsequent subsections, which includes + subgraphs (graph macros), graph sets, graph color classes, + anonymous nodes, the |fresh nodes| option, sublayouts, simple + graphs, edge annotations. + \item Placement strategies -- you either have to define all node + positions explicitly using |at=| or |x=| and |y=| or you must use + a graph drawing algorithm like |layered layout|. + \end{itemize} +\end{key} + + +\subsection{Simple Versus Multi-Graphs} + +\label{section-library-graphs-simple} + +The |graph| library allows you to construct both simple graphs and +multi-graphs. In a simple graph there can be at most one edge between +any two vertices, while in a multi-graph there can be multiple edges +(hence the name). The two keys |multi| and |simple| allow you to +switch (even locally inside on of the graph's scopes) between which +kind of graph is being constructed. By default, the |graph| command +produces a multi-graph since these are faster to construct. + +\begin{key}{/tikz/graphs/multi} + When this edge is set for a whole graph (which is the default) or + just for a group (which is useful if the whole graph is simple in + general, but a part is a multi-graph), then when you specify an edge + between two nodes several times, several such edges get created: + +\begin{codeexample}[] +\tikz \graph [multi] { % "multi" is not really necessary here + a ->[bend left, red] b; + a ->[bend right, blue] b; +}; +\end{codeexample} + In case |multi| is used for a scope inside a larger scope where the + |simple| option is specified, then inside the local |multi| scope + edges are immediately created and they are completely ignored when + it comes to deciding which kind of edges should be present in the + surrounding simple graph. From the surrounding scope's point of view + it is as if the local |multi| graph contained no edges at all. + + This means, in particular, that you can use the |multi| option with + a single edge to ``enforce'' this edge to be present in a simple + graph. +\end{key} + +\begin{key}{/tikz/graphs/simple} + In contrast a multi-graph, in a simple graph, at most one edge gets + created for every pair of vertices: +\begin{codeexample}[] +\tikz \graph [simple]{ + a ->[bend left, red] b; + a ->[bend right, blue] b; +}; +\end{codeexample} + As can be seen, the second edge ``wins'' over the first edge. The + general rule is as follows: In a simple graph, whenever an edge + between two vertices is specified multiple times, only the very last + specification and its options will actually be executed. + + The real power of the |simple| option lies in the fact that you can + first create a complicated graph and then later redirect and otherwise + modify edges easily: + +\begin{codeexample}[] +\tikz \graph [simple, grow right=2cm] { + {a,b,c,d} ->[complete bipartite] {e,f,g,h}; + + { [edges={red,thick}] a -> e -> d -> g -> a }; +}; +\end{codeexample} + + One particularly interesting kind of edge specification for a simple + graph is |-!-|. Recall that this is used to indicate that ``no + edge'' should be added between certain nodes. In a multi-graph, this + key usually has no effect (unless the key |new -!-| has been + redefined) and is pretty superfluous. In a simple graph, however, it + counts as an edge kind and you can thus use it to remove an edge + that been added previously: + +\begin{codeexample}[] +\tikz \graph [simple] { + subgraph K_n [n=8, clockwise]; + % Get rid of the following edges: + 1 -!- 2; + 3 -!- 4; + 6 -!- 8; + % And make one edge red: + 1 --[red] 3; +}; +\end{codeexample} + + Creating a graph such as the above in other fashions is pretty + awkward. + + For every unordered pair $\{u,v\}$ of vertices at most one edge will + be created in a simple graph. In particular, when you say |a -> b| + and later also |a <- b|, then only the edge |a <- b| will be + created. Similarly, when you say |a -> b| and later |b -> a|, then + only the edge |b -> a| will be created. + + The power of the |simple| command comes at a certain cost: As the + graph is being constructed, a (sparse) array is created that keeps + track for each edge of the last edge being specified. Then, at the + end of the scope containing the |simple| command, for every pair of + vertices the edge is created. This is implemented by two nested + loops iterating over all possible pairs of vertices -- which may + take quite a while in a graph of, say, 1000 vertices. + Internally, the |simple| command is implemented as an operator that + adds the edges when it is called, but + this should be unimportant in normal situations. +\end{key} + + + + +\subsection{Graph Edges: Labeling and Styling} + +When the |graph| library creates an edge between two nodes in a graph, +the appearance (called ``styling'' in \tikzname) can be specified in +different ways. Sometimes you will simply wish to say ``the edges +between these two groups of node should be red,'' but sometimes you +may wish to say ``this particular edge going into this node should be +red.'' In the following, different ways of specifying such styling +requirements are discussed. Note that adding labels to edges is, from +\tikzname's point of view, almost the same as styling edges, since +they are also specified using options. + + +\subsubsection{Options For All Edges Between Two Groups} + +When you write |... ->[options] ...| somewhere inside your graph +specification, this typically cause one or more edges to be created +between the nodes in the chain group before the |->| and the nodes in +the chain group following it. The |options| are applied to all of +them. In particular, if you use the |quotes| library and you write +some text in quotes inside the |options|, this text will be added as a +label to each edge: + +\begin{codeexample}[] +\tikz + \graph [edge quotes=near start] { + { a, b } -> [red, "x", complete bipartite] { c, d }; + }; +\end{codeexample} + +As documented in the |quotes| library in more detail, you can easily +modify the appearance of edge labels created using the quotes syntax +by adding options after the closing quotes: + +\begin{codeexample}[] +\tikz \graph { + a ->["x"] b ->["y"'] c ->["z" red] d; +}; +\end{codeexample} + +The following options make it easy to setup the styling of nodes +created in this way: + +\begin{key}{/tikz/graphs/edge quotes=\opt{\meta{options}}} + A shorthand for setting the style |every edge quotes| to \meta{options}. +\begin{codeexample}[] + \tikz \graph [edge quotes={blue,auto}] { + a ->["x"] b ->["y"'] c ->["b" red] d; +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/graphs/edge quotes center} + A shorthand for |edge quotes| to |anchor=center|. +\begin{codeexample}[] +\tikz \graph [edge quotes center] { + a ->["x"] b ->["y"] c ->["z" red] d; +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/graphs/edge quotes mid} + A shorthand for |edge quotes| to |anchor=mid|. +\begin{codeexample}[] +\tikz \graph [edge quotes mid] { + a ->["x"] b ->["y"] c ->["z" red] d; +}; +\end{codeexample} +\end{key} + + + +\subsubsection{Changing Options For Certain Edges} + + +Consider the following tree-like graph: + +\begin{codeexample}[] +\tikz \graph { a -> {b,c} }; +\end{codeexample} + +Suppose we wish to specify that the edge from |a| to |b| should be +red, while the edge from |a| to |c| should be blue. The difficulty +lies in the fact that \emph{both} edges are created by the single |->| +operator and we can only add one of these option |red| or |blue| to +the operator. + +There are several ways to solve this problem. First, we can simply +split up the specification and specify the two edges separately: + +\begin{codeexample}[] +\tikz \graph { + a -> [red] b; + a -> [blue] c; +}; +\end{codeexample} +While this works quite well, we can no longer use the nice chain group +syntax of the |graphs| library. For the rather simple graph |a->{b,c}| +this is not a big problem, but if you specify a tree with, say, 30 +nodes it is really worthwhile being able to specify the tree ``in its +natural form in the \TeX\ code'' rather than having to list all of the +edges explicitly. Also, as can be seen in the above example, the +node placement is changed, which is not always desirable. + +One can sidestep this problem using the |simple| option: This option +allows you to first specify a graph and then, later on, replace edges +by other edges and, thereby, provide new options: + +\begin{codeexample}[] +\tikz \graph [simple] { + a -> {b,c}; + a -> [red] b; + a -> [blue] c; +}; +\end{codeexample} + +The first line is the original specification of the tree, while the +following two lines replace some edges of the tree (in this case, all +of them) by edges with special options. While this method is slower +and in the above example creates even longer code, it is very useful +if you wish to, say, highlight a path in a larger tree: First specify +the tree normally and, then, ``respecify'' the path or paths with some +other edge options in force. In the following example, we use this to +highlight a whole subtree of a larger tree: + +\begin{codeexample}[] +\tikz \graph [simple] { + % The larger tree, no special options in force + a -> { + b -> {c,d}, + e -> {f,g}, + h + }, + { [edges=red] % Now highlight a part of the tree + a -> e -> {f,g} + } +}; +\end{codeexample} + + + +\subsubsection{Options For Incoming and Outgoing Edges} + +When you use the syntax |... ->[options] ...| to specify options, you +specify options for the ``connections between two sets of nodes''. In +many cases, however, it will be more natural to specify options ``for +the edges lead to or coming from a certain node'' and you will want to +specify these options ``at the node''. Returning to the example of the +graph |a->{b,c}| where we want a red edge between |a| and |b| and a +blue edge between |a| and |c|, this could also be phrased as follows: +``Make the edge leading to |b| red and make the edge leading to |c| +blue.'' + +For this situation, the |graph| library offers a number of special +keys, which are documented in the following. However, most of the time +you will not use these keys directly, but, rather, use a special +syntax explained in Section~\ref{section-syntax-outgoing-incoming}. + +\begin{key}{/tikz/graphs/target edge style=\meta{options}} + This key can (only) be used with a \emph{node} inside a graph + specification. When used, the \meta{options} will be added to every + edge that is created by a connector like |->| in which the node is a + \emph{target}. Consider the following example: +\begin{codeexample}[] +\tikz \graph { + { a, b } -> + { c [target edge style=red], d } -> + { e, f } +}; +\end{codeexample} + In the example, only when the edge from |a| to |c| is created, |c| + is the ``target'' of the edge. Thus, only this edge becomes red. + + When an edge already has options set directly, the \meta{options} + are executed after these direct options, thus, they ``overrule'' + them: +\begin{codeexample}[] +\tikz \graph { + { a, b } -> [blue, thick] + { c [target edge style=red], d } -> + { e, f } +}; +\end{codeexample} + + The \meta{options} set in this way will stay attached to the node, + so also for edges created later on that lead to the node will have + these options set: +\begin{codeexample}[] +\tikz \graph { + { a, b } -> + { c [target edge style=red], d } -> + { e, f }, + b -> c +}; +\end{codeexample} + + Multiple uses of this key accumulate. However, you may sometimes + also wish to ``clear'' these options for a key since at some later + point you no longer wish the \meta{options} to be added when some + further edges are added. This can be achieved using the following + key: + \begin{key}{/tikz/graphs/target edge clear} + Clears all \meta{options} for edges with the node as a target and + also edge labels (see below) for this node. + \end{key} +\begin{codeexample}[] +\tikz \graph { + { a, b } -> + { c [target edge style=red], d }, + b -> c[target edge clear] +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/graphs/target edge node=\meta{node specification}} + This key works like |target edge style|, only the \meta{node + specification} will not be added as options to any newly created + edges with the current node as their target, but rather it will be + added as a node specification. +\begin{codeexample}[] +\tikz \graph { + { a, b } -> + { c [target edge node=node{X}], d } -> + { e, f } +}; +\end{codeexample} + As for |target edge style| multiple uses of this key accumulate and + the key |target edge clear| will (also) clear all target edge nodes + that have been set for a node earlier on. +\end{key} + +\begin{key}{/tikz/graphs/source edge style=\meta{options}} + Works exactly like |target edge style|, only now the \meta{options} + are only added when the node is a source of a newly created edge: +\begin{codeexample}[] +\tikz \graph { + { a, b } -> + { c [source edge style=red], d } -> + { e, f } +}; +\end{codeexample} + If both for the source and also for the target of an edge + \meta{options} have been specified, the options are applied in the + following order: + \begin{enumerate} + \item First come the options from the edge itself. + \item Then come the options contributed by the source node using + this key. + \item Then come the options contributed by the target node using + |target node style|. + \end{enumerate} +\begin{codeexample}[] +\tikz \graph { + a [source edge style=red] ->[green] + b [target edge style=blue] % blue wins +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/graphs/source edge node=\meta{node specification}} + Works like |source edge style| and |target edge node|. +\end{key} + +\begin{key}{/tikz/graphs/source edge clear=\meta{node specification}} + Works like |target edge clear|. +\end{key} + + + +\subsubsection{Special Syntax for Options For Incoming and Outgoing Edges} +\label{section-syntax-outgoing-incoming} + +The keys |target node style| and its friends are powerful, but a bit +cumbersome to write down. For this reason, the |graphs| library +introduces a special syntax that is based on what I call the +``first-char syntax'' of keys. Inside the options of a node inside a +graph, the following special rules apply: +\begin{enumerate} +\item Whenever an option starts with |>|, the rest of the options are + passed to |target edge style|. For instance, when you write + |a[>red]|, then this has the same effect as if you had written +\begin{codeexample}[code only] +a[target edge style={red}] +\end{codeexample} +\item Whenever an options starts with |<|, the rest of the options are + passed to |source edge style|. +\item In both of the above case, in case the options following the |>| + or |<| sign start with a quote, the created edge label is passed to + |source edge node| or |target edge node|, respectively. + + This is exactly what you want to happen. +\end{enumerate} +Additionally, the following styles provide shorthands for ``clearing'' +the target and source options: +\begin{key}{/tikz/graphs/clear >} + A more easy-to-remember shorthand for |target edge clear|. +\end{key} +\begin{key}{/tikz/graphs/clear <} + A more easy-to-remember shorthand for |source edge clear|. +\end{key} + +These mechanisms make it especially easy to create trees in which the +edges are labeled in some special way: +\begin{codeexample}[] +\tikz + \graph [edge quotes={fill=white,inner sep=1pt}, + grow down, branch right] { + / -> h [>"9"] -> { + c [>"4" text=red,] -> { + a [>"2", >thick], + e [>"0"] + }, + j [>"7"] + } + }; +\end{codeexample} + + +\subsubsection{Placing Node Texts on Incoming Edges} + +Normally, the text of a node is shown (only) inside the node. In some +case, for instance when drawing certain kind of trees, the nodes +themselves should not get any text, but rather the edge leading to the +node should be labeled as in the following example: +\begin{codeexample}[] +\tikz \graph [empty nodes] +{ + root -> { + a [>"a"], + b [>"b"] -> { + c [>"c"], + d [>"d"] + } + } +}; +\end{codeexample} +As the example shows, it is a bit cumbersome that we have to label the +nodes and then specify the same text once more using the incoming edge +syntax. + +For these cases, it would be better if the text of the node where not +used with the node but, rather, be passed directly to the incoming or +the outgoing edge. The following styles do exactly this: + +\begin{key}{/tikz/graphs/put node text on incoming edges=\opt{\meta{options}}} + When this key is used with a node or a group, the following happens: + \begin{enumerate} + \item The command |target edge node={node[|\meta{options}|]{\tikzgraphnodetext}}| + is executed. This means that all incoming edges of the node get a + label with the text that would usually be displayed in the + node. You can use keys like |math nodes| normally. + \item The command |as={}| is executed. This means that the node + itself will display nothing. + \end{enumerate} + Here is an example that show how this command is used. +\begin{codeexample}[] +\tikz \graph [put node text on incoming edges, + math nodes, nodes={circle,draw}] + { a -> b -> {c, d} }; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/graphs/put node text on outgoing + edges=\opt{\meta{options}}} + Works like the previous key, only with |target| replaced by |source|. +\end{key} + + + +\subsection{Graph Operators, Color Classes, and Graph Expressions} +\label{section-library-graphs-color-classes} + +\tikzname's |graph| command employs a powerful mechanism for +adding edges between nodes and sets of nodes. To a graph theorist, +this mechanism may be known as a \emph{graph expression}: A graph is +specified by starting with small graphs and then applying +\emph{operators} to them that form larger graphs and that connect and +recolor colored subsets of the graph's node in different ways. + + +\subsubsection{Color Classes} + +\label{section-library-graph-coloring} + +\tikzname\ keeps track of a \emph{(multi)coloring} of the graph as it +is being constructed. This does not mean that the +actual color of the nodes on the page will be different, rather, in +the following we refer to ``logical'' colors in the way graph +theoreticians do. These ``logical'' colors are only important while +the graph is being constructed and they are ``thrown away'' at the end +of the construction. The actual (``physical'') colors of the nodes are +set independently of these logical colors. + +As a graph is being constructed, each node can be part of one or more +overlapping \emph{color classes}. So, unlike what is sometimes called a +\emph{legal coloring}, the logical colorings that \tikzname\ keeps +track of may assign multiple colors to the same node and two nodes +connected by an edge may well have the same color. + +Color classes must be declared prior to use. This is done using the +following key: +\begin{key}{/tikz/graphs/color class=\meta{color class name}} + This sets up a new color class called \meta{color class name}. Nodes + and whole groups of nodes can now be colored with \meta{color class + name}. This is done using the following keys, which become + available inside the current scope: + \begin{key}{/tikz/graphs/\meta{color class name}} + This key internally uses the |operator| command to setup an + operator that will cause all nodes of the current group to get the + ``logical color'' \meta{color class name}. Nodes retain this color + in all encompassing scopes, unless it is explicitly changed (see + below) or unset (again, see below). +\begin{codeexample}[] +\tikz \graph [color class=red] { + [cycle=red] % causes all "logically" red nodes to be connected in + % a cycle + a, + b [red], + { [red] c ->[bend right] d }, + e +}; +\end{codeexample} +\begin{codeexample}[] +\tikz \graph [color class=red, color class=green, + math nodes, clockwise, n=5] { + [complete bipartite={red}{green}] + { [red] r_1, r_2 }, + { [green] g_1, g_2, g_3 } +}; +\end{codeexample} + \end{key} + \begin{key}{/tikz/graphs/not \meta{color class name}} + Sets up an operator for the current scope so that all nodes in it + loose the color \meta{color class name}. You can also use + |!|\meta{color class name} as an alias for this key. +\begin{codeexample}[] +\tikz \graph [color class=red, color class=green, + math nodes, clockwise, n=5] { + [complete bipartite={red}{green}] + { [red] r_1, r_2 }, + { [green] g_1, g_2, g_3 }, + g_2 [recolor green by=red] +}; +\end{codeexample} + \end{key} + \begin{key}{/tikz/graphs/recolor \meta{color class name} by=\meta{new color}} + Causes all keys having color \meta{color class name} to get + \meta{new color} instead. They loose having color \meta{color + class name}, but other colors are not affected. +\begin{codeexample}[] +\tikz \graph [color class=red, color class=green, + math nodes, clockwise, n=5] { + [complete bipartite={red}{green}] + { [red] r_1, r_2 }, + { [green] g_1, g_2, g_3 }, + g_2 [not green] +}; +\end{codeexample} + \end{key} +\end{key} + +The following color classes are available by default: +\begin{itemize} +\item + Color class |all|. Every node is part of this class by default. This + is useful to access all nodes of a (sub)graph, since you can simply + access all nodes of this color class. +\item + Color classes |source| and |target|. These classes are used to + identify nodes that lead ``into'' a group of nodes and nodes from + which paths should ``leave'' the group. Details on how these colors + are assigned are explained in + Section~\ref{section-library-graphs-join}. By saying |not source| or + |not target| with a node, you can influence how it is connected: + \begin{codeexample}[] +\tikz \graph { a -> { b, c, d } -> e }; + \end{codeexample} + \begin{codeexample}[] +\tikz \graph { a -> { b[not source], c, d[not target] } -> e }; + \end{codeexample} +\item + Color classes |source'| and |target'|. These are temporary colors + that are also explained in + Section~\ref{section-library-graphs-join}. +\end{itemize} + + + +\subsubsection{Graph Operators on Groups of Nodes} + +Recall that the |graph| command constructs graphs recursively from +nested \meta{group specifications}. Each such \meta{group + specification} describes a subset of the nodes of the final graph. A +\emph{graph operator} is an algorithm that gets the nodes of a group +as input and (typically) adds edges between these nodes in some +sensible way. For instance, the |clique| operator will simply add +edges between all nodes of the group. + +\begin{key}{/tikz/graphs/operator=\meta{code}} + This key has an effect in three places: + \begin{enumerate} + \item It can be used in the \meta{options} of a \meta{direct node specification}. + \item It can be used in the \meta{options} of a \meta{group + specification}. + \item It can be used in the \meta{options} of an \meta{edge specification}. + \end{enumerate} + The first case is a special case of the second, since it is treated + like a group specification containing a single node. The last case + is more complicated and discussed in the next section. + So, let us focus on the second case. + + Even though the \meta{options} of a group are given at the beginning + of the \meta{group specification}, the \meta{code} is only executed + when the group has been parsed completely and all its nodes have + been identified. If you use the |operator| multiple times in the + \meta{options}, the effect accumulates, that is, all code passed to + the different calls of |operator| gets executed in the order it is + encountered. + + The \meta{code} can do ``whatever it wants,'' but it will typically + add edges between certain nodes. You can configure what kind of + edges (directed, undirected, etc.) are created by using the + following keys: + \begin{key}{/tikz/graphs/default edge kind=\meta{value} (initially --)} + This key stores one of the five edge kinds |--|, |<-|, |->|, + |<->|, and |-!-|. When an operator wishes to create a new edge, it + should typically set +\begin{codeexample}[code only] +\tikzgraphsset{new \pfkeysvalueof{/tikz/graphs/default edge kind}=...} +\end{codeexample} + While this key can be set explicitly, it may be more convenient to + use the abbreviating keys listed below. Also, this key is + automatically set to the current value of \meta{edge + specification} when a joining operator is called, see the + discussion of joining operators in + Section~\ref{section-library-graphs-join}. + \end{key} + \begin{key}{/tikz/graphs/--} + Sets the |default edge kind| to |--|. +\begin{codeexample}[] +\tikz \graph { subgraph K_n [--, n=5, clockwise, radius=6mm] }; +\end{codeexample} + \end{key} + \begin{key}{/tikz/graphs/->} + Sets the |default edge kind| to |->|. +\begin{codeexample}[] +\tikz \graph { subgraph K_n [->, n=5, clockwise, radius=6mm] }; +\end{codeexample} + \end{key} + \begin{key}{/tikz/graphs/<-} + Sets the |default edge kind| to |<-|. +\begin{codeexample}[] +\tikz \graph { subgraph K_n [<-, n=5, clockwise, radius=6mm] }; +\end{codeexample} + \end{key} + \begin{key}{/tikz/graphs/<->} + Sets the |default edge kind| to |<->|. +\begin{codeexample}[] +\tikz \graph { subgraph K_n [<->, n=5, clockwise, radius=6mm] }; +\end{codeexample} + \end{key} + \begin{key}{/tikz/graphs/-\protect\exclamationmarktext-} + Sets the |default edge kind| to |-!-|. + \end{key} + + When the \meta{code} of an operator is executed, the following + commands can be used to find the nodes that should be connected: + \begin{command}{\tikzgraphforeachcolorednode\marg{color name}\marg{macro}} + When this command is called inside \meta{code}, the following will + happen: \tikzname\ will iterate over all nodes inside the + just-specified group that have the color \meta{color name}. The + order in which they are iterated over is the order in which they + appear inside the group specification (if a node is encountered + several times inside the specification, only the first occurrence + counts). Then, for each node the \meta{macro} is executed with the + node's name as the only argument. + + In the following example we use an operator to connect every + node colored |all| inside the subgroup to he node |root|. + \begin{codeexample}[] +\def\myconnect#1{\tikzset{graphs/new ->={root}{#1}{}{}}} + +\begin{tikzpicture} + \node (root) at (-1,-1) {root}; + + \graph { + x, + { + [operator=\tikzgraphforeachcolorednode{all}{\myconnect}] + a, b, c + } + }; +\end{tikzpicture} + \end{codeexample} + \end{command} + + \begin{command}{\tikzgraphpreparecolor\marg{color + name}\marg{counter}\marg{prefix}} + This command is used to ``prepare'' the nodes of a certain color + for random access. The effect is the following: It is counted how + many nodes there are having color \meta{color name} in the current + group and the result is stored in \meta{counter}. Next, macros + named \meta{prefix}|1|, \meta{prefix}|2|, and so on are defined, + that store the names of the first, second, third, and so on node + having the color \meta{color name}. + + The net effect is that after you have prepared a color, you can + quickly iterate over them. This is especially useful when you + iterate over several color at the same time. + + As an example, let us create an operator then adds a zig-zag path + between two color classes: + \begin{codeexample}[] +\newcount\leftshorecount \newcount\rightshorecount +\newcount\mycount \newcount\myothercount +\def\zigzag{ + \tikzgraphpreparecolor{left shore}\leftshorecount{left shore prefix} + \tikzgraphpreparecolor{right shore}\rightshorecount{right shore prefix} + \mycount=0\relax + \loop + \advance\mycount by 1\relax% + % Add the "forward" edge + \tikzgraphsset{new ->= + {\csname left shore prefix\the\mycount\endcsname} + {\csname right shore prefix\the\mycount\endcsname}{}{}} + \myothercount=\mycount\relax% + \advance\myothercount by1\relax% + \tikzgraphsset{new <-= + {\csname left shore prefix\the\myothercount\endcsname} + {\csname right shore prefix\the\mycount\endcsname}{}{}} + \ifnum\myothercount<\leftshorecount\relax + \repeat +} +\begin{tikzpicture} + \graph [color class=left shore, color class=right shore] + { [operator=\zigzag] + { [left shore, Cartesian placement] a, b, c }, + { [right shore, Cartesian placement, nodes={xshift=1cm}] d, e, f } + }; +\end{tikzpicture} +\end{codeexample} + Naturally, in order to turn the above code into a usable operator, + some more code would be needed (like default values and taking + care of shores of different sizes). + \end{command} +\end{key} + +There are a number of predefined operators, like |clique| or |cycle|, +see the reference Section~\ref{section-library-graphs-reference} for a +complete list. + + + +\subsubsection{Graph Operators for Joining Groups} +\label{section-library-graphs-join} + +When you join two nodes |foo| and |bar| by the edge specification +|->|, it is fairly obvious, what should happen: An edge from |(foo)| +to |(bar)| should be created. However, suppose we use an edge +specification between two node sets like |{a,b,c}| and |{d,e,f}|. In +this case, it is not so clear which edges should be created. One might +argue that all possible edges from any node in the first set to any node +in the second set should be added. On the other hand, one might also +argue that only a matching between these two sets should be +created. Things get even more muddy when a longer chain of node sets +are joined. + +Instead of fixing how edges are created between two node sets, +\tikzname\ takes a somewhat more general, but also more complicated +approach, which can be broken into two parts. In the following, assume +that the following chain specification is given: +\begin{quote} + \meta{spec$_1$} \meta{edge specification} \meta{spec$_2$} +\end{quote} +An example might be |{a,b,c} -> {d, e->f}|. + +\medskip +\textbf{The source and target vertices.} Let us start with the +question of which vertices of the first node set should be connected to +vertices in the second node set. + +There are two predefined special color classes that are used for this: +|source| and |target|. For every group specification, some vertices +are colored as |source| vertices and some vertices are |target| +vertices (a node can both be a target and a source). Initially, every +vertex is both a source and a target, but that can change as we will +see in a moment. + +The intuition behind source and target vertices is that, in some +sense, edges ``from the outside'' lead into the group via the source +vertices and lead out of the group via the target vertices. To be more +precise, the following happens: +\begin{enumerate} +\item The target vertices of the first group are connected to + the source vertices of the second group. +\item In the group resulting from the union of the nodes from + \meta{spec$_1$} and \meta{spec$_2$}, the source vertices are only + those from the first group, and the target vertices are only those + from the second group. +\end{enumerate} + +Let us go over the effect of these rules for the example +|{a,b,c} -> {d, e->f}|. First, each individual node is initially both +a |source| and a |target| vertex. Then, in |{a,b,c}| all nodes are +still both source and target vertices since just grouping vertices +does not change their colors. Now, in |e->f| something interesting +happens for the first time: the target vertices of the ``group'' |e| +(which is just the node |e|) are connected to the source vertices of +the ``group'' |f|. This means, that an edge is added from |e| to +|f|. Then, in the resulting group |e->f| the only source vertex is |e| +and the only target vertex is |f|. This implies that in the group +|{d,e->f}| the sources are |d| and |e| and the targets are |d| and~|f|. + +Now, in |{a,b,c} -> {d,e->f}| the targets of |{a,b,c}| (which are all +three of them) are connected to the sources of |{d,e->f}| (which are +just |d| and~|e|). Finally, in the whole graph only |a|, |b|, and |c| +are sources while only |d| and |f| are targets. + +\begin{codeexample}[] +\def\hilightsource#1{\fill [green, opacity=.25] (#1) circle [radius=2mm]; } +\def\hilighttarget#1{\fill [red, opacity=.25] (#1) circle [radius=2mm]; } +\tikz \graph + [operator=\tikzgraphforeachcolorednode{source}{\hilightsource}, + operator=\tikzgraphforeachcolorednode{target}{\hilighttarget}] + { {a,b,c} -> {d, e->f} }; +\end{codeexample} + +The next objective is to make more precise what it means that ``the +targets of the first graph'' and the ``sources of the second graph'' +should be connected. We know already of a general way of connecting +nodes of a graph: operators! Thus, we use an operator for this job. +For instance, the |complete bipartite| operator adds an edge from every node +having a certain color to every node have a certain other color. This +is exactly what we need here: The first color is ``the color |target| +restricted to the nodes of the first graph'' and the second color is +``the color |source| restricted to the nodes of the second graph.'' + +However, we cannot really specify that only nodes from a certain +subgraph are meant -- the |operator| machinery only operates on all +nodes of the current graph. For this reason, what really happens is +the following: When the |graph| command encounters \meta{spec$_1$} +\meta{edge specification} \meta{spec$_2$}, it first computes and +colors the nodes of the first and the second specification +independently. Then, the |target| nodes of the first graph are +recolored to |target'| and the |source| nodes of the second graph are +recolored to |source'|. Then, the two graphs are united into one +graph and a \emph{joining operator} is executed, which should add +edges between |target'| and |source'|. Once this is done, +the colors |target'| and |source'| get erased. Note that in the +resulting graph only the |source| nodes from the first graph are still +|source| nodes and likewise for the |target| nodes of the second graph. + + +\medskip +\textbf{The joining operators.} The job of a joining operator is +to add edges between nodes colored |target'| and |source'|. The +following rule is used to determine which operator should be chosen +for performing this job: +\begin{enumerate} +\item If the \meta{edge specification} explicitly sets the |operator| + key to something non-empty (and also not to |\relax|), then the + \meta{code} of this |operator| call is used. +\item Otherwise, the current value of the following key is used: + \begin{key}{/tikz/graphs/default edge operator=\meta{key}} + This key stores the name of a \meta{key} that is executed for every + \meta{edge specification} whose \meta{options} do not contain the + |operator| key. +\begin{codeexample}[] +\tikz \graph [default edge operator=matching] { + {a, b} ->[matching and star] + {c, d, e} --[complete bipartite] + {f, g, h} -- + {i, j, k} +}; +\end{codeexample} + \end{key} +\end{enumerate} + +A typical joining operator is |complete bipartite|. It takes the names of two +color classes as input and adds edges from all vertices of the first +class to all vertices of the second class. Now, the trick is that the +default value for the |complete bipartite| key is |{target'}{source'}|. Thus, +if you just write |->[complete bipartite]|, the same happens as if you had +written +\begin{quote} +|->[complete bipartite={target'}{source'}]| +\end{quote} +This is exactly what we want to happen. The same default values are +also set for other joining operators like |matching| or |butterfly|. + +Even though an operator like |complete bipartite| is typically used +together with an edge specification, it can also be used as a normal +operator together with a group specification. In this case, however, +the color classes must be named explicitly: + +\begin{codeexample}[] +\begin{tikzpicture} + \graph [color class=red, color class=green, math nodes] + { [complete bipartite={red}{green}] + { [red, Cartesian placement] r_1, r_2, r_3 }, + { [green, Cartesian placement, nodes={xshift=1cm}] g_1, g_2, g_3 } + }; +\end{tikzpicture} +\end{codeexample} + +A list of predefined joining operators can be found in the reference +Section~\ref{section-library-graphs-reference}. + +The fact that joining operators can also be used as normal operators +leads to a subtle problem: A normal operator will typically use the +current value of |default edge kind| to decide which kind of edges +should be put between the identified vertices, while a joining +operator should, naturally, use the kind of edge specified by the +\meta{edge specification}. This problem is solved as follows: Like a +normal operator, a joining operator should also use the current value +of |default edge kind| for the edges it produces. The trick is that +this will automatically be set to the current \meta{edge + specification} when the operator explicitly in the \meta{options} of +the edge specification or implicitly in the |default edge operator|. + + + + +\subsection{Graph Macros} +\label{section-library-graphs-macros} + +A \emph{graph macro} is a small graph that is inserted at some point +into the graph that is currently being constructed. There is special +support for such graph macros in \tikzname. You might wonder why this +is necessary -- can't one use \TeX's normal macro mechanism? The +answer is ``no'': one cannot insert new nodes into a graph using +normal macros because the chains, groups, and nodes are determined +prior to macro expansion. Thus, any macro encountered where some node +text should go will only be expanded when this node is being named and +typeset. + +A graph macro is declared using the following key: + +\begin{key}{/tikz/graphs/declare=\marg{graph name}\marg{specification}} + This key declares that \meta{graph name} can subsequently be used as + a replacement for a \meta{node name}. Whenever the \meta{graph name} + is used in the following, a graph group will be inserted instead + whose content is exactly \meta{specification}. In case \meta{graph + name} is used together with some \meta{options}, they are executed + prior to inserting the \meta{specification}. +\begin{codeexample}[] +\tikz \graph [branch down=4mm, declare={claw}{1 -- {2,3,4}}] { + a; + claw; + b; +}; +\end{codeexample} + In the next example, we use a key to configure a subgraph: +\begin{codeexample}[] +\tikz \graph [ n/.code=\def\n{#1}, branch down=4mm, + declare={star}{root -- { \foreach \i in {1,...,\n} {\i} }}] +{ star [n=5]; }; +\end{codeexample} + Actually, the |n| key is already defined internally for a similar + purpose. + + As a last example, let us define a somewhat more complicated graph + macro. +\begin{codeexample}[] +\newcount\mycount +\tikzgraphsset{ + levels/.store in=\tikzgraphlevel, + levels=1, + declare={bintree}{% + [/utils/exec={% + \ifnum\tikzgraphlevel=1\relax% + \def\childtrees{ / }% + \else% + \mycount=\tikzgraphlevel% + \advance\mycount by-1\relax% + \edef\childtrees{ + / -> { + bintree[levels=\the\mycount], + bintree[levels=\the\mycount] + }} + \fi% + }, + parse/.expand once=\childtrees + ] + % Everything is inside the \childtrees... + } +} +\tikz \graph [grow down=5mm, branch right=5mm] { bintree [levels=5] }; +\end{codeexample} +\end{key} + +Note that when you use a graph macro several time inside the same +graph, you will typically have to use the |name| option so that +different copies of the subgraph are created: +\begin{codeexample}[] +\tikz \graph [branch down=4mm, declare={claw}{1 -- {2,3,4}}] { + claw [name=left], + claw [name=right] +}; +\end{codeexample} + +You will find a list of useful graph macros in the reference section, +Section~\ref{section-library-graphs-reference-macros}. + + +\subsection{Online Placement Strategies} +\label{section-library-graphs-placement} + +The main job of the |graph| library is to make it easy to specify +which nodes are present in a graph and how they are connected. In +contrast, it is \emph{not} the primary job of the library to compute +good positions for nodes in a graph -- use for instance a |\matrix|, +specify good positions ``by hand'' or use the graph drawing +facilities. Nevertheless, some basic support for automatic node +placement is provided for simple cases. The graph library will provide +you with information about the position of nodes inside their groups +and chains. + +As a graph is being constructed, a \emph{placement strategy} is used +to determine a (reasonably good) position for the nodes as they are +created. These placement strategies get some information about what +\tikzname\ has already seen concerning the already constructed nodes, +but it gets no information concerning the upcoming nodes. Because of +this lack of information concerning the future, the strategies need to +be what is called an \emph{online strategy} in computer science. (The +opposite are \emph{offline strategies}, which get information about +the whole graph and all the sizes of the nodes in it. The graph +drawing libraries employ such offline strategies.) + +Strategies are selected using keys like |no placement| or +|Cartesian placement|. It is permissible to use different strategies inside +different parts of a graph, even though the different strategies do +not always work together in perfect harmony. + + +\subsubsection{Manual Placement} +\label{section-graphs-xy} + +\begin{key}{/tikz/graphs/no placement} + This strategy simply ``switches off'' the whole placement + mechanism, causing all nodes to be placed at the origin by + default. You need to use this strategy if you position nodes ``by + hand''. For this, you can use the |at| key, the |shift| keys: +\begin{codeexample}[] +\tikz \graph [no placement] +{ + a[at={(0:0)}] -> b[at={(1,0)}] -> c[yshift=1cm]; +}; +\end{codeexample} + Since the syntax and the many braces and parentheses are a bit + cumbersome, the following two keys might also be useful: + \begin{key}{/tikz/graphs/x=\meta{x dimension}} + When you use this key, it will have the same effect as if you had written + |at={(|\meta{x dimension}|,|\meta{y dimension}|)}|, where \meta{y + dimension} is a value set using the |y| key: +\begin{codeexample}[] +\tikz \graph [no placement] +{ + a[x=0,y=0] -> b[x=1,y=0] -> c[x=0,y=1]; +}; +\end{codeexample} + Note that you can specify an |x| or a |y| key for a whole scope + and then vary only the other key: +\begin{codeexample}[] +\tikz \graph [no placement] +{ + a -> + { [x=1] % group option + b [y=0] -> c[y=1] + }; +}; +\end{codeexample} + Note that these keys have the path |/tikz/graphs/|, so they will + be available inside |graph|s and will not clash with the usual |x| + and |y| keys of \tikzname, which are used to specify the basic + lengths of vectors. + \end{key} + \begin{key}{/tikz/graphs/y=\meta{y dimension}} + See above. + \end{key} +\end{key} + + + + +\subsubsection{Placement on a Grid} + +\begin{key}{/tikz/graphs/Cartesian placement} + This strategy is the default strategy. It works, roughly, as + follows: For each new node on a chain, advance a ``logical width'' + counter and for each new node in a group, advance a ``logical + depth'' counter. When a chain contains a whole group, then the + ``logical width'' taken up by the group is the maximum over the + logical widths taken up by the chains inside the group; and + symmetrically the logical depth of a chain is the maximum of the + depths of the groups inside it. + + This slightly confusing explanation is perhaps best exemplified. In + the below example, the two numbers indicate the two logical width + and depth of each node as computed by the |graph| library. Just + ignore the arcane code that is used to print these numbers. +\begin{codeexample}[] +\tikz + \graph [nodes={align=center, inner sep=1pt}, grow right=7mm, + typeset={\tikzgraphnodetext\\[-4pt] + \tiny\mywidth\\[-6pt]\tiny\mydepth}, + placement/compute position/.append code= + \pgfkeysgetvalue{/tikz/graphs/placement/width}{\mywidth} + \pgfkeysgetvalue{/tikz/graphs/placement/depth}{\mydepth}] +{ + a, + b, + c -> d -> { + e -> f -> g, + h -> i + } -> j, + k -> l +}; +\end{codeexample} + You will find a detailed description of how these logical units are + computed, exactly, in Section~\ref{section-library-graphs-new-online}. + + Now, even though we talk about ``widths'' and ``depths'' and even + though by default a graph ``grows'' to the right and down, this is + by no means fixed. Instead, you can use the following keys to change + how widths and heights are interpreted: + \begin{key}{/tikz/graphs/chain shift=\meta{coordinate} (initially {(1,0)})} + Under the regime of the |Cartesian placement| strategy, each node is + shifted by the current logical width times this \meta{coordinate}. +\begin{codeexample}[] +\tikz \graph [chain shift=(45:1)] { + a -> b -> c; + d -> e; + f -> g -> h; +}; +\end{codeexample} + \end{key} + \begin{key}{/tikz/graphs/group shift=\meta{coordinate} (initially {(0,-1)})} + Like for |chain shift|, each node is shifted by the current + logical depth times this \meta{coordinate}. +\begin{codeexample}[] +\tikz \graph [chain shift=(45:7mm), group shift=(-45:7mm)] { + a -> b -> c; + d -> e; + f -> g -> h; +}; +\end{codeexample} + \end{key} +\end{key} + + +\begin{key}{/tikz/graphs/grow up=\meta{distance} (default 1)} + Sets the |chain shift| to |(|\meta{distance}|,0)|, so that chains + ``grow upward.'' The distance by which the center of each new + element is removed from the center of the previous one is + \meta{distance}. +\begin{codeexample}[] +\tikz \graph [grow up=7mm] { a -> b -> c}; +\end{codeexample} +\end{key} +\begin{key}{/tikz/graphs/grow down=\meta{distance} (default 1)} + Like |grow up|. +\begin{codeexample}[] +\tikz \graph [grow down=7mm] { a -> b -> c}; +\end{codeexample} +\end{key} +\begin{key}{/tikz/graphs/grow left=\meta{distance} (default 1)} + Like |grow up|. +\begin{codeexample}[] +\tikz \graph [grow left=7mm] { a -> b -> c}; +\end{codeexample} +\end{key} +\begin{key}{/tikz/graphs/grow right=\meta{distance} (default 1)} + Like |grow up|. +\begin{codeexample}[] +\tikz \graph [grow right=7mm] { a -> b -> c}; +\end{codeexample} +\end{key} +\begin{key}{/tikz/graphs/branch up=\meta{distance} (default 1)} + Sets the |group shift| so that groups ``branch upward.'' The + distance by which the center of each new element is removed from + the center of the previous one is \meta{distance}. +\begin{codeexample}[] +\tikz \graph [branch up=7mm] { a -> b -> {c, d, e} }; +\end{codeexample} + Note that when you draw a tree, the |branch ...| keys specify how + siblings (or adjacent branches) are arranged, while the |grow ...| + keys specify in which direction the branches ``grow''. +\end{key} +\begin{key}{/tikz/graphs/branch down=\meta{distance} (default 1)} +\begin{codeexample}[] +\tikz \graph [branch down=7mm] { a -> b -> {c, d, e}}; +\end{codeexample} +\end{key} +\begin{key}{/tikz/graphs/branch left=\meta{distance} (default 1)} +\begin{codeexample}[] +\tikz \graph [branch left=7mm, grow down=7mm] { a -> b -> {c, d, e}}; +\end{codeexample} +\end{key} +\begin{key}{/tikz/graphs/branch right=\meta{distance} (default 1)} +\begin{codeexample}[] +\tikz \graph [branch right=7mm, grow down=7mm] { a -> b -> {c, d, e}}; +\end{codeexample} +\end{key} + +The following keys place nodes in a $N\times M$ grid. +\begin{key}{/tikz/graphs/grid placement} + This key works similar to |Cartesian placement|. As for that placement + strategy, a node has logical width and depth 1. However, the computed + total width and depth are mapped to a $N\times M$ grid. + The values of $N$ and $M$ depend on the size of the graph and the + value of |wrap after|. The number of columns $M$ is either set to + |wrap after| explicitly or computed automatically as + $\sqrt{\verb!|V|!}$. $N$ is the number of rows needed to lay out the + graph in a grid with $M$ columns. +\begin{codeexample}[] +% An example with 6 nodes, 3 columns and therefor 2 rows +\tikz \graph [grid placement] { subgraph I_n[n=6, wrap after=3] }; +\end{codeexample} +\begin{codeexample}[] +% An example with 9 nodes with columns and rows computed automatically +\tikz \graph [grid placement] { subgraph Grid_n [n=9] }; +\end{codeexample} +\begin{codeexample}[] +% Directions can be changed +\tikz \graph [grid placement, branch up, grow left] { subgraph Grid_n [n=9] }; +\end{codeexample} + In case a user-defined graph instead of a pre-defined + |subgraph| is to be layed out using |grid placement|, |n| has to be + specified explicitly: +\begin{codeexample}[] +\tikz \graph [grid placement] { + [n=6, wrap after=3] + a -- b -- c -- d -- e -- f +}; +\end{codeexample} +\end{key} + + + +\subsubsection{Placement Taking Node Sizes Into Account} + +Options like |grow up| or |branch right| do not take the sizes of the +to-be-positioned nodes into account -- all nodes are placed quite +``dumbly'' at grid positions. It turns out that the +|Cartesian placement| can also be used to place notes in such a way +that their height and/or width is taken into account. Note, however, +that while the following options may yield an adequate placement in +many situations, when you need advanced alignments you should use a +|matrix| or advanced offline strategies to place the nodes. + + +\begin{key}{/tikz/graphs/grow right sep=\meta{distance} (default 1em)} + This key has several effects, but let us start with the bottom line: + Nodes along a chain are placed in such a way that the left end of a + new node is \meta{distance} from the right end of the previous node: +\begin{codeexample}[] +\tikz \graph [grow right sep, left anchor=east, right anchor=west] { + start -- { + long text -- {short, very long text} -- more text, + long -- longer -- longest + } -- end +}; +\end{codeexample} + What happens internally is the following: First, the |anchor| of the + nodes is set to |west| (or |north west| or |south west|, see + below). Second, the logical width of a node is no + longer |1|, but set to the actual width of the node (which we define + as the horizontal difference between the |west| anchor and the + |east| anchor) in points. Third, the |chain shift| is set to + |(1pt,0pt)|. +\end{key} +\begin{key}{/tikz/graphs/grow left sep=\meta{distance} (default 1em)} +\begin{codeexample}[] +\tikz \graph [grow left sep] { long -- longer -- longest }; +\end{codeexample} +\end{key} +\begin{key}{/tikz/graphs/grow up sep=\meta{distance} (default 1em)} +\begin{codeexample}[] +\tikz \graph [grow up sep] { + a / $a=x$ -- + b / {$b=\displaystyle \int_0^1 x dx$} -- + c [draw, circle, inner sep=7mm] +}; +\end{codeexample} +\end{key} +\begin{key}{/tikz/graphs/grow down sep=\meta{distance} (default 1em)} + As above. +\end{key} + +\begin{key}{/tikz/graphs/branch right sep=\meta{distance} (default 1em)} + This key works like |grow right sep|, only it affects groups rather + than chains. +\begin{codeexample}[] +\tikz \graph [grow down, branch right sep] { + start -- { + an even longer text -- {short, very long text} -- more text, + long -- longer -- longest, + some text -- a -- b + } -- end +}; +\end{codeexample} + When both this key and, say, |grow down sep| are set, instead of the + |west| anchor, the |north west| anchor will be selected + automatically. +\end{key} + +\begin{key}{/tikz/graphs/branch left sep=\meta{distance} (default 1em)} +\begin{codeexample}[] +\tikz \graph [grow down sep, branch left sep] { + start -- { + an even longer text -- {short, very long text} -- more text, + long -- longer, + some text -- a -- b + } -- end +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/graphs/branch up sep=\meta{distance} (default 1em)} +\begin{codeexample}[] +\tikz \graph [branch up sep] { a, b, c[draw, circle, inner sep=7mm] }; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/graphs/branch down sep=\meta{distance} (default 1em)} +\end{key} + + + +\subsubsection{Placement On a Circle} + +The following keys place nodes on circles. Note that, typically, you +do not use |circular placement| directly, but rather use one of the +two keys |clockwise| or |counterclockwise|. + +\begin{key}{/tikz/graphs/circular placement} + This key works quite similar to |Cartesian placement|. As for that + placement strategy, a node has logical width and depth |1|. However, + the computed total width and depth are mapped to polar coordinates + rather than Cartesian coordinates. + + \begin{key}{/tikz/graphs/chain polar shift=|(|\meta{angle}|:|\meta{radius}|)| (initially {(0:1)})} + Under the regime of the |circular placement| strategy, each node + on a chain is shifted by |(|\meta{logical + width}\meta{angle}|:|\meta{logical width}\meta{angle}|)|. +\begin{codeexample}[] +\tikz \graph [circular placement] { + a -> b -> c; + d -> e; + f -> g -> h; +}; +\end{codeexample} + \end{key} + \begin{key}{/tikz/graphs/group polar shift=|(|\meta{angle}|:|\meta{radius}|)| (initially {(45:0)})} + Like for |group shift|, each node + on a chain is shifted by |(|\meta{logical + depth}\meta{angle}|:|\meta{logical depth}\meta{angle}|)|. +\begin{codeexample}[] +\tikz \graph [circular placement, group polar shift=(30:0)] { + a -> b -> c; + d -> e; + f -> g -> h; +}; +\end{codeexample} +\begin{codeexample}[] +\tikz \graph [circular placement, + chain polar shift=(30:0), + group polar shift=(0:1cm)] { + a -- b -- c; + d -- e; + f -- g -- h; +}; +\end{codeexample} + \end{key} + \begin{key}{/tikz/graphs/radius=\meta{dimension} (initially 1cm)} + This is an initial value that is added to the total computed + radius when the polar shift of a node has been + calculated. Essentially, this key allows you to set the + \meta{radius} of the innermost circle. +\begin{codeexample}[] +\tikz \graph [circular placement, radius=5mm] { a, b, c, d }; +\end{codeexample} +\begin{codeexample}[] +\tikz \graph [circular placement, radius=1cm] { a, b, c, d }; +\end{codeexample} + \end{key} + \begin{key}{/tikz/graphs/phase=\meta{angle} (initially 90)} + This is an initial value that is added to the total computed + angle when the polar shift of a node has been + calculated. +\begin{codeexample}[] +\tikz \graph [circular placement] { a, b, c, d }; +\end{codeexample} +\begin{codeexample}[] +\tikz \graph [circular placement, phase=0] { a, b, c, d }; +\end{codeexample} + \end{key} +\end{key} + +\label{key-graphs-clockwise}% +\begin{key}{/tikz/graphs/clockwise=\meta{number} (default \string\tikzgraphVnum)} + This key sets the |group shift| so that if there are exactly + \meta{number} many nodes in a group, they will form a complete + circle. If you do not provide a \meta{number}, the current value of + |\tikzgraphVnum| is used, which is exactly what you want when you + use predefined graph macros like |subgraph K_n|. +\begin{codeexample}[] +\tikz \graph [clockwise=4] { a, b, c, d }; +\end{codeexample} +\begin{codeexample}[] +\tikz \graph [clockwise] { subgraph K_n [n=5] }; +\end{codeexample} +\end{key} + +\label{key-graphs-counterclockwise}% +\begin{key}{/tikz/graphs/counterclockwise=\meta{number} (default \string\tikzgraphVnum)} + Works like |clockwise|, only the direction is inverted. +\end{key} + + +\subsubsection{Levels and Level Styles} + +As a graph is being parsed, the |graph| command keeps track of a +parameter called the \emph{level} of a node. Provided that the graph +is actually constructed in a tree-like manner, the level is exactly +equal to the level of the node inside this tree. + +\begin{key}{/tikz/graphs/placement/level} + This key stores a number that is increased for each element on a + chain, but gets reset at the end of a group: +\begin{codeexample}[] +\tikz \graph [ branch down=5mm, typeset= + \tikzgraphnodetext:\pgfkeysvalueof{/tikz/graphs/placement/level}] +{ + a -> { + b, + c -> { + d, + e -> {f,g}, + h + }, + j + } +}; +\end{codeexample} + Unlike the parameters |depth| and |width| described in the next + section, the key |level| is always available. +\end{key} + +In addition to keeping track of the value of the |level| key, the +|graph| command also executes the following keys whenever it creates a +node: + +\begin{stylekey}{/tikz/graph/level=\meta{level}} + This key gets executed for each newly created node with \meta{level} + set to the current level of the node. You can use this key to, say, + reconfigure the node distance or the node color. +\end{stylekey} + +\begin{stylekey}{/tikz/graph/level \meta{level}} + This key also gets executed for each newly created node with + \meta{level} set to the current level of the node. +\begin{codeexample}[] +\tikz \graph [ + branch down=5mm, + level 1/.style={nodes=red}, + level 2/.style={nodes=green!50!black}, + level 3/.style={nodes=blue}] +{ + a -> { + b, + c -> { + d, + e -> {f,g}, + h + }, + j + } +}; +\end{codeexample} +\begin{codeexample}[] +\tikz \graph [ + branch down=5mm, + level 1/.style={grow right=2cm}, + level 2/.style={grow right=1cm}, + level 3/.style={grow right=5mm}] +{ + a -> { + b, + c -> { + d, + e -> {f,g}, + h + }, + j + } +}; +\end{codeexample} +\end{stylekey} + + + +\subsubsection{Defining New Online Placement Strategies} + +\label{section-library-graphs-new-online} + +In the following the details of how to define a new placement strategy +are explained. Most readers may wish to skip this section. + +As a graph specification is being parsed, the |graph| library will keep +track of different numbers that identify the positions of the +nodes. Let us start with what happens on a chain. First, the following +counter is increased for each element of the chain: +\begin{key}{/tikz/graphs/placement/element count} + This key stores a number that tells us the position of the node on + the current chain. However, you only have access to this value + inside the code passed to the macro |compute position|, explained + later on. +\begin{codeexample}[] +\tikz \graph [ + grow right sep, typeset=\tikzgraphnodetext:\mynum, + placement/compute position/.append code= + \pgfkeysgetvalue{/tikz/graphs/placement/element count}{\mynum}] +{ + a -> b -> c, + d -> {e, f->h} -> j +}; +\end{codeexample} + As can be seen, each group resets the element counter. +\end{key} + +The second value that is computed is more complicated to explain, but +it also gives more interesting information: +\begin{key}{/tikz/graphs/placement/width} + This key stores the ``logical width'' of the nodes parsed up to now + in the current group or chain (more precisely, parsed since the last + call of |place| in an enclosing group). This is not necessarily the + ``total physical width'' of the nodes, but rather a number + representing how ``big'' the elements prior to the current element + were. This \emph{may} be their width, but it may also be their + height or even their number (which, incidentally, is the default). + You can use the |width| to perform shifts or rotations of + to-be-created nodes (to be explained later). + + The logical width is defined recursively as follows. First, the + width of a single node is computed by calling the following key: + \begin{key}{/tikz/graphs/placement/logical node width=\meta{full + node name}} + This key is called to compute a physical or logical width of the + node \meta{full node name}. You can change the code of this + key. The code should return the computed value in the macro + |\pgfmathresult|. By default, this key returns |1|. + \end{key} + The width of a chain is the sum of the widths of its elements. The + width of a group is the maximum of the widths of its elements. + + To get a feeling what the above rules imply in practice, let us + first have a look at an example where each node has logical width + and height |1| (which is the default). The arcane options at the + beginning of the code just setup things so that the computed width + and depth of each node is displayed at the bottom of each node. +\begin{codeexample}[] +\tikz + \graph [nodes={align=center, inner sep=1pt}, grow right=7mm, + typeset={\tikzgraphnodetext\\[-4pt] + \tiny\mywidth\\[-6pt]\tiny\mydepth}, + placement/compute position/.append code= + \pgfkeysgetvalue{/tikz/graphs/placement/width}{\mywidth} + \pgfkeysgetvalue{/tikz/graphs/placement/depth}{\mydepth}] +{ + a, + b, + c -> d -> { + e -> f -> g, + h -> i + } -> j, + k -> l +}; +\end{codeexample} + In the next example the ``logical'' width and depth actually match + the ``physical'' width and height. This is caused by the + |grow right sep| option, which internally sets the + |logical node width| key so that it returns the width of its + parameter in points. +\begin{codeexample}[] +\tikz + \graph [grow right sep, branch down sep, nodes={align=left, inner sep=1pt}, + typeset={\tikzgraphnodetext\\[-4pt] \tiny Width: \mywidth\\[-6pt] \tiny Depth: \mydepth}, + placement/compute position/.append code= + \pgfkeysgetvalue{/tikz/graphs/placement/width}{\mywidth} + \pgfkeysgetvalue{/tikz/graphs/placement/depth}{\mydepth}] +{ + a, + b, + c -> d -> { + e -> f -> g, + h -> i + } -> j, + k -> l +}; +\end{codeexample} +\end{key} + +Symmetrically to chains, as a group is being constructed, counters are +available for the number of chains encountered so far in the current +group and for the logical depth of the current group: +\begin{key}{/tikz/graphs/placement/element count} + This key stores a number that tells us the sequence number of the + chain in the current group. +\begin{codeexample}[] +\tikz \graph [ + grow right sep, branch down=5mm, typeset=\tikzgraphnodetext:\mynum, + placement/compute position/.append code= + \pgfkeysgetvalue{/tikz/graphs/placement/chain count}{\mynum}] +{ + a -> b -> {c,d,e}, + f, + g -> h +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/graphs/placement/depth} + Similarly to the |width| key, this key stores the ``logical depth'' + of the nodes parsed up to now in the current group or chain and, also + similarly, this key may or may not be related to the actual + depth/height of the current node. + As for the |width|, the exact definition is as follows: For a single + node, the depth is computed by the following key: + \begin{key}{/tikz/graphs/placement/logical node depth=\meta{full + node name}} + The code behind this key should return the ``logical height'' of + the node \meta{full node name} in the macro |\pgfmathresult|. + \end{key} + Second, the depth of a group is the sum of the depths of its + elements. Third, the depth of a chain is the maximum of the depth of + its elements. +\end{key} + +The |width|, |depth|, |element count|, and |chain count| keys get +updated automatically, but do not have an effect by themselves. This +is to the following two keys: + +\begin{key}{/tikz/graphs/placement/compute position=\meta{code}} + The \meta{code} is called by the |graph| command just prior to + creating a new node (the exact moment when this key is called is + detailed in the description of the |place| key). When the + \meta{code} is called, all of the keys described above will hold + numbers computed in the way described above. + + The job of the \meta{code} is to setup node options appropriately so + that the to-be-created node will be placed correctly. Thus, the + \meta{code} should typically set the key + |nodes={shift=|\meta{coordinate}|}| where \meta{coordinate} is the + computed position for the node. The \meta{code} could + also set other options like, say, the color of a node depending on + its depth. + + The following example appends some code to the standard code of + |compute position| so that ``deeper'' nodes of a tree are + lighter. (Naturally, the same effect could be achieved much more + easily using the |level| key.) +\begin{codeexample}[] +\newcount\mycount +\def\lightendeepernodes{ + \pgfmathsetcount{\mycount}{ + 100-20*\pgfkeysvalueof{/tikz/graphs/placement/width} + } + \edef\mydepth{\the\mycount} + \tikzset{nodes={fill=red!\mydepth,circle,text=white}} +} +\tikz + \graph [placement/compute position/.append code=\lightendeepernodes] + { + a -> { + b -> c -> d, + e -> { + f, + g + }, + h + } + }; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/graphs/placement/place} + Executing this key has two effects: First, the key + |compute position| is called to compute a good + position for future nodes (usually, these ``future nodes'' are just + a single node that is created immediately). Second, all of the above + counters like |depth| or |width| are reset (but not |level|). + + There are two places where this key is sensibly called: First, just + prior to creating a node, which happens automatically. Second, when + you change the online strategy. In this case, the computed width and + depth values from one strategy typically make no sense in the other + strategy, which is why the new strategy should proceed ``from a + fresh start.'' In this case, the implicit call of |compute position| + ensures that the new strategy gets the last place the old strategy + would have used as its starting point, while the computation of its + positions is now relative to this new starting point. + + For these reasons, when an online strategy like + |Cartesian placement| is called, this key gets called + implicitly. You will rarely need to call this key directly, except + when you define a new online strategy. +\end{key} + + + +\subsection{Reference: Predefined Elements} + +\label{section-library-graphs-reference} + + +\subsubsection{Graph Macros} +\label{section-library-graphs-reference-macros} + +\begin{tikzlibrary}{graph.standard} + This library defines a number of graph macros that are often used in + the literature. When new graphs are added to this collection, they + will follow the definitions in the Mathematica program, see + |mathworld.wolfram.com/topics/SimpleGraphs.html|. +\end{tikzlibrary} + + +\begin{graph}{subgraph I\_n} + This graph consists just of $n$ unconnected vertices. The following + key is used to specify the set of these vertices: + \begin{key}{/tikz/graphs/V=\marg{list of vertices}} + Sets a list of vertex names for use with graphs like + |subgraph I_n| and also other graphs. This list is available in + the macro |\tikzgraphV|. The number of elements of this list is + available in |\tikzgraphVnum|. + \end{key} + \begin{key}{/tikz/graphs/n=\meta{number}} + This is an abbreviation for + |V={1,...,|\meta{number}|}, name shore V={name=V}|. + \end{key} +\begin{codeexample}[] +\tikz \graph [branch right, nodes={draw, circle}] + { subgraph I_n [V={a,b,c}] }; +\end{codeexample} + This graph is not particularly exciting by itself. However, it is + often used to introduce nodes into a graph that are then connected + as in the following example: +\begin{codeexample}[] +\tikz \graph [clockwise, clique] { subgraph I_n [n=4] }; +\end{codeexample} +\end{graph} + + +\begin{graph}{subgraph I\_nm} + This graph consists of two sets of once $n$ unconnected vertices and + then $m$ unconnected vertices. The first set consists of the + vertices set by the key |V|, the other set consists of the vertices + set by the key |W|. +\begin{codeexample}[] +\tikz \graph { subgraph I_nm [V={1,2,3}, W={a,b,c}] }; +\end{codeexample} + In order to set the graph path name of the two + sets, the following keys get executed: + \begin{stylekey}{/tikz/graphs/name shore V (initially \normalfont empty)} + Set this style to, say, |name=my V set| in order to set a + name for the |V| set. + \end{stylekey} + \begin{stylekey}{/tikz/graphs/name shore W (initially \normalfont empty)} + Same as for |name shore V|. + \end{stylekey} + \begin{key}{/tikz/graphs/W=\marg{list of vertices}} + Sets the list of vertices for the |W| set. The elements and + their number are available in the macros |\tikzgraphW| and + |\tikzgraphWnum|, respectively. + \end{key} + \begin{key}{/tikz/graphs/m=\meta{number}} + This is an abbreviation for + |W={1,...,|\meta{number}|}, name shore W={name=W}|. + \end{key} + The main purpose of this subgraph is to setup the nodes in a + bipartite graph: +\begin{codeexample}[] +\tikz \graph { + subgraph I_nm [n=3, m=4]; + + V 1 -- { W 2, W 3 }; + V 2 -- { W 1, W 3 }; + V 3 -- { W 1, W 4 }; +}; +\end{codeexample} +\end{graph} + +\begin{graph}{subgraph K\_n} + This graph is the complete clique on the vertices from the |V| key. +\begin{codeexample}[] +\tikz \graph [clockwise] { subgraph K_n [n=7] }; +\end{codeexample} +\end{graph} + + +\begin{graph}{subgraph K\_nm} + This graph is the complete bipartite graph with the two shores |V| + and |W| as in |subgraph I_nm|. +\begin{codeexample}[] +\tikz \graph [branch right, grow down] + { subgraph K_nm [V={6,...,9}, W={b,...,e}] }; +\end{codeexample} +\begin{codeexample}[] +\tikz \graph [simple, branch right, grow down] +{ + subgraph K_nm [V={1,2,3}, W={a,b,c,d}, ->]; + subgraph K_nm [V={2,3}, W={b,c}, <-]; +}; +\end{codeexample} +\end{graph} + +\begin{graph}{subgraph P\_n} + This graph is the path on the vertices in |V|. +\begin{codeexample}[] +\tikz \graph [branch right] { subgraph P_n [n=3] }; +\end{codeexample} +\end{graph} + + +\begin{graph}{subgraph C\_n} + This graph is the cycle on the vertices in |V|. +\begin{codeexample}[] +\tikz \graph [clockwise] { subgraph C_n [n=7, ->] }; +\end{codeexample} +\end{graph} + + +\begin{graph}{subgraph Grid\_n} + This graph is a grid of the vertices in |V|. + \begin{key}{/tikz/graphs/wrap after=\meta{number}} + Defines the number of nodes placed in a single row of the grid. This + value implicitly defines the number of grid columns as well. + In the following example a |grid placement| is used to visualize the + edges created between the nodes of a |Grid_n| |subgraph| using + different values for |wrap after|. + \begin{codeexample}[] +\tikz \graph [grid placement] { subgraph Grid_n [n=3,wrap after=1] }; +\tikz \graph [grid placement] { subgraph Grid_n [n=3,wrap after=3] }; + \end{codeexample} + \begin{codeexample}[] +\tikz \graph [grid placement] { subgraph Grid_n [n=4,wrap after=2] }; +\tikz \graph [grid placement] { subgraph Grid_n [n=4] }; + \end{codeexample} + \end{key} +\end{graph} + + +% TODO: Implement the Grid_nm subgraph described here: +% +%\begin{graph}{subgraph Grid\_nm} +% This graph is a grid built from the cartesian product of the two node +% sets |V| and |W| which are either defined using the keys +% |/tikz/graphs/V| and |/tikz/graphs/W| or |/tikz/graphs/n| and +% |/tikz/graphs/m| or a mixture of both. +% +% The resulting |Grid_nm| subgraph has $n$ ``rows'' and $m$ ``columns'' and +% the nodes are named |V i W j| with $1\le i\le n$ and $1\le j\le n$. +% The names of the two shores |V| and |W| can be changed as described in +% the documentation of the keys |/tikz/graphs/name shore V| and +% |/tikz/graphs/name shore W|. +% \begin{codeexample}[] +%\tikz \graph [grid placement] { subgraph Grid_nm [V={1,2,3}, W={4, 5, 6}] }; +% \end{codeexample} +%\end{graph} + + + +\subsubsection{Group Operators} + +The following keys use the |operator| key to setup operators that +connect the vertices of the current group having a certain color in a +specific way. + +\begin{key}{/tikz/graphs/clique=\meta{color} (default all)} + Adds an edge between all vertices of the current group having the + (logical) color \meta{color}. Since, by default, this color is set + to |all|, which is a color that all nodes get by default, when you + do not specify anything, all nodes will be connected. +\begin{codeexample}[] +\tikz \graph [clockwise, n=5] { + a, + b, + { + [clique] + c, d, e + } +}; +\end{codeexample} +\begin{codeexample}[] +\tikz \graph [color class=red, clockwise, n=5] { + [clique=red, ->] + a, b[red], c[red], d, e[red] +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/graphs/induced independent set=\meta{color} (default all)} + This key is the ``opposite'' of a |clique|: It removes all edges in + the current group having belonging to color class \meta{color}. More + precisely, an edge of kind |-!-| is added for each pair of + vertices. This means that edge only get removed if you specify the + |simple| option. +\begin{codeexample}[] +\tikz \graph [simple] { + subgraph K_n [<->, n=7, clockwise]; % create lots of edges + + { [induced independent set] 1, 3, 4, 5, 6 } +}; +\end{codeexample} +\end{key} + + +\begin{key}{/tikz/graphs/cycle=\meta{color} (default all)} + Connects the nodes colored \meta{color} is a cyclic fashion. The + ordering is the ordering in which they appear in the whole graph + specification. +\begin{codeexample}[] +\tikz \graph [clockwise, n=6, phase=60] { + { [cycle, ->] a, b, c }, + { [cycle, <-] d, e, f } +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/graphs/induced cycle=\meta{color} (default all)} + While the |cycle| command will only add edges, this key will also + remove all other edges between the nodes of the cycle, provided we + are constructing a |simple| graph. +\begin{codeexample}[] +\tikz \graph [simple] { + subgraph K_n [n=7, clockwise]; % create lots of edges + + { [induced cycle, ->, edge=red] 2, 3, 4, 6, 7 }, +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/graphs/path=\meta{color} (default all)} + Works like |cycle|, only there is no edge from the last to the first + vertex. +\begin{codeexample}[] +\tikz \graph [clockwise, n=6] { + { [path, ->] a, b, c }, + { [path, <-] d, e, f } +}; +\end{codeexample} +\end{key} +\begin{key}{/tikz/graphs/induced path=\meta{color} (default all)} + Works like |induced cycle|, only there is no edge from the last to the first + vertex. +\begin{codeexample}[] +\tikz \graph [simple] { + subgraph K_n [n=7, clockwise]; % create lots of edges + + { [induced path, ->, edges=red] 2, 3, 4, 6, 7 }, +}; +\end{codeexample} +\end{key} + + +\subsubsection{Joining Operators} + +The following keys are typically used as options of an \meta{edge + specification}, but can also be called in a group specification +(however, then, the colors need to be set explicitly). + +\begin{key}{/tikz/graphs/complete bipartite=\meta{from color}\meta{to + color} (default \char`\{source'\char`\}\char`\{target'\char`\})} + Adds all possible edges from every node having color \meta{from color} + to every node having color \meta{to color}: +\begin{codeexample}[] +\tikz \graph { {a, b} ->[complete bipartite] + {c, d, e} --[complete bipartite] + {g, h, i, j} --[complete bipartite] + k }; +\end{codeexample} +\begin{codeexample}[] +\tikz \graph [color class=red, color class=green, clockwise, n=6] { + [complete bipartite={red}{green}, ->] + a [red], b[red], c[red], d[green], e[green], f[green] +}; +\end{codeexample} +\end{key} +\begin{key}{/tikz/graphs/induced complete bipartite} + Works like the |complete bipartite| operator, but in a |simple| + graph any edges between the vertices in either shore are removed + (more precisely, they get replaced by |-!-| edges). +\begin{codeexample}[] +\tikz \graph [simple] { + subgraph K_n [n=5, clockwise]; % Lots of edges + + {2, 3} ->[induced complete bipartite] {4, 5} +}; +\end{codeexample} +\end{key} +\begin{key}{/tikz/graphs/matching=\meta{from color}\meta{to + color} (default \char`\{source'\char`\}\char`\{target'\char`\})} + This joining operator forms a maximum + \emph{matching} between the nodes of the two sets of nodes having + colors \meta{from color} and \meta{to color}, respectively. The first node of + the from set is connected to the first node of to set, the second + node of the from set is connected to the second node of the to set, + and so on. If the sets have the same + size, what results is what graph theoreticians call a \emph{perfect + matching}, otherwise only a maximum, but not perfect matching + results. +\begin{codeexample}[] +\tikz \graph { + {a, b, c} ->[matching] + {d, e, f} --[matching] + {g, h} --[matching] + {i, j, k} +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/graphs/matching and star=\meta{from color}\meta{to + color} (default \char`\{source'\char`\}\char`\{target'\char`\})} + The |matching and star| connector works like the |matching| + connector, only it behaves differently when the two to-be-connected + sets have different size. In this case, all the surplus nodes get + connected to the last node of the other set, resulting in what is known + as a \emph{star} in graph theory. This simple rule allows + for some powerful effects (since this connector is the default, + there is no need to add it here): + \begin{codeexample}[] +\tikz \graph { a -> {b, c} -> {d, e} -- f}; + \end{codeexample} + The |matching and star| connector also makes it easy to create trees and + series-parallel graphs. +\end{key} + +\begin{key}{/tikz/graphs/butterfly=\opt{\meta{options}}} + The |butterfly| connector is used to create the kind of connections + present between layers of a so-called \emph{butterfly network}. + As for other connectors, two sets of nodes are connected, which are + the nodes having color |target'| and |source'| by default. In a + \emph{level $l$} connection, the first $l$ nodes of the first set + are connected to the second $l$ nodes of the second set, while the + second $l$ nodes of the first set get connected to the first $l$ + nodes of the second set. Then, for next $2l$ nodes of both sets a + similar kind of connection is installed. Additionally, each node + gets connected to the corresponding node in the other set with the + same index (as in a |matching|): +\begin{codeexample}[] +\tikz \graph [left anchor=east, right anchor=west, + branch down=4mm, grow right=15mm] { + subgraph I_n [n=12, name=A] --[butterfly={level=3}] + subgraph I_n [n=12, name=B] --[butterfly={level=2}] + subgraph I_n [n=12, name=C] +}; +\end{codeexample} + Unlike most joining operators, the colors of the nodes in the first + and the second set are not passed as parameters to the |butterfly| + key. Rather, they can be set using the \meta{options}, which are + executed with the path prefix |/tikz/graphs/butterfly|. + \begin{key}{/tikz/graphs/butterfly/level=\meta{level} (initially 1)} + Sets the level $l$ for the connections. + \end{key} + \begin{key}{/tikz/graphs/butterfly/from=\meta{color} (initially target')} + Sets the color class of the from nodes. + \end{key} + \begin{key}{/tikz/graphs/butterfly/to=\meta{color} (initially source')} + Sets the color class of the to nodes. + \end{key} +\end{key} + + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "pgfmanual-pdftex-version" +%%% End: diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-matrices.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-matrices.tex index 265880d2b6e..051ede9e9c6 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-matrices.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-matrices.tex @@ -15,7 +15,7 @@ When creating pictures, one often faces the problem of correctly aligning parts of the picture. For example, you might wish that the -base lines of certain nodes should be on the same line and some +|baseline|s of certain nodes should be on the same line and some further nodes should be below these nodes with, say, their centers on a vertical lines. There are different ways of solving such problems. For example, by making clever use of anchors, nearly all @@ -29,7 +29,7 @@ little picture or a node. The sizes of the cells are automatically adjusted such that they are large enough to contain all the cell contents. -Matrices are a powerful tool and they need to handled with some care. +Matrices are a powerful tool and they need to be handled with some care. For impatient readers who skip the rest of this section: you \emph{must} end \emph{every} row with |\\|. In particular, the last row \emph{must} be ended with |\\|. @@ -96,7 +96,7 @@ effect as for normal nodes: \subsection{Cell Pictures} - +\label{section-tikz-cell-pictures} A matrix consists of rows of \emph{cells}. Each row (including the last one!) is ended by the command |\\|. The character |&| is used to separate cells. Inside each cell, you must place commands for @@ -119,7 +119,7 @@ the origin of the cell picture can be found (the origin might even lie outside the bounding box, but let us ignore this problem for the moment). The cell pictures are then shifted around such that all origins lie on the same horizontal line. This may make it necessary to -shift some cell pictures upwards and other downwards, but it can be +shift some cell pictures upwards and others downwards, but it can be done and this yields the vertical alignment of the cell pictures this row. The top of the row is then given by the top of the ``highest'' cell picture in the row, the bottom of the row is given by the bottom @@ -173,13 +173,13 @@ shifted horizontally such that the origins lie on the same vertical line. Then, the left end of the column is at the left end of the bounding box that protrudes furthest to the left. The right end of the column is at the right end of the bounding box that protrudes furthest -to the left. This fixes the horizontal alignment of the cell pictures +to the right. This fixes the horizontal alignment of the cell pictures in the first column and the same happens the cell pictures in the other columns. Then, the right end of the first column touches the left end of the second column (unless |column sep| is used). The right end of the second column touches the left end of the third column, and so on. (Internally, two columns are actually used to achieve the -desired horizontal alignment, but that is only and implementation +desired horizontal alignment, but that is only an implementation detail.) \begin{codeexample}[] @@ -251,7 +251,7 @@ the column or row or between their borders. origins of all the cells in the second column is exactly the given distance. - \emph{The |between origins| option can only be used for columns + \emph{The }|between origins|\emph{ option can only be used for columns mentioned in the first row, that is, you cannot specify this option for columns introduced only in later rows.} @@ -366,8 +366,8 @@ of this option in later rows have no effect. \subsubsection{Cell Styles and Options} -For following style and option are useful for changing the appearance -of the all cell pictures: +The following styles and options are useful for changing the appearance +of all cell pictures: \begin{stylekey}{/tikz/every cell=\marg{row}\marg{column} (initially \normalfont empty)} This style is installed at the beginning of each cell picture with @@ -382,13 +382,13 @@ of the all cell pictures: \end{stylekey} \begin{key}{/tikz/cells=\meta{options}} - This key adds the \meta{options} to the style |every cell|. It mainly + This key adds the \meta{options} to the style |every cell|. It is mainly just a shorthand for the code |every cell/.append style=|\meta{options}. \end{key} \begin{key}{/tikz/nodes=\meta{options}} - This key adds the \meta{options} to the style |every node|. It mainly + This key adds the \meta{options} to the style |every node|. It is mainly just a shorthand for the code |every node/.append style=|\meta{options}. The main use of this option is the install some options for the @@ -563,7 +563,7 @@ effect when given as an argument to a matrix: \begin{key}{/tikz/anchor=\meta{anchor or node.anchor}} Normally, the argument of this option refers to anchor of the matrix - node, which is the node than includes all of the stuff of the + node, which is the node that includes all of the stuff of the matrix. However, you can also provide an argument of the form \meta{node}|.|\meta{anchor} where \meta{node} must be node defined inside the matrix and \meta{anchor} is an anchor of this node. In @@ -604,7 +604,7 @@ having to type |\pgfmatrixnextcell| each time: If a macro name is provided, this macro will be defined to be equal to |\pgfmatrixnextcell| inside matrices and |&| will not be made active. For instance, you could say |ampersand replacement=\&| and - then use \& to separate columns as in the following example: + then use |\&| to separate columns as in the following example: \begin{codeexample}[] \tikz \matrix [ampersand replacement=\&] diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-paths.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-paths.tex index 77726100290..02456c9c869 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-paths.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-paths.tex @@ -21,7 +21,7 @@ present section. The \meta{specification} is a long stream of \emph{path operations}. Most of these path operations tell \tikzname\ how the path - is build. For example, when you write |--(0,0)|, you use a + is built. For example, when you write |--(0,0)|, you use a \emph{line-to operation} and it means ``continue the path from wherever you are to the origin.'' @@ -107,7 +107,7 @@ present section. everything in a scope. \begin{codeexample}[] \begin{tikzpicture} - [fill=examplefill, % only sets the color + [fill=yellow!80!black, % only sets the color every path/.style={draw}] % all paths are drawn \fill (0,0) rectangle +(1,1); \shade (2,0) rectangle +(1,1); @@ -186,27 +186,38 @@ expected. described next. \end{pathoperation} +There is special coordinate called |current subpath start| that is +always at the position of the last move-to operation on the current +path. -\subsection{The Line-To Operation} +\begin{codeexample}[] +\tikz [line width=2mm] + \draw (0,0) -- (1,0) -- (1,1) + -- (0,1) -- (current subpath start); +\end{codeexample} + +Note how in the above example the path is not closed (as |--cycle| +would do). Rather, the line just starts and ends at the origin without +being a closed path. +\subsection{The Line-To Operation} + \subsubsection{Straight Lines} -\begin{pathoperation}{--}{\meta{coordinate}} +\begin{pathoperation}{--}{\meta{coordinate or cycle}} The line-to operation extends the current path from the current - point in a straight line to the given coordinate. The ``current + point in a straight line to the given \meta{coordinate} (the ``or + cycle'' part is explained in a moment). The ``current point'' is the endpoint of the previous drawing operation or the point specified by a prior move-to operation. - You use two minus signs followed by a coordinate in round - brackets. You can add spaces before and after the~|--|. - When a line-to operation is used and some path segment has just been constructed, for example by another line-to operation, the two line segments become joined. This means that if they are drawn, the point where they meet is ``joined'' smoothly. To appreciate the difference, consider the following two examples: In the left example, the path - consists of two path segments that are not joined, but that happen to + consists of two path segments that are not joined, but they happen to share a point, while in the right example a smooth join is shown. \begin{codeexample}[] @@ -217,8 +228,36 @@ expected. \end{tikzpicture} \end{codeexample} + Instead of a coordinate following the two minus signs, you can also + use the text |cycle|. This causes the straight line from the current + point to go to the last point specified by a move-to operation. Note + that this need not be the beginning of the path. Furthermore, a + smooth join is created between the first segment created after the + last move-to operation and the straight line appended by the cycle + operation. + + Consider the following example. In the left example, two triangles are + created using three straight lines, but they are not joined at the + ends. In the second example cycle operations are used. + +\begin{codeexample}[] +\begin{tikzpicture}[line width=10pt] + \draw (0,0) -- (1,1) -- (1,0) -- (0,0) (2,0) -- (3,1) -- (3,0) -- (2,0); + \draw (5,0) -- (6,1) -- (6,0) -- cycle (7,0) -- (8,1) -- (8,0) -- cycle; + \useasboundingbox (0,1.5); % make bounding box higher +\end{tikzpicture} +\end{codeexample} \end{pathoperation} +Writing |cycle| instead of a coordinate at the end of a path operation +is possible with all path operations that end with a coordinate (such +as |--| or |..| or |sin| or |grid|, but not |graph| or |plot|). +In all cases, the effect is that the coordinate of the last moveto is +used as the coordinate expected by the path operation and that a +smooth join is added. (What actually happens that the text |cycle| +used with any path operation other than |--| gets replaced by +|(current subpath start)--cycle|.) + \subsubsection{Horizontal and Vertical Lines} @@ -227,21 +266,28 @@ only horizontal and vertical. For this, you can use two path construction operations. {\catcode`\|=12 -\begin{pathoperation}[noindex]{-|}{\meta{coordinate}} +\begin{pathoperation}[noindex]{-|}{\meta{coordinate or cycle}} \index{--1@\protect\texttt{-\protect\pgfmanualbar} path operation}% \index{Path operations!--1@\protect\texttt{-\protect\pgfmanualbar}}% \pgfmanualpdflabel[\catcode`\|=12 ]{-|}{}% This operation means ``first horizontal, then vertical.'' - \begin{codeexample}[] +\begin{codeexample}[] \begin{tikzpicture} \draw (0,0) node(a) [draw] {A} (1,1) node(b) [draw] {B}; \draw (a.north) |- (b.west); \draw[color=red] (a.east) -| (2,1.5) -| (b.north); \end{tikzpicture} \end{codeexample} + Instead of a coordinate you can also write \verb!cycle! to close the + path: +\begin{codeexample}[] +\begin{tikzpicture}[ultra thick] + \draw (0,0) -- (1,1) -| cycle; +\end{tikzpicture} +\end{codeexample} \end{pathoperation} -\begin{pathoperation}[noindex]{|-}{\meta{coordinate}} +\begin{pathoperation}[noindex]{|-}{\meta{coordinate or cycle}} \index{--2@\protect\texttt{\protect\pgfmanualbar-} path operation}% \index{Path operations!--2@\protect\texttt{\protect\pgfmanualbar-}}% \pgfmanualpdflabel[\catcode`\|=12 ]{|-}{}% @@ -252,13 +298,15 @@ construction operations. \subsection{The Curve-To Operation} -The curve-to operation allows you to extend a path using a Bézier +The curve-to operation allows you to extend a path using a B\'ezier curve. -\begin{pathoperation}{..}{\declare{|controls|}\meta{c}\opt{|and|\meta{d}}\declare{|..|\meta{y}}} +\begin{pathoperation}{..}{\declare{|controls|}\meta{c}\opt{|and|\meta{d}}\declare{|..|\meta{y or cycle}}} This operation extends the current path from the current - point, let us call it $x$, via a curve to a the current point~$y$. - The curve is a cubic Bézier curve. For such a curve, + point, let us call it $x$, via a curve to a point~$y$ (if, instead + of a coordinate you say |cycle| at the end, $y$ will be the + coordinate of the last move-to operation). + The curve is a cubic B\'ezier curve. For such a curve, apart from $y$, you also specify two control points $c$ and $d$. The idea is that the curve starts at $x$, ``heading'' in the direction of~$c$. Mathematically spoken, the tangent of the curve at $x$ goes @@ -277,38 +325,21 @@ curve. \end{tikzpicture} \end{codeexample} - As with the line-to operation, it makes a difference whether two curves - are joined because they resulted from consecutive curve-to or line-to - operations, or whether they just happen to have the same ending: - \begin{codeexample}[] -\begin{tikzpicture}[line width=10pt] - \draw (0,0) -- (1,1) (1,1) .. controls (1,0) and (2,0) .. (2,0); - \draw (3,0) -- (4,1) .. controls (4,0) and (5,0) .. (5,0); - \useasboundingbox (0,1.5); % make bounding box higher +\begin{tikzpicture} + \draw[line width=10pt] (0,0) -- (2,0) .. controls (1,1) .. cycle; \end{tikzpicture} \end{codeexample} -\end{pathoperation} - - -\subsection{The Cycle Operation} - -\begin{pathoperation}{--cycle}{} - This operation adds a straight line from the current - point to the last point specified by a move-to operation. Note that - this need not be the beginning of the path. Furthermore, a smooth join - is created between the first segment created after the last move-to - operation and the straight line appended by the cycle operation. - Consider the following example. In the left example, two triangles are - created using three straight lines, but they are not joined at the - ends. In the second example cycle operations are used. + As with the line-to operation, it makes a difference whether two curves + are joined because they resulted from consecutive curve-to or line-to + operations, or whether they just happen to have a common (end) point: \begin{codeexample}[] \begin{tikzpicture}[line width=10pt] - \draw (0,0) -- (1,1) -- (1,0) -- (0,0) (2,0) -- (3,1) -- (3,0) -- (2,0); - \draw (5,0) -- (6,1) -- (6,0) -- cycle (7,0) -- (8,1) -- (8,0) -- cycle; - \useasboundingbox (0,1.5); % make bounding box higher + \draw (0,0) -- (1,1) (1,1) .. controls (1,0) and (2,0) .. (2,0); + \draw [yshift=-1.5cm] + (0,0) -- (1,1) .. controls (1,0) and (2,0) .. (2,0); \end{tikzpicture} \end{codeexample} \end{pathoperation} @@ -321,10 +352,10 @@ A rectangle can obviously be created using four straight lines and a cycle operation. However, since rectangles are needed so often, a special syntax is available for them. -\begin{pathoperation}{rectangle}{\meta{corner}} +\begin{pathoperation}{rectangle}{\meta{corner or cycle}} When this operation is used, one corner will be the current point, another corner is given by \meta{corner}, which becomes the new - current point. + current point. \begin{codeexample}[] \begin{tikzpicture} @@ -332,6 +363,9 @@ special syntax is available for them. \draw (.5,1) rectangle (2,0.5) (3,0) rectangle (3.5,1.5) -- (2,0); \end{tikzpicture} \end{codeexample} + + Just for consistency, you can also use |cycle| instead of a + coordinate, but it is a bit unclear what use this might have. \end{pathoperation} @@ -440,7 +474,7 @@ special path operation. It is possible to set the |radius| also in some enclosing scope, in this case the options can be left out (but see the note below on - what may follow: + what may follow): \begin{codeexample}[] \begin{tikzpicture}[radius=2pt] \draw (0,0) circle -- (1,1) circle -- ++(0,1) circle; @@ -449,7 +483,7 @@ special path operation. The following style is used with every circle: \begin{stylekey}{/tikz/every circle} - You can use this key to setup, say, a default radius for every + You can use this key to set up, say, a default radius for every circle. The key will also be used with the |ellipse| operation. \end{stylekey} @@ -553,9 +587,12 @@ path. You can add a grid to the current path using the |grid| path operation. -\begin{pathoperation}{grid}{\opt{\oarg{options}}\meta{corner}} +\begin{pathoperation}{grid}{\opt{\oarg{options}}\meta{corner or cycle}} This operations adds a grid filling a rectangle whose two corners - are given by \meta{corner} and by the previous coordinate. Thus, the + are given by \meta{corner} and by the previous coordinate. (Instead + of a coordinate you can also say |cycle| to use the position of the + last move-to as the corner coordinate, but it not very natural to + do so.) corner Thus, the typical way in which a grid is drawn is |\draw (1,1) grid (3,3);|, which yields a grid filling the rectangle whose corners are at $(1,1)$ and $(3,3)$. All coordinate transformations apply to the @@ -643,20 +680,26 @@ equation $f(x) = x^2$ and looks like this: \tikz \draw (-1ex,1.5ex) parabola[parabola height=-1.5ex] +(2ex,0ex);. \begin{pathoperation}{parabola}{\opt{\oarg{options}|bend|\meta{bend - coordinate}}\meta{coordinate}} + coordinate}}\meta{coordinate or cycle}} This operation adds a parabola through the current point and the - given \meta{coordinate}. If the |bend| is given, it specifies where + given \meta{coordinate} or, if |cycle| is used instead of coordinate + at the end, the \meta{coordinate} is set to the position of the last + move-to and the path gets closed after the parabola. If the |bend| + is given, it specifies where the bend should go; the \meta{options} can also be used to specify where the bend is. By default, the bend is at the old current point. \begin{codeexample}[] \begin{tikzpicture} - \draw (0,0) rectangle (1,1.5) - (0,0) parabola (1,1.5); - \draw[xshift=1.5cm] (0,0) rectangle (1,1.5) - (0,0) parabola[bend at end] (1,1.5); - \draw[xshift=3cm] (0,0) rectangle (1,1.5) - (0,0) parabola bend (.75,1.75) (1,1.5); + \draw (0,0) rectangle (1,1.5) + (0,0) parabola (1,1.5); + \draw[xshift=1.5cm] (0,0) rectangle (1,1.5) + (0,0) parabola[bend at end] (1,1.5); + \draw[xshift=3cm] (0,0) rectangle (1,1.5) + (0,0) parabola bend (.75,1.75) (1,1.5); + + \draw[yshift=-2cm] (1,1.5) -- + (0,0) parabola cycle; \end{tikzpicture} \end{codeexample} @@ -672,7 +715,7 @@ parabola[parabola height=-1.5ex] +(2ex,0ex);. There is one special property of the \meta{coordinate}: When a relative coordinate is given like |+(0,0)|, the position relative - to which this coordinate is ``flexible.'' More precisely, this + to this coordinate is ``flexible.'' More precisely, this position lies somewhere on a line from the old current point to the new current point. The exact position depends on the next option. @@ -733,7 +776,7 @@ The |sin| and |cos| operations are similar to the |parabola| operation. They, too, can be used to draw (parts of) a sine or cosine curve. -\begin{pathoperation}{sin}{\meta{coordinate}} +\begin{pathoperation}{sin}{\meta{coordinate or cycle}} The effect of |sin| is to draw a scaled and shifted version of a sine curve in the interval $[0,\pi/2]$. The scaling and shifting is done in such a way that the start of the sine curve in the interval is at the @@ -746,7 +789,7 @@ curve. \end{codeexample} \end{pathoperation} -\begin{pathoperation}{cos}{\meta{coordinate}} +\begin{pathoperation}{cos}{\meta{coordinate or cycle}} This operation works similarly, only a cosine in the interval $[0,\pi/2]$ is drawn. By correctly alternating |sin| and |cos| operations, you can create a complete sine or cosine curve: @@ -770,21 +813,21 @@ given in the \textsc{svg} path data syntax. This syntax is described in detail in Section 8.3 of the \textsc{svg 1.1} specification, please consult this specification for details. -\begin{pathoperation}{svg}{\opt{\oarg{options}}|"|\meta{path data}|"|} +\begin{pathoperation}{svg}{\opt{\oarg{options}}\marg{path data}} This operation adds the path specified in the \meta{path data} in \textsc{svg 1.1 path data} syntax to the current path. Unlike the \textsc{svg}-specification, it \emph{is} permissible that the path - data does not start with a moveto command (|m| or |M|), in which + data does not start with a move-to command (|m| or |M|), in which case the last point of the current path is used as start point. The optional \meta{options} apply locally to this path operation, - typically you will use them to setup, say, some transformations. + typically you will use them to set up, say, some transformations. \begin{codeexample}[] \begin{tikzpicture} - \filldraw [fill=red!20] (0,1) svg[scale=2] "h 10 v 10 h -10" + \filldraw [fill=red!20] (0,1) svg[scale=2] {h 10 v 10 h -10} node [above left] {upper left} -- cycle; - \draw svg "M 0 0 L 20 20 h 10 a 10 10 0 0 0 -20 0"; + \draw svg {M 0 0 L 20 20 h 10 a 10 10 0 0 0 -20 0}; \end{tikzpicture} \end{codeexample} @@ -795,8 +838,11 @@ consult this specification for details. (yes, this works, although some rather evil magic is involved) will cause 1cm to be the basic unit. - \emph{Warning:} The arc operations (|a| and |A|) are not numerically - stable. This means that they will be quite imprecise, except when + Instead of curly braces, you can also use quotation marks to + indicate the start and end of the \textsc{svg} path. + + \emph{Warning:} The arc operations (|a| and |A|) are numerically + instable. This means that they will be quite imprecise, except when the angle is a multiple of $90^\circ$ (as is, fortunately, most often the case). \end{pathoperation} @@ -823,14 +869,14 @@ of 45$^\circ$ at |b|. This is because the options |in| and |out| trigger a special path to be used instead of the straight line. \begin{pathoperation}{to}{\opt{|[|\meta{options}|]|} - \opt{\meta{nodes}} |(|\meta{coordinate}|)|} + \opt{\meta{nodes}} \meta{coordinate or cycle}} - This path operation inserts the path current set via the |to path| + This path operation inserts the path currently set via the |to path| option at the current position. The \meta{options} can be used to - modify (perhaps implicitly) the |to path| and to setup how the path + modify (perhaps implicitly) the |to path| and to set up how the path will be rendered. - Before the |to path| is inserted, a number of macros are setup that + Before the |to path| is inserted, a number of macros are set up that can ``help'' the |to path|. These are |\tikztostart|, |\tikztotarget|, and |\tikztonodes|; they are explained in the following. @@ -838,28 +884,31 @@ trigger a special path to be used instead of the straight line. \medskip \textbf{Start and Target Coordinates.}\ \ The |to| operation is always followed by a \meta{coordinate}, called - the target coordinate. The macro |\tikztotarget| is set to this - coordinate (without the parentheses). There is also a \emph{start - coordinate}, which is the coordinate preceding the |to| - operation. This coordinate can be accessed via the macro - |\tikztostart|. In the following example, for the first |to|, the - macro |\tikztostart| is |0pt,0pt| and the |\tikztotarget| is - |0,2|. For the second |to|, the macro |\tikztostart| is |10pt,10pt| - and |\tikztotarget| is |a|. + the target coordinate, or the text |cycle|, in which case the last + move-to is used as a coordinate and the path gets closed. The macro + |\tikztotarget| is set to this coordinate (without its + parentheses). There is also a \emph{start coordinate}, which is the + coordinate preceding the |to| operation. This coordinate can be + accessed via the macro |\tikztostart|. In the following example, for + the first |to|, the macro |\tikztostart| is |0pt,0pt| and the + |\tikztotarget| is |0,2|. For the second |to|, the macro + |\tikztostart| is |10pt,10pt| and |\tikztotarget| is |a|. For the + third, they are set to |a| and |current subpath start|. \begin{codeexample}[] \begin{tikzpicture} \draw[help lines] (0,0) grid (3,2); + \node (a) at (2,2) {a}; - \draw (0,0) to (0,2); - \node (a) at (2,2) {a}; - \draw[red] (10pt,10pt) to (a); + \draw (0,0) to (0,2); + \draw[red] (10pt,10pt) to (a); + \draw[blue] (3,0) -- (3,2) -- (a) to cycle; \end{tikzpicture} \end{codeexample} \medskip - \textbf{Nodes on tos.}\ \ + \textbf{Nodes on to--paths.}\ \ It is possible to add nodes to the paths constructed by a |to| operation. To do so, you specify the nodes between the |to| keyword and the coordinate (if there are options to the |to| @@ -876,6 +925,42 @@ trigger a special path to be used instead of the straight line. \end{tikzpicture} \end{codeexample} + Instead of writing the node between the |to| keyword and the + target coordinate, you may also use the following keys to create + such nodes: + \begin{key}{/tikz/edge node=\meta{node specification}} + This key can be used inside the \meta{options} of a |to| path + command. It will add the \meta{node specification} to the list of + nodes to be placed on the connecting line, just as if you had + written the \meta{node specification} directly after the |to| + keyword: +\begin{codeexample}[] +\begin{tikzpicture} + \draw (0,0) to [edge node={node [sloped,above] {x}}] (3,2); + + \draw (0,0) to [out=90,in=180, + edge node={node [sloped,above] {x}}] (3,2); +\end{tikzpicture} +\end{codeexample} + This key is mostly useful to create labels automatically using + other keys. + \end{key} + \begin{key}{/tikz/edge label=\meta{text}} + A shorthand for |edge node={node[auto]{|\meta{text}|}}|. +\begin{codeexample}[] +\tikz \draw (0,0) to [edge label=x] (3,2); +\end{codeexample} + \end{key} + \begin{key}{/tikz/edge label'=\meta{text}} + A shorthand for |edge node={node[auto,swap]{|\meta{text}|}}|. +\begin{codeexample}[] +\tikz \draw (0,0) to [edge label=x, edge label'=y] (3,2); +\end{codeexample} + \end{key} + + When the |quotes| library is loaded, additional ways of specifying + nodes on to--paths become available, see Section~\ref{section-edge-quotes}. + \medskip \textbf{Styles for to-paths.}\ \ In addition to the \meta{options} given after the |to| operation, @@ -886,6 +971,14 @@ trigger a special path to be used instead of the straight line. \tikz[every to/.style={bend left}] \draw (0,0) to (3,2); \end{codeexample} + Note that, as explained below, every to path is implicitly + surrounded by curly braces. This means that options like |draw| + given in an |every to| do not actually influence the path. You can + fix this by using the |append after command| option: +\begin{codeexample}[] +\tikz[every to/.style={append after command={[draw,dashed]}}] + \draw (0,0) to (3,2); +\end{codeexample} \end{stylekey} \medskip @@ -910,16 +1003,16 @@ trigger a special path to be used instead of the straight line. Inside the \meta{path}, different macros are used to reference the from- and to-coordinates. In detail, these are: \begin{itemize} - \item \declare{|\tikztostart|} will expand to the from-coordinate + \item \declareandlabel{\tikztostart} will expand to the from-coordinate (without the parentheses). - \item \declare{|\tikztotarget|} will expand to the to-coordinate. - \item \declare{|\tikztonodes|} will expand to the nodes between + \item \declareandlabel{\tikztotarget} will expand to the to-coordinate. + \item \declareandlabel{\tikztonodes} will expand to the nodes between the |to| operation and the coordinate. Furthermore, these nodes will have the |pos| option set implicitly. \end{itemize} Let us have a look at a simple example. The standard straight line - for an to is achieved by the following \meta{path}: + for a |to| is achieved by the following \meta{path}: \begin{quote} |-- (\tikztotarget) \tikztonodes| \end{quote} @@ -932,7 +1025,7 @@ trigger a special path to be used instead of the straight line. \end{quote} the \meta{path} will expand to \begin{quote} - |(a) -- (b) node[pos] {x}| + |(a) -- (b) node[red] {x}| \end{quote} It is not possible to specify the path @@ -976,7 +1069,7 @@ trigger a special path to be used instead of the straight line. \end{codeexample} \begin{key}{/tikz/execute at begin to=\meta{code}} - The \meta{code} is executed prior to the to. This can be used to + The \meta{code} is executed prior to the |to|. This can be used to draw one or more additional paths or to do additional computations. \end{key} @@ -998,6 +1091,23 @@ There are a number of predefined |to path|s, see Section~\ref{library-to-paths} for a reference. +\subsection{The Foreach Operation} + +\begin{pathoperation}{foreach}{\meta{variables}\opt{\oarg{options}} |in| + \marg{path commands}} + The |foreach| operation can be used to repeatedly insert the + \meta{path commands} into the current path. Naturally, the + \meta{path commands} should internally reference some of the + \meta{variables} so that you do not insert exactly the same path + repeatedly, but rather variations. For historical reasons, you can + also write |\foreach| instead of |foreach|. +\begin{codeexample}[] +\tikz \draw (0,0) foreach \x in {1,...,3} { -- (\x,1) -- (\x,0) }; +\end{codeexample} + See Section~\ref{section-foreach} for more details on the + for-each-command. +\end{pathoperation} + \subsection{The Let Operation} The \emph{let operation} is the first of a number of path operations @@ -1020,7 +1130,7 @@ local, effects. |\n|\meta{number register}|={|\meta{formula}|}| \end{quote} When an assignment has this form, the \meta{formula} is evaluated - using the |\pgfmathparse| operation. The result stored in the + using the |\pgfmathparse| operation. The result is stored in the \meta{number register}. If the \meta{formula} involves a dimension anywhere (as in |2*3cm/2|), then the \meta{number register} stores the resulting dimension with a trailing |pt|. A \meta{number register} can @@ -1050,7 +1160,7 @@ local, effects. \end{quote} Point position registers store a single point, consisting of an $x$-part and a $y$-part measured in \TeX\ points (|pt|). In - particular, point registers do not stored nodes or node names. + particular, point registers do not store nodes or node names. Here is an example: \begin{codeexample}[] \begin{tikzpicture} @@ -1077,7 +1187,7 @@ local, effects. what you intended. \end{command} \begin{command}{\x\marg{point register}} - This macro expand just to the $x$-part of the point + This macro expands just to the $x$-part of the point register. If we say as above, as we did above, |let \p1=(1pt,1pt+2pt) in ...|, then inside the |...| part the macro |\x1| expands to |1pt|. @@ -1127,7 +1237,7 @@ local, effects. \end{tikzpicture} \end{codeexample} - For a more useful application of the let operation, let use draw a + For a more useful application of the let operation, let us draw a circle that touches a given line: \begin{codeexample}[] \begin{tikzpicture} @@ -1164,8 +1274,7 @@ please see Section~\ref{section-scopes-relative}. \subsection{The Node and Edge Operations} -There are two more operations that can be found in paths: -|node| and |edge|. The first is used to add a so-called node to a +The |node| operation adds a so-called node to a path. This operation is special in the following sense: It does not change the current path in any way. In other words, this operation is not really a path operation, but has an effect that is @@ -1178,6 +1287,20 @@ Since these operations are quite complex, they are described in the separate Section~\ref{section-nodes}. +\subsection{The Graph Operation} + +The |graph| operation can be used to specify easily how a large number +of nodes are connected. This operation is documented in a separate +section, see Section~\ref{section-library-graphs}. + + +\subsection{The Pic Operation} + +The |pic| operation is used to insert a ``short picture'' (hence the +``short'' name) at the current position of the path. This operation is +somewhat similar to the |node| operation and discussed in detail in +Section~\ref{section-pics}. + \subsection{The PGF-Extra Operation} @@ -1209,9 +1332,9 @@ used deep inside clever macros, not on normal paths. This is an alternative syntax for the |\pgfextra| command. If the code following |\pgfextra| does not start with a brace, the \meta{code} is executed until |\endpgfextra| is encountered. What - actually happens is that |\pgfextra| that is not followed by a brace - completely shuts down the \tikzname\ parse and |\endpgfextra| is a - normal macro that restarts the parser. + actually happens is that when |\pgfextra| is not followed by a + brace, this completely shuts down the \tikzname\ parser and + |\endpgfextra| is a normal macro that restarts the parser. \begin{codeexample}[] \newdimen\mydim diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-pics.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-pics.tex new file mode 100644 index 00000000000..fcc88e1e5dc --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-pics.tex @@ -0,0 +1,531 @@ +% Copyright 2013 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\section{Pics: Small Pictures on Paths} + +\label{section-pics} + +\subsection{Overview} + +A ``pic'' is a ``short picture'' (hence the short name\dots) that can +be inserted anywhere in \tikzname\ picture where you could also insert +a node. Similarly to nodes, pics have a ``shape'' (called \emph{type} +to avoid confusion) that someone has defined. Each time a pic of a +specified type is used, the type's code is executed, resulting in some +drawings to be added to the current picture. The syntax for adding +nodes and adding pics to a picture are also very similar. The core +difference is that pics are typically more complex than nodes and may +consist of a whole bunch of nodes themselves together with complex +paths joining them. + +As a very simple example, suppose we want to define a pic type +|seagull| that just draw ``two bumps.'' The code for this definition +is quite easy: +\begin{codeexample}[code only] +\tikzset{ + seagull/.pic={ + % Code for a "seagull". Do you see it?... + \draw (-3mm,0) to [bend left] (0,0) to [bend left] (3mm,0); + } +} +\end{codeexample} + +The first line just tells \TeX\ that you set some \tikzname\ options +for the current scope (which is the whole document); you could put +|seagull/.pic=...| anywhere else where \tikzname\ options are allowed +(which is just about anywhere). We have now defined a |seagull| pic +type and can use it as follows: + +\tikzset{ + seagull/.pic={ + % Code for a "seagull". Do you see it?... + \draw (-3mm,0) to [bend left] (0,0) to [bend left] (3mm,0); + } +} +\begin{codeexample}[] +\tikz \fill [fill=blue!20] + (1,1) + -- (2,2) pic {seagull} + -- (3,2) pic {seagull} + -- (3,1) pic [rotate=30] {seagull} + -- (2,1) pic [red] {seagull}; +\end{codeexample} + +As can be see, defining new types of pics is much easier than defining +new shapes for nodes; but see Section~\ref{section-new-pic-types} +for the fine details. + +Since defining new pics types is easier than defining new node shapes +and since using pics is as easy as using nodes, why should you use +nodes at all? There are chiefly two reasons: + +\begin{enumerate} +\item Unlike nodes, pics cannot be referenced later on. You \emph{can} + reference nodes that are inside a pic, but not ``the pic itself.'' + In particular, you cannot draw lines between pics the way you + can draw them between nodes. In general, whenever it makes sense + that some drawing could conceivably be connected to other + node-like-things, then a node is better than a pic. +\item If pics are used to emulate the full power of a node (which is + possible, in principle), they will be slower to construct and take + up more memory than a node achieving the same effect. +\end{enumerate} + +Despite these drawbacks, pics are an excellent choice for creating +highly configurable reusable pieces of drawings that can be inserted +into larger contexts. + + +\subsection{The Pic Syntax} + +\begin{command}{\pic} + Inside |{tikzpicture}| this is an abbreviation for |\path pic|. +\end{command} + +The syntax for adding a pic to a picture is very similar to the syntax +used for nodes (indeed, internally the same parser code is used). The +main difference is that instead of a node contents you provide the +picture's type between the braces: + +\begin{pathoperation}{pic}{\opt{\meta{foreach statements}}% + \opt{|[|\meta{options}|]|}\opt{|(|\meta{prefix}|)|}% + \opt{|at(|\meta{coordinate}|)|}\opt{\marg{pic type}}} + + Adds a pic to the current \tikzname\ picture of the specified + \meta{pic type}. The effect is, basically, that some code associated + with the \meta{pic type} is executed (how this works, exactly, is explained + later). This code can consist of arbitrary \tikzname\ code. As for + nodes, the current path will not be modified by this path command, + all drawings produced by the code are ``external'' to the path the + same way neither a node nor its border are part of the path on which + they are specified. + + Just like the |node| command, this path operation is somewhat + complex and we go over it step by step. + + \medskip + \textbf{Order of the parts of the specification.} + Just like for nodes, everything between ``|pic|'' and the opening + brace of the \meta{pic type} is optional and can be given in any + order. If there are \meta{foreach statements}, they must come + first, directly following ``|pic|.'' As for nodes, the ``end'' of + the pic specification is normally detected by the presence of the + opening brace. You can, however, use the |pic type| + option to specify the pic type as an option. + + \begin{key}{/tikz/pic type=\meta{pic type}} + This key sets the pic type of the current~|pic|. When this option + is used inside an option block of a |pic|, the parsing of the + |pic| ends immediately and no pic type in braces is expected. (In + other words, this option behaves exactly like the |node contents| + option and, indeed, the two are interchangeable.) +\begin{codeexample}[] +\tikz { + \path (0,0) pic [pic type = seagull] + (1,0) pic {seagull}; +} +\end{codeexample} + \end{key} + + \medskip + \textbf{The location of a pic.} + Just like nodes, pics are placed at the last position mentioned on + the path or, when |at| is used, at a specified position. ``Placing'' + a pic somewhere actually means that the coordinate system is + translated (shifted) to this last position. This means that inside + of the pic type's code any mentioning of the origin refers to the + last position used on the path or to the specified |at|. + +\begin{codeexample}[] +\tikz { % different ways of placing pics + \draw [help lines] (0,0) grid (3,2); + \pic at (1,0) {seagull}; + \path (2,1) pic {seagull}; + \pic [at={(3,2)}] {seagull}; +} +\end{codeexample} + + As for nodes, except for the described shifting, the coordinate + system of a pic is reset prior to executing the pic type's + code. This can be changed using the |transform shape| option, which + has the same effect as for nodes: The ``outer'' transformation gets + applied to the node: +\begin{codeexample}[] +\tikz [scale=2] { + \pic at (0,0) {seagull}; + \pic at (1,0) [transform shape] {seagull}; +} +\end{codeexample} + + When the \meta{options} contain transformation commands like |scale| + or |rotate|, these transformations always apply to the pic: +\begin{codeexample}[] +\tikz [rotate=30] { + \pic at (0,0) {seagull}; + \pic at (1,0) [rotate=90] {seagull}; +} +\end{codeexample} + + Just like nodes, pics can also be positioned implicitly and, + somewhat unsurprisingly, the same rules concerning positioning and + sloping apply: +\begin{codeexample}[] +\tikz \draw + (0,0) to [bend left] + pic [near start] {seagull} + pic {seagull} + pic [sloped, near end] {seagull} (4,0); +\end{codeexample} + + \medskip + \textbf{The options of a node.} + As always, any given \meta{options} apply only to the pic and have + no effect outside. As for nodes, most ``outside'' options also apply + to the pics, but not the ``action'' options like |draw| or + |fill|. These must be given in the \meta{options} of the pic. + + \medskip + \textbf{The code of a pic.} + As stated earlier, the main job of a pic is to execute some code in + a scope that is shifted according to the last point on the path or + to the |at| position specified in the pic. It was also claimed that + this code is specified by the \meta{pic type}. However, this + specification is somewhat indirect. What really happens is the + following: When a |pic| is encountered, the current path is + suspended and a new internal scope is started. The \meta{options} + are executed and also the \meta{pic type} (as explained + in a moment). After all this is done, the code stored in the following key + gets executed: + + \begin{key}{/tikz/pics/code=\meta{code}} + This key stores the \meta{code} that should be drawn in the + current pic. Normally, setting this key is done by the \meta{pic + type}, but you can also set it in the \meta{options} and leave + the \meta{pic type} empty: +\begin{codeexample}[] +\tikz \pic [pics/code={\draw (-3mm,0) to[bend left] (0,0) + to[bend left] (3mm,0);}] + {}; % no pic type specified +\end{codeexample} + \end{key} + + Now, how does the \meta{pic type} set |pics/code|? It turns out that + the \meta{pic type} is actually just a list of keys that are + executed with the prefix |/tikz/pics/|. In the above examples, this + ``list of keys'' just consisted of the single key ``|seagull|'' that + did not take any arguments, but, in principle, you could provide any + arbitrary text understood by |\pgfkeys| here. This means that when + we write |pic{seagull}|, \tikzname\ will execute the key + |/tikz/pics/seagull|. It turns out, see + Section~\ref{section-new-pic-types}, that this key is just a style + set to |code={\draw(-3mm,0)...;}|. Thus, |pic{seagull}| will cause + the |pics/code| key to be set to the text needed to draw the + seagull. + + Indeed, you can also use the \meta{pic type} simply to set the + |code| of the pic. This is useful for cases when you have some code + that you ``just want to execute, but do not want to define a new pic + type.'' Here is a typical example where we use pics to add some + markings to a path: +\begin{codeexample}[] +\tikz \draw (0,0) .. controls(1,0) and (2,1) .. (3,1) + foreach \t in {0, 0.1, ..., 1} { + pic [pos=\t] {code={\draw circle [radius=2pt];}} + }; +\end{codeexample} + + + In our seagull example, we always explicitly used |\draw| to draw + the seagull. This implies that when a user writes something + |pic[fill]{seagull}| in the hope of having a ``filled'' seagull, + nothing special will happen: The |\draw| inside the pic explicitly + states that the path should be drawn, not filled, and the fact that + in the surrounding scope the |fill| option is set has no effect. + The following key can be used to change this: + \begin{key}{/tikz/pic action} + This key is a style that can be used (only) inside the code of a + pic. There, it will set the ``action'' keys set inside the + \meta{options} of the pic (``actions'' are drawing, filling, + shading, and clipping or any combination thereof). + + To see how this key works, let us define the following pic: +\begin{codeexample}[code only] +\tikzset{ + my pic/.pic = { + \path [pic actions] (0,0) circle[radius=3mm]; + \draw (-3mm,-3mm) rectangle (3mm,3mm); + } +} +\end{codeexample} + In the code, whether or not the circle gets drawn/filled/shaded + depends on which options where given to the |pic| command when it + is used. In contrast, the rectangle will always (just) be drawn. +\tikzset{ + my pic/.pic = { + \path [pic actions] (0,0) circle[radius=3mm]; + \draw (-3mm,-3mm) rectangle (3mm,3mm); + } +} +\begin{codeexample}[width=6cm] +\tikz \pic {my pic}; \space +\tikz \pic [red] {my pic}; \space +\tikz \pic [draw] {my pic}; \space +\tikz \pic [draw=red] {my pic}; \space +\tikz \pic [draw, shading=ball] {my pic}; \space +\tikz \pic [fill=red!50] {my pic}; +\end{codeexample} + \end{key} + + \medskip + \textbf{Code executed behind or in front of the path.} + As for nodes, a pic can be ``behind'' the current path or ``in front + of it'' and, just as for nodes, the two options |behind path| and + |in front of path| are used to specify which is meant. In detail, if + |node| and |pic| are both used repeatedly on a path, in the + resulting picture we first see all nodes and pics with the + |behind path| option set in the order they appear on the path (nodes + and pics are interchangeable in this regard), then comes the path, + and then come all nodes and pics that are in front of the path in + the order they appeared. +\begin{codeexample}[] +\tikz \fill [fill=blue!20] + (1,1) + -- (2,2) pic [behind path] {seagull} + -- (3,2) pic {seagull} + -- (3,1) pic [rotate=30] {seagull} + -- (2,1) pic [red, behind path] {seagull}; +\end{codeexample} + In contrast to nodes, a pic need not only be completely behind + the path or in front of the path as specified by the user. Instead, + a pic type may also specify that a certain part of the drawing + should always be behind the path and it may specify that a certain + other part should always be before the path. For this, the values of + the following keys are relevant: + + \begin{key}{/tikz/pics/foreground code=\meta{code}} + This key stores \meta{code} that will always be drawn in front of + the current path, even when |behind path| is used. If + |behind path| is not used and |code| is (also) set, the code of + |code| is + drawn first, following by the foreground \meta{code}. + \end{key} + + \begin{key}{/tikz/pics/background code=\meta{code}} + Like |foreground code|, only that the \meta{code} is always put + behind the path, never in front of it. + \end{key} + + \medskip + \textbf{The foreach statement for pics.} + As for nodes, a pic specification may start with |foreach|. The + effect and semantics are the same as for nodes. +\begin{codeexample}[] +\tikz \pic foreach \x in {1,2,3} at (\x,0) {seagull}; +\end{codeexample} + + \medskip + \textbf{Styles for pics.} + The following styles influence how nodes are rendered: + \begin{stylekey}{/tikz/every pic (initially \normalfont empty)} + This style is installed at the beginning of every pic. +\begin{codeexample}[] +\begin{tikzpicture}[every node/.style={draw}] + \draw (0,0) node {A} -- (1,1) node {B}; +\end{tikzpicture} +\end{codeexample} + \end{stylekey} + + + \medskip + \textbf{Name scopes.} + You can specify a \meta{name} for a pic using the key + |name=|\meta{name} or by giving the name in parenthesis inside the + pic's specification. The effect of this is, for once, quite + different from what happens for nodes: All that happens is that + |name prefix| is set to \meta{name} at the beginning of the pic. + + The |name prefix| key was already introduced in the description of + the |node| command: It allows you to set some text that is prefixed + to all nodes in a scope. For pics this makes particular sense: All + nodes defined by a pic's code can be referenced from outside the pic + with the prefix provided. + + To see how this works, let us add some nodes to the code of the + seagull: +\begin{codeexample}[code only] +\tikzset{ + seagull/.pic={ + % Code for a "seagull". Do you see it?... + \coordinate (-left wing) at (-3mm,0); + \coordinate (-head) at (0,0); + \coordinate (-right wing) at (3mm,0); + + \draw (-left wing) to [bend left] (0,0) (-head) to [bend left] (-right wing); + } +} +\end{codeexample} +\tikzset{ + seagull/.pic={ + % Code for a "seagull". Do you see it?... + \coordinate (-left wing) at (-3mm,0); + \coordinate (-head) at (0,0); + \coordinate (-right wing) at (3mm,0); + + \draw (-left wing) to [bend left] (0,0) (-head) to [bend left] (-right wing); + } +} + + Now, we can use it as follows: +\begin{codeexample}[code only] +\tikz { + \pic (Emma) {seagull}; + \pic (Alexandra) at (0,1) {seagull}; + + \draw (Emma-left wing) -- (Alexandra-right wing); +} +\end{codeexample} + + Sometimes, you may also wish your pic to access nodes outside the + pic (typically, because they are given as parameters). In this case, + the name prefix gets in the way since the nodes outside the picture + do not have this prefix. The trick is to locally reset the name + prefix to the value it had outside the picture, which is achieved + using the following style: + + \begin{key}{/tikz/name prefix ..} + This key is available only inside the code of a pic. There, it + (locally) changes the name prefix to the value it had outside the + pic. This allows you to access nodes outside the current pic. + \end{key} + +\end{pathoperation} + + +There are two general purpose keys that pics may find useful: + +\begin{key}{/tikz/pic text=\meta{text}} + This macro stores the \meta{text} in the macro |\tikzpictext|, which + is |\let| to |\relax| by default. Setting the |pic text| to some + value is the ``preferred'' way of communicating a (single) piece of + text that should become part of a pic (typically of a node). In + particular, the |quotes| library maps quoted parameters to this key. +\end{key} + +\begin{key}{/tikz/pic text options=\meta{options}} + This macro stores the \meta{options} in the macro + |\tikzpictextoptions|, which is |\let| to the empty string by + default. The |quotes| library maps options for quoted parameters to + this key. +\end{key} + + + +\subsubsection{The Quotes Syntax} +\label{section-pic-quotes} + +When you load the |quotes| library, you can use the ``quotes syntax'' +inside the options of a pic. Recall that for nodes this syntax is used +to add a label to a node. For pics, the quotes syntax is used to set +the |pic text| key. Whether or not the pic type's code takes this key +into consideration is, however, up to the key. + +In detail, when the |quotes| library is loaded, each time a key--value +pair in a list of options passed to an |pic| starts with |"|, the +key--value pair must actually be a string of the following form: +\begin{quote} + |"|\meta{text}|"|\opt{|'|}\opt{\meta{options}} +\end{quote} +This string is transformed into the following: +\begin{quote} + |every pic quotes/.try,pic text=|\meta{text}|, pic text options={|\meta{options}|}| +\end{quote} + +As example of a pic type that takes these values into account is the +|angle| pic type: +\begin{codeexample}[] +\tikz \draw (3,0) coordinate (A) + -- (0,1) coordinate (B) + -- (1,2) coordinate (C) + pic [draw, "$\alpha$"] {angle}; +\end{codeexample} + +As described in Section~\ref{section-label-quotes}, the apostrophe +becomes part of the \meta{options}, when present. As can be seen +above, the following style is executed: +\begin{stylekey}{/tikz/every pic quotes (initially \normalfont empty)} +\end{stylekey} + +\subsection{Defining New Pic Types} +\label{section-new-pic-types} + +As explained in the description of the |pic| command, in order to +define a new pic type you need to +\begin{enumerate} +\item define a key with the path prefix |/tikz/pics| that +\item sets the key |/tikz/pics/code| to the code of the pic. +\end{enumerate} + +It turns out that this is easy enough to achieve using styles: + +\begin{codeexample}[code only] +\tikzset{ + pics/seagull/.style ={ + % Ok, this is the key that should, when + % executed, set the code key: + code = { % + \draw (...) ... ; + } + } +} +\end{codeexample} + +Even though the above pattern is easy enough, there is a special +so-called key handler that allows us to write even simpler code, +namely: + +\begin{codeexample}[code only] +\tikzset{ + seagull/.pic = { + \draw (...) ... ; + } +} +\end{codeexample} + +\begin{handler}{{.pic}|=|\meta{some code}} + This handler can only be used with a key with the prefix |/tikz/|, + so just should normally use it only as an option to a \tikzname\ + command or to the |\tikzset| command. It takes the \meta{key}'s path + and, inside that path, it replaces |/tikz/| by |/tikz/pics/| (so, + basically, it adds the ``missing'' |pics| part of the path). Then, + it sets up things so that the resulting name to key is a style that + executes |code=some code|. +\end{handler} + +In almost all cases, the |.pic| key handler will suffice to setup +keys. However, there are cases where you really need to use the first +version using |.style| and |code=|: +\begin{itemize} +\item Whenever your pic type needs to set the foreground or the + background code. +\item In case of complicated arguments given to the keys. +\end{itemize} + +As an example, let us define a simple pic that draws a filled circle +behind the path. Furthermore, we make the circle's radius a parameter +of the pic: + +\begin{codeexample}[] +\tikzset{ + pics/my circle/.style = { + background code = { \fill circle [radius=#1]; } + } +} +\tikz [fill=blue!30] + \draw (0,0) pic {my circle=2mm} -- (1,1) pic {my circle=5mm}; +\end{codeexample} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-plots.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-plots.tex index 00f8d874b6c..35f83f1546f 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-plots.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-plots.tex @@ -7,17 +7,22 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. - \section{Plots of Functions} \label{section-tikz-plots} -\subsection{When Should One Use \tikzname\ for Generating Plots? } +A warning before we get started: \emph{If you are looking for an easy + way to create a normal plot of a function with scientific axes, + ignore this section and instead look at the |pgfplots| package or at + the |datavisualization| command from Part~\ref{part-dv}.} + +\subsection{Overview} \label{section-why-pgname-for-plots} -There exist many powerful programs that produce plots, examples are -\textsc{gnuplot} or \textsc{mathematica}. These programs can produce +\tikzname\ can be used to create plots of functions, a job that is +normally handled by powerful programs like \textsc{gnuplot} or +\textsc{mathematica}. These programs can produce two different kinds of output: First, they can output a complete plot picture in a certain format (like \pdf) that includes all low-level commands necessary for drawing the complete plot (including axes and @@ -27,41 +32,41 @@ consider it a to be ``a bit boring'' to just output tabled data and very much prefer to produce fancy pictures. Nevertheless, when coaxed, they can also provide the plain data. -\emph{Note that is often not necessary to use \tikzname\ for plots.} -Programs like \textsc{gnuplot} can produce very sophisticated plots -and it is usually much easier to simply include these plots as a -finished \textsc{pdf} or PostScript graphics. - -However, there are a number of reasons why you may wish to invest time -and energy into mastering the \pgfname\ commands for creating plots: - -\begin{itemize} -\item - Virtually all plots produced by ``external programs'' use different - fonts from the one used in your document. -\item - Even worse, formulas will look totally different, if they can be - rendered at all. -\item - Line width will usually be too large or too small. -\item - Scaling effects upon inclusion can create a mismatch between sizes - in the plot and sizes in the text. -\item - The automatic grid generated by most programs is mostly - distracting. -\item - The automatic ticks generated by most programs are cryptic - numerics. (Try adding a tick reading ``$\pi$'' at the right point.) -\item - Most programs make it very easy to create ``chart junk'' in a most - convenient fashion. All show, no content. -\item - Arrows and plot marks will almost never match the arrows used in the - rest of the document. -\end{itemize} +The advantage of creating plots directly using \tikzname\ is +\emph{consistency:} Plots created using \tikzname\ will automatically +have the same styling and fonts as those used in the rest of a +document -- something that is hard to do right when an external +program gets involved. Other problems people encounter with external +programs include: Formulas will look different, if they can be +rendered at all; line widths will usually be too thick or too thin; +scaling effects upon inclusion can create a mismatch between sizes in +the plot and sizes in the text; the automatic grid generated by most +programs is mostly distracting; the automatic ticks generated by most +programs are cryptic numerics (try adding a tick reading ``$\pi$'' at +the right point); most programs make it very easy to create ``chart +junk'' in a most convenient fashion; arrows and plot marks will almost +never match the arrows used in the rest of the document. This list is +not exhaustive, unfortunately. + +There are basically three ways of creating plots using \tikzname: -The above list is not exhaustive, unfortunately. +\begin{enumerate} +\item Use the |plot| path operation. How this works is explained in + the present section. This is the most ``basic'' of the three options + and forces you to do a lot of things ``by hand'' like adding axes or + ticks. +\item Use the |datavisualization| path command, which is documented in + Part~\ref{part-dv}. This command is much more powerful that the + |plot| path operation and produces complete plots including axes and + ticks. The downside is that you cannot use it to ``just'' to quickly + plot a simple curve (or, more precisely, it is hard to use it in + this way). +\item Use the |pgfplots| package, which is basically an alternative to + the |datavisualization| command. While the underlying philosophy of + this package is not as ``ambitious'' as that of the command + |datavisualization|, it is somewhat more mature, has a + simpler design, and wider support base. +\end{enumerate} \subsection{The Plot Path Operation} @@ -87,7 +92,7 @@ The syntax of the |plot| comes in different versions. coordinate of the curve. \end{pathoperation} -The \meta{further arguments} are used in three different ways to +The \meta{further arguments} are used in different ways to specifying the coordinates of the points to be plotted: \begin{enumerate} @@ -107,7 +112,7 @@ These different ways are explained in the following. \subsection{Plotting Points Given Inline} -In the first two cases, the points are given directly in the \TeX-file +Points can be given directly in the \TeX-file as in the following example: \begin{codeexample}[] @@ -131,12 +136,19 @@ The second way of specifying points is to put them in an external file named \meta{filename}. Currently, the only file format that \tikzname\ allows is the following: Each line of the \meta{filename} should contain one line starting with two numbers, separated by a -space. Anything following the two numbers on the line is -ignored. Also, lines starting with a |%| or a |#| are ignored as well -as empty lines. (This is exactly the format that \textsc{gnuplot} -produces when you say |set terminal table|.) If necessary, more -formats will be supported in the future, but it is usually easy to -produce a file containing data in this form. +space. A line may also be empty or, if it starts with |#| or |%| it is +considered empty. For such lines, a ``new data set'' is started, +typically resulting in a new subpath being started in the plot (see +Section~\ref{section-plot-jumps} on how to change this behaviour, if +necessary). For lines containing two numbers, they must be separated +by a space. They may be following by arbitrary text, which is ignored, +\emph{except} if it is |o| or |u|. In the first case, the point is +considered to be an \emph{outlier} and normally also results in a new +subpath being started. In the second case, the point is considered to +be \emph{undefined}, which also results in a new subpath being +started. Again, see Section~\ref{section-plot-jumps} on how to change +this, if necessary. (This is exactly the format that \textsc{gnuplot} +produces when you say |set terminal table|.) \begin{codeexample}[] \tikz \draw plot[mark=x,smooth] file {plots/pgfmanual-sine.table}; @@ -202,7 +214,7 @@ is evaluated: \end{key} \begin{key}{/tikz/domain=\meta{start}|:|\meta{end} (initially -5:5)} - Sets the domain between which the samples are taken. + Sets the domain from which the samples are taken. \end{key} \begin{key}{/tikz/samples at=\meta{sample list}} @@ -213,7 +225,7 @@ is evaluated: syntax, so you can use |...| inside the \meta{sample list}. When this option is used, the |samples| and |domain| option are - overruled. The other ways round, setting either |samples| or + overruled. The other way round, setting either |samples| or |domain| will overrule this option. \end{key} @@ -225,6 +237,7 @@ is evaluated: \draw[->] (0,-1.2) -- (0,4.2) node[above] {$f(x)$}; \draw[color=red] plot (\x,\x) node[right] {$f(x) =x$}; + % \x r means to convert '\x' from degrees to _r_adians: \draw[color=blue] plot (\x,{sin(\x r)}) node[right] {$f(x) = \sin x$}; \draw[color=orange] plot (\x,{0.05*exp(\x)}) node[right] {$f(x) = \frac{1}{20} \mathrm e^x$}; \end{tikzpicture} @@ -246,7 +259,7 @@ is evaluated: Often, you will want to plot points that are given via a function like $f(x) = x \sin x$. Unfortunately, \TeX\ does not really have enough -computational power to generate the points on such a function +computational power to generate the points of such a function efficiently (it is a text processing program, after all). However, if you allow it, \TeX\ can try to call external programs that can easily produce the necessary points. Currently, \tikzname\ knows how to @@ -256,17 +269,14 @@ When \tikzname\ encounters your operation |plot[id=|\meta{id}|] function{x*sin(x)}| for the first time, it will create a file called \meta{prefix}\meta{id}|.gnuplot|, where \meta{prefix} is |\jobname.| by -default, that is, the name of you main |.tex| file. If no \meta{id} is +default, that is, the name of your main |.tex| file. If no \meta{id} is given, it will be empty, which is alright, but it is better when each plot has a unique \meta{id} for reasons explained in a moment. Next, \tikzname\ writes some initialization code into this file followed by |plot x*sin(x)|. The initialization code sets up things such that the |plot| operation will write the coordinates into another file called \meta{prefix}\meta{id}|.table|. Finally, this table file -is read as if you had said |plot file{|\meta{prefix}\meta{id}|.table}|. However, -there is just one difference: |gnuplot| supports a ``type'' field following -the coordinates. If this type field contains `|u|' which means unbounded, \tikzname\ will -ignore the complete coordinate\footnote{Thanks to Andy Schlaikjer for this patch.}. +is read as if you had said |plot file{|\meta{prefix}\meta{id}|.table}|. For the plotting mechanism to work, two conditions must be met: \begin{enumerate} @@ -342,7 +352,7 @@ plots, use |t| as the variable for parametric plots. Here are some examples: \end{codeexample} -The plot in influenced by the following options: First, the options +The plot is influenced by the following options: First, the options |samples| and |domain| explained earlier. Second, there are some more specialized options. @@ -357,6 +367,28 @@ specialized options. \end{codeexample} \end{key} +\begin{key}{/tikz/range=\meta{start}|:|\meta{end}} + This key sets the range of the plot. If set, all points whose + $y$-coordinates lie outside this range will be considered to be + outliers and will cause jumps in the plot, by default: +\begin{codeexample}[] +\tikz \draw[scale=0.5,domain=-3.141:3.141, samples=100, smooth, range=-3:3] + plot[id=tan-example] function{tan(x)}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/yrange=\meta{start}|:|\meta{end}} + Same as |range|. +\end{key} + +\begin{key}{/tikz/xrange=\meta{start}|:|\meta{end}} + Set the $x$-range. This makes sense only for parametric plots. +\begin{codeexample}[] +\tikz \draw[scale=0.5,domain=-3.141:3.141,smooth,xrange=0:1] + plot[parametric,id=parametric-example-cut] function{t*sin(t),t*cos(t)}; +\end{codeexample} +\end{key} + \begin{key}{/tikz/id=\meta{id}} Sets the identifier of the current plot. This should be a unique identifier for each plot (though things will also work if it is not, @@ -419,7 +451,7 @@ In detail, the following options govern how marks are drawn: marks. One plot mark is special: the |ball| plot mark is available only - it \tikzname. The |ball color| determines the balls's color. Do not use + in \tikzname. The |ball color| option determines the balls's color. Do not use this option with a large number of marks since it will take very long to render in PostScript. @@ -552,7 +584,8 @@ use options to change the behavior of |plot|. \end{key} \begin{key}{/tikz/const plot} - This option causes the points on the path to be connected using piecewise constant series of lines: + This option causes the points on the path to be connected using + piecewise constant series of lines: \begin{codeexample}[] \tikz\draw plot[const plot] file{plots/pgfmanual-sine.table}; @@ -573,9 +606,22 @@ use options to change the behavior of |plot|. \end{codeexample} \end{key} +\begin{key}{/tikz/const plot mark mid} + A variant of |/tikz/const plot| which places its mark in the middle + of the horizontal lines: +\begin{codeexample}[] +\tikz\draw plot[const plot mark mid,mark=*] file{plots/pgfmanual-sine.table}; +\end{codeexample} + More precisely, it generates vertical lines in the middle between + each pair of consecutive points. If the mesh width is constant, this + leads to symmetrically placed marks (``middle''). +\end{key} + \begin{key}{/tikz/jump mark left} - This option causes the points on the path to be drawn using piecewise constant, non-connected series of lines. If there are any marks, they will be placed on left open ends: + This option causes the points on the path to be drawn using + piecewise constant, non-connected series of lines. If there are any + marks, they will be placed on left open ends: \begin{codeexample}[] \tikz\draw plot[jump mark left, mark=*] file{plots/pgfmanual-sine.table}; @@ -583,11 +629,26 @@ use options to change the behavior of |plot|. \end{key} \begin{key}{/tikz/jump mark right} - This option causes the points on the path to be drawn using piecewise constant, non-connected series of lines. If there are any marks, they will be placed on right open ends: + This option causes the points on the path to be drawn using + piecewise constant, non-connected series of lines. If there are any + marks, they will be placed on right open ends: + +\begin{codeexample}[] +\tikz\draw plot[jump mark right, mark=*] file{plots/pgfmanual-sine.table}; +\end{codeexample} +\end{key} + +\begin{key}{/tikz/jump mark mid} + This option causes the points on the path to be drawn using + piecewise constant, non-connected series of lines. If there are any + marks, they will be placed in the middle of the horizontal line + segments: \begin{codeexample}[] \tikz\draw plot[jump mark right, mark=*] file{plots/pgfmanual-sine.table}; \end{codeexample} + + In case of non--constant mesh widths, the same remarks as for |const plot mark mid| apply. \end{key} \begin{key}{/tikz/ycomb} @@ -632,7 +693,9 @@ use options to change the behavior of |plot|. \end{key} \begin{key}{/tikz/ybar} - This option produces fillable bar plots. It is thus very similar to |ycomb|, but it employs rectangular shapes instead of line-to operations. It thus allows to use any fill- or pattern style. + This option produces fillable bar plots. It is thus very similar to + |ycomb|, but it employs rectangular shapes instead of line-to + operations. It thus allows to use any fill- or pattern style. \begin{codeexample}[] \tikz\draw[draw=blue,fill=blue!60!black] plot[ybar] file{plots/pgfmanual-sine.table}; @@ -646,7 +709,10 @@ use options to change the behavior of |plot|. plot coordinates{(0,1.2) (.5,1.3) (1,.5) (1.5,.2) (2,.5)}; \end{tikzpicture} \end{codeexample} - The use of |bar width| and |bar shift| is explained in the plot handler library documentation, section~\ref{section-plotlib-bar-handlers}. Please refer to page~\pageref{key-bar-width}. + The use of |bar width| and |bar shift| is explained in the plot + handler library documentation, + section~\ref{section-plotlib-bar-handlers}. Please refer to + page~\pageref{key-bar-width}. \end{key} \begin{key}{/tikz/xbar} @@ -659,7 +725,10 @@ use options to change the behavior of |plot|. \end{key} \begin{key}{/tikz/ybar interval} - As |/tikz/ybar|, this options produces vertical bars. However, bars are centered at coordinate \emph{intervals} instead of interval edges, and the bar's width is also determined relatively to the interval's length: + As |/tikz/ybar|, this options produces vertical bars. However, bars + are centered at coordinate \emph{intervals} instead of interval + edges, and the bar's width is also determined relatively to the + interval's length: \begin{codeexample}[] \begin{tikzpicture}[ybar interval,x=10pt] @@ -667,9 +736,14 @@ use options to change the behavior of |plot|. plot coordinates{(0,2) (2,1.2) (3,.3) (5,1.7) (8,.9) (9,.9)}; \end{tikzpicture} \end{codeexample} - Since there are $N$ intervals $[x_i,x_{i+1}]$ for given $N+1$ coordinates, you will always have one coordinate more than bars. The last $y$ value will be ignored. + Since there are $N$ intervals $[x_i,x_{i+1}]$ for given $N+1$ + coordinates, you will always have one coordinate more than bars. The + last $y$ value will be ignored. - You can configure relative shifts and relative bar width, which is explained in the plot handler library documentation, section~\ref{section-plotlib-bar-handlers}. Please refer to page~\pageref{key-bar-interval-width}. + You can configure relative shifts and relative bar widths, which is + explained in the plot handler library documentation, + section~\ref{section-plotlib-bar-handlers}. Please refer to + page~\pageref{key-bar-interval-width}. \end{key} \begin{key}{/tikz/xbar interval} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-scopes.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-scopes.tex index 063b4570a7e..07d04943cc8 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-scopes.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-scopes.tex @@ -31,7 +31,7 @@ apply to everything within the environment. \pgfname\ needs to know what \TeX\ driver you are intending to use. In most cases \pgfname\ is clever enough to determine the correct driver - for you; this is true in particular if you use \LaTeX. Currently, the only + for you; this is true in particular if you use \LaTeX. One situation where \pgfname\ cannot know the driver ``by itself'' is when you use plain \TeX\ or Con\TeX t together with |dvipdfm|. In this case, you have to write |\def\pgfsysdriver{pgfsys-dvipdfm.def}| @@ -47,17 +47,19 @@ apply to everything within the environment. like. If you try to load a library a second time, nothing will happen. - \example |\usetikzlibrary{arrows}| + \example |\usetikzlibrary{arrows.meta}| The above command will load a whole bunch of extra arrow tip definitions. What this command does is to load the file |tikzlibrary|\meta{library}|.code.tex| for each \meta{library} in - the \meta{list of libraries}. Thus, to write your own library file, - all you need to do is to place a file of the appropriate name - somewhere where \TeX\ can find it. \LaTeX, plain \TeX, and Con\TeX t - users can then use your library. + the \meta{list of libraries}. If this file does not exist, the file + |pgflibrary|\meta{library}|.code.tex| is loaded instead. If this + file also does not exist, an error message is printed. Thus, to + write your own library file, all you need to do is to place a file + of the appropriate name somewhere where \TeX\ can find it. \LaTeX, + plain \TeX, and Con\TeX t users can then use your library. \end{command} @@ -111,7 +113,7 @@ they apply. coordinates. This will usually give a good approximation of the bounding box, but will not always be accurate. First, the line thickness of diagonal lines is not taken - into account correctly. Second, controls points of a curve often lie far + into account correctly. Second, control points of a curve often lie far ``outside'' the curve and make the bounding box too large. In this case, you should use the |[use as bounding box]| option. @@ -121,9 +123,11 @@ they apply. Normally, the lower end of the picture is put on the baseline of the surrounding text. For example, when you give the code |\tikz\draw(0,0)circle(.5ex);|, \pgfname\ will find out that the - lower end of the picture is at $-.5\mathrm{ex}$ and that the upper - end is at $.5\mathrm{ex}$. Then, the lower end will be put on the - baseline, resulting in the following: \tikz\draw(0,0)circle(.5ex);. + lower end of the picture is at $-.5\mathrm{ex} - 0.2\mathrm{pt}$ + (the 0.2pt are half the line width, which is 0.4pt) and that the + upper end is at $.5\mathrm{ex}+.5\mathrm{pt}$. Then, the lower end + will be put on the baseline, resulting in the following: + \tikz\draw(0,0)circle(.5ex);. Using this option, you can specify that the picture should be raised or lowered such that the height \meta{dimension} is on the @@ -138,11 +142,11 @@ $A \mathbin{\tikz[baseline] \draw[->>] (0pt,.5ex) -- (3ex,.5ex);} B$ Instead of a \meta{dimension} you can also provide a coordinate in parentheses. Then the effect is to put the baseline on the - $y$-coordinate that the give \meta{coordinate} has \emph{at the + $y$-coordinate that the given \meta{coordinate} has \emph{at the end of the picture}. This means that, at the end of the picture, the \meta{coordinate} is evaluated and then the baseline is set to the $y$-coordinate of the resulting point. This makes it easy - to reference the $y$-coordinate of, say, the base line of nodes. + to reference the $y$-coordinate of, say, the baseline of nodes. \begin{codeexample}[] Hello \tikz[baseline=(X.base)] @@ -211,7 +215,7 @@ Top align: This will have the desired effect. \end{environment} -In other \TeX\ format, you should use instead the following commands: +In other \TeX\ formats, you should use the following commands instead: \begin{plainenvironment}{{tikzpicture}\opt{\oarg{options}}} This is the plain \TeX\ version of the environment. @@ -247,6 +251,23 @@ commands. \end{command} +\subsubsection{Handling Catcodes and the Babel Package} + +Inside a \tikzname\ picture, most symbols need to have the category +code 12 (normal text) in order to ensure that the parser works +properly. This is typically not the case when packages like |babel| +are used, which change catcodes aggressively. + +To solve this problem, \tikzname\ provides a small library also called +|babel| (which can, however, also be used together with any other +package that globally changes category codes). What it does is to +reset the category codes at the beginning of every |{tikzpicture}| and +to restore them at the beginning of every node. In almost all cases, +this is exactly would you would expect and need, so I recommend to +always load this library by saying |\usetikzlibrary{babel}|. For +details on what, exactly, happens with the category codes, see +Section~\ref{section-library-babel}. + \subsubsection{Adding a Background} @@ -365,6 +386,34 @@ square bracket must follow, otherwise the brace is treated as a normal \TeX\ scope. +\subsubsection{Single Command Scopes} + +In some situations it is useful to create a scope for a single +command. For instance, when you wish to use algorithm graph drawing +in order to layout a tree, the path of the tree needs to be surrounded +by a scope whose only purpose is to take a key that selects a layout +for the scope. Similarly, in order to put something on a background +layer, a scope needs to be created. In such cases, where it will +cumbersome to create a |\begin{scope}| and |\end{scope}| pair just for +a single command, the |\scoped| command may be useful: + +\begin{command}{\scoped\opt{\oarg{options}}\meta{path command}} + This command works like |\tikz|, only you can use it inside a + |{tikzpicture}|. It will take the following \meta{path command} and + put it inside a |{scope}| with the \meta{options} set. The + \meta{path command} may either be a single command ended by a + semicolon or it may contain multiple commands, but then they must be + surrounded by curly braces. + \begin{codeexample}[] +\begin{tikzpicture} + \node [fill=white] at (1,1) {Hello world}; + \scoped [on background layer] + \draw (0,0) grid (3,2); +\end{tikzpicture} + \end{codeexample} +\end{command} + + \subsubsection{Using Scopes Inside Paths} The |\path| command, which is described in much more detail in later @@ -463,7 +512,7 @@ my style/.style={draw=red,fill=red!20} \end{codeexample} The meaning of the curious |/.style| is the following: ``The key -|my style| should not be used here but, rather, be defined. So, setup +|my style| should not be used here but, rather, be defined. So, set up things such that using the key |my style| will, in the following, have the same effect as if we had written |draw=red,fill=red!20| instead.'' diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-shapes.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-shapes.tex index 5cd58695209..e5fe70f35c7 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-shapes.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-shapes.tex @@ -19,8 +19,8 @@ another simple shape with some text on it. Nodes are added to paths using the special path operation |node|. Nodes \emph{are not part of the path - itself}. Rather, they are added to the picture after the path has -been drawn. + itself}. Rather, they are added to the picture just before or after +the path has been drawn. In Section~\ref{section-nodes-basic} the basic syntax of the node operation is explained, followed in Section~\ref{section-nodes-multi} @@ -33,8 +33,8 @@ Section~\ref{section-nodes-transformations} the different ways transformations affect nodes are studied. Sections~\ref{section-nodes-placing-1} and~\ref{section-nodes-placing-2} are about placing nodes on or next -to straight lines and curves. In -Section~\ref{section-nodes-connecting} it is explained how a node can +to straight lines and curves. +Section~\ref{section-nodes-connecting} explains how a node can be used as a ``pseudo-coordinate.'' Section~\ref{section-nodes-edges} introduces the |edge| operation, which works similar to the |to| operation and also similar to the |node| @@ -58,7 +58,7 @@ There are no special \TeX\ commands for adding a node to a picture; rather, there is path operation called |node| for this. Nodes are created whenever \tikzname\ encounters |node| or |coordinate| at a point on a path where it would expect a normal path operation (like |-- (1,1)| or -|sin (1,1)|). It is also possible to give node specifications +|rectangle (1,1)|). It is also possible to give node specifications \emph{inside} certain path operations as explained later. The node operation is typically followed by some options, which apply @@ -66,27 +66,129 @@ only to the node. Then, you can optionally \emph{name} the node by providing a name in round braces. Lastly, for the |node| operation you must provide some label text for the node in curly braces, while for the |coordinate| operation you may not. The node is placed at the -current position of the path \emph{after the path has been - drawn}. Thus, all nodes are drawn ``on top'' of the path and -retained until the path is complete. If there are several nodes on a -path, they are drawn on top of the path in the order they are -encountered. +current position of the path either \emph{after the path has been + drawn} or (more seldomly and only if you add the |behind path| +option) \emph{just before the path is drawn.} Thus, all nodes are +drawn ``on top'' or ``behind'' the path and are retained until the +path is complete. If there are several nodes on a path, perhaps some +behind and some on top of the path, first come the nodes behind the +path in the order they were encountered, then comes that path, and +then come the remaining node, again in the order they are +encountered. \begin{codeexample}[] -\tikz \fill[fill=examplefill] - (0,0) node {first node} - -- (1,1) node {second node} - -- (0,2) node {third node}; +\tikz \fill [fill=yellow!80!black] + (0,0) node {first node} + -- (1,1) node[behind path] {second node} + -- (0,2) node {third node}; \end{codeexample} +\subsubsection{Syntax of the Node Command} + The syntax for specifying nodes is the following: -\begin{pathoperation}{node}{\opt{|[|\meta{options}|]|}\opt{|(|\meta{name}|)|}% - \opt{|at(|\meta{coordinate}|)|}\opt{\marg{text}}} - The effect of |at| is to place the node at the coordinate given - after |at| and not, as would normally be the case, at the last - position. The |at| syntax is not available when a node is given - inside a path operation (it would not make any sense, there). +\begin{pathoperation}{node}{\opt{\meta{foreach statements}}% + \opt{|[|\meta{options}|]|}\opt{|(|\meta{name}|)|}% + \opt{|at(|\meta{coordinate}|)|}\opt{\marg{node contents}}} + Since this path operation is one of the most involved around, let us + go over it step by step. + + \medskip + \textbf{Order of the parts of the specification.} + Everything between ``|node|'' and the opening brace of a node is + optional. If there are \meta{foreach statements}, they must come + first, directly following ``|node|.'' Other than that, the ordering + of all the other elements of a node specification (the + \meta{options}, the \meta{name}, and \meta{coordinate}) is + arbitrary, indeed, there can be multiple occurrences of any of these + elements (although only for options this makes much sense). + + \medskip + \textbf{The text of a node.} + At the end of a node, you must (normally) provide some \meta{node contents} + in curly braces; indeed, the ``end'' of the node specification is + detected by the opening curly brace. For normal nodes it is possible to use + ``fragile'' stuff inside the \meta{node contents} like the |\verb| + command (for the technically savvy: code inside the \meta{node + contents} is allowed to change catcodes; however, this rule does + not apply to ``nodes on a path'' to be discussed later). + + Instead of giving \meta{node contents} at the end of the node in + curly braces, you can also use the following key: + \begin{key}{/tikz/node contents=\meta{node contents}} + \label{option-node-contents}% + This key sets that contents of the node to the given text as if + you had given it at the end in curly braces. When the option is + used inside the options of a node, the parsing of the node stops + immediately after the end of the option block. In particular, the + option block cannot be followed by further option blocks or curly + braces (or, rather, these do not count as part of the node + specification.) Also note that the \meta{node contents} may not + contain fragile stuff since the catcodes get fixed upon reading + the options. Here is an example: +\begin{codeexample}[] +\tikz { + \path (0,0) node [red] {A} + (1,0) node [blue] {B} + (2,0) node [green, node contents=C] + (3,0) node [node contents=D] ; +} +\end{codeexample} +\end{key} + + \medskip + \textbf{Specifying the location of the node.} + Nodes are placed at the last position mentioned on the path. The + effect of adding ``|at|'' to a node + specification is that the coordinate given after |at| is used + instead. The |at| syntax is not available when a node is given + inside a path operation (it would not make any sense there). + + \begin{key}{/tikz/at=\meta{coordinate}} + This is another way of specifying the |at| coordinate. Note that, + typically, you will have to enclose the \meta{coordinate} in curly + braces so that a comma inside the \meta{coordinate} does not + confuse \TeX. + \end{key} + + Another aspect of the ``location'' of a node is whether it appears + \emph{in front of} or \emph{behind} the current path. You can change + which of these two possibilities happens on a node-by-node basis + using the following keys: + \begin{key}{/tikz/behind path} + When this key is set, either as a local option for the node or + some surrounding scope, the node will be drawn behind the current + path. For this, \tikzname\ collects all nodes defined on the + current path with this option set and then inserts all of them, in + the order they appear, just before it draws the path. Thus, + several nodes with this option set may obscure one anther, but + never the path itself. ``Just before it draws the path'' actually + means that the nodes are inserted into the page output just before + any pre-actions are applied to the path (see below for what + pre-actions are). +\begin{codeexample}[] +\tikz \fill [fill=blue!50, draw=blue, very thick] + (0,0) node [behind path, fill=red!50] {first node} + -- (1.5,0) node [behind path, fill=green!50] {second node} + -- (1.5,1) node [behind path, fill=brown!50] {third node} + -- (0,1) node [ fill=blue!30] {fourth node}; +\end{codeexample} + + Note that |behind path| only applies to the current path; not to + the current scope or picture. To put a node ``behind everything'' + you need to use layers and options like |on background layer|, see + the background library in Section~\ref{section-tikz-backgrounds}. + \end{key} + \begin{key}{/tikz/in front of path} + This is the opposite of |behind path|: It causes nodes to be drawn + on top of the path. Since this is the default behaviour, you + usually do not need this option; it is only needed when an + enclosing scope has used |behind path| and you now wish to + ``switch back'' to the normal behaviour. + \end{key} + + \medskip + \textbf{The name of a node.} The |(|\meta{name}|)| is a name for later reference and it is optional. You may also add the option |name=|\meta{name} to the \meta{option} list; it has the same effect. @@ -104,17 +206,13 @@ The syntax for specifying nodes is the following: \begin{key}{/tikz/alias=\meta{another node name}} This option allows you to provide another name for the node. Giving this option multiple times will allow you to access - the node via several aliases. Using the |late options| options, - you can also assign an alias name to a node at a later point. + the node via several aliases. Using the |node also| syntax, + you can also assign an alias name to a node at a later point, see + Section~\ref{section-node-also}. \end{key} - - \begin{key}{/tikz/at=\meta{coordinate}} - This is another way of specifying the |at| coordinate. Note that, - typically, you will have to enclose the \meta{coordinate} in curly - braces so that a comma inside the \meta{coordinate} does not - confuse \TeX. - \end{key} - + + \medskip + \textbf{The options of a node.} The \meta{options} is an optional list of options that \emph{apply only to the node} and have no effect outside. The other way round, most ``outside'' options also apply to the node, but not all. For @@ -123,12 +221,14 @@ The syntax for specifying nodes is the following: |draw| or |fill|, never applies to the node and must be given in the node (unless some special other options are used, deep sigh). + \medskip + \textbf{The shape of a node.} As mentioned before, we can add a border and even a background to a node: \begin{codeexample}[] -\tikz \fill[fill=examplefill] +\tikz \fill[fill=yellow!80!black] (0,0) node {first node} - -- (1,1) node[draw] {second node} + -- (1,1) node[draw, behind path] {second node} -- (0,2) node[fill=red!20,draw,double,rounded corners] {third node}; \end{codeexample} @@ -139,16 +239,15 @@ The syntax for specifying nodes is the following: |shapes.geometric| library for the latter shape): \begin{codeexample}[] -\tikz \fill[fill=examplefill] - (0,0) node{first node} - -- (1,1) node[ellipse,draw] {second node} - -- (0,2) node[circle,fill=red!20] {third node}; +\tikz \fill[fill=yellow!80!black] + (0,0) node {first node} + -- (1,1) node[ellipse,draw, behind path] {second node} + -- (0,2) node[circle,fill=red!20] {third node}; \end{codeexample} - In the future, there might be much more complicated shapes available - such as, say, a shape for a resistor or a shape for a \textsc{uml} - class. Unfortunately, creating new shapes is a bit tricky and makes - it necessary to use the basic layer directly. Life is hard. + There are many more shapes available such as, say, a shape for a + resistor or a large arrow, see the |shapes| library in + Section~\ref{section-libs-shapes} for details. To select the shape of a node, the following option is used: \begin{key}{/tikz/shape=\meta{shape name} (initially rectangle)} @@ -163,13 +262,44 @@ The syntax for specifying nodes is the following: check whether this option is the name of some shape. If so, that shape is selected as if you had said |shape=|\meta{shape name}. - By default, the following shapes are available: |rectangle|, % this par has to be adapted: no more shapes library available, only several sublibraries - |circle|, |coordinate|, and, when the package |pgflibraryshapes| is - loaded, also |ellipse|. Details of these shapes, like their anchors + By default, the following shapes are available: |rectangle|, + |circle|, |coordinate|. Details of these shapes, like their anchors and size options, are discussed in Section~\ref{section-the-shapes}. \end{key} - The following styles influences how nodes are rendered: + \medskip + \textbf{The foreach statement for nodes.} + At the beginning of a node specification (and only there) you can provide multiple + \meta{foreach statements}, each of which has the form |foreach| \meta{var} + |in| |{|\meta{list}|}| (note that there is no slash before + |foreach|). When they are given, instead of a single node, multiple + nodes will be created: The \meta{var} will iterate over all values + of \meta{list} and for each of them, a new node is created. These + nodes are all created using all the text following the \meta{foreach + statements}, but in each copy the \meta{var} will have the current + value of the current element in the \meta{list}. + + As an example, the following two codes have the same effect: +\begin{codeexample}[] +\tikz \draw (0,0) node foreach \x in {1,2,3} at (\x,0) {\x}; +\end{codeexample} +\begin{codeexample}[] +\tikz \draw (0,0) node at (1,0) {1} node at (2,0) {2} node at (3,0) {3}; +\end{codeexample} + When you provide several |foreach| statements, they work like + ``nested loops'': +\begin{codeexample}[] +\tikz \node foreach \x in {1,...,4} foreach \y in {1,2,3} + [draw] at (\x,\y) {\x,\y}; +\end{codeexample} + As the example shows, a \meta{list} can contain ellipses (three + dots) to indicated that a larger number of numbers is meant. Indeed, + you can use the full power of the |\foreach| command here, including + multiple parameters and options, see Section~\ref{section-foreach}. + + \medskip + \textbf{Styles for nodes.} + The following styles influence how nodes are rendered: \begin{stylekey}{/tikz/every node (initially \normalfont empty)} This style is installed at the beginning of every node. \begin{codeexample}[] @@ -190,16 +320,56 @@ The syntax for specifying nodes is the following: \end{tikzpicture} \end{codeexample} \end{stylekey} + + \medskip + \textbf{Name scopes.} + It turns out that the name of a node can further be influenced using + two keys: + \begin{key}{/tikz/name prefix=\meta{text} (initially \normalfont empty)} + The value of this key is prefixed to every node inside the + current scope. This includes both the naming of the node (via + the |name| key or via the implicit |(|\meta{name}|)| syntax) as + well as any referencing of the node. Outside the scope, + the nodes can (and need to) be referenced using ``full name'' + consisting of the prefix and the node name. + + The net effect of this is that you can set the name prefix at + the beginning of a scope to some value and then use short and + simple names for the nodes inside the scope. Later, outside the + scope, you can reference the nodes via their full name: +\begin{codeexample}[] +\tikz { + \begin{scope}[name prefix = top-] + \node (A) at (0,1) {A}; + \node (B) at (1,1) {B}; + \draw (A) -- (B); + \end{scope} + \begin{scope}[name prefix = bottom-] + \node (A) at (0,0) {A}; + \node (B) at (1,0) {B}; + \draw (A) -- (B); + \end{scope} + + \draw [red] (top-A) -- (bottom-B); +} +\end{codeexample} + As can be seen, name prefixing makes it easy to write + ``recycable'' code. + \end{key} + \begin{key}{/tikz/name suffix=\meta{text} (initially \normalfont empty)} + Works as |name prefix|, only the \meta{text} is appended to + every node name in the current scope. + \end{key} \end{pathoperation} -There is a special syntax for specifying ``light-weighed'' nodes: +There is a special syntax for specifying ``light-weight'' nodes: \begin{pathoperation}{coordinate}{\opt{|[|\meta{options}|]|}|(|\meta{name}|)|\opt{|at(|\meta{coordinate}|)|}} This has the same effect as - |node[shape=coordinate][|\meta{options}|](|\meta{name}|)at(|\meta{coordinate}|){}|, + |\node[shape=coordinate]|\verb|[|\meta{options}|](|\meta{name}|)at(|\meta{coordinate}|){}|, - where the |at| part might be missing. + where the |at| part may be omitted. \end{pathoperation} Since nodes are often the only path operation on paths, there are two @@ -246,12 +416,12 @@ demonstrates the difference: \path[yshift=1.5cm,shape=rectangle] (0,0) node(a1){} (1,0) node(a2){} (1,1) node(a3){} (0,1) node(a4){}; - \filldraw[fill=examplefill] (a1) -- (a2) -- (a3) -- (a4); + \filldraw[fill=yellow!80!black] (a1) -- (a2) -- (a3) -- (a4); \path[shape=coordinate] (0,0) coordinate(b1) (1,0) coordinate(b2) (1,1) coordinate(b3) (0,1) coordinate(b4); - \filldraw[fill=examplefill] (b1) -- (b2) -- (b3) -- (b4); + \filldraw[fill=yellow!80!black] (b1) -- (b2) -- (b3) -- (b4); \end{tikzpicture} \end{codeexample} @@ -283,7 +453,7 @@ shapes: \begin{tikzpicture} \draw (0,0) node[inner sep=0pt,draw] {tight} (0cm,2em) node[inner sep=5pt,draw] {loose} - (0cm,4em) node[fill=examplefill] {default}; + (0cm,4em) node[fill=yellow!80!black] {default}; \end{tikzpicture} \end{codeexample} \end{key} @@ -312,11 +482,11 @@ shapes: exactly on the ``outside border'' of the path (not on the path itself). When the shape is filled, but not drawn, this may not be desirable. In this case, the |outer sep| should be set to zero - point. + points. \begin{codeexample}[] \begin{tikzpicture} \draw[line width=5pt] - (0,0) node[outer sep=0pt,fill=examplefill] (f) {filled} + (0,0) node[outer sep=0pt,fill=yellow!80!black] (f) {filled} (2,0) node[inner sep=.5\pgflinewidth+2pt,draw] (d) {drawn}; \draw[->] (1,-1) -- (f); @@ -393,10 +563,8 @@ node contents, but \emph{in addition} to any other transformations. \begin{codeexample}[] \tikzstyle{every node}=[dart, shape border uses incircle, inner sep=1pt, draw] -\begin{tikzpicture} - \foreach \a/\b/\c in {A/0/0, B/45/0, C/0/45, D/45/45} - \node [shape border rotate=\b, rotate=\c] at (\b/36,-\c/36) {\a}; -\end{tikzpicture} +\tikz \node foreach \a/\b/\c in {A/0/0, B/45/0, C/0/45, D/45/45} + [shape border rotate=\b, rotate=\c] at (\b/36,-\c/36) {\a}; \end{codeexample} There are two types of rotation: restricted and unrestricted. Which @@ -424,7 +592,7 @@ node contents. \end{tikzpicture} \end{codeexample} -There are \pgfname{} keys determine how a shape border is +There are \pgfname{} keys that determine how a shape border is constructed, and to specify its rotation. It should be noted that not all shapes support these keys, so reference should be made to the documentation for individual @@ -479,13 +647,13 @@ two values will be used. \label{section-nodes-multi} Most nodes just have a single simple text label. However, nodes of a -more complicated shapes might be made up from several \emph{node +more complicated shape might be made up from several \emph{node parts}. For example, in automata theory a so-called Moore state has a state name, drawn in the upper part of the state circle, and an output text, drawn in the lower part of the state circle. These two parts are quite independent. Similarly, a \textsc{uml} class shape would have a name part, a method part, and an attributes -part. Different molecule shape might use parts for the different atoms +part. Different molecule shapes might use parts for the different atoms to be drawn at the different positions, and so on. Both \pgfname\ and \tikzname\ support such multipart nodes. On the @@ -555,29 +723,68 @@ set the color used for text using the following option: \end{key} Just like the color itself, you may also wish to set the opacity of -the text only. For this, use the option |text opacity| option, which +the text only. For this, use the |text opacity| option, which is detailed in Section~\ref{section-tikz-transparency}. \subsubsection{Text Parameters: Font} -Next, you may wish to adjust the font used for the text. Use the -following option for this: +Next, you may wish to adjust the font used for the text. Naturally, +you can just use a font command like |\small| or |\rm| at the +beginning of a node. However, the following two options make it easier +to set the font used in nodes on a general basis. Let us start with: + +\begin{key}{/tikz/node font=\meta{font commands}} + This option sets the font used for all text used in a node. +\begin{codeexample}[] +\begin{tikzpicture} + \draw[node font=\itshape] (1,0) -- +(1,1) node[above] {italic}; +\end{tikzpicture} +\end{codeexample} + Since the \meta{font commands} are executed at a very early stage in + the construction of the node, the font selected using this command + will also dictate the values of dimensions defined in terms of |em| + or |ex|. For instance, when the |minimum height| of a node is |3em|, + the actual height will be (at least) three times the line distance + selected by the \meta{font commands}: +\begin{codeexample}[] +\tikz \node [node font=\tiny, minimum height=3em, draw] {tiny}; +\tikz \node [node font=\small, minimum height=3em, draw] {small}; +\end{codeexample} +\end{key} + +The other font command is: + \begin{key}{/tikz/font=\meta{font commands}} - Sets the font used for text labels. + Sets the font used for the text inside nodes. However, this font + will \emph{not} (yet) be installed when any of the dimensions of the + node are being computed, so dimensions like |1em| will be with + respect to the font used outside the node (usually the font that was + in force when the picture started). \begin{codeexample}[] \begin{tikzpicture} - \draw[font=\itshape] (1,0) -- +(1,1) node[above] {italic}; + \node [font=\itshape] {italic}; \end{tikzpicture} \end{codeexample} - A perhaps more useful example is the following: + +\begin{codeexample}[] +\tikz \node [font=\tiny, minimum height=3em, draw] {tiny}; +\tikz \node [font=\small, minimum height=3em, draw] {small}; +\end{codeexample} + + A useful example of how the |font| option can be used is the + following: \begin{codeexample}[] \tikz [every text node part/.style={font=\itshape}, every lower node part/.style={font=\footnotesize}] \node [circle split,draw] {state \nodepart{lower} output}; \end{codeexample} -\end{key} + As can be seen, the font can be changed for each node part. This + does \emph{not} work with the |node font| command since, as the name + suggests, this command can only be used to select the ``overall'' + font for the node and this is done very early. +\end{key} \subsubsection{Text Parameters: Alignment and Width for Multi-Line Text} @@ -615,7 +822,7 @@ lines of text. There are three different ways of achieving this: The |\\| command takes an optional extra space as an argument in square brackets. \begin{codeexample}[] -\tikz \node[fill=examplefill,align=right] +\tikz \node[fill=yellow!80!black,align=right] {This is a\\[-2pt] demonstration text for\\[1ex] alignments.}; \end{codeexample} \item You can request that \tikzname\ does an automatic line-breaking @@ -640,45 +847,45 @@ Let us now first have a look at the |text width| command. change the alignment using |align| or directly using commands line |\centering|. \begin{codeexample}[] -\tikz \draw (0,0) node[fill=examplefill,text width=3cm] +\tikz \draw (0,0) node[fill=yellow!80!black,text width=3cm] {This is a demonstration text for showing how line breaking works.}; \end{codeexample} Setting \meta{dimension} to an empty string causes the automatic line breaking to be disabled. \end{key} -\begin{key}{/tikz/align=\meta{how}} - This key is used to setup an alignment for multi-line text inside a +\begin{key}{/tikz/align=\meta{alignment option}} + This key is used to set up an alignment for multi-line text inside a node. If |text width| is set to some width (let us call this \emph{alignment with line breaking}), the |align| key will setup the |\leftskip| and the |\rightskip| in such a way that the - text is broken and aligned according to \meta{how}. If |text width| + text is broken and aligned according to \meta{alignment option}. If |text width| is not set (that is, set to the empty string; let us call this \emph{alignment without line breaking}), then a different mechanism is used internally, namely the key |node halign header|, is set to an appropriate value. While this key, which is documented below, is not to be used by beginners, the net effect is simple: When |text width| is not set, you can use |\\| to break lines and - align them according to \meta{how} and the resulting node's width + align them according to \meta{alignment option} and the resulting node's width will be minimal to encompass the resulting lines. - In detail, you can set \meta{how} to one of the following values: + In detail, you can set \meta{alignment option} to one of the following values: \begin{description} \item[|align=|\declare{|left|}] For alignment without line breaking, the different lines are simply aligned such that their left borders are below one another. \begin{codeexample}[] -\tikz \node[fill=examplefill,align=left] +\tikz \node[fill=yellow!80!black,align=left] {This is a\\ demonstration text for\\ alignments.}; \end{codeexample} For alignment with line breaking, the same will happen only the lines will now, additionally, be broken automatically: \begin{codeexample}[] -\tikz \node[fill=examplefill,text width=3cm,align=left] +\tikz \node[fill=yellow!80!black,text width=3cm,align=left] {This is a demonstration text for showing how line breaking works.}; \end{codeexample} - \item[|align=|\declare{|flush left|}] + \item[|align=|\declare{\texttt{flush left}}] For alignment without line breaking this option has exactly the same effect as |left|. However, for alignment with line breaking, there is a difference: While |left| uses the @@ -689,55 +896,79 @@ Let us now first have a look at the |text width| command. it may be useful for very narrow boxes and when you wish to avoid hyphenations. \begin{codeexample}[] -\tikz \node[fill=examplefill,text width=3cm,align=flush left] +\tikz \node[fill=yellow!80!black,text width=3cm,align=flush left] {This is a demonstration text for showing how line breaking works.}; \end{codeexample} \item[|align=|\declare{|right|}] Works like |left|, only for right alignment. \begin{codeexample}[] -\tikz \node[fill=examplefill,align=right] +\tikz \node[fill=yellow!80!black,align=right] {This is a\\ demonstration text for\\ alignments.}; \end{codeexample} \begin{codeexample}[] -\tikz \node[fill=examplefill,text width=3cm,align=right] +\tikz \node[fill=yellow!80!black,text width=3cm,align=right] {This is a demonstration text for showing how line breaking works.}; \end{codeexample} - \item[|align=|\declare{|flush right|}] + \item[|align=|\declare{\texttt{flush right}}] Works like |flush left|, only for right alignment. \begin{codeexample}[] -\tikz \node[fill=examplefill,text width=3cm,align=flush right] +\tikz \node[fill=yellow!80!black,text width=3cm,align=flush right] {This is a demonstration text for showing how line breaking works.}; \end{codeexample} \item[|align=|\declare{|center|}] Works like |left| or |right|, only for centered alignment. \begin{codeexample}[] -\tikz \node[fill=examplefill,align=center] +\tikz \node[fill=yellow!80!black,align=center] {This is a\\ demonstration text for\\ alignments.}; \end{codeexample} \begin{codeexample}[] -\tikz \node[fill=examplefill,text width=3cm,align=center] +\tikz \node[fill=yellow!80!black,text width=3cm,align=center] {This is a demonstration text for showing how line breaking works.}; \end{codeexample} - \item[|align=|\declare{|flush center|}] - Works like |flush left| or |flush right|, only for center alignment. + There is one annoying problem with the |center| + alignment (but not with |flush center| and the other options): If + you specify a large line width and the node text + fits on a single line and is, in fact, much shorter than the + specified |text width|, an underfull horizontal box will + result. Unfortunately, this cannot be avoided, due to the way \TeX\ works. + For this reason, \tikzname\ switches off horizontal badness + warnings inside boxes with |align=center|. Since this will also + suppress some ``wanted'' warnings, there is also an option for + switching the warnings on once more: + + \begin{key}{/tikz/badness warnings for centered text=\meta{true or + false} (initially false)} + If set to true, normal badness warnings will be issued for + centered boxes. Note that you may get annoying warnings for + perfectly normal boxes, namely whenever the box is very large + and the contents is not long enough to fill the box + sufficiently. + \end{key} + + \item[|align=|\declare{\texttt{flush center}}] + Works like |flush left| or |flush right|, only for center + alignment. Because of all the trouble that results from the + |center| option in conjunction with narrow lines, I suggest picking + this option rather than |center| \emph{unless} you have longer + text, in which case |center| will give the typographically better + results. \begin{codeexample}[] -\tikz \node[fill=examplefill,text width=3cm,align=flush center] +\tikz \node[fill=yellow!80!black,text width=3cm,align=flush center] {This is a demonstration text for showing how line breaking works.}; \end{codeexample} \item[|align=|\declare{|justify|}] For alignment without line breaking, this has the same effect as |left|. For alignment with line breaking, this causes the text to - be ``justified.'' Use this - only with pretty broad nodes. + be ``justified.'' Use this only with rather broad nodes. {% \hbadness=10000 \begin{codeexample}[] -\tikz \node[fill=examplefill,text width=3cm,align=justify] +\tikz \node[fill=yellow!80!black,text width=3cm,align=justify] {This is a demonstration text for showing how line breaking works.}; \end{codeexample} } @@ -759,7 +990,7 @@ Let us now first have a look at the |text width| command. with the |\halign| command. This key only has an effect if |text width| - is empty, otherwise it is ignored. Furthermore, if \meta{header} is + is empty, otherwise it is ignored. Furthermore, if \meta{macro storing a header} is empty, then this key also has no effect. So, suppose |text width| is empty, but \meta{header} is not. In this case the following happens: @@ -858,7 +1089,7 @@ better to have the node to the right or above the actual coordinate. \subsubsection{Positioning Nodes Using Anchors} \pgfname\ uses a so-called anchoring mechanism to give you a very fine -control over the placement. The idea is simple: Imaging a node of +control over the placement. The idea is simple: Imagine a node of rectangular shape of a certain size. \pgfname\ defines numerous anchor positions in the shape. For example to upper right corner is called, well, not ``upper right anchor,'' but the |north east| anchor of the @@ -1090,7 +1321,7 @@ differently. automatically used, as explained later. The effect of this option is the following. First, the point - |(|\meta{number of dimension 2}|,|\meta{number or dimension 1}|)| + |(|\meta{number or dimension 2}|,|\meta{number or dimension 1}|)| is computed (note the inversed order), using the normal rules for evaluating such a coordinate, yielding some position. Then, the node is shifted by the vertical component of this point. The @@ -1106,8 +1337,8 @@ differently. The \meta{shifting part} can optionally be followed by a \meta{of-part}, which has one of the following forms: \begin{enumerate} - \item The \meta{of-part} can be declare{|of |\meta{coordinate}}, - where\meta{coordinate} is \emph{not} in parentheses and it is + \item The \meta{of-part} can be \declareandlabel{of}| |\meta{coordinate}, + where \meta{coordinate} is \emph{not} in parentheses and it is \emph{not} just a node name. An example would be |of somenode.north| or |of 2,3|. In this case, the following happens: First, the node's |at| parameter is set to the @@ -1129,9 +1360,9 @@ differently. |somenode|. The same effect could have been achieved writing |above=5mm| followed by |at=(somenode.north east)|. - If the \meta{shift-part} is missing, the shift is not zero, but + If the \meta{shifting-part} is missing, the shift is not zero, but rather the value of the |node distance| key is used, see below. - \item The \meta{of-part} can have be |of |\meta{node name}. An + \item The \meta{of-part} can be |of |\meta{node name}. An example would be |of somenode|. In this case, the following usually happens: \begin{itemize} @@ -1160,8 +1391,7 @@ differently. \begin{key}{/tikz/on grid=\meta{boolean} (initially false)} When this key is set to |true|, an \meta{of-part} of the current form behaves differently: The anchors set for the - current node as well as the anchor used for other \meta{node - name} are set the |center|. + current node as well as the anchor used for the other \meta{node name} are set to |center|. This has the following effect: When you say |above=1cm of somenode| with |on grid| set to true, the new node @@ -1256,13 +1486,6 @@ differently. \begin{codeexample}[] \begin{tikzpicture}[every node/.style={draw,circle}] \draw[help lines] (0,0) grid (2,5); - \begin{scope}[node distance=5mm] - \node (a) at (1,1) {a}; - \node [left=of a] {1}; \node [right=of a] {2}; - \node [above=of a] {3}; \node [below=of a] {4}; - \node [above left=of a] {5}; \node [above right=of a] {6}; - \node [below left=of a] {7}; \node [below right=of a] {8}; - \end{scope} \begin{scope}[node distance=5mm and 5mm] \node (b) at (1,4) {b}; \node [left=of b] {1}; \node [right=of b] {2}; @@ -1270,11 +1493,6 @@ differently. \node [above left=of b] {5}; \node [above right=of b] {6}; \node [below left=of b] {7}; \node [below right=of b] {8}; \end{scope} -\end{tikzpicture} -\end{codeexample} -\begin{codeexample}[] -\begin{tikzpicture}[every node/.style={draw,rectangle}] - \draw[help lines] (0,0) grid (2,5); \begin{scope}[node distance=5mm] \node (a) at (1,1) {a}; \node [left=of a] {1}; \node [right=of a] {2}; @@ -1282,6 +1500,11 @@ differently. \node [above left=of a] {5}; \node [above right=of a] {6}; \node [below left=of a] {7}; \node [below right=of a] {8}; \end{scope} +\end{tikzpicture} +\end{codeexample} +\begin{codeexample}[] +\begin{tikzpicture}[every node/.style={draw,rectangle}] + \draw[help lines] (0,0) grid (2,5); \begin{scope}[node distance=5mm and 5mm] \node (b) at (1,4) {b}; \node [left=of b] {1}; \node [right=of b] {2}; @@ -1289,6 +1512,13 @@ differently. \node [above left=of b] {5}; \node [above right=of b] {6}; \node [below left=of b] {7}; \node [below right=of b] {8}; \end{scope} + \begin{scope}[node distance=5mm] + \node (a) at (1,1) {a}; + \node [left=of a] {1}; \node [right=of a] {2}; + \node [above=of a] {3}; \node [below=of a] {4}; + \node [above left=of a] {5}; \node [above right=of a] {6}; + \node [below left=of a] {7}; \node [below right=of a] {8}; + \end{scope} \end{tikzpicture} \end{codeexample} \begin{codeexample}[] @@ -1315,10 +1545,10 @@ differently. \begin{key}{/tikz/below left=\opt{\meta{specification}}} Works similar to |above left|. \end{key} -\begin{key}{/tikz/above left=\opt{\meta{specification}}} +\begin{key}{/tikz/above right=\opt{\meta{specification}}} Works similar to |above left|. \end{key} -\begin{key}{/tikz/above right=\opt{\meta{specification}}} +\begin{key}{/tikz/below right=\opt{\meta{specification}}} Works similar to |above left|. \end{key} @@ -1359,7 +1589,7 @@ keys: -\subsubsection{Arranging Nodes Using a Chains and Matrices} +\subsubsection{Arranging Nodes Using Chains and Matrices} The simple |above| and |right| options may not always suffice for arranging a large number of nodes. For such situations \tikzname\ @@ -1379,11 +1609,11 @@ It is sometimes desirable that the size and position of a node is not given using anchors and size parameters, rather one would sometimes have a box be placed and be sized such that it ``is just large enough to contain this, that, and that point.'' This situation typically -arises when a picture has been drawn an, afterwards, parts of the +arises when a picture has been drawn and, afterwards, parts of the picture are supposed to be encircled or highlighted. In this situation the |fit| option from the |fit| library is useful, -see Section~\ref{section-library-fit} for a the details. The idea is +see Section~\ref{section-library-fit} for the details. The idea is that you may give the |fit| option to a node. The |fit| option expects a list of coordinates (one after the other without commas) as its parameter. The effect will be that the node's text area has exactly @@ -1435,7 +1665,7 @@ transformed. Scaling text is evil, rotating slightly less so. However, sometimes you \emph{do} wish to transform a node, for example, it certainly sometimes makes sense to rotate a node by -90 degrees. There are two ways in which you can achieve this: +90 degrees. There are two ways to achieve this: \begin{enumerate} \item @@ -1447,7 +1677,7 @@ example, it certainly sometimes makes sense to rotate a node by will get a ``huge'' X in your graphic. \end{key} \item - You can give transformation option \emph{inside} the option list of + You can give transformation options \emph{inside} the option list of the node. \emph{These} transformations always apply to the node. \begin{codeexample}[] \begin{tikzpicture}[every node/.style={draw}] @@ -1463,6 +1693,41 @@ example, it certainly sometimes makes sense to rotate a node by \end{enumerate} +Even though \tikzname\ currently does not allow you to configure +so-called \emph{nonlinear transformations,} see +Section~\ref{section-nonlinear-transformations}, there is an option +that influences how nodes are transformed when nonlinear +transformations are in force: + +\begin{key}{/tikz/transform shape nonlinear=\opt{\meta{true or false}} (initially false)} + When set to true, \tikzname\ will try to apply any current nonlinear + transformation also to nodes. Typically, for the text in nodes this + is not possible in general, in such cases a linear approximation of + the nonlinear transformation is used. For more details, see + Section~\ref{section-nonlinear-transformations}. +\makeatletter +\begin{codeexample}[] +\begin{tikzpicture} + % Install a nonlinear transformation: + \pgfsetcurvilinearbeziercurve + {\pgfpoint{0mm}{20mm}} + {\pgfpoint{10mm}{20mm}} + {\pgfpoint{10mm}{10mm}} + {\pgfpoint{20mm}{10mm}} + \pgftransformnonlinear{\pgfpointcurvilinearbezierorthogonal\pgf@x\pgf@y}% + + % Draw something: + \draw [help lines] (0,-30pt) grid [step=10pt] (80pt,30pt); + + \foreach \x in {0,20,...,80} + \node [fill=red!20] at (\x pt, -20pt) {\x}; + + \foreach \x in {0,20,...,80} + \node [fill=blue!20, transform shape nonlinear] at (\x pt, 20pt) {\x}; +\end{tikzpicture} +\end{codeexample} +\end{key} + \subsection{Placing Nodes on a Line or Curve Explicitly} @@ -1485,7 +1750,7 @@ ways are described in the following. coordinate. Rather, it is anchored on some point on the line from the previous coordinate to the current point. The \meta{fraction} dictates how ``far'' on the line the point should be. A - \meta{fraction} or 0 is the previous coordinate, 1 is the current + \meta{fraction} of 0 is the previous coordinate, 1 is the current one, everything else is in between. In particular, 0.5 is the middle. @@ -1499,6 +1764,16 @@ ways are described in the following. node[pos=0]{0} node[pos=0.5]{1/2} node[pos=0.9]{9/10}; \end{codeexample} + For the |arc| operation, the position is simply the corresponding + position on the arc: +\begin{codeexample}[] +\tikz { + \draw [help lines] (0,0) grid (3,2); + \draw (2,0) arc [x radius=1, y radius=2, start angle=0, end angle=180] + node foreach \t in {0,0.125,...,1} [pos=\t,auto] {\t}; +} +\end{codeexample} + The next case is the curve-to operation (the |..| operation). In this case, the ``middle'' of the curve, that is, the position |0.5| is not necessarily the point at the exact half distance on the @@ -1509,10 +1784,10 @@ ways are described in the following. connect the start and end points to the control points). The exact math is a bit complicated (depending on your point of view, of course); you may wish to consult a good book on computer graphics - and Bézier curves if you are intrigued. + and B\'ezier curves if you are intrigued. \begin{codeexample}[] - \tikz \draw (0,0) .. controls +(right:3.5cm) and +(right:3.5cm) .. (0,3) - \foreach \p in {0,0.125,...,1} {node[pos=\p]{\p}}; +\tikz \draw (0,0) .. controls +(right:3.5cm) and +(right:3.5cm) .. (0,3) + node foreach \p in {0,0.125,...,1} [pos=\p]{\p}; \end{codeexample} Another interesting case are the horizontal/vertical line-to operations @@ -1530,11 +1805,10 @@ ways are described in the following. \end{codeexample} For all other path construction operations, \emph{the position - placement does not work}, currently. This will hopefully change in - the future (especially for the arc operation). + placement does not work}, currently. \end{key} -\begin{key}{/tikz/auto=\meta{left or right} (default \normalfont is scope's setting)} +\begin{key}{/tikz/auto=\opt{\meta{direction}} (default \normalfont is scope's setting)} This option causes an anchor positions to be calculated automatically according to the following rule. Consider a line between to points. If the \meta{direction} is |left|, then the @@ -1577,10 +1851,10 @@ ways are described in the following. \draw[help lines,use as bounding box] (0,-.5) grid (4,5); \draw (0.5,0) .. controls (9,6) and (-5,6) .. (3.5,0) - \foreach \pos in {0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1} - {node [pos=\pos,swap,fill=red!20] {\pos}} - \foreach \pos in {0.025,0.2,0.4,0.6,0.8,0.975} - {node [pos=\pos,fill=blue!20] {\pos}}; + node foreach \pos in {0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1} + [pos=\pos,swap,fill=red!20] {\pos} + node foreach \pos in {0.025,0.2,0.4,0.6,0.8,0.975} + [pos=\pos,fill=blue!20] {\pos}; \end{tikzpicture} \end{codeexample} \begin{codeexample}[] @@ -1602,6 +1876,10 @@ ways are described in the following. \end{codeexample} \end{key} +\begin{key}{/tikz/'} + This is a very short alias for |swap|. +\end{key} + \begin{key}{/tikz/sloped} This option causes the node to be rotated such that a horizontal line becomes a tangent to the curve. The rotation is normally @@ -1610,7 +1888,7 @@ ways are described in the following. |[allow upside down]|, see below. \begin{codeexample}[] \tikz \draw (0,0) .. controls +(up:2cm) and +(left:2cm) .. (1,3) - \foreach \p in {0,0.25,...,1} {node[sloped,above,pos=\p]{\p}}; + node foreach \p in {0,0.25,...,1} [sloped,above,pos=\p]{\p}; \end{codeexample} \begin{codeexample}[] \begin{tikzpicture}[->] @@ -1626,7 +1904,7 @@ ways are described in the following. \begin{codeexample}[] \tikz [allow upside down] \draw (0,0) .. controls +(up:2cm) and +(left:2cm) .. (1,3) - \foreach \p in {0,0.25,...,1} {node[sloped,above,pos=\p]{\p}}; + node foreach \p in {0,0.25,...,1} [sloped,above,pos=\p]{\p}; \end{codeexample} \begin{codeexample}[] \begin{tikzpicture}[->,allow upside down] @@ -1642,13 +1920,13 @@ There exist styles for specifying positions a bit less ``technically'': This has the same effect as |pos=0.5|. \begin{codeexample}[] \tikz \draw (0,0) .. controls +(up:2cm) and +(left:3cm) .. (1,5) - node[at end] {|at end|} - node[very near end] {|very near end|} - node[near end] {|near end|} - node[midway] {|midway|} - node[near start] {|near start|} - node[very near start] {|very near start|} - node[at start] {|at start|}; + node[at end] {\texttt{at end}} + node[very near end] {\texttt{very near end}} + node[near end] {\texttt{near end}} + node[midway] {\texttt{midway}} + node[near start] {\texttt{near start}} + node[very near start] {\texttt{very near start}} + node[at start] {\texttt{at start}}; \end{codeexample} \end{stylekey} @@ -1730,9 +2008,39 @@ the operation with the |pos| option set. \subsection{The Label and Pin Options} -In addition to the |node| path operation, nodes can also be added -using the |label| and the |pin| option. This is mostly useful -for simple nodes. +\subsubsection{Overview} + +In addition to the |node| path operation, the two options |label| and +|pin| can be used to ``add a node next to another node''. As an +example, suppose we want to draw a graph in which the nodes are +small circles: +\begin{codeexample}[] +\tikz [circle] { + \node [draw] (s) {}; + \node [draw] (a) [right=of s] {} edge (s); + \node [draw] (b) [right=of a] {} edge (a); + \node [draw] (t) [right=of b] {} edge (b); +} +\end{codeexample} + +Now, in the above example, suppose we wish to indicate that the first +node is the start node and the last node is the target node. We could +write |\node (s) {$s$};|, but this would enlarge the first +node. Rather, we want the ``$s$'' to be placed next to the node. For +this, we need to create \emph{another} node, but next to the existing +node. The |label| and |pin| option allow us to do exactly this without +having to use the cumbersome |node| syntax: + +\begin{codeexample}[] +\tikz [circle] { + \node [draw] (s) [label=$s$] {}; + \node [draw] (a) [right=of s] {} edge (s); + \node [draw] (b) [right=of a] {} edge (a); + \node [draw] (t) [right=of b, label=$t$] {} edge (b); +} +\end{codeexample} + +\subsubsection{The Label Option} \begin{key}{/tikz/label=\opt{|[|\meta{options}|]|\meta{angle}|:|}\meta{text}} \label{label-option}% @@ -1780,20 +2088,34 @@ for simple nodes. \node [transform shape,rectangle,draw,label=right:label] {main node}; \end{codeexample} \end{key} - \item Then, an anchor point for the |label node|. It is determined - in such a way that the |labe node| will ``face away'' from the + \item Then, an anchor point for the |label node| is computed. It is determined + in such a way that the |label node| will ``face away'' from the border of the |main node|. The anchor that is chosen depends on the position of the border point that is chosen and its position relative to the center of the |main node| and on whether the - |transform shape| option is set. In general, the choice should be - what you would expect, but you may have to set the anchor yourself - in difficult situations. -\begin{codeexample}[] -\tikz - \node [circle,draw, + |transform shape| option is set. In detail, when the computed + border point is at $0^\circ$, the anchor |west| will be + used. Similarly, when the border point is at $90^\circ$, the + anchor |south| will be used, and so on for $180^\circ$ and + $270^\circ$. + + For angles between these ``major'' angles, like + $30^\circ$ or $110^\circ$, combined anchors, like |south west| for + $30^\circ$ or |south east| for $110^\circ$, are used. However, for + angles close to the major angles, (differing by up to $2^\circ$ + from the major angle), the anchor for the major angle is + used. Thus, a label at a border point for $2^\circ$ will have the + anchor |west|, while a label for $3^\circ$ will have the anchor + |south west|, resulting in a ``jump'' of the anchor. If this is + not desired, you will have to set the anchor yourself. +\begin{codeexample}[] +\tikz + \node [circle, draw, label=default, label=60:$60^\circ$, - label=below:$-90^\circ$] {my circle}; + label=below:$-90^\circ$, + label=3:$3^\circ$, + label=2:$2^\circ$] {my circle}; \end{codeexample} \item One \meta{angle} is special: If you set the \meta{angle} to @@ -1842,9 +2164,12 @@ for simple nodes. \end{stylekey} \end{key} + +\subsubsection{The Pin Option} + \begin{key}{/tikz/pin=\opt{|[|\meta{options}|]|}\meta{angle}|:|\meta{text}} - This is option is quite similar to the |label| option, but there is - one difference: In addition to adding a extra node to the picture, + This option is quite similar to the |label| option, but there is + one difference: In addition to adding an extra node to the picture, it also adds an edge from this node to the main node. This causes the node to look like a pin that has been added to the main node: \begin{codeexample}[] @@ -1901,6 +2226,213 @@ for simple nodes. \end{key} +\subsubsection{The Quotes Syntax} +\label{section-label-quotes} + +The |label| and |pin| option provide a syntax for +creating nodes next to existing nodes, but this syntax is often a +bit too verbose. By including the following library, you get access to +an even more concise syntax: + +\begin{tikzlibrary}{quotes} + Enables the quotes syntax for labels, pins, edge nodes, and pic + texts. +\end{tikzlibrary} + +Let us start with the basics of what this library does: Once loaded, +inside the options of a |node| command, instead of the usual +\meta{key}|=|\meta{value} pairs, you may also provide strings of the +following form (the actual syntax slightly more general, see the +detailed descriptions later on): +\begin{quote} + |"|\meta{text}|"|\opt{\meta{options}} +\end{quote} +The \meta{options} must be surrounded in curly braces when they +contain a comma, otherwise the curly braces are optional. The may be +preceded by an optional space. + +When a \meta{string} of the above form is encountered inside the +options of a |node|, then it is internally transformed to +\begin{quote} + |label={[|\meta{options}|]|\meta{text}|}| +\end{quote} + +Let us have a look at an example: +\begin{codeexample}[] +\tikz \node ["my label" red, draw] {my node}; +\end{codeexample} +The above has the same effect as the following: +\begin{codeexample}[] +\tikz \node [label={[red]my label}, draw] {my node}; +\end{codeexample} + +Here are further examples, one where no \meta{options} are added +to the |label|, one where a position is specified, and examples with +more complicated options in curly braces: + +\begin{codeexample}[] +\begin{tikzpicture} + \matrix [row sep=5mm] { + \node [draw, "label"] {A}; \\ + \node [draw, "label" left] {B}; \\ + \node [draw, "label" color=red] {C}; \\ + \node [draw, "label" {red,draw,thick}] {D}; \\ + }; +\end{tikzpicture} +\end{codeexample} + +Let us now have a more detailed look at what which commands this +library provides: + +\begin{key}{/tikz/quotes mean label} + When this option is used (which is the default when this library is + loaded), then, as described above, inside the options of a node a + special syntax check is done. + + \medskip + \noindent\textbf{The syntax.} + For each string in the list of options + it is tested whether it starts with a quotation mark (note that this + will never happen for normal keys since the normal keys of + \tikzname\ do not start with quotation marks). When this happens, + the \meta{string} should not be a key--value pair, but, rather, must + have the form: + \begin{quote} + |"|\meta{text}|"|\opt{|'|}\opt{\meta{options}} + \end{quote} + + (We will discuss the optional apostrophe in a moment. It is not + really important for the current option, but only for + edge labels, which are discussed later). + + \medskip + \noindent\textbf{Transformation to a label option.} + When a \meta{string} has the above form, it is treated (almost) as + if you had written + \begin{quote} + |label={[|\meta{options}|]|\meta{text}|}| + \end{quote} + instead. The ``almost'' refers to the following additional feature: + In reality, before the \meta{options} are executed inside the + |label| command, the direction keys |above|, |left|, |below right| + and so on are redefined so that |above| is a shorthand for + |label position=90| and similarly for the other keys. The net effect + is that in order to specify the position of the \meta{text} relative + to the main node you can just put something like |left| or + |above right| inside the \meta{options}: +\begin{codeexample}[] +\tikz + \node ["$90^\circ$" above, "$180^\circ$" left, circle, draw] {circle}; +\end{codeexample} + + Alternatively, you can also use \meta{direction}|:|\meta{actual + text} as your \meta{text}. This works since the |label| command + allows you to specify a direction at the beginning when it is + separated by a colon: +\begin{codeexample}[] +\tikz + \node ["90:$90^\circ$", "left:$180^\circ$", circle, draw] {circle}; +\end{codeexample} + Arguably, placing |above| or |left| behind the \meta{text} seems + more natural than having it inside the \meta{text}. + + In addition to the above, before the \meta{options} are executed, + the following style is also executed: + \begin{stylekey}{/tikz/every label quotes} +\begin{codeexample}[] +\tikz [every label quotes/.style=red] + \node ["90:$90^\circ$", "left:$180^\circ$", circle, draw] {circle}; +\end{codeexample} + \end{stylekey} + + \medskip + \noindent\textbf{Handling commas and colons inside the text.} + The \meta{text} may not contain a comma, unless it is inside curly + braces. The reason is that the key handler separates the total + options of a |node| along the commas it finds. So, in order to have + text containing a comma, just add curly braces around either the + comma or just around the whole \meta{text}: +\begin{codeexample}[] +\tikz \node ["{yes, we can}", draw] {foo}; +\end{codeexample} + The same is true for a colon, only in this case you may need to + surround specifically the colon by curly braces to stop the |label| + option from interpreting everything before the colon as a direction: +\begin{codeexample}[] +\tikz \node ["yes{:} we can", draw] {foo}; +\end{codeexample} + + \medskip + \noindent\textbf{The optional apostrophe.} + Following the closing quotation marks in a \meta{string} there may + (but need + not) be a single quotation mark (an apostrophe), possibly surrounded + by whitespaces. If it is present, it is simply added to the + \meta{options} as another option (and, indeed, a single apostrophe + is a legal option in \tikzname, it is a shorthand for |swap|): + + \begin{tabular}{ll} + String & has the same effect as \\\hline + |"foo"'| & |"foo" {'}| \\ + |"foo"' red| & |"foo" {',red}| \\ + |"foo"'{red}| & |"foo" {',red}| \\ + |"foo"{',red}| & |"foo" {',red}| \\ + |"foo"{red,'}| & |"foo" {red,'}| \\ + |"foo"{'red}| & |"foo" {'red}| (illegal; there is no key |'red|)\\ + |"foo" red'| & |"foo" {red'}| (illegal; there is no key |red'|)\\ + \end{tabular} +\end{key} + +\begin{key}{/tikz/quotes mean pin} + This option has exactly the same effect as |quotes mean label|, only + instead of transforming quoted text to the |label| option, they get + transformed to the |pin| option: +\begin{codeexample}[] +\tikz [quotes mean pin] + \node ["$90^\circ$" above, "$180^\circ$" left, circle, draw] {circle}; +\end{codeexample} + Instead of |every label quotes|, the following style is executed + with each such pin: + \begin{stylekey}{/tikz/every pin quotes} + \end{stylekey} +\end{key} + +If instead of |label|s or |pin|s you would like quoted strings to be +interpreted in a different manner, you can also define your own +handlers: + +\begin{key}{/tikz/node quotes mean=\meta{replacement}} + This key allows you to define your own handler for quotes + options. Inside the options of a |node|, whenever a key--value pair + with the syntax + \begin{quote} + |"|\meta{text}|"|\opt{|'|}\opt{\meta{options}} + \end{quote} + is encountered, the following happens: The above string gets + replaced by \meta{replacement} where inside the \meta{replacement} + the parameter |#1| is \meta{text} and |#2| is \meta{options}. If the + apostrophe is present (see also the discussion of + |quotes mean label|), the \meta{options} start with |',|. + + The \meta{replacement} is then parsed normally as options (using + |\pgfkeys|). + + Here is an example, where the quotes are used to define labels that + are automatically named according to the |text|: +\begin{codeexample}[] +\tikzset{node quotes mean={label={[#2,name={#1}]#1}}} + +\tikz { + \node ["1", "2" label position=left, circle, draw] {circle}; + \draw (1) -- (2); +} +\end{codeexample} +\end{key} + +Some further options provided by the |quotes| library concern labels +next to edges rather than nodes and they are described in +Section~\ref{section-edge-quotes}. + \subsection{Connecting Nodes: Using Nodes as Coordinates} \label{section-nodes-connecting} @@ -1925,7 +2457,7 @@ Section~\ref{section-node-coordinates}. Suppose you have said same effect. However, for most other shapes, some path construction operations like - |--| try to be ``clever'' when this they are asked to draw a line + |--| try to be ``clever'' when they are asked to draw a line from such a coordinate or to such a coordinate. When you say |(x)--(1,1)|, the |--| path operation will not draw a line from the center of |x|, but \emph{from the border} of |x| in the direction going @@ -1955,9 +2487,11 @@ Section~\ref{section-node-coordinates}. Suppose you have said \label{section-nodes-edges} +\subsubsection{Basic Syntax of the Edge Operation} + The |edge| operation works like a |to| operation that is added after the main path has been drawn, much like a node is added after the main -path has been drawn. This allows you to have each |edge| to have a +path has been drawn. This allows each |edge| to have a different appearance. As the |node| operation, an |edge| temporarily suspends the construction of the current path and a new path $p$ is constructed. This new path $p$ will be drawn after the main path has @@ -1965,7 +2499,7 @@ been drawn. Note that $p$ can be totally different from the main path with respect to its options. Also note that if there are several |to| and/or |node| operations in the main path, each creates its own path(s) and they are drawn in the order that they -are encountered on the path. +are encountered on the main path. \begin{pathoperation}{edge}{\opt{|[|\meta{options}|]|} \opt{\meta{nodes}} |(|\meta{coordinate}|)|} @@ -2013,8 +2547,8 @@ are encountered on the path. \begin{codeexample}[] \begin{tikzpicture} - \foreach \name/\angle in {a/0,b/90,c/180,d/270} - \node (\name) at (\angle:1) {$\name$}; + \node foreach \name/\angle in {a/0,b/90,c/180,d/270} + (\name) at (\angle:1) {$\name$}; \path[->] (b) edge (a) edge (c) @@ -2030,8 +2564,8 @@ are encountered on the path. \begin{codeexample}[] \begin{tikzpicture} - \foreach \name/\angle in {a/0,b/90,c/180,d/270} - \node (\name) at (\angle:1.5) {$\name$}; + \node foreach \name/\angle in {a/0,b/90,c/180,d/270} + (\name) at (\angle:1.5) {$\name$}; \path[->] (b) edge node[above right] {$5$} (a) edge (c) @@ -2045,18 +2579,98 @@ are encountered on the path. Instead of |every to|, the style |every edge| is installed at the beginning of the main path. - \begin{stylekey}{/tikz/every edge (inititially draw)} % inititially --> initially? (ff) (this is the definition of the key, so please have a look) + \begin{stylekey}{/tikz/every edge (initially draw)} Executed for each |edge|. \begin{codeexample}[] \begin{tikzpicture}[every to/.style={draw,dashed}] - \path (0,0) to (3,2); + \path (0,0) edge (3,2); \end{tikzpicture} \end{codeexample} \end{stylekey} \end{pathoperation} -\subsection{Referencing Nodes Outside the Current Pictures} +\subsubsection{Nodes on Edges: Quotes Syntax} +\label{section-edge-quotes} + +The standard way of specifying nodes that are placed ``on'' an edge +(or on a to-path; all of the following is also true for to--paths) is +to put node specifications after the |edge| keyword, but before the +target coordinate. Another way is to use the |edge node| option and +its friends. Yet another way is to use the quotes syntax. + +The syntax is essentially the same as for labels added to nodes as +described in Section~\ref{section-label-quotes} and you also need to +load the |quotes| library. + +In detail, when the |quotes| library is loaded, each time a key--value +pair in a list of options passed to an |edge| or a |to| path command +starts with |"|, the key--value pair must actually be a string of the +following form: +\begin{quote} + |"|\meta{text}|"|\opt{|'|}\opt{\meta{options}} +\end{quote} +This string is transformed into the following: +\begin{quote} + |edge node=node [every edge quotes,|\meta{options}|]{|\meta{text}|}| +\end{quote} +As described in Section~\ref{section-label-quotes}, the apostrophe +becomes part of the \meta{options}, when present. + +The following style is important for the placement of the labels: +\begin{stylekey}{/tikz/every edge quotes (initially auto)} + This style is |auto| by default, which causes labels specified using + the quotes-syntax to be placed next to the edges. Unless the setting + of |auto| has been changed, they will be placed to the left. +\begin{codeexample}[] +\tikz \draw (0,0) edge ["left", ->] (2,0); +\end{codeexample} + + In order to place all labels to the right by default, change this + style to |auto=right|: +\begin{codeexample}[] +\tikz [every edge quotes/.style={auto=right}] + \draw (0,0) edge ["right", ->] (2,0); +\end{codeexample} + + To place all nodes ``on'' the edge, just make this style empty (and, + possibly, make your labels opaque): +\begin{codeexample}[] +\tikz [every edge quotes/.style={fill=white,font=\footnotesize}] + \draw (0,0) edge ["mid", ->] (2,1); +\end{codeexample} +\end{stylekey} + +You may often wish to place some edge nodes to the right of edges and +some to the left. For this, the special treatment of the apostrophe is +particularly convenient: Recall that in \tikzname\ there is an option +just called |'|, which is a shorthand for |swap|. Now, following the +closing quotation mark come the options of an edge node. Thus, if the +closing quotation mark is followed by an apostrophe, the |swap| option +will be added to the edge label, causing it is be placed on the other +side. Because of the special treatment, you can even add another +option like |near end| after the apostrophe without having to add +curly braces and commas: + +\begin{codeexample}[] +\tikz + \draw (0,0) edge ["left", "right"', + "start" near start, + "end"' near end] (4,0); +\end{codeexample} + +In order to modify the distance between the edge labels and the edge, +you should consider introducing some styles: + +\begin{codeexample}[] +\tikz [tight/.style={inner sep=1pt}, loose/.style={inner sep=.7em}] + \draw (0,0) edge ["left" tight, + "right"' loose, + "start" near start] (4,0); +\end{codeexample} + + +\subsection{Referencing Nodes Outside the Current Picture} \label{section-cross-picture-tikz} @@ -2166,7 +2780,7 @@ access the current page. It is a node of shape rectangle whose |north east| anchor is the upper right corner of the page. While this node is handled in a special way internally, you can reference it as if it were defined in some remembered picture other than the current -one. Thus, by giving the |remembered picture| and the |overlay| +one. Thus, by giving the |remember picture| and the |overlay| options to a picture, you can position nodes \emph{absolutely} on a page. @@ -2204,12 +2818,41 @@ page). \subsection{Late Code and Late Options} +\label{section-node-also} All options given to a node only locally affect this one node. While this is a blessing in most cases, you may sometimes want to cause options to have effects ``later'' on. The other way round, you may sometimes note ``only later'' that some options should be added to the -options of a node. +options of a node. For this, the following version of the |node| path +command can be used: + +\begin{pathoperation}{node also}{\opt{|[|\meta{late options}|]|}|(|\meta{name}|)|} + Note that the \meta{name} is compulsory and that \emph{no} text may + be given. Also, the ordering of options and node label must be as above. + + The effect of the above is the following effect: The node + \meta{name} must already be existing. Now, the \meta{late options} are + executed in a local scope. Most of these options will have no effect + since you \emph{cannot change the appearance of the node,} that is, + you cannot change a red node into a green node using these ``late'' + options. However, giving the |append after command| and + |prefix after command| options inside + the \meta{late options} (directly or indirectly) does have the desired + effect: The given path gets executed with the |\tikzlastnode| + set to the determined node. + + The net effect of all this is that you can provide, say, the |label| + option inside the \meta{options} to a add a label to a node that has + already been constructed. + +\begin{codeexample}[] +\begin{tikzpicture} + \node [draw,circle] (a) {Hello}; + \node also [label=above:world] (a); +\end{tikzpicture} +\end{codeexample} +\end{pathoperation} As explained in Section~\ref{section-paths}, you can use the options |append after command| and @@ -2219,41 +2862,20 @@ useful there: Expands to the last node on the path. \end{command} -A \emph{late option} for a node is an option that is given a long time -after the node has already been constructed. +Instead of the |node also| syntax, you can also the following option: \begin{key}{/tikz/late options=\meta{options}} This option can be given on a path (but not as an argument to a - |node| path command). It has the following effect: An already - \meta{existing node} is determined (in a way to be described in a moment) - and, then, the \meta{options} are executed in a local scope. Most of - these options will have no effect since you \emph{cannot change the - appearance of the node,} that is, you cannot change a red node - into a green node using late options. However, giving - the |append after command| and |prefix after command| options inside - the \meta{options} (directly or indirectly) does have the desired - effect: The given path gets executed with the |\tikzlastnode| - set to the determined node. - - The net effect of all this is that you can provide, say, the |label| - option inside the \meta{options} to a add a label to a node that has - already been constructed. Likewise, you can use the |on chain| - option to make an already \meta{existing node} part of a chain. - - The \meta{existing node} is determined as follows: If the - |name=|\meta{existing node} option is used inside the - \meta{options}, then this name is used. Otherwise, if the last - coordinate on the current path was of the form |(|\meta{existing - node}|)|, then this \meta{existing node} name is used. Otherwise, - an error results. - + |node| path command) and has the same effect as the |node also| path + command. Inside the \meta{options}, you should use the |name| option + to specify the node for which you wish to add late options: + \begin{codeexample}[] \begin{tikzpicture} - \node (a) [draw,circle] {Hello}; - \path (a) [late options={label=above:world}]; + \node [draw,circle] (a) {Hello}; + \path [late options={name=a, label=above:world}]; \end{tikzpicture} \end{codeexample} - \end{key} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-transformations.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-transformations.tex index 27ba94e4cf4..95a3bc7b7fb 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-transformations.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-transformations.tex @@ -36,7 +36,7 @@ coordinate like $(1,2)$ before a point on the screen is chosen: inside the picture. \item The backend driver (like |dvips| or |pdftex|) adds transformation - commands such the coordinate is shifted to the correct position in + commands such that the coordinate is shifted to the correct position in \TeX's page coordinate system. \item \textsc{pdf} (or PostScript) apply the canvas transformation @@ -58,7 +58,7 @@ The $xy$-coordinate system and the coordinate transformation matrix the canvas transformation matrix, but you have to use commands of the core layer directly to do so and you ``better know what you are doing'' when you do this. The moment you start modifying the -canvas matrix, \pgfname\ immediately looses track of all +canvas matrix, \pgfname\ immediately loses track of all coordinates and shapes, anchors, and bounding box computations will no longer work. @@ -87,7 +87,7 @@ options: \begin{key}{/tikz/x=\meta{value} (initially 1cm)} If \meta{value} is a dimension, the $x$-vector of - \pgfname's $xyz$-coordinate system is setup to point + \pgfname's $xyz$-coordinate system is set up to point \meta{value} to the right, that is, to $(\meta{value},0pt)$. \begin{codeexample}[] @@ -135,7 +135,7 @@ options: \end{key} \begin{key}{/tikz/z=\meta{value} (initially \normalfont$-3.85$mm)} - Works like the |y=| option, but now a dimension is means the point + Works like the |y=| option, but now a dimension is the point $(\meta{value},\meta{value})$. \begin{codeexample}[] @@ -162,7 +162,7 @@ options: The next step is to apply the current \emph{coordinate transformation matrix} to the coordinate. For example, the coordinate transformation matrix might currently be set such that it adds a -certain constant to the $x$ value. Also, it might be setup such that +certain constant to the $x$ value. Also, it might be set up such that it, say, exchanges the $x$ and $y$ value. In general, any ``standard'' transformation like translation, rotation, slanting, or scaling or any combination thereof is possible. (Internally, \pgfname\ @@ -267,7 +267,7 @@ singular (if you do not know what singular matrices are, you are blessed). \begin{key}{/tikz/scale=\meta{factor}} Multiplies all coordinates by the given \meta{factor}. The \meta{factor} should not be excessively large in absolute terms or - very near to zero. + very close to zero. \begin{codeexample}[] \begin{tikzpicture} \draw[help lines] (0,0) grid (3,2); @@ -279,7 +279,7 @@ singular (if you do not know what singular matrices are, you are blessed). \end{key} \begin{key}{/tikz/scale around={\ttfamily\char`\{}\meta{factor}|:|\meta{coordinate}{\ttfamily\char`\}}} - Scales the coordinate system by \meta{factor}, put with the ``origin + Scales the coordinate system by \meta{factor}, with the ``origin of scaling'' centered on \meta{coordinate} rather than the origin. \begin{codeexample}[] \begin{tikzpicture} @@ -360,6 +360,78 @@ singular (if you do not know what singular matrices are, you are blessed). \end{key} +\begin{key}{/tikz/rotate around x=\meta{angle}} + + This key sets the $x$, $y$ and $z$ vectors of the \pgfname\ + $xyz$-coordinate system so that they + are rotated by \meta{angle} around the axis corresponding + to the $x$-vector. + The rotation is applied so that when looking towards the origin + along this axis, positive angles result in an anticlockwise rotation. + +\begin{codeexample}[] +\begin{tikzpicture}[>=stealth] + \draw [->] (0,0,0) -- (2,0,0) node [at end, right] {$x$}; + \draw [->] (0,0,0) -- (0,2,0) node [at end, left] {$y$}; + \draw [->] (0,0,0) -- (0,0,2) node [at end, left] {$z$}; + + \draw [red, rotate around x=0] (0,0,0) -- (1,1,0) -- (1,0,0); + \draw [green, rotate around x=45] (0,0,0) -- (1,1,0) -- (1,0,0); + \draw [blue, rotate around x=90] (0,0,0) -- (1,1,0) -- (1,0,0); +\end{tikzpicture} +\end{codeexample} + +\end{key} + + +\begin{key}{/tikz/rotate around y=\meta{angle}} + + This key sets the $x$, $y$ and $z$ vectors of the \pgfname\ + $xyz$-coordinate system so that they + are rotated by \meta{angle} around the axis corresponding + to the $y$-vector. + The rotation is applied so that when looking towards the origin + along this axis, positive angles result in an anticlockwise rotation. + +\begin{codeexample}[] +\begin{tikzpicture}[>=stealth] + \draw [->] (0,0,0) -- (2,0,0) node [at end, right] {$x$}; + \draw [->] (0,0,0) -- (0,2,0) node [at end, left] {$y$}; + \draw [->] (0,0,0) -- (0,0,2) node [at end, left] {$z$}; + + \draw [red, rotate around y=0] (0,0,0) -- (1,1,0) -- (1,0,0); + \draw [green, rotate around y=-45] (0,0,0) -- (1,1,0) -- (1,0,0); + \draw [blue, rotate around y=-90] (0,0,0) -- (1,1,0) -- (1,0,0); +\end{tikzpicture} +\end{codeexample} + +\end{key} + + +\begin{key}{/tikz/rotate around z=\meta{angle}} + + This key sets the $x$, $y$ and $z$ vectors of the \pgfname\ + $xyz$-coordinate system so that they + are rotated by \meta{angle} around the axis corresponding + to the $z$-vector. + The rotation is applied so that when looking towards the origin + along this axis, positive angles result in an anticlockwise rotation. + +\begin{codeexample}[] +\begin{tikzpicture}[>=stealth] + \draw [->] (0,0,0) -- (2,0,0) node [at end, right] {$x$}; + \draw [->] (0,0,0) -- (0,2,0) node [at end, left] {$y$}; + \draw [->] (0,0,0) -- (0,0,2) node [at end, left] {$z$}; + + \draw [red, rotate around z=0] (0,0) -- (1,1) -- (1,0); + \draw [green, rotate around z=45] (0,0) -- (1,1) -- (1,0); + \draw [blue, rotate around z=90] (0,0) -- (1,1) -- (1,0); +\end{tikzpicture} +\end{codeexample} + +\end{key} + + \begin{key}{/tikz/cm={\ttfamily\char`\{}\meta{$a$}|,|\meta{$b$}|,|\meta{$c$}|,|\meta{$d$}|,|\meta{coordinate}{\ttfamily\char`\}}} applies the following transformation to all coordinates: Let $(x,y)$ be the coordinate to be transformed and let \meta{coordinate} @@ -406,13 +478,13 @@ circumstances you do \emph{not} want line widths to change in a picture as this creates visual inconsistency. Just as important, when -you use canvas transformations \emph{\pgfname\ looses track of +you use canvas transformations \emph{\pgfname\ loses track of positions of nodes and of picture sizes} since it does not take the effect of canvas transformations into account when it computes -coordinates of nodes (you not, however, rely on this; it may change in +coordinates of nodes (do not, however, rely on this; it may change in the future). -Finally, not that a canvas transformation always applies to a path as +Finally, note that a canvas transformation always applies to a path as a whole, it is not possible (as for coordinate transformations) to use different transformations in different parts of a path. diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-transparency.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-transparency.tex index 5f7eba71c8c..3891d152987 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-transparency.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-transparency.tex @@ -65,7 +65,7 @@ following options. \begin{codeexample}[] \begin{tikzpicture}[line width=1ex] \draw (0,0) -- (3,1); - \filldraw [fill=examplefill,draw opacity=0.5] (1,0) rectangle (2,1); + \filldraw [fill=yellow!80!black,draw opacity=0.5] (1,0) rectangle (2,1); \end{tikzpicture} \end{codeexample} \end{key} @@ -188,7 +188,7 @@ option |opacity| sets both at the same time. \end{key} -Note the following effect: If you setup a certain opacity for stroking +Note the following effect: If you set up a certain opacity for stroking or filling and you stroke or fill the same area twice, the effect accumulates: @@ -203,6 +203,185 @@ Often, this is exactly what you intend, but not always. You can use transparency groups, see the end of this section, to change this. + +\subsection{Blend Modes} +\label{section-blend-modes} + +A \emph{blend mode} specifies how colors mix when you paint on a +canvas. Normally, if you paint a red box on a green circle, the red +color will completely replace the green circle. However, in some +situations you might also wish the red color to somehow ``mix'' or +``blend'' with the green circle. We already saw that, using transparency, +we can draw something without completely obscuring the +background. \emph{Blending} is a similar operation, only here we mix +colors in more complicated ways. + +\emph{Note:} Blending is a rather ``advanced'' feature of +\textsc{pdf}. Most renderers, let alone printers, will have trouble +rendering blending correctly. + +\begin{key}{/tikz/blend mode=\meta{mode}} + Sets the current blend mode to \meta{mode}. Here \meta{mode} must be + one of the modes listed below. More details on these modes can also + be found in Section 7.2.4 of the \textsc{pdf} Specification, version 1.7. + + In the following example, the blend mode is only used and set inside + a transparency group (see also + Section~\ref{section-transparency-groups}). This is because most + renderers (viewing + programs) have trouble rendering blending correctly otherwise. For + instance, at the time of writing, the versions of Adobe's Reader and + Apple's Preview render the following drawing very differently, if + the transparency group is not used in the following example. + +\begin{codeexample}[] +\tikz { + \begin{scope}[transparency group] + \begin{scope}[blend mode=screen] + \fill[red!90!black] ( 90:.6) circle (1); + \fill[green!80!black] (210:.6) circle (1); + \fill[blue!90!black] (330:.6) circle (1); + \end{scope} + \end{scope} +} +\end{codeexample} + + Because of the trouble with rendering blending correctly outside + transparency groups, there is a special key that establishes a + transparency group and sets a blend mode simultaneously: + + \begin{key}{/tikz/blend group=\meta{mode}} + This key can only be used with a scope (like + |transparency group|). It will cause the current scope to become a + transparency group and, inside this group, the blend mode will be + set to \meta{mode}. + +\begin{codeexample}[] +\tikz [blend group=screen] { + \fill[red!90!black] ( 90:.6) circle (1); + \fill[green!80!black] (210:.6) circle (1); + \fill[blue!90!black] (330:.6) circle (1); +} +\end{codeexample} + \end{key} + + Here is an overview of the effects of the different available blend + modes. In the examples, we always have three circles drawn on + top of each other (as in the example code earlier): We start with a + triple of pure red, green, and blue. Below it, we have a triple of + light versions of these three colors (|red!50|, |green!50|, and + |blue!50|). Next comes the triple yellow, cyan, and magenta; again + with a triple of light versions below it. The large example consists + of three balls (produced using |ball color|) having the colors red, + green, and blue, are drawn on top of each other just like the + circles. + + \definecolor{rg}{rgb}{1,1,0} + \definecolor{gb}{rgb}{0,1,1} + \definecolor{br}{rgb}{1,0,1} + + \def\makeline#1#2#3{\leavevmode + \hbox to 4cm{#1\hss}\ \hbox to + 2cm{#2\hss}\ \begin{minipage}[t]{9cm}\raggedright#3\end{minipage}\par + \textcolor{black!25}{\hrule height1pt} + } + + \def\showmode#1#2{ + \makeline{ + \tikz [blend mode=#1,baseline=-.5ex] { + \fill[red] ( 90:.5em) circle (.75em); + \fill[green] (210:.5em) circle (.75em); + \fill[blue] (330:.5em) circle (.75em); + \scoped[yshift=-2.5em]{ + \fill[red!50] ( 90:.5em) circle (.75em); + \fill[green!50] (210:.5em) circle (.75em); + \fill[blue!50] (330:.5em) circle (.75em); + } + } + \tikz [blend mode=#1,baseline=-.5ex] { + \fill[rg] ( 90:.5em) circle (.75em); + \fill[gb] (210:.5em) circle (.75em); + \fill[br] (330:.5em) circle (.75em); + \scoped[yshift=-2.5em]{ + \fill[rg!50] ( 90:.5em) circle (.75em); + \fill[gb!50] (210:.5em) circle (.75em); + \fill[br!50] (330:.5em) circle (.75em); + } + } + \tikz [blend mode=#1,baseline=-.5ex+1.25em] { + \shade[ball color=red] ( 90:1em) circle (1.5em); + \shade[ball color=green] (210:1em) circle (1.5em); + \shade[ball color=blue] (330:1em) circle (1.5em); + }}{|#1|}{#2}} + + \medskip + \makeline{\emph{Example}}{\emph{Mode}}{\emph{Explanations quoted from Table 7.2 of the + \textsc{pdf} Specification, Version 1.7}} + \showmode{normal}{When painting a pixel with a some color (called + the ``source color''), the background color + (called the ``backdrop'') is completely ignored.} + \showmode{multiply}{Multiplies the backdrop and source color + values. The result color is always at least as dark as + either of the two constituent colors. Multiplying any color with + black produces black; multiplying with white leaves the original + color unchanged. Painting successive overlapping objects with a + color other than black or white produces progressively darker + colors.} + \showmode{screen}{Multiplies the complements of the backdrop and + source color values, then complements the result. The + result color is always + at least as light as either of the two constituent + colors. Screening any color with white produces white; screening + with black leaves the original color unchanged. The effect is + similar to projecting multiple photographic slides + simultaneously onto a single screen.} + \showmode{overlay}{Multiplies or screens the colors, depending on + the backdrop color value. Source colors overlay the backdrop + while preserving its highlights and shadows. The backdrop color + is not replaced but is mixed with the source color to reflect + the lightness or darkness of the backdrop.} + \showmode{darken}{Selects the darker of the backdrop and source + colors. The backdrop is replaced with the source where the + source is darker; otherwise, it is left unchanged.} + \showmode{lighten}{Selects the lighter of the backdrop and source + colors. The backdrop is replaced with the source where the + source is lighter; otherwise, it is left unchanged.} + \showmode{color dodge}{Brightens the backdrop color to reflect the + source color. Painting with black produces no changes.} + \showmode{color burn}{Darkens the backdrop color to reflect the + source color. Painting with white produces no change.} + \showmode{hard light}{Multiplies or screens the colors, depending + on the source color value. The effect is similar to shining a + harsh spotlight on the backdrop.} + \showmode{soft light}{Darkens or lightens the colors, depending on + the source color value. The effect is similar to shining a + diffused spotlight on the backdrop.} + \showmode{difference}{Subtracts the darker of the two constituent + colors from the lighter color. Painting with white inverts the + backdrop color; painting with black produces no change.} + \showmode{exclusion}{Produces an effect similar to that of the + Difference mode but lower in contrast. Painting with white + inverts the backdrop color; painting with black produces no + change.} + \showmode{hue}{Creates a color with the hue of the source color + and the saturation and luminosity of the backdrop color.} + \showmode{saturation}{Creates a color with the saturation of the + source color and the hue and luminosity of the backdrop + color. Painting with this mode in an area of the backdrop that + is a pure gray (no saturation) produces no change.} + \showmode{color}{Creates a color with the hue and saturation of + the source color and the luminosity of the backdrop color. This + preserves the gray levels of the backdrop and is useful for + coloring monochrome images or tinting color images.} + \showmode{luminosity}{Creates a color with the luminosity of the + source color and the hue and saturation of the backdrop + color. This produces an inverse effect to that of the Color + mode.} + +\end{key} + + + \subsection{Fadings} For complicated graphics, uniform transparency settings are not always @@ -220,7 +399,7 @@ How do we specify a fading? This is a bit of an art since the underlying mechanism is quite powerful, but a bit difficult to use. Let us start with a bit of terminology. A \emph{fading} specifies for -each point of an area to transparency of the point. This transparency +each point of an area the transparency of that point. This transparency can by any number between 0 and 1. A \emph{fading picture} is a normal graphic that, in a way to be described in a moment, determines the transparency of points inside the fading. Each fading has an @@ -236,7 +415,7 @@ opaque is the point in the fading. In particular, a white point of the fading picture is completely opaque in the fading and a black point of the fading picture is completely transparent in the fading. (The background of the fading picture is always transparent in the fading -as if the background where black.) +as if the background were black.) It is rather counter-intuitive that a \emph{white} pixel of the fading picture will be \emph{opaque} in the fading and a \emph{black} pixel @@ -244,7 +423,7 @@ will be \emph{transparent}. For this reason, \tikzname\ defines a color called |transparent| that is the same as |black|. The nice thing about this definition is that the color |transparent!|\meta{percentage} in the fading picture yields a -pixel that is \meta{percentage} per cent transparent in the fading. +pixel that is \meta{percentage} percent transparent in the fading. Turning a fading picture into a normal picture is achieved using the following commands, which are \emph{only defined in the library}, @@ -261,7 +440,7 @@ namely the library |fadings|. So, to use them, you have to say set the name of the fading. You \emph{must} provide this option. \end{key} - The following shading is 2cm by 2cm and changes gets more and more + The following shading is 2cm by 2cm and gets more and more transparent from left to right, but is 50\% transparent for a large circle in the middle. {\tikzexternaldisable @@ -303,6 +482,9 @@ namely the library |fadings|. So, to use them, you have to say \end{tikzpicture} \end{codeexample} }% + + The same effect can also be achieved using knockout groups, see + Section~\ref{section-transparency-groups}. \end{environment} \begin{plainenvironment}{{tikzfadingfrompicture}\oarg{options}} @@ -314,7 +496,7 @@ namely the library |fadings|. So, to use them, you have to say \end{contextenvironment} \begin{command}{\tikzfading\oarg{options}} - This command is used to define a fading similarly to that way a + This command is used to define a fading similarly to the way a shading is defined. In the \meta{options} you should \begin{enumerate} \item use the |name=|\meta{name} option to set a name for the fading, @@ -363,7 +545,7 @@ namely the library |fadings|. So, to use them, you have to say \subsubsection{Fading a Path} -Aa fading specifies for each pixel of a certain area how transparent +A fading specifies for each pixel of a certain area how transparent this pixel will be. The following options are used to install such a fading for the current scope or path. @@ -402,11 +584,11 @@ fading for the current scope or path. \begin{key}{/tikz/fit fading=\meta{boolean} (default true, initially true)} When set to |true|, the fading is shifted and resized (in exactly - the same way as a shading) so that is covers the current + the same way as a shading) so that it covers the current path. When set to |false|, the fading is only shifted so that it is centered on the path's center, but it is not resized. This can be useful for special-purpose fadings, for instance when you use a - fading to ``punsh out'' something. % TODOsp: punsh out --> punch out?? + fading to ``punch out'' something. \end{key} \begin{key}{/tikz/fading transform=\meta{transformation options}} @@ -444,7 +626,7 @@ fading for the current scope or path. \end{tikzpicture} \end{codeexample} - The |fade inside| of the following example more transparent in the middle than on the + The |fade inside| of the following example is more transparent in the middle than on the outside. \begin{codeexample}[] @@ -563,6 +745,7 @@ conjunction, see the end of this section. \subsection{Transparency Groups} +\label{section-transparency-groups} Consider the following cross and sign. They ``look wrong'' because we can see how they were constructed, while this is not really part of @@ -606,9 +789,9 @@ Transparency groups are used to render them correctly: \end{tikzpicture} \end{codeexample} -\begin{key}{/tikz/transparency group} +\begin{key}{/tikz/transparency group=\oarg{options}} This option can be given to a |scope|. It will have the following - effect: The scope's contents is stroked/filled + effect: The scope's contents is stroked\,/\penalty0\,filled ``ignoring any outside transparency.'' This means, all previous transparency settings are ignored (you can still set transparency inside the group, but never mind). For instance, in the forbidden @@ -623,15 +806,93 @@ Transparency groups are used to render them correctly: is just red at the end, so this red color will be blended with whatever is ``behind'' the group on the page. - Note that, depending on the driver, it is possible to directly put - objects in a transparency group that lie outside the picture. This - has to do with internal bounding box computations. - Section~\ref{section-transparency} explains how to sidestep this - problem. +\begin{codeexample}[] +\begin{tikzpicture} + \pattern[pattern=checkerboard,pattern color=black!15](-1,-1) rectangle (3,1); + \node at (0,0) [forbidden sign,line width=2ex,draw=red,fill=white] {Smoking}; + + \begin{scope}[transparency group,opacity=.5] + \node at (2,0) [forbidden sign,line width=2ex,draw=red,fill=white] + {Smoking}; + \end{scope} +\end{tikzpicture} +\end{codeexample} + + Note that in the example, the |opacity=.5| is not active inside the + transparency group: The group is only established at beginning of + the scope and all options given to the |{scope}| environment are set + before the group is established. To change the opacity \emph{inside} + the group, you need to open another scope inside it or use the + |opacity| key with a command inside the group: + +\begin{codeexample}[] +\begin{tikzpicture} + \pattern[pattern=checkerboard,pattern color=black!15](-1,-1) rectangle (3,1); + \node at (0,0) [forbidden sign,line width=2ex,draw=red,fill=white] {Smoking}; + + \begin{scope}[transparency group,opacity=.5] + \node (s) at (2,0) [forbidden sign,line width=2ex,draw=red,fill=white] + {Smoking}; + + \draw [opacity=.5, line width=2ex, blue] (1.2,0) -- (2.8,0); + \end{scope} +\end{tikzpicture} +\end{codeexample} + + The \meta{options} are a list of comma-separated options: + \begin{itemize} + \item \declare{|knockout|} When this option is given inside the + \meta{options}, the group becomes a so-called \emph{knockout} + group. This means, essentially, that inside the group everything + is painted as if the ``opacity'' of a line or area were just + another color channel. In particular, if you paint a pixel with + opacity $0$ inside a knockout group, this pixel becomes perfectly + transparent immediately. In contrast, painting a pixel with + something of opacity 0 normally has no effect. + + Not all renderers, let alone printers, will support + this. At the time of writing, Apple's Preview will not show the + following correctly (you should see the text \tikzname\ in the + middle): +\begin{codeexample}[] +\begin{tikzpicture} + \shade [left color=red,right color=blue] (-2,-1) rectangle (2,1); + \begin{scope}[transparency group=knockout] + \fill [white] (-1.9,-.9) rectangle (1.9,.9); + \node [opacity=0,font=\fontfamily{ptm}\fontsize{45}{45}\bfseries] + {Ti\emph{k}Z}; + \end{scope} +\end{tikzpicture} +\end{codeexample} + In the example, we first draw a large shading and then, inside the + transparency group ``overwrite'' most of this shading by a big + white rectangle. The interesting part is the text of the node, + which has opacity |0|. Normally, this would mean that nothing is + shown. However, in a knockout group, we ``paint'' the text with an + ``opacity zero'' color. The effect is that part of the totally + opaque white rectangle gets overwritten by a perfectly transparent + area (namely exactly the area taken up by the pixels of the + text). When this whole knockout group is then placed on top of the + shading, the shading will ``shine through'' at the knocked-out + pixels. + + \item \declare{|isolated|}|=false| A group can be isolated or + not. By default, they are isolated, since this is typically what you + want. For details on what isolated groups are, exactly, see + Section~7.3.4 of the \textsc{pdf} Specification, version 1.7. + \end{itemize} + + Note that when a transparency group is created, \tikzname\ must + correctly determine the size of the material inside the + group. Usually, this is no problem, but when you use things like + |overlay| or |transform canvas|, trouble may result. In this case, + please consult Section~\ref{section-transparency} on how to sidestep + this problem in such cases. \end{key} + %%% Local Variables: %%% mode: latex %%% TeX-master: "pgfmanual" diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-trees.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-trees.tex index ac0a00bda5f..cdf2cf45456 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-trees.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tikz-trees.tex @@ -32,7 +32,7 @@ not downward as above. You can tell whether the author of a paper is a mathematician or a computer scientist by looking at the direction their trees grow. A computer scientist's trees will grow downward while a mathematician's tree will grow upward. Naturally, the -\emph{correct} way is the mathematician's way, which can be specify as +\emph{correct} way is the mathematician's way, which can be specified as follows: \begin{codeexample}[] \begin{tikzpicture} @@ -45,6 +45,12 @@ follows: \end{tikzpicture} \end{codeexample} +In \tikzname, there are two ways of specifying trees: Using either the +|graph| path operation, which is covered in +Section~\ref{section-library-graphs}, or using the |child| path +operation, which is covered in the present section. Both methods have +their advantages. + In \tikzname, trees are specified by adding \emph{children} to a node on a path using the |child| operation: @@ -86,7 +92,7 @@ node {root} child [red] foreach \name in {1,2} {node {\name}} \end{codeexample} the effect will be the same as if you had said \begin{codeexample}[code only] -node {root} child[red] {node {1}} child[ref] {node {2}} +node {root} child[red] {node {1}} child[red] {node {2}} \end{codeexample} When you write \begin{codeexample}[code only] @@ -114,7 +120,7 @@ node {root} child[left] {node[left] {1}} child[right] {node[right] {2}} -\subsection{Child Paths and the Child Nodes} +\subsection{Child Paths and Child Nodes} For each |child| of a root node, its \meta{child path} is inserted at a specific location in the picture (the placement rules are discussed @@ -133,9 +139,9 @@ the second child, no child node is specified and, thus, it is just As for any normal node, you can give the child node a name, shift it around, or use options to influence how it is rendered. \begin{codeexample}[] -\begin{tikzpicture} +\begin{tikzpicture}[sibling distance=15mm] \node[rectangle,draw] {root} - child {node[circle,draw] (left node) {left}} + child {node[circle,draw,yshift=-5mm] (left node) {left}} child {node[ellipse,draw] (right node) {right}}; \draw[dashed,->] (left node) -- (right node); \end{tikzpicture} @@ -208,7 +214,7 @@ first and/or second child of |parent|. Here is an example: \begin{codeexample}[] -\begin{tikzpicture} +\begin{tikzpicture}[sibling distance=15mm] \node (root) {root} child child { @@ -231,7 +237,8 @@ example: \begin{codeexample}[] \begin{tikzpicture} - [thick,level 2/.style={sibling distance=10mm}] + [thick,level 1/.style={sibling distance=15mm}, + level 2/.style={sibling distance=10mm}] \coordinate child[red] {child child} child[green] {child child[blue]}; @@ -284,16 +291,16 @@ Here is the set of rules: \begin{codeexample}[code only] \begin{tikzpicture} - \path - [...] % Options apply to the whole tree - node[...] {root} % Options apply to the root node only - [...] % Options apply to all children - child[...] % Options apply to this child and all its children - { - node[...] {} % Options apply to the child node only - ... - } - child[...] % Options apply to this child and all its children + \scoped + [...] % Options apply to the whole tree + \node[...] {root} % Options apply to the root node only + [...] % Options apply to all children + child[...] % Options apply to this child and all its children + { + node[...] {} % Options apply to the child node only + ... + } + child[...] % Options apply to this child and all its children ; \end{tikzpicture} \end{codeexample} @@ -358,7 +365,9 @@ evenly spaced or their centers are evenly distributed. Calculating good positions is especially difficult since a good position for the first child may depend on the size of the last child. -In \tikzname, a comparatively simple approach is taken to placing the +In basic \tikzname, when you do not make use of the graph drawing +facilities explained in Part~\ref{part-gd}, a comparatively simple +approach is taken to placing the children. In order to compute a child's position, all that is taken into account is the number of the current child in the list of children and the number of children in this list. Thus, if a node has @@ -391,7 +400,7 @@ is given by the |level distance|. {\catcode`\|=12 \begin{codeexample}[] -\begin{tikzpicture} +\begin{tikzpicture}[sibling distance=15mm, level distance=15mm] \path [help lines] node (root) {root} [grow=-10] @@ -637,7 +646,7 @@ will not be rendered. \end{codeexample} In the next example, the top and bottom nodes are aligned at the top - and the bottom. + and the bottom, respectively. \begin{codeexample}[] \begin{tikzpicture} [level distance=2cm,growth parent anchor=north, @@ -662,7 +671,7 @@ will not be rendered. The effect of executing the macro should be the following: It should transform the coordinate system in such a way that the origin becomes the place where the current child should be anchored. When - the macro is called, the current coordinate system will be setup + the macro is called, the current coordinate system will be set up such that the anchor of the parent node is in the origin. Thus, in each call, the \meta{macro name} must essentially do a shift to the child's origin. When the macro is called, the \TeX\ counter @@ -690,18 +699,34 @@ edge called the |edge from parent|. This edge is added to the \begin{pathoperation}{edge from parent}{\opt{\oarg{options}}} This path operation can only be used inside \meta{child paths} and - should be given at the end, possibly followed by node specifications - (we will come to that). If a \meta{child path} does not contain this - operation, it will be added at the end of the \meta{child path} - automatically. - - This operation has several effects. The most important is that it - inserts the current ``edge from parent path'' into the child - path. The edge from parent path can be set using the following - key: + should be given at the end, possibly followed by \meta{node + specifications} like |node {a}|. If a \meta{child path} does not + contain this operation, it will be added at the end of the + \meta{child path} automatically. + + By default, this operation does the following: + \begin{enumerate} + \item The following style is executed: + \begin{stylekey}{/tikz/edge from parent (initially draw)} + This style is inserted right before the |edge from parent path| and + before the \meta{options} are inserted. +\begin{codeexample}[] +\begin{tikzpicture} + [edge from parent/.style={draw,red,thick}] + \node {root} + child {node {left} edge from parent[dashed]} + child {node {right} + child {node {child}} + child {node {child} edge from parent[draw=none]} + }; +\end{tikzpicture} +\end{codeexample} + \end{stylekey} + \item Next, the \meta{options} are executed. + \item Next, the text stored in the following key is inserted: \begin{key}{/tikz/edge from parent path=\meta{path} (initially \normalfont code shown below)} - This options allows you to set the edge from parent path to a new + This option allows you to set the |edge from parent path| to a new path. Initially, this path is the following: \begin{codeexample}[code only] (\tikzparentnode\tikzparentanchor) -- (\tikzchildnode\tikzchildanchor) @@ -719,7 +744,8 @@ edge called the |edge from parent|. This edge is added to the effects. For example, we could replace the straight line by a curve as follows: \begin{codeexample}[] -\begin{tikzpicture}[edge from parent path= +\begin{tikzpicture}[level distance=15mm, sibling distance=15mm, + edge from parent path= {(\tikzparentnode.south) .. controls +(0,-1) and +(0,1) .. (\tikzchildnode.north)}] \node {root} @@ -731,71 +757,14 @@ edge called the |edge from parent|. This edge is added to the \end{tikzpicture} \end{codeexample} - Further useful edge from parent paths are defined in the tree + Further useful |edge from parent path|s are defined in the tree library, see Section~\ref{section-tree-library}. - \end{key} - - As said before, the anchors in the default edge from parent path - are empty. However, you can set them using the following keys: - \begin{key}{/tikz/child anchor=\meta{anchor} (initially border)} - Specifies the anchor where the edge from parent meets the child - node by setting the macro |\tikzchildanchor| to - |.|\meta{anchor}. - - If you specify |border| as the \meta{anchor}, then the macro - |\tikzchildanchor| is set to the empty string. The effect of - this is that the edge from the parent will meet the child on the - border at an automatically calculated position. -\begin{codeexample}[] -\begin{tikzpicture} - \node {root} - [child anchor=north] - child {node {left} edge from parent[dashed]} - child {node {right} - child {node {child}} - child {node {child} edge from parent[draw=none]} - }; -\end{tikzpicture} -\end{codeexample} - \end{key} - - \begin{key}{/tikz/parent anchor=\meta{anchor} (initially border)} - This option works the same way as the |child anchor|, only for - the parent. - \end{key} - - Besides inserting the edge from parent path, the |edge from parent| - operation has another effect: The \meta{options} are inserted - directly before the edge from parent path and the following style is - also installed prior to inserting the path: - \begin{stylekey}{/tikz/edge from parent (initially draw)} - This style is inserted right before the edge from parent path and - before the \meta{options} are inserted. -\begin{codeexample}[] -\begin{tikzpicture} - [edge from parent/.style={draw,red,thick}] - \node {root} - child {node {left} edge from parent[dashed]} - child {node {right} - child {node {child}} - child {node {child} edge from parent[draw=none]} - }; -\end{tikzpicture} -\end{codeexample} - \end{stylekey} - - Note: The \meta{options} inserted before the edge from parent path - is added \emph{apply to the whole child path}. Thus, it is not - possible to, say, draw a circle in red as part of the child path and - then have an edge to parent in blue. However, as always, the child - node is a node and can be drawn in a totally different way. + + The nodes in a \meta{node specification} following the + |edge from parent| path command get executed as if the |pos| option + had been added to all these nodes, see also Section~\ref{section-pos-option}. - Finally, the |edge from parent| operation has one more effect: It - causes all nodes \emph{following} the operation to be placed on the - edge. This is the same effect as if you had added the |pos| option - to all these nodes, see also Section~\ref{section-pos-option}. - - As an example, consider the following code: + As an example, consider the following code: \begin{codeexample}[code only] \node (root) {} child {node (child) {} edge to parent node {label}}; \end{codeexample} @@ -805,7 +774,7 @@ edge called the |edge from parent|. This edge is added to the (root) -- (child) node [pos=0.5] {label} \end{codeexample} - Here is a more complicated example: + Here is a more complicated example: \begin{codeexample}[] \begin{tikzpicture} \node {root} @@ -828,7 +797,64 @@ edge called the |edge from parent|. This edge is added to the }; \end{tikzpicture} \end{codeexample} + + As said before, the anchors in the default |edge from parent path| + are empty. However, you can set them using the following keys: + \begin{key}{/tikz/child anchor=\meta{anchor} (initially border)} + Specifies the anchor where the edge from parent meets the child + node by setting the macro |\tikzchildanchor| to + |.|\meta{anchor}. + If you specify |border| as the \meta{anchor}, then the macro + |\tikzchildanchor| is set to the empty string. The effect of + this is that the edge from the parent will meet the child on the + border at an automatically calculated position. +\begin{codeexample}[] +\begin{tikzpicture} + \node {root} + [child anchor=north] + child {node {left} edge from parent[dashed]} + child {node {right} + child {node {child}} + child {node {child} edge from parent[draw=none]} + }; +\end{tikzpicture} +\end{codeexample} + \end{key} + + \begin{key}{/tikz/parent anchor=\meta{anchor} (initially border)} + This option works the same way as the |child anchor|, only for + the parent. + \end{key} + \end{key} + \end{enumerate} + + All of the above describes the standard functioning of the + |edge from parent| command. You may, however, sometimes need even + more fine-grained control (the graph drawing engine needs it, for + instance). In such cases the following key gives you complete + control: + \begin{key}{/tikz/edge from parent macro=\meta{macro}} + The \meta{macro} gets expanded each time the |edge from parent| + path operation is used. This \meta{macro} must take two parameters + and must expand to some text that is subsequently parsed by the + parser. The first parameter will be the set of \meta{options} that + where passed to the |edge from parent| command, the second + parameter will be the \meta{node specifications} that following + the command. + + The standard behaviour of drawing a straight line from the parent + node to the child node could be achieved by setting the + \meta{macro} to the following: +\begin{codeexample}[code only] +\def\mymacro#1#2{ + [style=edge from parent, #1] + (\tikzparentnode\tikzparentanchor) -- #2 (\tikzchildnode\tikzchildanchor) +} +\end{codeexample} + Note that |#2| is placed between |--| and the node to ensure that + nodes are put ``on top'' of the line. + \end{key} \end{pathoperation} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-Euclid.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-Euclid.tex index 2ca446abecc..e8717cf9718 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-Euclid.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-Euclid.tex @@ -106,9 +106,7 @@ Let us have a look at how Euclid can turn this into \tikzname\ code. As in the previous tutorials, Euclid needs to load \tikzname, together with some libraries. These libraries are |calc|, |intersections|, -|through|, and |backgrounds|. Depending on which format\footnote{Note - that \pgfname/\tikzname{} is not supported by recent Con\TeX t versions - (like mark IV, the Lua\TeX-aware part of Con\TeX t).} he uses, +|through|, and |backgrounds|. Depending on which format he uses, Euclid would use one of the following in the preamble: \begin{codeexample}[code only] @@ -200,7 +198,7 @@ The new code for the coordinates is the following: \end{codeexample} Note that if a coordinate in such a computation has a factor (like -|.1|) you must place a |*| directly before the opening parenthesis of +|.1|), you must place a |*| directly before the opening parenthesis of the coordinate. You can nest such computations. @@ -545,7 +543,7 @@ The computation of the point $D$ in Euclid's second proposition is a bit more complicated. It can be expressed as follows: Consider the line from $X$ to $B$. Suppose we rotate this line around $X$ for 90$^\circ$ and then stretch it by a -factor of $\sin(60^\circ)/2$. This yields the desired point~$D$. We +factor of $\sin(60^\circ) \cdot 2$. This yields the desired point~$D$. We can do the stretching using the partway modifier above, for the rotation we need a new modifier: the rotation modifier. The idea is that the second coordinate in a partway computation can be prefixed by @@ -610,11 +608,11 @@ computation has the form \meta{p}|!|\meta{factor}|!|\meta{q}, resulting in the point $(1-\meta{factor})\meta{p} + \meta{factor}\meta{q}$. Alternatively, instead of \meta{factor} you can also use a \meta{dimension} between the points. In this case, you -get the point that is \meta{dimension} removed from \meta{p} on the +get the point that is \meta{dimension} away from \meta{p} on the straight line to \meta{q}. We know that the point $G$ is on the way from $B$ to $F$. The distance -is given by the radius of the circle~$H$. Here is the code form +is given by the radius of the circle~$H$. Here is the code for computing $H$: {\tikzexternaldisable \begin{codeexample}[pre={ diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-chains.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-chains.tex index 725702513fb..e6b05fd6bd7 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-chains.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-chains.tex @@ -8,9 +8,9 @@ % See the file doc/generic/pgf/licenses/LICENSE for more details. -\section{Tutorial: Putting a Diagram in Chains} +\section{Tutorial: Diagrams as Simple Graphs} -In this tutorial we have a look at how chains and matrices can be used +In this tutorial we have a look at how graphs and matrices can be used to typeset a diagram. Ilka, who just got tenure for her professorship on Old and @@ -155,7 +155,7 @@ perhaps a bit cleaner and perhaps also bit ``cooler.'' \end{tikzpicture} }\medskip -Having read the previous tutorials, Ilka knows already how to setup +Having read the previous tutorials, Ilka knows already how to set up the environment for her diagram, namely using a |tikzpicture| environment. She wonders which libraries she will need. She decides that she will postpone the decision and add the necessary libraries as @@ -205,7 +205,7 @@ text. By giving this option to all nodes, they will all have the same height of 6mm. Styling the terminals is a bit more difficult because of the round -corners. Ilka has several options how she can achieve them. Once way +corners. Ilka has several options how she can achieve them. One way is to use the |rounded corners| option. It gets a dimension as parameter and causes all corners to be replaced by little arcs with the given dimension as radius. By setting the radius to 3mm, she will @@ -379,7 +379,7 @@ A third way is to use matrices, which we will do later. Now that the nodes have been placed, Ilka needs to add connections. Here, some connections are more difficult than -other. Consider for instance the ``repeat'' line around the +others. Consider for instance the ``repeat'' line around the |digit|. One way of describing this line is to say ``it starts a little to the right of |digit| than goes down and then goes to the left and finally ends at a point a little to the left of |digit|.'' @@ -405,11 +405,11 @@ Ilka can put this into code as follows: \end{tikzpicture} \end{codeexample} -Since Ilka needs this ``go up/down then horizontally and than up/down +Since Ilka needs this ``go up/down then horizontally and then up/down to a target'' several times, it seems sensible to define a special \emph{to-path} for this. Whenever the |edge| command is used, it simply adds the current value of |to path| to the path. So, Ilka can -setup a style that contains the correct path: +set up a style that contains the correct path: \begin{codeexample}[] \begin{tikzpicture}[node distance=5mm and 5mm, skip loop/.style={to path={-- ++(0,-.5) -| (\tikztotarget)}}] @@ -488,285 +488,521 @@ where she would like connections to start and end. skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}}] \matrix[row sep=1mm,column sep=2mm] { % First row: - & & & & & & & & & & & \node [terminal] {+};\\ + & & & & & & & & & & & \node (plus) [terminal] {+};\\ % Second row: - \node (p1) [point] {}; & \node [nonterminal] {unsigned integer}; & - \node (p2) [point] {}; & \node [terminal] {.}; & - \node (p3) [point] {}; & \node [terminal] {digit}; & - \node (p4) [point] {}; & \node (p5) [point] {}; & - \node (p6) [point] {}; & \node [terminal] {E}; & - \node (p7) [point] {}; & & - \node (p8) [point] {}; & \node [nonterminal] {unsigned integer}; & - \node (p9) [point] {}; \\ + \node (p1) [point] {}; & \node (ui1) [nonterminal] {unsigned integer}; & + \node (p2) [point] {}; & \node (dot) [terminal] {.}; & + \node (p3) [point] {}; & \node (digit) [terminal] {digit}; & + \node (p4) [point] {}; & \node (p5) [point] {}; & + \node (p6) [point] {}; & \node (e) [terminal] {E}; & + \node (p7) [point] {}; & & + \node (p8) [point] {}; & \node (ui2) [nonterminal] {unsigned integer}; & + \node (p9) [point] {}; & \node (p10) [point] {};\\ % Third row: - & & & & & & & & & & & \node [terminal] {-};\\ + & & & & & & & & & & & \node (minus)[terminal] {-};\\ }; \path (p4) edge [->,skip loop=-5mm] (p3) (p2) edge [->,skip loop=5mm] (p6); \end{tikzpicture} \end{codeexample} -Now, its only a small step to add all the missing edges. +Now, it's only a small step to add all the missing edges. -\subsection{Using Chains} +\subsection{The Diagram as a Graph} Matrices allow Ilka to align the nodes nicely, but the connections are not quite perfect. The problem is that the code does not really -reflect the paths that underlie the diagram. - - -For this reason, Ilka decides to try out \emph{chains} by including -the |chain| library. Basically, a chain is just a sequence of -(usually) connected nodes. The nodes can already have been constructed -or they can be constructed as the chain is constructed (or these -processes can be mixed). - -\subsubsection{Creating a Simple Chain} - - -Ilka starts with creating a chain from scratch. For this, she starts a -chain using the |start chain| option in a scope. Then, inside the -scope, she uses the |on chain| option on nodes to add them to the -chain. -\begin{codeexample}[] -\begin{tikzpicture}[start chain,node distance=5mm] - \node [on chain,nonterminal] {unsigned integer}; - \node [on chain,terminal] {.}; - \node [on chain,terminal] {digit}; - \node [on chain,terminal] {E}; - \node [on chain,nonterminal] {unsigned integer}; +reflect the paths that underlie the diagram. For this, it seems +natural enough to Ilka to use the |graph| library since, after all, +connecting nodes by edges is exactly what happens in a graph. +The |graph| library can both be used to connect nodes that have +already been created, but it can also be used to create nodes ``on the +fly'' and these processes can also be mixed. + + +\subsubsection{Connecting Already Positioned Nodes} + +Ilka has already a fine method for positioning her nodes (using a +|matrix|), so all that she needs is an easy way of specifying the +edges. For this, she uses the |\graph| command (which is actually just +a shorthand for |\path graph|). It allows her to write down edges +between them in a simple way (the macro |\matrixcontent| contains +exactly the matrix content from the previous example; no need to +repeat it here): +\def\matrixcontent{ + % First row: + \& \& \& \& \& \& \& \& \& \& \& \node (plus) [terminal] {+};\\ + % Second row: + \node (p1) [point] {}; \& \node (ui1) [nonterminal] {unsigned integer}; \& + \node (p2) [point] {}; \& \node (dot) [terminal] {.}; \& + \node (p3) [point] {}; \& \node (digit) [terminal] {digit}; \& + \node (p4) [point] {}; \& \node (p5) [point] {}; \& + \node (p6) [point] {}; \& \node (e) [terminal] {E}; \& + \node (p7) [point] {}; \& \& + \node (p8) [point] {}; \& \node (ui2) [nonterminal] {unsigned integer}; \& + \node (p9) [point] {}; \& \node (p10) [point] {};\\ + % Third row: + \& \& \& \& \& \& \& \& \& \& \& \node (minus)[terminal] {-};\\ +} +\begin{codeexample}[pre={\tikzset{ampersand replacement=\&,point/.style={coordinate}}}] +\begin{tikzpicture}[skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}}, + hv path/.style={to path={-| (\tikztotarget)}}, + vh path/.style={to path={|- (\tikztotarget)}}] + \matrix[row sep=1mm,column sep=2mm] { \matrixcontent }; + + \graph { + (p1) -> (ui1) -- (p2) -> (dot) -- (p3) -> (digit) -- (p4) + -- (p5) -- (p6) -> (e) -- (p7) -- (p8) -> (ui2) -- (p9) -> (p10); + (p4) ->[skip loop=-5mm] (p3); + (p2) ->[skip loop=5mm] (p5); + (p6) ->[skip loop=-11mm] (p9); + (p7) ->[vh path] (plus) -> [hv path] (p8); + (p7) ->[vh path] (minus) -> [hv path] (p8); + }; \end{tikzpicture} \end{codeexample} -(Ilka will add the plus and minus nodes later.) -As can be seen, the nodes of a chain are placed in a row. This can be -changed, for instance by saying |start chain=going below| we get a -chain where each node is below the previous one. - -The next step is to \emph{join} the nodes of the chain. For this, we -add the |join| option to each node. This joins the node with the -previous node (for the first node nothing happens). -\begin{codeexample}[] -\begin{tikzpicture}[start chain,node distance=5mm] - \node [on chain,join,nonterminal] {unsigned integer}; - \node [on chain,join,terminal] {.}; - \node [on chain,join,terminal] {digit}; - \node [on chain,join,terminal] {E}; - \node [on chain,join,nonterminal] {unsigned integer}; -\end{tikzpicture} -\end{codeexample} -In order to get a arrow tip, we redefine the |every join| style. Also, -we move the |join| and |on chain| options to the |every node| -style so that we do not have to repeat them so often. -\begin{codeexample}[] -\begin{tikzpicture}[start chain,node distance=5mm, every node/.style={on chain,join}, every join/.style={->}] - \node [nonterminal] {unsigned integer}; - \node [terminal] {.}; - \node [terminal] {digit}; - \node [terminal] {E}; - \node [nonterminal] {unsigned integer}; +This is already pretty near to the desired result, just a few +``finishing touches'' are needed to style the edges more nicely. + +However, Ilka does not have the feeling that the |graph| command is +all that hot in the example. It certainly does cut down on the number +of characters she has to write, but the overall graph structure is not +that much clear -- it is still mainly a list of paths through the +graph. It would be nice to specify that, say, there the path from +|(p7)| sort of splits to |(plus)| and |(minus)| and then merges once +more at |(p8)|. Also, all these parentheses are bit hard to type. + +It turns out that edges from a node to a whole group of nodes are +quite easy to specify, as shown in the next example. Additionally, by +using the |use existing nodes| option, Ilka can also leave out all the +parentheses (again, some options have been moved outside to keep the +examples shorter): + +\begin{codeexample}[pre={\tikzset{ampersand replacement=\&,point/.style={coordinate}, + skip loop/.style={to path={-- ++(0,##1) -| (\tikztotarget)}}, + hv path/.style={to path={-| (\tikztotarget)}}, + vh path/.style={to path={|- (\tikztotarget)}}}}] +\begin{tikzpicture}[,>=stealth',thick,black!50,text=black, + every new ->/.style={shorten >=1pt}, + graphs/every graph/.style={edges=rounded corners}] + \matrix[column sep=4mm] { \matrixcontent }; + + \graph [use existing nodes] { + p1 -> ui1 -- p2 -> dot -- p3 -> digit -- p4 -- p5 -- p6 -> e -- p7 -- p8 -> ui2 -- p9 -> p10; + p4 ->[skip loop=-5mm] p3; + p2 ->[skip loop=5mm] p5; + p6 ->[skip loop=-11mm] p9; + p7 ->[vh path] { plus, minus } -> [hv path] p8; + }; \end{tikzpicture} \end{codeexample} -\subsubsection{Branching and Joining a Chain} +\subsubsection{Creating Nodes Using the Graph Command} -It is now time to add the plus and minus signs. They obviously -\emph{branch off} the main chain. For this reason, we start a branch -for them using the |start branch| option. +Ilka has heard that the |graph| command is also supposed to make it +easy to create nodes, not only to connect them. This is, indeed, +correct: When the |use existing node| option is not used and when a +node name is not surrounded by parentheses, then \tikzname\ will +actually create a node whose name and text is the node name: \begin{codeexample}[] -\begin{tikzpicture}[start chain,node distance=5mm, every node/.style={on chain,join}, every join/.style={->}] - \node [nonterminal] {unsigned integer}; - \node [terminal] {.}; - \node [terminal] {digit}; - \node [terminal] {E}; - \begin{scope}[start branch=plus] - \node (plus) [terminal,on chain=going above right] {+}; - \end{scope} - \begin{scope}[start branch=minus] - \node (minus) [terminal,on chain=going below right] {-}; - \end{scope} - \node [nonterminal,join=with plus,join=with minus] {unsigned integer}; -\end{tikzpicture} +\tikz \graph [grow right=2cm] { unsigned integer -> d -> digit -> E }; \end{codeexample} - -Let us see, what is going on here. First, the |start branch| begins a -branch, starting with the node last created on the current chain, -which is the |E| node in our case. This is implicitly also the first -node on this branch. A branch is nothing different from a chain, which -is why the plus node is put on this branch using the |on chain| -option. However, this time we specify the placement of the node -explicitly using |going |\meta{direction}. This causes the plus sign -to be placed above and right of the |E| node. It is automatically -joined to its predecessor on the branch by the implicit |join| -option. - -When the first branch ends, only the plus node has been added and the -current chain is the original chain once more and we are back to the -|E| node. Now we start a new branch for the minus node. After this -branch, the current chain ends at |E| node once more. - -Finally, the rightmost unsigned integer is added to the (main) chain, -which is why it is joined correctly with the |E| node. The two -additional |join| options get a special |with| parameter. This allows -you to join a node with a node other than the predecessor on the -chain. The |with| should be followed by the name of a node. - -Since Ilka will need scopes more often in the following, she includes -the |scopes| library. This allows her to replace |\begin{scope}| - simply by an opening brace and |\end{scope}| by the corresponding -closing brace. Also, in the following example we reference -the nodes |plus| and |minus| using -their automatic name: The $i$th node on a chain is called -|chain-|\meta{i}. For a branch \meta{branch}, the $i$th node is called -|chain/|\meta{branch}|-|\meta{i}. The \meta{i} can be replaced by -|begin| and |end| to reference the first and (currently) last node on -the chain. - +Not quite perfect, but we are getting somewhere. First, let us change +the positioning algorithm by saying |grow right sep|, which causes new +nodes to be placed to the right of the previous nodes with a certain +fixed separation (|1em| by default). Second, we add some options to +make the node ``look nice''. Third, note the funny |d| node above: Ilka +tried writing just |.| there first, but got some error messages. The +reason is that a node cannot be called |.| in \tikzname, so she had to +choose a different name -- which is not good, since she wants a dot to +be shown! The trick is to put the dot in quotation marks, this allows +you to use ``quite arbitrary text'' as a node name: \begin{codeexample}[] -\begin{tikzpicture}[start chain,node distance=5mm, every on chain/.style={join}, every join/.style={->}] - \node [on chain,nonterminal] {unsigned integer}; - \node [on chain,terminal] {.}; - \node [on chain,terminal] {digit}; - \node [on chain,terminal] {E}; - { [start branch=plus] - \node (plus) [terminal,on chain=going above right] {+}; - } - { [start branch=minus] - \node (minus) [terminal,on chain=going below right] {-}; - } - \node [nonterminal,on chain,join=with chain/plus-end,join=with chain/minus-end] {unsigned integer}; -\end{tikzpicture} +\tikz \graph [grow right sep] { + unsigned integer[nonterminal] -> "."[terminal] -> digit[terminal] -> E[terminal] +}; \end{codeexample} - - -The next step is to add intermediate coordinate nodes in the same -manner as Ilka did for the matrix. For them, we change the |join| -style slightly, namely for these nodes we do not want an arrow -tip. This can be achieved either by (locally) changing the -|every join| style or, which is what is done in the below example, by -giving the desired style using |join=by ...|, where |...| is the style -to be used for the join. - +Now comes the fork to the plus and minus signs. Here, Ilka can use the +grouping mechanism of the |graph| command to create a split: \begin{codeexample}[] -\begin{tikzpicture}[start chain,node distance=5mm and 2mm, - every node/.style={on chain}, - nonterminal/.append style={join=by ->}, - terminal/.append style={join=by ->}, - point/.style={join=by -,circle,fill=red,minimum size=2pt,inner sep=0pt}] - \node [point] {}; \node [nonterminal] {unsigned integer}; - \node [point] {}; \node [terminal] {.}; - \node [point] {}; \node [terminal] {digit}; - \node [point] {}; \node [point] {}; - \node [point] {}; \node [terminal] {E}; - \node [point] {}; - { [node distance=5mm and 1cm] % local change in horizontal distance - { [start branch=plus] - \node (plus) [terminal,on chain=going above right] {+}; - } - { [start branch=minus] - \node (minus) [terminal,on chain=going below right] {-}; - } - \node [point,below right=of plus,join=with chain/plus-end by ->,join=with chain/minus-end by ->] {}; - } - \node [nonterminal] {unsigned integer}; - \node [point] {}; -\end{tikzpicture} +\tikz \graph [grow right sep] { + unsigned integer [nonterminal] -> + "." [terminal] -> + digit [terminal] -> + E [terminal] -> + { + "+" [terminal], + "" [coordinate], + "-" [terminal] + } -> + ui2/unsigned integer [nonterminal] +}; \end{codeexample} - - -\subsubsection{Chaining Together Already Positioned Nodes} - -The final step is to add the missing arrows. We can also use branches -for them (even though we do not have to, but it is good practice and -they exhibit the structure of the diagram in the code). - -Let us start with the repeat loop around the |digit|. This can be -thought of as a branch that starts at the point after the digit and -that ends at the point before the digit. However, we have already -constructed the point before the digit! In such cases, it is possible -to ``chain in'' an already positioned node, using the |\chainin| -command. This command must be followed by a coordinate that contains a -node name and optionally some options. The effect is that the named -node is made part of the current chain. - -\begin{codeexample}[pre={\tikzset{node distance=5mm and 2mm, - every node/.style={on chain}, - terminal/.append style={join=by ->}, - point/.style={join=by -,circle,fill=red,minimum size=2pt,inner sep=0pt}}}] -\begin{tikzpicture}[start chain] % plus some styles that are not shown - \node [point] {}; - \node (before digit) [point] {}; - \node [terminal] {digit}; - \node [point] {}; - { [start branch=digit loop] - \chainin (before digit) [join=by {->,skip loop=-5mm}]; - } - \node [point] {}; +Let us see, what is happening here. We want two |unsigned integer| +nodes, but if we just were to use this text twice, then \tikzname\ +would have noticed that the same name was used already in the current +graph and, being smart (actually too smart in this case), would have +created an edge back to the already-created node. Thus, a fresh name +is needed here. However, Ilka also cannot just write +|unsigned integer2|, because she wants the original text to be shown, +after all! The trick is to use a slash inside the node name: In +order to ``render'' the node, the text following the slash +is used instead of the node name, which is the text before the +slash. Alternatively, the |as| option can be used, which also +allows you to specify how a node should be rendered. + +It turns out that Ilka does not need to invent a name like +|ui2| for a node that she will not reference again +anyway. In this case, she can just leave out the name (write nothing +before |/|), which always stands for a ``fresh, anonymous'' node name. + +Next, Ilka needs to add some coordinates in between of some nodes +where the back-loops should got and she needs to shift the nodes a +bit: +\begin{codeexample}[pre={\tikzset{ + skip loop/.style={to path={-- ++(0,##1) -| (\tikztotarget)}}, + hv path/.style={to path={-| (\tikztotarget)}}, + vh path/.style={to path={|- (\tikztotarget)}}}}] +\begin{tikzpicture}[>=stealth', thick, black!50, text=black, + every new ->/.style={shorten >=1pt}, + graphs/every graph/.style={edges=rounded corners}] + \graph [grow right sep, branch down=7mm] { + / [coordinate] -> + unsigned integer [nonterminal] -- + p1 [coordinate] -> + "." [terminal] -- + p2 [coordinate] -> + digit [terminal] -- + p3 [coordinate] -- + p4 [coordinate] -- + p5 [coordinate] -> + E [terminal] -- + q1 [coordinate] ->[vh path] + { [nodes={yshift=7mm}] + "+" [terminal], + q2/ [coordinate], + "-" [terminal] + } -> [hv path] + q3 [coordinate] -- + /unsigned integer [nonterminal] -- + p6 [coordinate] -> + / [coordinate]; + + p1 ->[skip loop=5mm] p4; + p3 ->[skip loop=-5mm] p2; + p5 ->[skip loop=-11mm] p6; + }; \end{tikzpicture} \end{codeexample} - -\subsubsection{Combined Use of Matrices and Chains} - -Ilka's final idea is to combine matrices and chains in the following -manner: She will use a matrix to position the nodes. However, to show -the logical ``flow structure'' inside the diagram, she will create -chains and branches that show what is going on. - -Ilka starts with the matrix we had earlier, only with slightly adapted -styles. Then she writes down the main chain and its branches: - +All that remains to be done is to somehow get rid of the strange +curves between the |E| and the unsigned integer. They are caused by +\tikzname's attempt at creating an edge that first goes vertical and +then horizontal but is actually just horizontal. Additionally, the +edge should not really be pointed; but it seems difficult to get rid +of this since the \emph{other} edges from |q1|, namely to |plus| and +|minus| should be pointed. + +It turns out that there is a nice way of solving this problem: You can +specify that a graph is |simple|. This means that there can be at most +one edge between any two nodes. Now, if you specify an edge twice, the +options of the second specification ``win.'' Thus, by adding two more +lines that ``correct'' these edges, we get the final diagram with its +complete code: \begin{codeexample}[] -\begin{tikzpicture}[point/.style={coordinate},>=stealth',thick,draw=black!50, - tip/.style={->,shorten >=1pt},every join/.style={rounded corners}, - hv path/.style={to path={-| (\tikztotarget)}}, - vh path/.style={to path={|- (\tikztotarget)}}] - \matrix[column sep=4mm] { - % First row: - & & & & & & & & & & & \node (plus) [terminal] {+};\\ - % Second row: - \node (p1) [point] {}; & \node (ui1) [nonterminal] {unsigned integer}; & - \node (p2) [point] {}; & \node (dot) [terminal] {.}; & - \node (p3) [point] {}; & \node (digit) [terminal] {digit}; & - \node (p4) [point] {}; & \node (p5) [point] {}; & - \node (p6) [point] {}; & \node (e) [terminal] {E}; & - \node (p7) [point] {}; & & - \node (p8) [point] {}; & \node (ui2) [nonterminal] {unsigned integer}; & - \node (p9) [point] {}; & \node (p10) [point] {};\\ - % Third row: - & & & & & & & & & & & \node (minus)[terminal] {-};\\ +\tikz [>=stealth', black!50, text=black, thick, + every new ->/.style = {shorten >=1pt}, + graphs/every graph/.style = {edges=rounded corners}, + skip loop/.style = {to path={-- ++(0,#1) -| (\tikztotarget)}}, + hv path/.style = {to path={-| (\tikztotarget)}}, + vh path/.style = {to path={|- (\tikztotarget)}}, + nonterminal/.style = { + rectangle, minimum size=6mm, very thick, draw=red!50!black!50, top color=white, + bottom color=red!50!black!20, font=\itshape, text height=1.5ex,text depth=.25ex}, + terminal/.style = { + rounded rectangle, minimum size=6mm, very thick, draw=black!50, top color=white, + bottom color=black!20, font=\ttfamily, text height=1.5ex, text depth=.25ex}, + shape = coordinate + ] + \graph [grow right sep, branch down=7mm, simple] { + / -> unsigned integer[nonterminal] -- p1 -> "." [terminal] -- p2 -> digit[terminal] -- + p3 -- p4 -- p5 -> E[terminal] -- q1 ->[vh path] + {[nodes={yshift=7mm}] + "+"[terminal], q2, "-"[terminal] + } -> [hv path] + q3 -- /unsigned integer [nonterminal] -- p6 -> /; + + p1 ->[skip loop=5mm] p4; + p3 ->[skip loop=-5mm] p2; + p5 ->[skip loop=-11mm] p6; + + q1 -- q2 -- q3; % make these edges plain }; - - { [start chain] - \chainin (p1); - \chainin (ui1) [join=by tip]; - \chainin (p2) [join]; - \chainin (dot) [join=by tip]; - \chainin (p3) [join]; - \chainin (digit) [join=by tip]; - \chainin (p4) [join]; - { [start branch=digit loop] - \chainin (p3) [join=by {skip loop=-6mm,tip}]; - } - \chainin (p5) [join,join=with p2 by {skip loop=6mm,tip}]; - \chainin (p6) [join]; - \chainin (e) [join=by tip]; - \chainin (p7) [join]; - { [start branch=plus] - \chainin (plus) [join=by {vh path,tip}]; - \chainin (p8) [join=by {hv path,tip}]; - } - { [start branch=minus] - \chainin (minus) [join=by {vh path,tip}]; - \chainin (p8) [join=by {hv path,tip}]; - } - \chainin (p8) [join]; - \chainin (ui2) [join=by tip]; - \chainin (p9) [join,join=with p6 by {skip loop=-11mm,tip}]; - \chainin (p10) [join=by tip]; - } -\end{tikzpicture} \end{codeexample} + + + +% \subsection{Using Chains} + +% Matrices allow Ilka to align the nodes nicely, but the connections are +% not quite perfect. The problem is that the code does not really +% reflect the paths that underlie the diagram. + + +% For this reason, Ilka decides to try out \emph{chains} by including +% the |chain| library. Basically, a chain is just a sequence of +% (usually) connected nodes. The nodes can already have been constructed +% or they can be constructed as the chain is constructed (or these +% processes can be mixed). + +% \subsubsection{Creating a Simple Chain} + + +% Ilka starts with creating a chain from scratch. For this, she starts a +% chain using the |start chain| option in a scope. Then, inside the +% scope, she uses the |on chain| option on nodes to add them to the +% chain. +% \begin{codeexample}[] +% \begin{tikzpicture}[start chain,node distance=5mm] +% \node [on chain,nonterminal] {unsigned integer}; +% \node [on chain,terminal] {.}; +% \node [on chain,terminal] {digit}; +% \node [on chain,terminal] {E}; +% \node [on chain,nonterminal] {unsigned integer}; +% \end{tikzpicture} +% \end{codeexample} +% (Ilka will add the plus and minus nodes later.) + +% As can be seen, the nodes of a chain are placed in a row. This can be +% changed, for instance by saying |start chain=going below| we get a +% chain where each node is below the previous one. + +% The next step is to \emph{join} the nodes of the chain. For this, we +% add the |join| option to each node. This joins the node with the +% previous node (for the first node nothing happens). +% \begin{codeexample}[] +% \begin{tikzpicture}[start chain,node distance=5mm] +% \node [on chain,join,nonterminal] {unsigned integer}; +% \node [on chain,join,terminal] {.}; +% \node [on chain,join,terminal] {digit}; +% \node [on chain,join,terminal] {E}; +% \node [on chain,join,nonterminal] {unsigned integer}; +% \end{tikzpicture} +% \end{codeexample} +% In order to get a arrow tip, we redefine the |every join| style. Also, +% we move the |join| and |on chain| options to the |every node| +% style so that we do not have to repeat them so often. +% \begin{codeexample}[] +% \begin{tikzpicture}[start chain,node distance=5mm, every node/.style={on chain,join}, every join/.style={->}] +% \node [nonterminal] {unsigned integer}; +% \node [terminal] {.}; +% \node [terminal] {digit}; +% \node [terminal] {E}; +% \node [nonterminal] {unsigned integer}; +% \end{tikzpicture} +% \end{codeexample} + + +% \subsubsection{Branching and Joining a Chain} + +% It is now time to add the plus and minus signs. They obviously +% \emph{branch off} the main chain. For this reason, we start a branch +% for them using the |start branch| option. +% \begin{codeexample}[] +% \begin{tikzpicture}[start chain,node distance=5mm, every node/.style={on chain,join}, every join/.style={->}] +% \node [nonterminal] {unsigned integer}; +% \node [terminal] {.}; +% \node [terminal] {digit}; +% \node [terminal] {E}; +% \begin{scope}[start branch=plus] +% \node (plus) [terminal,on chain=going above right] {+}; +% \end{scope} +% \begin{scope}[start branch=minus] +% \node (minus) [terminal,on chain=going below right] {-}; +% \end{scope} +% \node [nonterminal,join=with plus,join=with minus] {unsigned integer}; +% \end{tikzpicture} +% \end{codeexample} + +% Let us see, what is going on here. First, the |start branch| begins a +% branch, starting with the node last created on the current chain, +% which is the |E| node in our case. This is implicitly also the first +% node on this branch. A branch is nothing different from a chain, which +% is why the plus node is put on this branch using the |on chain| +% option. However, this time we specify the placement of the node +% explicitly using |going |\meta{direction}. This causes the plus sign +% to be placed above and right of the |E| node. It is automatically +% joined to its predecessor on the branch by the implicit |join| +% option. + +% When the first branch ends, only the plus node has been added and the +% current chain is the original chain once more and we are back to the +% |E| node. Now we start a new branch for the minus node. After this +% branch, the current chain ends at |E| node once more. + +% Finally, the rightmost unsigned integer is added to the (main) chain, +% which is why it is joined correctly with the |E| node. The two +% additional |join| options get a special |with| parameter. This allows +% you to join a node with a node other than the predecessor on the +% chain. The |with| should be followed by the name of a node. + +% Since Ilka will need scopes more often in the following, she includes +% the |scopes| library. This allows her to replace |\begin{scope}| +% simply by an opening brace and |\end{scope}| by the corresponding +% closing brace. Also, in the following example we reference +% the nodes |plus| and |minus| using +% their automatic name: The $i$th node on a chain is called +% |chain-|\meta{i}. For a branch \meta{branch}, the $i$th node is called +% |chain/|\meta{branch}|-|\meta{i}. The \meta{i} can be replaced by +% |begin| and |end| to reference the first and (currently) last node on +% the chain. + +% \begin{codeexample}[] +% \begin{tikzpicture}[start chain,node distance=5mm, every on chain/.style={join}, every join/.style={->}] +% \node [on chain,nonterminal] {unsigned integer}; +% \node [on chain,terminal] {.}; +% \node [on chain,terminal] {digit}; +% \node [on chain,terminal] {E}; +% { [start branch=plus] +% \node (plus) [terminal,on chain=going above right] {+}; +% } +% { [start branch=minus] +% \node (minus) [terminal,on chain=going below right] {-}; +% } +% \node [nonterminal,on chain,join=with chain/plus-end,join=with chain/minus-end] {unsigned integer}; +% \end{tikzpicture} +% \end{codeexample} + + +% The next step is to add intermediate coordinate nodes in the same +% manner as Ilka did for the matrix. For them, we change the |join| +% style slightly, namely for these nodes we do not want an arrow +% tip. This can be achieved either by (locally) changing the +% |every join| style or, which is what is done in the below example, by +% giving the desired style using |join=by ...|, where |...| is the style +% to be used for the join. + +% \begin{codeexample}[] +% \begin{tikzpicture}[start chain,node distance=5mm and 2mm, +% every node/.style={on chain}, +% nonterminal/.append style={join=by ->}, +% terminal/.append style={join=by ->}, +% point/.style={join=by -,circle,fill=red,minimum size=2pt,inner sep=0pt}] +% \node [point] {}; \node [nonterminal] {unsigned integer}; +% \node [point] {}; \node [terminal] {.}; +% \node [point] {}; \node [terminal] {digit}; +% \node [point] {}; \node [point] {}; +% \node [point] {}; \node [terminal] {E}; +% \node [point] {}; +% { [node distance=5mm and 1cm] % local change in horizontal distance +% { [start branch=plus] +% \node (plus) [terminal,on chain=going above right] {+}; +% } +% { [start branch=minus] +% \node (minus) [terminal,on chain=going below right] {-}; +% } +% \node [point,below right=of plus,join=with chain/plus-end by ->,join=with chain/minus-end by ->] {}; +% } +% \node [nonterminal] {unsigned integer}; +% \node [point] {}; +% \end{tikzpicture} +% \end{codeexample} + + +% \subsubsection{Chaining Together Already Positioned Nodes} + +% The final step is to add the missing arrows. We can also use branches +% for them (even though we do not have to, but it is good practice and +% they exhibit the structure of the diagram in the code). + +% Let us start with the repeat loop around the |digit|. This can be +% thought of as a branch that starts at the point after the digit and +% that ends at the point before the digit. However, we have already +% constructed the point before the digit! In such cases, it is possible +% to ``chain in'' an already positioned node, using the |\chainin| +% command. This command must be followed by a coordinate that contains a +% node name and optionally some options. The effect is that the named +% node is made part of the current chain. + +% \begin{codeexample}[pre={\tikzset{node distance=5mm and 2mm, +% every node/.style={on chain}, +% terminal/.append style={join=by ->}, +% point/.style={join=by -,circle,fill=red,minimum size=2pt,inner sep=0pt}}}] +% \begin{tikzpicture}[start chain] % plus some styles that are not shown +% \node [point] {}; +% \node (before digit) [point] {}; +% \node [terminal] {digit}; +% \node [point] {}; +% { [start branch=digit loop] +% \chainin (before digit) [join=by {->,skip loop=-5mm}]; +% } +% \node [point] {}; +% \end{tikzpicture} +% \end{codeexample} + + +% \subsubsection{Combined Use of Matrices and Chains} + +% Ilka's final idea is to combine matrices and chains in the following +% manner: She will use a matrix to position the nodes. However, to show +% the logical ``flow structure'' inside the diagram, she will create +% chains and branches that show what is going on. + +% Ilka starts with the matrix we had earlier, only with slightly adapted +% styles. Then she writes down the main chain and its branches: + +% \begin{codeexample}[] +% \begin{tikzpicture}[point/.style={coordinate},>=stealth',thick,draw=black!50, +% tip/.style={->,shorten >=1pt},every join/.style={rounded corners}, +% hv path/.style={to path={-| (\tikztotarget)}}, +% vh path/.style={to path={|- (\tikztotarget)}}] +% \matrix[column sep=4mm] { +% % First row: +% & & & & & & & & & & & \node (plus) [terminal] {+};\\ +% % Second row: +% \node (p1) [point] {}; & \node (ui1) [nonterminal] {unsigned integer}; & +% \node (p2) [point] {}; & \node (dot) [terminal] {.}; & +% \node (p3) [point] {}; & \node (digit) [terminal] {digit}; & +% \node (p4) [point] {}; & \node (p5) [point] {}; & +% \node (p6) [point] {}; & \node (e) [terminal] {E}; & +% \node (p7) [point] {}; & & +% \node (p8) [point] {}; & \node (ui2) [nonterminal] {unsigned integer}; & +% \node (p9) [point] {}; & \node (p10) [point] {};\\ +% % Third row: +% & & & & & & & & & & & \node (minus)[terminal] {-};\\ +% }; + +% { [start chain] +% \chainin (p1); +% \chainin (ui1) [join=by tip]; +% \chainin (p2) [join]; +% \chainin (dot) [join=by tip]; +% \chainin (p3) [join]; +% \chainin (digit) [join=by tip]; +% \chainin (p4) [join]; +% { [start branch=digit loop] +% \chainin (p3) [join=by {skip loop=-6mm,tip}]; +% } +% \chainin (p5) [join,join=with p2 by {skip loop=6mm,tip}]; +% \chainin (p6) [join]; +% \chainin (e) [join=by tip]; +% \chainin (p7) [join]; +% { [start branch=plus] +% \chainin (plus) [join=by {vh path,tip}]; +% \chainin (p8) [join=by {hv path,tip}]; +% } +% { [start branch=minus] +% \chainin (minus) [join=by {vh path,tip}]; +% \chainin (p8) [join=by {hv path,tip}]; +% } +% \chainin (p8) [join]; +% \chainin (ui2) [join=by tip]; +% \chainin (p9) [join,join=with p6 by {skip loop=-11mm,tip}]; +% \chainin (p10) [join=by tip]; +% } +% \end{tikzpicture} +% \end{codeexample} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-map.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-map.tex index ec0ea535f38..99a173f9e39 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-map.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-map.tex @@ -43,17 +43,17 @@ Johannes wishes to create a lecture map with the following features: \end{enumerate} As always, Johannes will have to include the right libraries and -setup the environment. Since Johannes is going to use the -|mindmap| library and since he wishes to show a calendar, he will need -the |mindmap| and the |calendar| libraries. In order to put something +set up the environment. Johannes is going to use the +|mindmap| library and since he wishes to show a calendar, he will also need +the |calendar| library. In order to put something on a background layer, it seems like a good idea to also include the -|background| library. +|backgrounds| library. \subsection{Introduction to Trees} The first choice Johannes must make is whether he will organize the -concepts are a tree, with root concepts and concept branches and leaf +concepts as a tree, with root concepts and concept branches and leaf concepts, or as a general graph. The tree implicitly organizes the concepts, while a graph is more flexible. Johannes decides to compromise: Basically, the concepts will be organized as a @@ -229,7 +229,7 @@ a rainy Sunday afternoon, if you are really interested.) The |grow| key is used to configure the direction in which a tree grows. You can change growth direction ``in the middle of a tree'' simply by changing this key for a single child or a whole level. By -including the |tree| library you also get access to additional growth +including the |trees| library you also get access to additional growth strategies such as a ``circular'' growth: @@ -271,7 +271,7 @@ strategies such as a ``circular'' growth: Johannes is pleased to learn that he can access and manipulate the -nodes of tree like any normal node. In particular, he can name them +nodes of the tree like any normal node. In particular, he can name them using the |name=| option or the |(|\meta{name}|)| notation and he can use any available shape or style for the trees nodes. He can connect trees later on using the normal |\draw (some node) -- (another node);| @@ -302,7 +302,7 @@ of a tree will be real concepts, while other nodes might just be ``simple children.'' Typically, this is not the case, so you might consider saying |every node/.style=concept|. -The third step is to setup the sibling \emph{angle} (rather than a +The third step is to set up the sibling \emph{angle} (rather than a sibling distance) to specify the angle between sibling concepts. \begin{codeexample}[render instead={ @@ -449,7 +449,7 @@ of a parent concept smoothly changes to the color of a child concept. For the root concept Johannes decides to do something special: He sets the concept color to black, sets the line width to a large value, and sets the fill color to white. The effect of this is that the root -concept will encircled with a thick black line and the children are +concept will be encircled with a thick black line and the children are connected to the central concept via bars. \begin{codeexample}[render instead={ @@ -530,7 +530,7 @@ of the main concepts to small caps. Second, he decides that some concepts should be ``faded,'' namely those that are important in principle and belong on the map, but which he will not talk about in his lecture. To achieve this, Johannes defines four styles, one for -each of the four main branches. These styles (a) setup the +each of the four main branches. These styles (a) set up the correct concept color for the whole branch and (b) define the |faded| style appropriately for this branch. Third, he adds a |circular drop shadow|, defined in the |shadows| library, to the @@ -621,7 +621,7 @@ qualifications his students should acquire during this particular lecture (note that learning targets are not the same as the contents of a lecture). For each lecture he intends to put a little rectangle on the map containing these learning targets and the name of the -lecture, each time somewhere near to the topic of the lecture. Such +lecture, each time somewhere near the topic of the lecture. Such ``little rectangles'' are called ``annotations'' by the mindmap library. @@ -851,7 +851,7 @@ Johannes would have thought. At first sight, what he needs is some sort of ``color wheel'' that is blue in the lower right direction and then changes smoothly to orange in the upper right direction and then to green in the upper left direction and so on. Unfortunately, there -is no easy way of creating a true such a color wheel shading (although +is no easy way of creating such a color wheel shading (although it can be done, in principle, but only at a very high cost, see page~\pageref{shading-color-wheel} for an example). @@ -923,7 +923,7 @@ subject will be addressed. Johannes intends to share this plan with his students by adding a calendar to the lecture map. In addition to serving as a reference on which particular day a certain topic will be addressed, the -calendar is also useful so show the overall chronological order of the +calendar is also useful to show the overall chronological order of the course. In order to add a calendar to a \tikzname\ graphic, the |calendar| diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-nodes.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-nodes.tex index f9c5eb8de53..b9a97e2046e 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-nodes.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-nodes.tex @@ -14,11 +14,11 @@ In this second tutorial we explore the node mechanism of Hagen must give a talk tomorrow about his favorite formalism for distributed systems: Petri nets! Hagen used to give his talks using a -blackboard and everyone seemed to be perfectly concent with % TODOsp: concent --> consent? +blackboard and everyone seemed to be perfectly content with this. Unfortunately, his audience has been spoiled recently with fancy projector-based presentations and there seems to be a certain amount -of peer pressure that this Petri nets should also be drawn using a -graphic program. One of the professors at his institutes recommends +of peer pressure that his Petri nets should also be drawn using a +graphic program. One of the professors at his institute recommends \tikzname\ for this and Hagen decides to give it a try. @@ -102,10 +102,10 @@ capacities. The graphic should look like this, ideally: edge [post,bend left] node {2} (w2'); \end{scope} - \begin{pgfonlayer}{background} + \begin{scope}[on background layer] \node (r1) [fill=black!10,rounded corners,fit=(w1)(w2)(e1)(e2)(l1)(l2)] {}; \node (r2) [fill=black!10,rounded corners,fit=(w1')(w2')(e1')(e2')(l1')(l2')] {}; - \end{pgfonlayer} + \end{scope} \draw [shorten >=1mm,-to,thick,decorate,decoration={snake,amplitude=.4mm,segment length=2mm,pre=moveto,pre length=1mm,post length=2mm}] @@ -128,7 +128,7 @@ loaded explicitly. Hagen will need to load several libraries: The |arrows| library for the special arrow tip used in the graphic, the |decoration.pathmorphing| -library for the ``snaking line'' in the middle, the background +library for the ``snaking line'' in the middle, the |backgrounds| library for the two rectangular areas that are behind the two main parts of the picture, the |fit| library to easily compute the sizes of these rectangles, and the |positioning| library for placing nodes @@ -173,9 +173,7 @@ When using plain \TeX\ use: \subsubsection{Setting up the Environment in Con\TeX t} -When using Con\TeX\ use\footnote{Note that \pgfname/\tikzname{} is not - supported by recent Con\TeX t versions (like mark IV, the - Lua\TeX-aware part of Con\TeX t).}: +When using Con\TeX, use: \begin{codeexample}[code only] %% ConTeXt file \usemodule[tikz] @@ -201,8 +199,7 @@ However, this approach has numerous disadvantages: First, it is hard to change anything at a later stage. For example, if we decide to add more places to the Petri nets (the circles are called places in Petri net theory), all of the coordinates change and we need to recalculate -everything. Second, it is hard to read the code for the Petri net as -it just a long and complicated list of coordinates and drawing +everything. Second, it is hard to read the code for the Petri net as it is just a long and complicated list of coordinates and drawing commands -- the underlying structure of the Petri net is lost. Fortunately, \tikzname\ offers a powerful mechanism for avoiding the @@ -214,7 +211,7 @@ A node is a small part of a picture. When a node is created, you provide a position where the node should be drawn and a \emph{shape}. A node of shape |circle| will be drawn as a circle, a node of shape |rectangle| as a rectangle, and so on. A node may also -contain same text, which is why Karl used nodes to show text. Finally, +contain some text, which is why Karl used nodes to show text. Finally, a node can get a \emph{name} for later reference. In Hagen's picture we will use nodes for the places and for the @@ -239,7 +236,7 @@ Hagen notes that this does not quite look like the final picture, but it seems like a good first step. Let us have a more detailed look at the code. The whole picture -consists of a single path. Ignoring the |node| operations there is not +consists of a single path. Ignoring the |node| operations, there is not much going on in this path: It is just a sequence of coordinates with nothing ``happening'' between them. Indeed, even if something were to happen like a line-to or a curve-to, the |\path| command would not @@ -256,10 +253,10 @@ answer is the |draw| option for the |node| operation: It causes the So, the code |(0,2) node [shape=circle,draw] {}| means the following: ``In the main path, add a move-to to the coordinate |(0,2)|. Then, temporarily suspend the construction of the main path while the node -is build. This node will be a |circle| around an empty text. This +is built. This node will be a |circle| around an empty text. This circle is to be |draw|n, but not filled or otherwise used. Once this whole node is constructed, it is saved until after the -main path is finished. Then, it is drawn.'' Then following +main path is finished. Then, it is drawn.'' The following |(0,1) node [shape=circle,draw] {}| then has the following effect: ``Continue the main path with a move-to to |(0,1)|. Then construct a node at this position also. This node is also shown after the main @@ -353,7 +350,7 @@ places and another style for transitions: Before Hagen starts naming and connecting the nodes, let us first make sure that the nodes get their final appearance. They are still too small. Indeed, Hagen wonders why they have any size at all, after -all, the text is empty. The reason is than \tikzname\ automatically +all, the text is empty. The reason is that \tikzname\ automatically adds some space around the text. The amount is set using the option |inner sep|. So, to increase the size of the nodes, Hagen could write: @@ -373,7 +370,7 @@ adds some space around the text. The amount is set using the option However, this is not really the best way to achieve the desired effect. It is much better to use the |minimum size| option instead. This option allows Hagen to specify a minimum size that the -node should have. If the nodes actually needs to be bigger because of +node should have. If the node actually needs to be bigger because of a longer text, it will be larger, but if the text is empty, then the node will have |minimum size|. This option is also useful to ensure that several nodes containing different amounts of text have the same @@ -414,7 +411,7 @@ Fortunately, \pgfname\ will perform all the necessary calculations for him. However, he first has to assign names to the nodes so that he can reference them later on. -There are two ways to name a node. The first is the use the |name=| +There are two ways to name a node. The first is to use the |name=| option. The second method is to write the desired name in parentheses after the |node| operation. Hagen thinks that this second method seems strange, but he will soon change his opinion. @@ -425,7 +422,7 @@ strange, but he will soon change his opinion. transition/.style={rectangle,draw=black!50,fill=black!20,thick, inner sep=0pt,minimum size=4mm}} \begin{codeexample}[] -% ... setup styles +% ... set up styles \begin{tikzpicture} \node (waiting 1) at ( 0,2) [place] {}; \node (critical 1) at ( 0,1) [place] {}; @@ -499,7 +496,7 @@ either the distance between the centers of the nodes (when the |on grid| option is set to true) or the distance between the borders (when the |on grid| option is set to false, which is the default). -Even though the above code has the same effect the earlier code, Hagen +Even though the above code has the same effect as the earlier code, Hagen can pass it to his colleagues who will be able to just read and understand it, perhaps without even having to see the picture. @@ -710,7 +707,7 @@ transition/.style={rectangle,draw=black!50,fill=black!20,thick, There is another option for the |to| operation, that is even better suited to Hagen's problem: The |bend right| option. This option also takes an angle, but this angle only specifies the angle by which the -curve is bend to the right: +curve is bent to the right: { \tikzset{place/.style={circle,draw=blue!50,fill=blue!20,thick, @@ -737,7 +734,7 @@ to the |to| operation, but there is one important difference: Like a node the edge generated by the |edge| operation is not part of the main path, but is added only later. This may not seem very important, but it has some nice consequences. For example, every edge can have -its own arrow tips and its own color and so one and, still, all the +its own arrow tips and its own color and so on and, still, all the edges can be given on the same path. This allows Hagen to write the following: @@ -869,7 +866,7 @@ nets. What he is unsure of is how he can create the snaked line between the nets. For this he can use a \emph{decoration}. -To draw the snake, Hagen only needs to set the two options +To draw the snaked line, Hagen only needs to set the two options |decoration=snake| and |decorate| on the path. This causes all lines of the path to be replaced by snakes. It is also possible to use snakes only in certain parts of a @@ -943,8 +940,9 @@ rectangle. If Hagen draws the rectangle first, then he needs to know the exact size of the Petri net -- which he does not. The solution is to use \emph{layers}. When the background library is -loaded, Hagen can put parts of his picture inside a |{pgfonlayer}| -environment. Then this part of the picture becomes part of the layer +loaded, Hagen can put parts of his picture inside a scope with the +|on background layer| option. Then this part of the picture becomes +part of the layer that is given as an argument to this environment. When the |{tikzpicture}| environment ends, the layers are put on top of each other, starting with the background layer. This causes everything @@ -955,7 +953,7 @@ Naturally, Hagen can compute the size ``by hand'' or using some clever observations concerning the $x$- and $y$-coordinates of the nodes, but it would be nicer to just have \tikzname\ compute a rectangle into which all the nodes ``fit.'' For this, the |fit| library can be -used. It defines the |fit| options, which, when give to a node, causes +used. It defines the |fit| options, which, when given to a node, causes the node to be resized and shifted such that it exactly covers all the nodes and coordinates given as parameters to the |fit| option. @@ -982,17 +980,16 @@ post/.style={->,shorten >=1pt,>=stealth',semithick}} edge [pre, bend left] (waiting) edge [post,bend right] (semaphore); - \begin{pgfonlayer}{background} + \begin{scope}[on background layer] \node [fill=black!30,fit=(waiting) (critical) (semaphore) (leave critical) (enter critical)] {}; - \end{pgfonlayer} + \end{scope} \end{tikzpicture} \end{codeexample} } - \subsection{The Complete Code} Hagen has now finally put everything together. Only then does he learn @@ -1096,10 +1093,10 @@ every picture/.style={on grid,node distance=1.3cm,>=stealth',bend angle=45,auto} The code for the background and the snake is the following: \begin{codeexample}[code only] - \begin{pgfonlayer}{background} + \begin{scope}[on background layer] \node (r1) [fill=black!10,rounded corners,fit=(w1)(w2)(e1)(e2)(l1)(l2)] {}; \node (r2) [fill=black!10,rounded corners,fit=(w1')(w2')(e1')(e2')(l1')(l2')] {}; - \end{pgfonlayer} + \end{scope} \draw [shorten >=1mm,-to,thick,decorate, decoration={snake,amplitude=.4mm,segment length=2mm, diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-nodes.tex.orig b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-nodes.tex.orig deleted file mode 100644 index 99ac79cd642..00000000000 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial-nodes.tex.orig +++ /dev/null @@ -1,1108 +0,0 @@ -% Copyright 2006 by Tilo Tantau -% -% This file may be distributed and/or modified -% -% 1. under the LaTeX Project Public License and/or -% 2. under the GNU Free Documentation License. -% -% See the file doc/generic/pgf/licenses/LICENSE for more details. - -\section{Tutorial: A Petri-Net for Hagen} - -In this second tutorial we explore the node mechanism of -\tikzname\ and \pgfname. - -Hagen must give a talk tomorrow about his favorite formalism for -distributed systems: Petri nets! Hagen used to give his talks using a -blackboard and everyone seemed to be perfectly concent with % TODOsp: concent --> consent? -this. Unfortunately, his audience has been spoiled recently with fancy -projector-based presentations and there seems to be a certain amount -of peer pressure that this Petri nets should also be drawn using a -graphic program. One of the professors at his institutes recommends -\tikzname\ for this and Hagen decides to give it a try. - - -\subsection{Problem Statement} - -For his talk, Hagen wishes to create a graphic that demonstrates how a -net with place capacities can be simulated by a net without -capacities. The graphic should look like this, ideally: - -\begin{quote} -\begin{tikzpicture} - [node distance=1.3cm,>=stealth',bend angle=45,auto, - place/.style={circle,thick,draw=blue!75,fill=blue!20,minimum size=6mm}, - red place/.style={place,draw=red!75,fill=red!20}, - transition/.style={rectangle,thick,draw=black!75,fill=black!20,minimum size=4mm}, - every label/.style={red},on grid] - - \begin{scope} - % First net - \node [place,tokens=1] (w1) {}; - \node [place] (c1) [below=of w1] {}; - \node [place] (s) [below=of c1,label=above:$s\le 3$] {}; - \node [place] (c2) [below=of s] {}; - \node [place,tokens=1] (w2) [below=of c2] {}; - - \node [transition] (e1) [left=of c1] {} - edge [pre,bend left] (w1) - edge [post,bend right] (s) - edge [post] (c1); - - \node [transition] (e2) [left=of c2] {} - edge [pre,bend right] (w2) - edge [post,bend left] (s) - edge [post] (c2); - - \node [transition] (l1) [right=of c1] {} - edge [pre] (c1) - edge [pre,bend left] (s) - edge [post,bend right] node[swap] {2} (w1); - - \node [transition] (l2) [right=of c2] {} - edge [pre] (c2) - edge [pre,bend right] (s) - edge [post,bend left] node {2} (w2); - \end{scope} - - \begin{scope}[xshift=6cm] - % Second net - \node [place,tokens=1] - (w1') {}; - \node [place] (c1') [below=of w1'] {}; - \node [red place] (s1') [below=of c1',xshift=-5mm,label=left:$s$] {}; - \node [red place,tokens=3] - (s2') [below=of c1',xshift=5mm,label=right:$\bar s$] {}; - \node [place] (c2') [below=of s1',xshift=5mm] {}; - \node [place,tokens=1] - (w2') [below=of c2'] {}; - - \node [transition] (e1') [left=of c1'] {} - edge [pre,bend left] (w1') - edge [post] (s1') - edge [pre] (s2') - edge [post] (c1'); - - \node [transition] (e2') [left=of c2'] {} - edge [pre,bend right] (w2') - edge [post] (s1') - edge [pre] (s2') - edge [post] (c2'); - - \node [transition] (l1') [right=of c1'] {} - edge [pre] (c1') - edge [pre] (s1') - edge [post] (s2') - edge [post,bend right] node[swap] {2} (w1'); - - \node [transition] (l2') [right=of c2'] {} - edge [pre] (c2') - edge [pre] (s1') - edge [post] (s2') - edge [post,bend left] node {2} (w2'); - \end{scope} - - \begin{pgfonlayer}{background} - \node (r1) [fill=black!10,rounded corners,fit=(w1)(w2)(e1)(e2)(l1)(l2)] {}; - \node (r2) [fill=black!10,rounded corners,fit=(w1')(w2')(e1')(e2')(l1')(l2')] {}; - \end{pgfonlayer} - - \draw [shorten >=1mm,-to,thick,decorate,decoration={snake,amplitude=.4mm,segment - length=2mm,pre=moveto,pre length=1mm,post length=2mm}] - (r1) -- (r2) - node [above=1mm,midway,text width=3cm,align=center] - {replacement of the \textcolor{red}{capacity} by \textcolor{red}{two places}}; - -\end{tikzpicture} -\end{quote} - - -\subsection{Setting up the Environment} - -For the picture Hagen will need to load the \tikzname\ package as did -Karl in the previous tutorial. However, Hagen will also need to load -some additional \emph{library packages} that Karl did not need. These -library packages contain additional definitions like extra arrow tips -that are typically not needed in a picture and that need to be -loaded explicitly. - -Hagen will need to load several libraries: The |arrows| library for the -special arrow tip used in the graphic, the |decoration.pathmorphing| -library for the ``snaking line'' in the middle, the background -library for the two rectangular areas that are behind the two main -parts of the picture, the |fit| library to easily compute the sizes of -these rectangles, and the |positioning| library for placing nodes -relative to other nodes. - - -\subsubsection{Setting up the Environment in \LaTeX} - -When using \LaTeX\ use: - -\begin{codeexample}[code only] -\documentclass{article} % say - -\usepackage{tikz} -\usetikzlibrary{arrows,decorations.pathmorphing,backgrounds,positioning,fit,petri} - -\begin{document} -\begin{tikzpicture} - \draw (0,0) -- (1,1); -\end{tikzpicture} -\end{document} -\end{codeexample} - - -\subsubsection{Setting up the Environment in Plain \TeX} - -When using plain \TeX\ use: - -\begin{codeexample}[code only] -%% Plain TeX file -\input tikz.tex -\usetikzlibrary{arrows,decorations.pathmorphing,backgrounds,positioning,fit,petri} -\baselineskip=12pt -\hsize=6.3truein -\vsize=8.7truein -\tikzpicture - \draw (0,0) -- (1,1); -\endtikzpicture -\bye -\end{codeexample} - - -\subsubsection{Setting up the Environment in Con\TeX t} - -When using Con\TeX\ use: -\begin{codeexample}[code only] -%% ConTeXt file -\usemodule[tikz] -\usetikzlibrary[arrows,decorations.pathmorphing,backgrounds,positioning,fit,petri] - -\starttext - \starttikzpicture - \draw (0,0) -- (1,1); - \stoptikzpicture -\stoptext -\end{codeexample} - - - -\subsection{Introduction to Nodes} - -In principle, we already know how to create the graphics that Hagen -desires (except perhaps for the snaked line, we will come to that): We -start with big light gray rectangle and then add lots of circles and -small rectangle, plus some arrows. - -However, this approach has numerous disadvantages: First, it is hard -to change anything at a later stage. For example, if we decide to add -more places to the Petri nets (the circles are called places in Petri -net theory), all of the coordinates change and we need to recalculate -everything. Second, it is hard to read the code for the Petri net as -it just a long and complicated list of coordinates and drawing -commands -- the underlying structure of the Petri net is lost. - -Fortunately, \tikzname\ offers a powerful mechanism for avoiding the -above problems: nodes. We already came across nodes in the previous -tutorial, where we used them to add labels to Karl's graphic. In the -present tutorial we will see that nodes are much more powerful. - -A node is a small part of a picture. When a node is created, you -provide a position where the node should be drawn and a -\emph{shape}. A node of shape |circle| will be drawn as a circle, a -node of shape |rectangle| as a rectangle, and so on. A node may also -contain same text, which is why Karl used nodes to show text. Finally, -a node can get a \emph{name} for later reference. - -In Hagen's picture we will use nodes for the places and for the -transitions of the Petri net (the places are the circles, the -transitions are the rectangles). Let us start with the upper half of -the left Petri net. In this upper half we have three places and two -transitions. Instead of drawing three circles and two rectangles, we -use three nodes of shape |circle| and two nodes of shape -|rectangle|. - -\begin{codeexample}[] -\begin{tikzpicture} - \path ( 0,2) node [shape=circle,draw] {} - ( 0,1) node [shape=circle,draw] {} - ( 0,0) node [shape=circle,draw] {} - ( 1,1) node [shape=rectangle,draw] {} - (-1,1) node [shape=rectangle,draw] {}; -\end{tikzpicture} -\end{codeexample} - -Hagen notes that this does not quite look like the final picture, but -it seems like a good first step. - -Let us have a more detailed look at the code. The whole picture -consists of a single path. Ignoring the |node| operations there is not -much going on in this path: It is just a sequence of coordinates with -nothing ``happening'' between them. Indeed, even if something were to -happen like a line-to or a curve-to, the |\path| command would not -``do'' anything with the resulting path. So, all the magic must be in -the |node| commands. - -In the previous tutorial we learned that a |node| will add a piece of -text at the last coordinate. Thus, each of the five nodes is added at -a different position. In the above code, this text is empty -(because of the empty |{}|). So, why do we see anything at all? The -answer is the |draw| option for the |node| operation: It causes the -``shape around the text'' to be drawn. - -So, the code |(0,2) node [shape=circle,draw] {}| means the following: -``In the main path, add a move-to to the coordinate |(0,2)|. Then, -temporarily suspend the construction of the main path while the node -is build. This node will be a |circle| around an empty text. This -circle is to be |draw|n, but not filled or otherwise used. Once this -whole node is constructed, it is saved until after the -main path is finished. Then, it is drawn.'' Then following -|(0,1) node [shape=circle,draw] {}| then has the following effect: -``Continue the main path with a move-to to |(0,1)|. Then construct a -node at this position also. This node is also shown after the main -path is finished.'' And so on. - - - -\subsection{Placing Nodes Using the At Syntax} - -Hagen now understands how the |node| operation adds nodes to the path, -but it seems a bit silly to create a path using the |\path| operation, -consisting of numerous superfluous move-to operations, only to place -nodes. He is pleased to learn that there are ways to add nodes in a -more sensible manner. - -First, the |node| operation allows one to add -|at (|\meta{coordinate}|)| in order to directly specify where the node -should be placed, sidestepping the rule that nodes are placed on the -last coordinate. Hagen can then write the following: - -\begin{codeexample}[] -\begin{tikzpicture} - \path node at ( 0,2) [shape=circle,draw] {} - node at ( 0,1) [shape=circle,draw] {} - node at ( 0,0) [shape=circle,draw] {} - node at ( 1,1) [shape=rectangle,draw] {} - node at (-1,1) [shape=rectangle,draw] {}; -\end{tikzpicture} -\end{codeexample} - -Now Hagen is still left with a single empty path, but at least the -path no longer contains strange move-tos. It turns out that this can -be improved further: The |\node| command is an abbreviation for -|\path node|, which allows Hagen to write: - -\begin{codeexample}[] -\begin{tikzpicture} - \node at ( 0,2) [circle,draw] {}; - \node at ( 0,1) [circle,draw] {}; - \node at ( 0,0) [circle,draw] {}; - \node at ( 1,1) [rectangle,draw] {}; - \node at (-1,1) [rectangle,draw] {}; -\end{tikzpicture} -\end{codeexample} - -Hagen likes this syntax much better than the previous one. Note that -Hagen has also omitted the |shape=| since, like |color=|, \tikzname\ -allows you to omit the |shape=| if there is no confusion. - - - -\subsection{Using Styles} - -Feeling adventurous, Hagen tries to make the nodes look nicer. In the -final picture, the circles and rectangle should be filled with -different colors, resulting in the following code: - -\begin{codeexample}[] -\begin{tikzpicture}[thick] - \node at ( 0,2) [circle,draw=blue!50,fill=blue!20] {}; - \node at ( 0,1) [circle,draw=blue!50,fill=blue!20] {}; - \node at ( 0,0) [circle,draw=blue!50,fill=blue!20] {}; - \node at ( 1,1) [rectangle,draw=black!50,fill=black!20] {}; - \node at (-1,1) [rectangle,draw=black!50,fill=black!20] {}; -\end{tikzpicture} -\end{codeexample} - -While this looks nicer in the picture, the code starts to get a bit -ugly. Ideally, we would like our code to transport the message ``there -are three places and two transitions'' and not so much which -filling colors should be used. - -To solve this problem, Hagen uses styles. He defines a style for -places and another style for transitions: - -\begin{codeexample}[] -\begin{tikzpicture} - [place/.style={circle,draw=blue!50,fill=blue!20,thick}, - transition/.style={rectangle,draw=black!50,fill=black!20,thick}] - \node at ( 0,2) [place] {}; - \node at ( 0,1) [place] {}; - \node at ( 0,0) [place] {}; - \node at ( 1,1) [transition] {}; - \node at (-1,1) [transition] {}; -\end{tikzpicture} -\end{codeexample} - - -\subsection{Node Size} - -Before Hagen starts naming and connecting the nodes, let us first -make sure that the nodes get their final appearance. They are still -too small. Indeed, Hagen wonders why they have any size at all, after -all, the text is empty. The reason is than \tikzname\ automatically -adds some space around the text. The amount is set using the option -|inner sep|. So, to increase the size of the nodes, Hagen could write: - -\begin{codeexample}[] -\begin{tikzpicture} - [inner sep=2mm, - place/.style={circle,draw=blue!50,fill=blue!20,thick}, - transition/.style={rectangle,draw=black!50,fill=black!20,thick}] - \node at ( 0,2) [place] {}; - \node at ( 0,1) [place] {}; - \node at ( 0,0) [place] {}; - \node at ( 1,1) [transition] {}; - \node at (-1,1) [transition] {}; -\end{tikzpicture} -\end{codeexample} - -However, this is not really the best way to achieve the desired -effect. It is much better to use the |minimum size| option -instead. This option allows Hagen to specify a minimum size that the -node should have. If the nodes actually needs to be bigger because of -a longer text, it will be larger, but if the text is empty, then the -node will have |minimum size|. This option is also useful to ensure -that several nodes containing different amounts of text have the same -size. The options |minimum height| and |minimum width| allow you to -specify the minimum height and width independently. - -So, what Hagen needs to do is to provide |minimum size| for the -nodes. To be on the safe side, he also sets |inner sep=0pt|. This -ensures that the nodes will really have size |minimum size| and not, -for very small minimum sizes, the minimal size necessary to encompass -the automatically added space. - -\begin{codeexample}[] -\begin{tikzpicture} - [place/.style={circle,draw=blue!50,fill=blue!20,thick, - inner sep=0pt,minimum size=6mm}, - transition/.style={rectangle,draw=black!50,fill=black!20,thick, - inner sep=0pt,minimum size=4mm}] - \node at ( 0,2) [place] {}; - \node at ( 0,1) [place] {}; - \node at ( 0,0) [place] {}; - \node at ( 1,1) [transition] {}; - \node at (-1,1) [transition] {}; -\end{tikzpicture} -\end{codeexample} - - - - -\subsection{Naming Nodes} - -Hagen's next aim is to connect the nodes using arrows. This seems like -a tricky business since the arrows should not start in the middle of -the nodes, but somewhere on the border and Hagen would very much like -to avoid computing these positions by hand. - -Fortunately, \pgfname\ will perform all the necessary calculations for -him. However, he first has to assign names to the nodes so that he can -reference them later on. - -There are two ways to name a node. The first is the use the |name=| -option. The second method is to write the desired name in parentheses -after the |node| operation. Hagen thinks that this second method seems -strange, but he will soon change his opinion. - -{ -\tikzset{place/.style={circle,draw=blue!50,fill=blue!20,thick, - inner sep=0pt,minimum size=6mm}, -transition/.style={rectangle,draw=black!50,fill=black!20,thick, - inner sep=0pt,minimum size=4mm}} -\begin{codeexample}[] -% ... setup styles -\begin{tikzpicture} - \node (waiting 1) at ( 0,2) [place] {}; - \node (critical 1) at ( 0,1) [place] {}; - \node (semaphore) at ( 0,0) [place] {}; - \node (leave critical) at ( 1,1) [transition] {}; - \node (enter critical) at (-1,1) [transition] {}; -\end{tikzpicture} -\end{codeexample} -} - -Hagen is pleased to note that the names help in understanding the -code. Names for nodes can be pretty arbitrary, but they should not -contain commas, periods, parentheses, colons, and some other special -characters. However, they can contain underscores and hyphens. - -The syntax for the |node| operation is quite liberal with respect to -the order in which node names, the |at| specifier, and the options -must come. Indeed, you can even have multiple option blocks between -the |node| and the text in curly braces, they accumulate. You can -rearrange them arbitrarily and perhaps the following might be preferable: - -{ -\tikzset{place/.style={circle,draw=blue!50,fill=blue!20,thick, - inner sep=0pt,minimum size=6mm}, -transition/.style={rectangle,draw=black!50,fill=black!20,thick, - inner sep=0pt,minimum size=4mm}} -\begin{codeexample}[] -\begin{tikzpicture} - \node[place] (waiting 1) at ( 0,2) {}; - \node[place] (critical 1) at ( 0,1) {}; - \node[place] (semaphore) at ( 0,0) {}; - \node[transition] (leave critical) at ( 1,1) {}; - \node[transition] (enter critical) at (-1,1) {}; -\end{tikzpicture} -\end{codeexample} -} - - - -\subsection{Placing Nodes Using Relative Placement} - -Although Hagen still wishes to connect the nodes, he first wishes to -address another problem again: The placement of the nodes. Although he -likes the |at| syntax, in this particular case he would prefer placing -the nodes ``relative to each other.'' So, Hagen would like to say that -the |critical 1| node should be below the |waiting 1| node, wherever -the |waiting 1| node might be. There are different ways of achieving -this, but the nicest one in Hagen's case is the |below| option: - -{ -\tikzset{place/.style={circle,draw=blue!50,fill=blue!20,thick, - inner sep=0pt,minimum size=6mm}, -transition/.style={rectangle,draw=black!50,fill=black!20,thick, - inner sep=0pt,minimum size=4mm}} -\begin{codeexample}[] -\begin{tikzpicture} - \node[place] (waiting) {}; - \node[place] (critical) [below=of waiting] {}; - \node[place] (semaphore) [below=of critical] {}; - \node[transition] (leave critical) [right=of critical] {}; - \node[transition] (enter critical) [left=of critical] {}; -\end{tikzpicture} -\end{codeexample} -} - -With the |positioning| library loaded, when an option like |below| -is followed by |of|, then the position of the node is shifted -such a manner that it is placed at the distance |node distance| in the -specified direction of the given direction. The |node distance| is -either the distance between the centers of the nodes (when the -|on grid| option is set to true) or the distance between the borders -(when the |on grid| option is set to false, which is the default). - -Even though the above code has the same effect the earlier code, Hagen -can pass it to his colleagues who will be able to just read and -understand it, perhaps without even having to see the picture. - - - -\subsection{Adding Labels Next to Nodes} - -Before we have a look at how Hagen can connect the nodes, let us add -the capacity ``$s \le 3$'' to the bottom node. For this, two -approaches are possible: -\begin{enumerate} -\item Hagen can just add a new node above the |north| anchor of the - |semaphore| node. -{ -\tikzset{place/.style={circle,draw=blue!50,fill=blue!20,thick, - inner sep=0pt,minimum size=6mm}, -transition/.style={rectangle,draw=black!50,fill=black!20,thick, - inner sep=0pt,minimum size=4mm}} -\begin{codeexample}[] -\begin{tikzpicture} - \node[place] (waiting) {}; - \node[place] (critical) [below=of waiting] {}; - \node[place] (semaphore) [below=of critical] {}; - \node[transition] (leave critical) [right=of critical] {}; - \node[transition] (enter critical) [left=of critical] {}; - - \node [red,above] at (semaphore.north) {$s\le 3$}; -\end{tikzpicture} -\end{codeexample} -} -This is a general approach that will ``always work.'' - -\item Hagen can use the special |label| option. This option is given - to a |node| and it causes \emph{another} node to be added next to - the node where the option is given. Here is the idea: When we - construct the |semaphore| node, we wish to indicate that we want - another node with the capacity above it. For this, we use the option - |label=above:$s\le 3$|. This option is interpreted as follows: We - want a node above the |semaphore| node and this node should read - ``$s \le 3$.'' Instead of |above| we could also use things like - |below left| before the colon or a number like |60|. -{ -\tikzset{place/.style={circle,draw=blue!50,fill=blue!20,thick, - inner sep=0pt,minimum size=6mm}, -transition/.style={rectangle,draw=black!50,fill=black!20,thick, - inner sep=0pt,minimum size=4mm}} -\begin{codeexample}[] -\begin{tikzpicture} - \node[place] (waiting) {}; - \node[place] (critical) [below=of waiting] {}; - \node[place] (semaphore) [below=of critical, - label=above:$s\le3$] {}; - \node[transition] (leave critical) [right=of critical] {}; - \node[transition] (enter critical) [left=of critical] {}; -\end{tikzpicture} -\end{codeexample} -} - It is also possible to give multiple |label| options, this causes - multiple labels to be drawn. -\begin{codeexample}[] -\tikz - \node [circle,draw,label=60:$60^\circ$,label=below:$-90^\circ$] {my circle}; -\end{codeexample} - Hagen is not fully satisfied with the |label| option since the label - is not red. To achieve this, he has two options: First, he can - redefine the |every label| style. Second, he can add options to the - label's node. These options are given following the |label=|, so he - would write |label=[red]above:$s\le3$|. However, this does not quite - work since \TeX\ thinks that the |]| closes the whole option list of - the |semaphore| node. So, Hagen has to add braces and writes - |label={[red]above:$s\le3$}|. Since this looks a bit ugly, Hagen - decides to redefine the |every label| style. -{ -\tikzset{place/.style={circle,draw=blue!50,fill=blue!20,thick, - inner sep=0pt,minimum size=6mm}, -transition/.style={rectangle,draw=black!50,fill=black!20,thick, - inner sep=0pt,minimum size=4mm}} -\begin{codeexample}[] -\begin{tikzpicture}[every label/.style={red}] - \node[place] (waiting) {}; - \node[place] (critical) [below=of waiting] {}; - \node[place] (semaphore) [below=of critical, - label=above:$s\le3$] {}; - \node[transition] (leave critical) [right=of critical] {}; - \node[transition] (enter critical) [left=of critical] {}; -\end{tikzpicture} -\end{codeexample} -} -\end{enumerate} - - - -\subsection{Connecting Nodes} - -It is now high time to connect the nodes. Let us start with something -simple, namely with the straight line from |enter critical| to -|critical|. We want this line to start at the right side of -|enter critical| and to end at the left side of |critical|. For -this, we can use the \emph{anchors} of the nodes. Every node defines a -whole bunch of anchors that lie on its border or inside it. For -example, the |center| anchor is at the center of the node, the |west| -anchor is on the left of the node, and so on. To access the coordinate -of a node, we use a coordinate that contains the node's name followed -by a dot, followed by the anchor's name: - -{ -\tikzset{place/.style={circle,draw=blue!50,fill=blue!20,thick, - inner sep=0pt,minimum size=6mm}, -transition/.style={rectangle,draw=black!50,fill=black!20,thick, - inner sep=0pt,minimum size=4mm}} -\begin{codeexample}[] -\begin{tikzpicture} - \node[place] (waiting) {}; - \node[place] (critical) [below=of waiting] {}; - \node[place] (semaphore) [below=of critical] {}; - \node[transition] (leave critical) [right=of critical] {}; - \node[transition] (enter critical) [left=of critical] {}; - \draw [->] (critical.west) -- (enter critical.east); -\end{tikzpicture} -\end{codeexample} -} - -Next, let us tackle the curve from |waiting| to |enter critical|. This -can be specified using curves and controls: - -{ -\tikzset{place/.style={circle,draw=blue!50,fill=blue!20,thick, - inner sep=0pt,minimum size=6mm}, -transition/.style={rectangle,draw=black!50,fill=black!20,thick, - inner sep=0pt,minimum size=4mm}} -\begin{codeexample}[] -\begin{tikzpicture} - \node[place] (waiting) {}; - \node[place] (critical) [below=of waiting] {}; - \node[place] (semaphore) [below=of critical] {}; - \node[transition] (leave critical) [right=of critical] {}; - \node[transition] (enter critical) [left=of critical] {}; - \draw [->] (enter critical.east) -- (critical.west); - \draw [->] (waiting.west) .. controls +(left:5mm) and +(up:5mm) - .. (enter critical.north); -\end{tikzpicture} -\end{codeexample} -} - -Hagen sees how he can now add all his edges, but the whole process -seems a but awkward and not very flexible. Again, the code seems to -obscure the structure of the graphic rather than showing it. - -So, let us start improving the code for the edges. First, Hagen can -leave out the anchors: - -{ -\tikzset{place/.style={circle,draw=blue!50,fill=blue!20,thick, - inner sep=0pt,minimum size=6mm}, -transition/.style={rectangle,draw=black!50,fill=black!20,thick, - inner sep=0pt,minimum size=4mm}} -\begin{codeexample}[] -\begin{tikzpicture} - \node[place] (waiting) {}; - \node[place] (critical) [below=of waiting] {}; - \node[place] (semaphore) [below=of critical] {}; - \node[transition] (leave critical) [right=of critical] {}; - \node[transition] (enter critical) [left=of critical] {}; - \draw [->] (enter critical) -- (critical); - \draw [->] (waiting) .. controls +(left:8mm) and +(up:8mm) - .. (enter critical); -\end{tikzpicture} -\end{codeexample} -} - -Hagen is a bit surprised that this works. After all, how did -\tikzname\ know that the line from |enter critical| to |critical| -should actually start on the borders? Whenever \tikzname\ encounters a -whole node name as a ``coordinate,'' it tries to ``be smart'' about -the anchor that it should choose for this node. Depending on what -happens next, \tikzname\ will choose an anchor that lies on the border -of the node on a line to the next coordinate or control point. The -exact rules are a bit complex, but the chosen point will usually be -correct -- and when it is not, Hagen can still specify the desired -anchor by hand. - -Hagen would now like to simplify the curve operation somehow. It turns -out that this can be accomplished using a special path operation: the -|to| operation. This operation takes many options (you can even define -new ones yourself). One pair of option is useful for Hagen: The pair -|in| and |out|. These options take angles at which a curve should -leave or reach the start or target coordinates. Without these options, -a straight line is drawn: - -{ -\tikzset{place/.style={circle,draw=blue!50,fill=blue!20,thick, - inner sep=0pt,minimum size=6mm}, -transition/.style={rectangle,draw=black!50,fill=black!20,thick, - inner sep=0pt,minimum size=4mm}} -\begin{codeexample}[] -\begin{tikzpicture} - \node[place] (waiting) {}; - \node[place] (critical) [below=of waiting] {}; - \node[place] (semaphore) [below=of critical] {}; - \node[transition] (leave critical) [right=of critical] {}; - \node[transition] (enter critical) [left=of critical] {}; - \draw [->] (enter critical) to (critical); - \draw [->] (waiting) to [out=180,in=90] (enter critical); -\end{tikzpicture} -\end{codeexample} -} - -There is another option for the |to| operation, that is even better -suited to Hagen's problem: The |bend right| option. This option also -takes an angle, but this angle only specifies the angle by which the -curve is bend to the right: - -{ -\tikzset{place/.style={circle,draw=blue!50,fill=blue!20,thick, - inner sep=0pt,minimum size=6mm}, -transition/.style={rectangle,draw=black!50,fill=black!20,thick, - inner sep=0pt,minimum size=4mm}} -\begin{codeexample}[] -\begin{tikzpicture} - \node[place] (waiting) {}; - \node[place] (critical) [below=of waiting] {}; - \node[place] (semaphore) [below=of critical] {}; - \node[transition] (leave critical) [right=of critical] {}; - \node[transition] (enter critical) [left=of critical] {}; - \draw [->] (enter critical) to (critical); - \draw [->] (waiting) to [bend right=45] (enter critical); - \draw [->] (enter critical) to [bend right=45] (semaphore); -\end{tikzpicture} -\end{codeexample} -} - -It is now time for Hagen to learn about yet another way of specifying -edges: Using the |edge| path operation. This operation is very similar -to the |to| operation, but there is one important difference: Like a -node the edge generated by the |edge| operation is not part of the -main path, but is added only later. This may not seem very important, -but is has some nice consequences. For example, every edge can have -its own arrow tips and its own color and so one and, still, all the -edges can be given on the same path. This allows Hagen to write the -following: - - -{ -\tikzset{place/.style={circle,draw=blue!50,fill=blue!20,thick, - inner sep=0pt,minimum size=6mm}, -transition/.style={rectangle,draw=black!50,fill=black!20,thick, - inner sep=0pt,minimum size=4mm}} -\begin{codeexample}[] -\begin{tikzpicture} - \node[place] (waiting) {}; - \node[place] (critical) [below=of waiting] {}; - \node[place] (semaphore) [below=of critical] {}; - \node[transition] (leave critical) [right=of critical] {}; - \node[transition] (enter critical) [left=of critical] {} - edge [->] (critical) - edge [<-,bend left=45] (waiting) - edge [->,bend right=45] (semaphore); -\end{tikzpicture} -\end{codeexample} -} - -Each |edge| caused a new path to be constructed, consisting of a |to| -between the node |enter critical| and the node following the |edge| -command. - -The finishing touch is to introduce two styles |pre| and |post| and to -use the |bend angle=45| option to set the bend angle once and for all: - -{ -\tikzset{place/.style={circle,draw=blue!50,fill=blue!20,thick, - inner sep=0pt,minimum size=6mm}, -transition/.style={rectangle,draw=black!50,fill=black!20,thick, - inner sep=0pt,minimum size=4mm}} -\begin{codeexample}[] -% Styles place and transition as before -\begin{tikzpicture} - [bend angle=45, - pre/.style={<-,shorten <=1pt,>=stealth',semithick}, - post/.style={->,shorten >=1pt,>=stealth',semithick}] - - \node[place] (waiting) {}; - \node[place] (critical) [below=of waiting] {}; - \node[place] (semaphore) [below=of critical] {}; - - \node[transition] (leave critical) [right=of critical] {} - edge [pre] (critical) - edge [post,bend right] (waiting) - edge [pre, bend left] (semaphore); - \node[transition] (enter critical) [left=of critical] {} - edge [post] (critical) - edge [pre, bend left] (waiting) - edge [post,bend right] (semaphore); -\end{tikzpicture} -\end{codeexample} -} - - - - -\subsection{Adding Labels Next to Lines} - -The next thing that Hagen needs to add is the ``$2$'' at the arcs. For -this Hagen can use \tikzname's automatic node placement: By adding the -option |auto|, \tikzname\ will position nodes on curves and lines in -such a way that they are not on the curve but next to it. Adding -|swap| will mirror the label with respect to the line. Here is a -general example: - -{ -\begin{codeexample}[] -\begin{tikzpicture}[auto,bend right] - \node (a) at (0:1) {$0^\circ$}; - \node (b) at (120:1) {$120^\circ$}; - \node (c) at (240:1) {$240^\circ$}; - - \draw (a) to node {1} node [swap] {1'} (b) - (b) to node {2} node [swap] {2'} (c) - (c) to node {3} node [swap] {3'} (a); -\end{tikzpicture} -\end{codeexample} -} - -What is happening here? The nodes are given somehow inside the |to| -operation! When this is done, the node is placed on the middle of the -curve or line created by the |to| operation. The |auto| option then -causes the node to be moved in such a way that it does not lie on the -curve, but next to it. In the example we provide even two nodes on -each |to| operation. - -For Hagen that |auto| option is not really necessary since the two -``2'' labels could also easily be placed ``by hand.'' However, in a -complicated plot with numerous edges automatic placement can be a -blessing. - -{ -\tikzset{place/.style={circle,draw=blue!50,fill=blue!20,thick, - inner sep=0pt,minimum size=6mm}, -transition/.style={rectangle,draw=black!50,fill=black!20,thick, - inner sep=0pt,minimum size=4mm}, -pre/.style={<-,shorten <=1pt,>=stealth',semithick}, -post/.style={->,shorten >=1pt,>=stealth',semithick}} -\begin{codeexample}[] -% Styles as before -\begin{tikzpicture}[bend angle=45] - \node[place] (waiting) {}; - \node[place] (critical) [below=of waiting] {}; - \node[place] (semaphore) [below=of critical] {}; - - \node[transition] (leave critical) [right=of critical] {} - edge [pre] (critical) - edge [post,bend right] node[auto,swap] {2} (waiting) - edge [pre, bend left] (semaphore); - \node[transition] (enter critical) [left=of critical] {} - edge [post] (critical) - edge [pre, bend left] (waiting) - edge [post,bend right] (semaphore); -\end{tikzpicture} -\end{codeexample} -} - - - -\subsection{Adding the Snaked Line and Multi-Line Text} - -With the node mechanism Hagen can now easily create the two Petri -nets. What he is unsure of is how he can create the snaked line -between the nets. - -For this he can use a \emph{decoration}. -To draw the snake, Hagen only needs to set the two options -|decoration=snake| and |decorate| on -the path. This causes all lines of the path to be replaced by -snakes. It is also possible to use snakes only in certain parts of a -path, but Hagen will not need this. - -\begin{codeexample}[] -\begin{tikzpicture} - \draw [->,decorate,decoration=snake] (0,0) -- (2,0); -\end{tikzpicture} -\end{codeexample} - -Well, that does not look quite right, yet. The problem is that the -snake happens to end exactly at the position where the arrow -begins. Fortunately, there is an option that helps here. Also, the -snake should be a bit smaller, which can be influenced by even more -options. - -\begin{codeexample}[] -\begin{tikzpicture} - \draw [->,decorate, - decoration={snake,amplitude=.4mm,segment length=2mm,post length=1mm}] - (0,0) -- (3,0); -\end{tikzpicture} -\end{codeexample} - -Now Hagen needs to add the text above the snake. This text is a bit -challenging since it is a multi-line text. Hagen has two options for -this: First, he can specify an |align=center| and then use the |\\| -command to enforce the line breaks at the desired positions. - -\begin{codeexample}[] -\begin{tikzpicture} - \draw [->,decorate, - decoration={snake,amplitude=.4mm,segment length=2mm,post length=1mm}] - (0,0) -- (3,0) - node [above,align=center,midway] - { - replacement of\\ - the \textcolor{red}{capacity}\\ - by \textcolor{red}{two places} - }; -\end{tikzpicture} -\end{codeexample} - -Instead of specifying the line breaks ``by hand,'' Hagen can also -specify a width for the text and let \TeX\ perform the line breaking -for him: - -\begin{codeexample}[] -\begin{tikzpicture} - \draw [->,decorate, - decoration={snake,amplitude=.4mm,segment length=2mm,post length=1mm}] - (0,0) -- (3,0) - node [above,text width=3cm,align=center,midway] - { - replacement of the \textcolor{red}{capacity} by - \textcolor{red}{two places} - }; -\end{tikzpicture} -\end{codeexample} - - - -\subsection{Using Layers: The Background Rectangles} - -Hagen still needs to add the background rectangles. These are a bit -tricky: Hagen would like to draw the rectangles \emph{after} the Petri -nets are finished. The reason is that only then can he conveniently -refer to the coordinates that make up the corners of the -rectangle. If Hagen draws the rectangle first, then he needs to know -the exact size of the Petri net -- which he does not. - -The solution is to use \emph{layers}. When the background library is -loaded, Hagen can put parts of his picture inside a |{pgfonlayer}| -environment. Then this part of the picture becomes part of the layer -that is given as an argument to this environment. When the -|{tikzpicture}| environment ends, the layers are put on top of each -other, starting with the background layer. This causes everything -drawn on the background layer to be behind the main text. - -The next tricky question is, how big should the rectangle be? -Naturally, Hagen can compute the size ``by hand'' or using some clever -observations concerning the $x$- and $y$-coordinates of the nodes, but -it would be nicer to just have \tikzname\ compute a rectangle into -which all the nodes ``fit.'' For this, the |fit| library can be -used. It defines the |fit| options, which, when give to a node, causes -the node to be resized and shifted such that it exactly covers all the -nodes and coordinates given as parameters to the |fit| option. - -{ -\tikzset{place/.style={circle,draw=blue!50,fill=blue!20,thick, - inner sep=0pt,minimum size=6mm}, -transition/.style={rectangle,draw=black!50,fill=black!20,thick, - inner sep=0pt,minimum size=4mm}, -pre/.style={<-,shorten <=1pt,>=stealth',semithick}, -post/.style={->,shorten >=1pt,>=stealth',semithick}} -\begin{codeexample}[] -% Styles as before -\begin{tikzpicture}[bend angle=45] - \node[place] (waiting) {}; - \node[place] (critical) [below=of waiting] {}; - \node[place] (semaphore) [below=of critical] {}; - - \node[transition] (leave critical) [right=of critical] {} - edge [pre] (critical) - edge [post,bend right] node[auto,swap] {2} (waiting) - edge [pre, bend left] (semaphore); - \node[transition] (enter critical) [left=of critical] {} - edge [post] (critical) - edge [pre, bend left] (waiting) - edge [post,bend right] (semaphore); - - \begin{pgfonlayer}{background} - \node [fill=black!30,fit=(waiting) (critical) (semaphore) - (leave critical) (enter critical)] {}; - \end{pgfonlayer} -\end{tikzpicture} -\end{codeexample} -} - - - - -\subsection{The Complete Code} - -Hagen has now finally put everything together. Only then does he learn -that there is already a library for drawing Petri nets! It turns out -that this library mainly provides the same definitions as Hagen -did. For example, it defines a |place| style in a similar way as Hagen -did. Adjusting the code so that it uses the library shortens Hagen -code a bit, as shown in the following. - -First, Hagen needs less style definitions, but he still needs to -specify the colors of places and transitions. - -\begin{codeexample}[code only] -\begin{tikzpicture} - [node distance=1.3cm,on grid,>=stealth',bend angle=45,auto, - every place/.style= {minimum size=6mm,thick,draw=blue!75,fill=blue!20}, - every transition/.style={thick,draw=black!75,fill=black!20}, - red place/.style= {place,draw=red!75,fill=red!20}, - every label/.style= {red}] -\end{codeexample} - -Now comes the code for the nets: - -{ -\tikzset{% - every place/.style={minimum size=6mm,thick,draw=blue!75,fill=blue!20}, - every transition/.style={thick,draw=black!75,fill=black!20}, - red place/.style={place,draw=red!75,fill=red!20}, - every label/.style={red}, - every picture/.style={on grid,node distance=1.3cm,>=stealth',bend angle=45,auto}} -\tikzexternaldisable -\begin{codeexample}[pre=\begin{tikzpicture},post=\end{tikzpicture}] - \node [place,tokens=1] (w1) {}; - \node [place] (c1) [below=of w1] {}; - \node [place] (s) [below=of c1,label=above:$s\le 3$] {}; - \node [place] (c2) [below=of s] {}; - \node [place,tokens=1] (w2) [below=of c2] {}; - - \node [transition] (e1) [left=of c1] {} - edge [pre,bend left] (w1) - edge [post,bend right] (s) - edge [post] (c1); - \node [transition] (e2) [left=of c2] {} - edge [pre,bend right] (w2) - edge [post,bend left] (s) - edge [post] (c2); - \node [transition] (l1) [right=of c1] {} - edge [pre] (c1) - edge [pre,bend left] (s) - edge [post,bend right] node[swap] {2} (w1); - \node [transition] (l2) [right=of c2] {} - edge [pre] (c2) - edge [pre,bend right] (s) - edge [post,bend left] node {2} (w2); -\end{codeexample} -} - -{ -\tikzset{ -every place/.style= {minimum size=6mm,thick,draw=blue!75,fill=blue!20}, -every transition/.style={thick,draw=black!75,fill=black!20}, -red place/.style= {place,draw=red!75,fill=red!20}, -every label/.style={red}, -every picture/.style={on grid,node distance=1.3cm,>=stealth',bend angle=45,auto}} -\tikzexternaldisable -\begin{codeexample}[pre=\begin{tikzpicture},post=\end{tikzpicture}] - \begin{scope}[xshift=6cm] - \node [place,tokens=1] (w1') {}; - \node [place] (c1') [below=of w1'] {}; - \node [red place] (s1') [below=of c1',xshift=-5mm] - [label=left:$s$] {}; - \node [red place,tokens=3] (s2') [below=of c1',xshift=5mm] - [label=right:$\bar s$] {}; - \node [place] (c2') [below=of s1',xshift=5mm] {}; - \node [place,tokens=1] (w2') [below=of c2'] {}; - - \node [transition] (e1') [left=of c1'] {} - edge [pre,bend left] (w1') - edge [post] (s1') - edge [pre] (s2') - edge [post] (c1'); - \node [transition] (e2') [left=of c2'] {} - edge [pre,bend right] (w2') - edge [post] (s1') - edge [pre] (s2') - edge [post] (c2'); - \node [transition] (l1') [right=of c1'] {} - edge [pre] (c1') - edge [pre] (s1') - edge [post] (s2') - edge [post,bend right] node[swap] {2} (w1'); - \node [transition] (l2') [right=of c2'] {} - edge [pre] (c2') - edge [pre] (s1') - edge [post] (s2') - edge [post,bend left] node {2} (w2'); - \end{scope} -\end{codeexample} -} - -The code for the background and the snake is the following: - -\begin{codeexample}[code only] - \begin{pgfonlayer}{background} - \node (r1) [fill=black!10,rounded corners,fit=(w1)(w2)(e1)(e2)(l1)(l2)] {}; - \node (r2) [fill=black!10,rounded corners,fit=(w1')(w2')(e1')(e2')(l1')(l2')] {}; - \end{pgfonlayer} - - \draw [shorten >=1mm,-to,thick,decorate, - decoration={snake,amplitude=.4mm,segment length=2mm, - pre=moveto,pre length=1mm,post length=2mm}] - (r1) -- (r2) node [above=1mm,midway,text width=3cm,align=center] - {replacement of the \textcolor{red}{capacity} by \textcolor{red}{two places}}; -\end{tikzpicture} -\end{codeexample} diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial.tex index b2dcfbe5a05..99585ce2b48 100644 --- a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial.tex +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-tutorial.tex @@ -9,9 +9,9 @@ \section{Tutorial: A Picture for Karl's Students} -This tutorial is intended for new users of \pgfname\ and \tikzname. It -does not give an exhaustive account of all the features of \tikzname\ or -\pgfname, just of those that you are likely to use right away. +This tutorial is intended for new users of \tikzname. It +does not give an exhaustive account of all the features of \tikzname, +just of those that you are likely to use right away. Karl is a math and chemistry high-school teacher. He used to create the graphics in his worksheets and exams using \LaTeX's |{picture}| @@ -66,7 +66,7 @@ cosine. What he would like to have is something that looks like this % The graphic \draw[help lines,step=0.5cm] (-1.4,-1.4) grid (1.4,1.4); - \draw (0,0) circle (1cm); + \draw (0,0) circle [radius=1cm]; \begin{scope}[axes] \draw[->] (-1.5,0) -- (1.5,0) node[right] {$x$}; @@ -236,9 +236,7 @@ His version of the example looks like this: \end{codeexample} Hans will now typeset this file in the usual way using -|texexec|\footnote{Note that \pgfname/\tikzname{} is not supported by - recent Con\TeX t versions (like mark IV, the Lua\TeX-aware part of - Con\TeX t).}. +|texexec| or |context|. @@ -288,10 +286,10 @@ $z$ and the tangent of the curve at point $z$ will go through $w$. Here is an example (the control points have been added for clarity): \begin{codeexample}[] \begin{tikzpicture} - \filldraw [gray] (0,0) circle (2pt) - (1,1) circle (2pt) - (2,1) circle (2pt) - (2,0) circle (2pt); + \filldraw [gray] (0,0) circle [radius=2pt] + (1,1) circle [radius=2pt] + (2,1) circle [radius=2pt] + (2,0) circle [radius=2pt]; \draw (0,0) .. controls (1,1) and (2,1) .. (2,0); \end{tikzpicture} \end{codeexample} @@ -320,38 +318,36 @@ way to be extremely awkward. Fortunately, there is a much simpler way. \subsection{Circle Path Construction} In order to draw a circle, the path construction operation |circle| can -be used. This operation is followed by a radius in round brackets as in +be used. This operation is followed by a radius in brackets as in the following example: (Note that the previous position is used as the \emph{center} of the circle.) \begin{codeexample}[] -\tikz \draw (0,0) circle (10pt); +\tikz \draw (0,0) circle [radius=10pt]; \end{codeexample} You can also append an ellipse to the path using the |ellipse| -operation. Instead of a single radius you can specify two of them, one -for the $x$-direction and one for the $y$-direction, separated by -|and|: +operation. Instead of a single radius you can specify two of them: \begin{codeexample}[] -\tikz \draw (0,0) ellipse (20pt and 10pt); +\tikz \draw (0,0) ellipse [x radius=20pt, y radius=10pt]; \end{codeexample} To draw an ellipse whose axes are not horizontal and vertical, but point in an arbitrary direction (a ``turned ellipse'' like \tikz -\draw[rotate=30] (0,0) ellipse (6pt and 3pt);) you can use +\draw[rotate=30] (0,0) ellipse [x radius=6pt, y radius=3pt];) you can use transformations, which are explained later. The code for the little -ellipse is |\tikz \draw[rotate=30] (0,0) ellipse (6pt and 3pt);|, by +ellipse is |\tikz \draw[rotate=30] (0,0) ellipse [x radius=6pt, y radius=3pt];|, by the way. So, returning to Karl's problem, he can write -|\draw (0,0) circle (1cm);| to draw the circle: +|\draw (0,0) circle [radius=1cm];| to draw the circle: \begin{codeexample}[] \begin{tikzpicture} \draw (-1.5,0) -- (1.5,0); \draw (0,-1.5) -- (0,1.5); - \draw (0,0) circle (1cm); + \draw (0,0) circle [radius=1cm]; \end{tikzpicture} \end{codeexample} @@ -380,7 +376,7 @@ rectangle. So, let us add two rectangles to the picture: \begin{tikzpicture} \draw (-1.5,0) -- (1.5,0); \draw (0,-1.5) -- (0,1.5); - \draw (0,0) circle (1cm); + \draw (0,0) circle [radius=1cm]; \draw (0,0) rectangle (0.5,0.5); \draw (-0.5,-0.5) rectangle (-1,-1); \end{tikzpicture} @@ -415,7 +411,7 @@ For Karl, the following code could be used: \begin{tikzpicture} \draw (-1.5,0) -- (1.5,0); \draw (0,-1.5) -- (0,1.5); - \draw (0,0) circle (1cm); + \draw (0,0) circle [radius=1cm]; \draw[step=.5cm] (-1.4,-1.4) grid (1.4,1.4); \end{tikzpicture} \end{codeexample} @@ -434,7 +430,7 @@ top. \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4); \draw (-1.5,0) -- (1.5,0); \draw (0,-1.5) -- (0,1.5); - \draw (0,0) circle (1cm); + \draw (0,0) circle [radius=1cm]; \end{tikzpicture} \end{codeexample} @@ -508,18 +504,16 @@ very thick lines, |ultra thick| yields really, really thick lines and |ultra thin| yields lines that are so thin that low-resolution printers and displays will have trouble showing them. He wonders what gives lines of ``normal'' thickness. It turns out that |thin| is the correct -choice. This seems strange to Karl, but his son explains him that -\LaTeX\ has two commands called |\thinlines| and |\thicklines| and -that |\thinlines| gives the line width of ``normal'' lines, more -precisely, of the thickness that, say, the stem of a letter like ``T'' -or ``i'' has. Nevertheless, Karl would like to know whether there is +choice, since it gives the same thickness as \TeX's |\hrule| +command. Nevertheless, Karl would like to know whether there is anything ``in the middle'' between |thin| and |thick|. There is: |semithick|. Another useful thing one can do with lines is to dash or dot them. For this, the two styles |dashed| and |dotted| can be used, yielding -\tikz \draw[dashed] (0,0) -- (10pt,0pt); and \tikz \draw[dotted] (0,0) --- (10pt,0pt);. Both options also exist in a loose and a dense +\tikz[baseline] \draw[dashed] (0,.5ex) -- ++(2em,0pt); and +\tikz[baseline] \draw[dotted] (0,.5ex) +-- ++(2em,0pt);. Both options also exist in a loose and a dense version, called |loosely dashed|, |densely dashed|, |loosely dotted|, and |densely dotted|. If he really, really needs to, Karl can also define much more complex dashing patterns with the |dash pattern| @@ -533,26 +527,23 @@ patterns are evil. Karl's students do not care about dashing patterns. Our next obstacle is to draw the arc for the angle. For this, the |arc| path construction operation is useful, which draws part of a -circle or ellipse. This |arc| operation must be followed by a triple in -rounded brackets, where the components of the triple are separated by -colons. The first two components are angles, the last one is a -radius. An example would be |(10:80:10pt)|, which means ``an arc from -10 degrees to 80 degrees on a circle of radius 10pt.'' Karl obviously +circle or ellipse. This |arc| operation is followed by options in +brackets that specify the arc. An example would be \texttt{arc[start + angle=10, end angle=80, radius=10pt]}, which means exactly what it +says. Karl obviously needs an arc from $0^\circ$ to $30^\circ$. The radius should be something relatively small, perhaps around one third of the circle's -radius. This gives: |(0:30:3mm)|. - -When one uses the arc path construction operation, the specified arc will -be added with its starting point at the current position. So, we first -have to ``get there.'' +radius. When one uses the arc path construction operation, the +specified arc will be added with its starting point at the current +position. So, we first have to ``get there.'' \begin{codeexample}[] \begin{tikzpicture} \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4); \draw (-1.5,0) -- (1.5,0); \draw (0,-1.5) -- (0,1.5); - \draw (0,0) circle (1cm); - \draw (3mm,0mm) arc (0:30:3mm); + \draw (0,0) circle [radius=1cm]; + \draw (3mm,0mm) arc [start angle=0, end angle=30, radius=3mm]; \end{tikzpicture} \end{codeexample} @@ -567,8 +558,8 @@ causes this option to apply to everything within. \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4); \draw (-1.5,0) -- (1.5,0); \draw (0,-1.5) -- (0,1.5); - \draw (0,0) circle (1cm); - \draw (3mm,0mm) arc (0:30:3mm); + \draw (0,0) circle [radius=1cm]; + \draw (3mm,0mm) arc [start angle=0, end angle=30, radius=3mm]; \end{tikzpicture} \end{codeexample} @@ -576,7 +567,9 @@ As for circles, you can specify ``two'' radii in order to get an elliptical arc. \begin{codeexample}[] - \tikz \draw (0,0) arc (0:315:1.75cm and 1cm); + \tikz \draw (0,0) + arc [start angle=0, end angle=315, + x radius=1.75cm, y radius=1cm]; \end{codeexample} @@ -585,7 +578,7 @@ elliptical arc. In order to save space in this manual, it would be nice to clip Karl's graphics a bit so that we can focus on the ``interesting'' parts. Clipping is pretty easy in \tikzname. You can use the |\clip| -command clip all subsequent drawing. It works like |\draw|, only it +command to clip all subsequent drawing. It works like |\draw|, only it does not draw anything, but uses the given path to clip everything subsequently. @@ -595,8 +588,8 @@ subsequently. \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4); \draw (-1.5,0) -- (1.5,0); \draw (0,-1.5) -- (0,1.5); - \draw (0,0) circle (1cm); - \draw (3mm,0mm) arc (0:30:3mm); + \draw (0,0) circle [radius=1cm]; + \draw (3mm,0mm) arc [start angle=0, end angle=30, radius=3mm]; \end{tikzpicture} \end{codeexample} @@ -614,8 +607,8 @@ and |\clip| is a shorthand for |\path[clip]| and you could also say \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4); \draw (-1.5,0) -- (1.5,0); \draw (0,-1.5) -- (0,1.5); - \draw (0,0) circle (1cm); - \draw (3mm,0mm) arc (0:30:3mm); + \draw (0,0) circle [radius=1cm]; + \draw (3mm,0mm) arc [start angle=0, end angle=30, radius=3mm]; \end{tikzpicture} \end{codeexample} @@ -666,13 +659,14 @@ with a very light green. For this he uses |\fill| instead of \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4); \draw (-1.5,0) -- (1.5,0); \draw (0,-1.5) -- (0,1.5); - \draw (0,0) circle (1cm); - \fill[green!20!white] (0,0) -- (3mm,0mm) arc (0:30:3mm) -- (0,0); + \draw (0,0) circle [radius=1cm]; + \fill[green!20!white] (0,0) -- (3mm,0mm) + arc [start angle=0, end angle=30, radius=3mm] -- (0,0); \end{tikzpicture} \end{codeexample} The color |green!20!white| means 20\% green and 80\% white mixed -together. Such color expression are possible since \pgfname\ uses Uwe +together. Such color expression are possible since \tikzname\ uses Uwe Kern's |xcolor| package, see the documentation of that package for details on color expressions. @@ -681,7 +675,8 @@ What would have happened, if Karl had not ``closed'' the path using so this could have been omitted. Indeed, it would even have been better to write the following, instead: \begin{codeexample}[code only] - \fill[green!20!white] (0,0) -- (3mm,0mm) arc (0:30:3mm) -- cycle; + \fill[green!20!white] (0,0) -- (3mm,0mm) + arc [start angle=0, end angle=30, radius=3mm] -- cycle; \end{codeexample} The |--cycle| causes the current path to be closed (actually the current part of the current path) by smoothly joining the first and @@ -708,9 +703,9 @@ arguments like this: \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4); \draw (-1.5,0) -- (1.5,0); \draw (0,-1.5) -- (0,1.5); - \draw (0,0) circle (1cm); - \filldraw[fill=green!20!white, draw=green!50!black] - (0,0) -- (3mm,0mm) arc (0:30:3mm) -- cycle; + \draw (0,0) circle [radius=1cm]; + \filldraw[fill=green!20!white, draw=green!50!black] (0,0) -- (3mm,0mm) + arc [start angle=0, end angle=30, radius=3mm] -- cycle; \end{tikzpicture} \end{codeexample} @@ -719,7 +714,7 @@ arguments like this: \subsection{Shading} Karl briefly considers the possibility of making the angle ``more -fancy'' by \emph{shading} it. Instead of filling the with a uniform +fancy'' by \emph{shading} it. Instead of filling the area with a uniform color, a smooth transition between different colors is used. For this, |\shade| and |\shadedraw|, for shading and drawing at the same time, can be used: @@ -747,9 +742,10 @@ For Karl, the following might be appropriate: \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4); \draw (-1.5,0) -- (1.5,0); \draw (0,-1.5) -- (0,1.5); - \draw (0,0) circle (1cm); + \draw (0,0) circle [radius=1cm]; \shadedraw[left color=gray,right color=green, draw=green!50!black] - (0,0) -- (3mm,0mm) arc (0:30:3mm) -- cycle; + (0,0) -- (3mm,0mm) + arc [start angle=0, end angle=30, radius=3mm] -- cycle; \end{tikzpicture} \end{codeexample} @@ -760,7 +756,7 @@ adding anything to the picture. \subsection{Specifying Coordinates} Karl now wants to add the sine and cosine lines. He knows already that -he can use the |color=| option to set the lines's colors. So, what is +he can use the |color=| option to set the lines' colors. So, what is the best way to specify the coordinates? There are different ways of specifying coordinates. The easiest way is @@ -788,9 +784,9 @@ For example, we can draw the sine line as follows: \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4); \draw (-1.5,0) -- (1.5,0); \draw (0,-1.5) -- (0,1.5); - \draw (0,0) circle (1cm); - \filldraw[fill=green!20,draw=green!50!black] - (0,0) -- (3mm,0mm) arc (0:30:3mm) -- cycle; + \draw (0,0) circle [radius=1cm]; + \filldraw[fill=green!20,draw=green!50!black] (0,0) -- (3mm,0mm) + arc [start angle=0, end angle=30, radius=3mm] -- cycle; \draw[red,very thick] (30:1cm) -- +(0,-0.5); \end{tikzpicture} \end{codeexample} @@ -813,15 +809,15 @@ Next, let us draw the cosine line. One way would be to say \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4); \draw (-1.5,0) -- (1.5,0); \draw (0,-1.5) -- (0,1.5); - \draw (0,0) circle (1cm); - \filldraw[fill=green!20,draw=green!50!black] (0,0) -- (3mm,0mm) arc - (0:30:3mm) -- cycle; + \draw (0,0) circle [radius=1cm]; + \filldraw[fill=green!20,draw=green!50!black] (0,0) -- (3mm,0mm) + arc [start angle=0, end angle=30, radius=3mm] -- cycle; \draw[red,very thick] (30:1cm) -- +(0,-0.5); \draw[blue,very thick] (30:1cm) ++(0,-0.5) -- (0,0); \end{tikzpicture} \end{codeexample} -Note the there is no |--| between |(30:1cm)| and |++(0,-0.5)|. In +Note that there is no |--| between |(30:1cm)| and |++(0,-0.5)|. In detail, this path is interpreted as follows: ``First, the |(30:1cm)| tells me to move by pen to $(\cos 30^\circ,1/2)$. Next, there comes another coordinate specification, so I move my pen there without drawing @@ -861,9 +857,18 @@ economically like this (either with a single of a double |+|): \subsection{Intersecting Paths} Karl is left with the line for $\tan \alpha$, which seems difficult to -specify using transformations and polar coordinates. For this he needs -another way of specifying coordinates: Karl can specify intersections -of paths as coordinates. The line for $\tan \alpha$ starts at $(1,0)$ +specify using transformations and polar coordinates. The first -- and +easiest -- thing he can do is so simply use the coordinate +|(1,{tan(30)})| since \tikzname's math engine knows how to compute +things like |tan(30)|. Note the added braces since, otherwise, +\tikzname's parser would think that the first closing parenthesis ends +the coordinate (in general, you need to add braces around components +of coordinates when these components contain parentheses). + +Karl can, however, also use a more elaborate, but also more +``geometric'' way of computing the length of the orange line: He can +specify intersections of paths as coordinates. The line for $\tan +\alpha$ starts at $(1,0)$ and goes upward to a point that is at the intersection of a line going ``up'' and a line going from the origin through |(30:1cm)|. Such computations are made available by the |intersections| library. @@ -889,7 +894,7 @@ later reference. Karl now wants to add the little arrow tips at the end of the axes. He has noticed that in many plots, even in scientific journals, these arrow tips -seem to missing, presumably because the generating programs cannot +seem to be missing, presumably because the generating programs cannot produce them. Karl thinks arrow tips belong at the end of axes. His son agrees. His students do not care about arrow tips. @@ -902,9 +907,9 @@ It turns out that adding arrow tips is pretty easy: Karl adds the option \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4); \draw[->] (-1.5,0) -- (1.5,0); \draw[->] (0,-1.5) -- (0,1.5); - \draw (0,0) circle (1cm); - \filldraw[fill=green!20,draw=green!50!black] (0,0) -- (3mm,0mm) arc - (0:30:3mm) -- cycle; + \draw (0,0) circle [radius=1cm]; + \filldraw[fill=green!20,draw=green!50!black] (0,0) -- (3mm,0mm) + arc [start angle=0, end angle=30, radius=3mm] -- cycle; \draw[red,very thick] (30:1cm) -- +(0,-0.5); \draw[blue,very thick] (30:1cm) ++(0,-0.5) -- (0,0); @@ -921,38 +926,35 @@ arrow tips at both ends of the path. There are certain restrictions to the kind of paths to which arrow tips can be added. As a rule of thumb, you can add arrow tips only to a -single open ``line.'' For example, you should not try to add tips to, -say, a rectangle or a circle. (You can try, but no guarantees as to what -will happen now or in future versions.) However, you can add arrow +single open ``line.'' For example, you cannot add tips to, +say, a rectangle or a circle. However, you can add arrow tips to curved paths and to paths that have several segments, as in the following examples: \begin{codeexample}[] \begin{tikzpicture} - \draw [<->] (0,0) arc (180:30:10pt); + \draw [<->] (0,0) arc [start angle=180, end angle=30, radius=10pt]; \draw [<->] (1,0) -- (1.5cm,10pt) -- (2cm,0pt) -- (2.5cm,10pt); \end{tikzpicture} \end{codeexample} Karl has a more detailed look at the arrow that \tikzname\ puts at the -end. It looks like this when he zooms it: \tikz { \useasboundingbox - (0pt,-.5ex) rectangle (10pt,.5ex); \draw[->,line width=1pt] (0pt,0pt) -- - (10pt,0pt); }. The shape seems vaguely familiar and, indeed, this is -exactly the end of \TeX's standard arrow used in something like -$f\colon A \to B$. - +end. It looks like this when he zooms it: \tikz[baseline] +\draw[->,line width=1pt] (0pt,.5ex) -- ++(10pt,0pt);. The shape seems +vaguely familiar and, indeed, this is exactly the end of \TeX's +standard arrow used in something like $f\colon A \to B$. Karl likes the arrow, especially since it is not ``as thick'' as the arrows offered by many other packages. However, he expects that, sometimes, he might need to use some other kinds of arrow. -To do so, Karl can say |>=|\meta{right arrow tip kind}, where -\meta{right arrow tip kind} is a special arrow tip specification. For -example, if Karl says |>=stealth|, then he tells \tikzname\ +To do so, Karl can say |>=|\meta{kind of end arrow tip}, where +\meta{kind of end arrow tip} is a special arrow tip specification. For +example, if Karl says |>=Stealth|, then he tells \tikzname\ that he would like ``stealth-fighter-like'' arrow tips: \begin{codeexample}[] -\begin{tikzpicture}[>=stealth] - \draw [->] (0,0) arc (180:30:10pt); +\begin{tikzpicture}[>=Stealth] + \draw [->] (0,0) arc [start angle=180, end angle=30, radius=10pt]; \draw [<<-,very thick] (1,0) -- (1.5cm,10pt) -- (2cm,0pt) -- (2.5cm,10pt); \end{tikzpicture} \end{codeexample}%>> @@ -962,12 +964,9 @@ necessary. He is not really mollified when his son tells him that Microsoft's PowerPoint uses the same name. He decides to have his students discuss this at some point. -In addition to |stealth| there are several other predefined arrow tip -kinds Karl can choose from, see -Section~\ref{section-library-arrows}. Furthermore, he can define -arrows types himself, if he needs new ones. - - +In addition to |Stealth| there are several other predefined kinds of +arrow tips Karl can choose from, see Section~\ref{section-arrows}. Furthermore, +he can define arrows types himself, if he needs new ones. \subsection{Scoping} @@ -1016,7 +1015,7 @@ can be given anywhere on the path. So, instead of |\draw (0,0) [thin] -- (1,0);| or |\draw (0,0) -- (1,0) [thin];|; all of these have the same effect. This might seem strange since in the last case, it would appear that the |thin| should take effect only -``after'' the line from $(0,0)$ to $(1,0)$ has been draw. However, +``after'' the line from $(0,0)$ to $(1,0)$ has been drawn. However, most graphic options only apply to the whole path. Indeed, if you say both |thin| and |thick| on the same path, the last option given will ``win.'' @@ -1035,11 +1034,11 @@ apply only to this path. When you specify a coordinate like |(1cm,1cm)|, where is that coordinate placed on the page? To determine the position, \tikzname, \TeX, and \textsc{pdf} or PostScript all apply certain transformations -to the given coordinate in order to determine the finally position on +to the given coordinate in order to determine the final position on the page. \tikzname\ provides numerous options that allow you to transform -coordinates in \pgfname's private coordinate system. For example, the +coordinates in \tikzname's private coordinate system. For example, the |xshift| option allows you to shift all subsequent points by a certain amount: @@ -1049,15 +1048,15 @@ amount: It is important to note that you can change transformation ``in the middle of a path,'' a feature that is not supported by \pdf\ -or PostScript. The reason is that \pgfname\ keeps track of its own +or PostScript. The reason is that \tikzname\ keeps track of its own transformation matrix. Here is a more complicated example: \begin{codeexample}[] \begin{tikzpicture}[even odd rule,rounded corners=2pt,x=10pt,y=10pt] - \filldraw[fill=examplefill] (0,0) rectangle (1,1) - [xshift=5pt,yshift=5pt] (0,0) rectangle (1,1) - [rotate=30] (-1,-1) rectangle (2,2); + \filldraw[fill=yellow!80!black] (0,0) rectangle (1,1) + [xshift=5pt,yshift=5pt] (0,0) rectangle (1,1) + [rotate=30] (-1,-1) rectangle (2,2); \end{tikzpicture} \end{codeexample} @@ -1084,11 +1083,11 @@ $-1/2$, $1/2$, and $1$. For this, it would be nice to use some kind of these positions. There are different packages for doing this. \LaTeX\ has its own internal command for this, |pstricks| comes along with the powerful |\multido| command. All of these can be used together with -\pgfname\ and \tikzname, so if you are familiar with them, feel free to -use them. \pgfname\ introduces yet another command, called |\foreach|, +\tikzname, so if you are familiar with them, feel free to +use them. \tikzname\ introduces yet another command, called |\foreach|, which I introduced since I could never remember the syntax of the other packages. |\foreach| is defined in the package |pgffor| and can be used -independently of \pgfname. \tikzname\ includes it automatically. +independently \tikzname, but \tikzname\ includes it automatically. In its basic form, the |\foreach| command is easy to use: \begin{codeexample}[] @@ -1107,11 +1106,11 @@ For Karl and the ticks on the axes, he could use the following code: \begin{tikzpicture}[scale=3] \clip (-0.1,-0.2) rectangle (1.1,1.51); \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4); - \filldraw[fill=green!20,draw=green!50!black] (0,0) -- (3mm,0mm) arc - (0:30:3mm) -- cycle; + \filldraw[fill=green!20,draw=green!50!black] (0,0) -- (3mm,0mm) + arc [start angle=0, end angle=30, radius=3mm] -- cycle; \draw[->] (-1.5,0) -- (1.5,0); \draw[->] (0,-1.5) -- (0,1.5); - \draw (0,0) circle (1cm); + \draw (0,0) circle [radius=1cm]; \foreach \x in {-1cm,-0.5cm,1cm} \draw (\x,-1pt) -- (\x,1pt); @@ -1189,7 +1188,7 @@ path has been completely drawn/filled/shaded/clipped/whatever. \begin{codeexample}[] \begin{tikzpicture} \draw (0,0) rectangle (2,2); - \draw (0.5,0.5) node [fill=examplefill] + \draw (0.5,0.5) node [fill=yellow!80!black] {Text at \verb!node 1!} -- (1.5,1.5) node {Text at \verb!node 2!}; \end{tikzpicture} @@ -1201,7 +1200,7 @@ right of these positions. For this, every node object that you put in your picture is equipped with several \emph{anchors}. For example, the |north| anchor is in the middle at the upper end of the shape, the |south| anchor is at the bottom and the |north east| anchor is in -the upper right corner. When you given the option |anchor=north|, the +the upper right corner. When you give the option |anchor=north|, the text will be placed such that this northern anchor will lie on the current position and the text is, thus, below the current position. Karl uses this to draw the ticks as follows: @@ -1210,10 +1209,10 @@ position. Karl uses this to draw the ticks as follows: \begin{tikzpicture}[scale=3] \clip (-0.6,-0.2) rectangle (0.6,1.51); \draw[step=.5cm,help lines] (-1.4,-1.4) grid (1.4,1.4); - \filldraw[fill=green!20,draw=green!50!black] - (0,0) -- (3mm,0mm) arc (0:30:3mm) -- cycle; + \filldraw[fill=green!20,draw=green!50!black] (0,0) -- (3mm,0mm) + arc [start angle=0, end angle=30, radius=3mm] -- cycle; \draw[->] (-1.5,0) -- (1.5,0); \draw[->] (0,-1.5) -- (0,1.5); - \draw (0,0) circle (1cm); + \draw (0,0) circle [radius=1cm]; \foreach \x in {-1,-0.5,1} \draw (\x cm,1pt) -- (\x cm,-1pt) node[anchor=north] {$\x$}; @@ -1258,10 +1257,10 @@ will be used again. So, here is the new code for the ticks: \begin{tikzpicture}[scale=3] \clip (-0.6,-0.2) rectangle (0.6,1.51); \draw[step=.5cm,help lines] (-1.4,-1.4) grid (1.4,1.4); - \filldraw[fill=green!20,draw=green!50!black] - (0,0) -- (3mm,0mm) arc (0:30:3mm) -- cycle; + \filldraw[fill=green!20,draw=green!50!black] (0,0) -- (3mm,0mm) + arc [start angle=0, end angle=30, radius=3mm] -- cycle; \draw[->] (-1.5,0) -- (1.5,0); \draw[->] (0,-1.5) -- (0,1.5); - \draw (0,0) circle (1cm); + \draw (0,0) circle [radius=1cm]; \foreach \x/\xtext in {-1, -0.5/-\frac{1}{2}, 1} \draw (\x cm,1pt) -- (\x cm,-1pt) node[anchor=north] {$\xtext$}; @@ -1280,7 +1279,7 @@ with a white color. The next thing Karl wants to do is to add the labels like $\sin \alpha$. For this, he would like to place a label ``in the middle of -line.'' To do so, instead of specifying the label +the line.'' To do so, instead of specifying the label |node {$\sin\alpha$}| directly after one of the endpoints of the line (which would place the label at that endpoint), Karl can give the label directly after @@ -1294,11 +1293,11 @@ modify this position: \begin{tikzpicture}[scale=3] \clip (-2,-0.2) rectangle (2,0.8); \draw[step=.5cm,gray,very thin] (-1.4,-1.4) grid (1.4,1.4); - \filldraw[fill=green!20,draw=green!50!black] (0,0) -- (3mm,0mm) arc - (0:30:3mm) -- cycle; + \filldraw[fill=green!20,draw=green!50!black] (0,0) -- (3mm,0mm) + arc [start angle=0, end angle=30, radius=3mm] -- cycle; \draw[->] (-1.5,0) -- (1.5,0) coordinate (x axis); \draw[->] (0,-1.5) -- (0,1.5) coordinate (y axis); - \draw (0,0) circle (1cm); + \draw (0,0) circle [radius=1cm]; \draw[very thick,red] (30:1cm) -- node[left=1pt,fill=white] {$\sin \alpha$} (30:1cm |- x axis); @@ -1347,9 +1346,6 @@ desired effect. So, here is the full code: important line/.style={very thick}, information text/.style={rounded corners,fill=red!10,inner sep=1ex}] - % Local definitions - \def\costhirty{0.8660256} - % Colors \colorlet{anglecolor}{green!50!black} \colorlet{sincolor}{red} @@ -1359,7 +1355,7 @@ desired effect. So, here is the full code: % The graphic \draw[help lines,step=0.5cm] (-1.4,-1.4) grid (1.4,1.4); - \draw (0,0) circle (1cm); + \draw (0,0) circle [radius=1cm]; \begin{scope}[axes] \draw[->] (-1.5,0) -- (1.5,0) node[right] {$x$} coordinate(x axis); @@ -1372,7 +1368,8 @@ desired effect. So, here is the full code: \draw[yshift=\y cm] (1pt,0pt) -- (-1pt,0pt) node[left,fill=white] {$\ytext$}; \end{scope} - \filldraw[fill=green!20,draw=anglecolor] (0,0) -- (3mm,0pt) arc(0:30:3mm); + \filldraw[fill=green!20,draw=anglecolor] (0,0) -- (3mm,0pt) + arc [start angle=0, end angle=30, radius=3mm]; \draw (15:2mm) node[anglecolor] {$\alpha$}; \draw[important line,sincolor] @@ -1403,3 +1400,58 @@ desired effect. So, here is the full code: }; \end{tikzpicture} \end{codeexample} + + + +\subsection{Pics: The Angle Revisited} + +Karl expects that the code of certain parts of the picture he created +might be so useful that he might wish to reuse them in the +future. A natural thing to do is to create \TeX\ macros that store +the code he wishes to reuse. However, \tikzname\ offers another way +that is integrated directly into its parser: pics! + +A ``pic'' is ``not quite a full picture,'' hence the short name. The +idea is that a pic is simply some code that you can add to a picture +at different places using the |pic| command whose syntax is almost +identical to the |node| command. The main difference is that instead +of specifying some text in curly braces that should be shown, you +specify the name of a predefined picture that should be shown. + +Defining new pics is easy enough, see Section~\ref{section-pics}, but +right now we just want to use one such predefined pic: the |angle| +pic. As the name suggests, it is a small drawing of an angle +consisting of a little wedge and an arc together with some text (Karl +needs to load the |angle| library and the |quotes| for the following +examples). What makes this pic useful is the fact that the size of the +wedge will be computed automatically. + +The |angle| pic draws an angle between the two lines $BA$ and $BC$, +where $A$, $B$, and $C$ are three coordinates. In our case, $B$ is the +origin, $A$ is somewhere on the $x$-axis and $C$ is somewhere on a +line at $30^\circ$. + +\begin{codeexample}[] +\begin{tikzpicture}[scale=3] + \coordinate (A) at (1,0); + \coordinate (B) at (0,0); + \coordinate (C) at (30:1cm); + + \draw (A) -- (B) -- (C) + pic [draw=green!50!black, fill=green!20, angle radius=9mm, + "$\alpha$"] {angle = A--B--C}; +\end{tikzpicture} +\end{codeexample} + +Let us see, what is happening here. First we have specified three +\emph{coordinates} using the |\coordinate| command. It allows us to +name a specific coordinate in the picture. Then comes something that +starts as a normal |\draw|, but then comes the |pic| command. This +command gets lots of options and, in curly braces, comes the most +important point: We specify that we want to add an |angle| pic and +this angle should be between the points we named |A|, |B|, and |C| (we +could use other names). Note that the text that we want to be shown in +the pic is specified in quotes inside the options of the |pic|, not +inside the curly braces. + +To learn more about pics, please see Section~\ref{section-pics}.
\ No newline at end of file diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/plots/pgf-tan-example.gnuplot b/Master/texmf-dist/doc/generic/pgf/text-en/plots/pgf-tan-example.gnuplot new file mode 100644 index 00000000000..0b0a1ad8ff3 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/plots/pgf-tan-example.gnuplot @@ -0,0 +1,2 @@ +set table "plots/pgf-tan-example.table"; set format "%.5f" +set samples 100.0; plot [x=-3.141:3.141] [-3:3]tan(x) diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/plots/pgf-tan-example.table b/Master/texmf-dist/doc/generic/pgf/text-en/plots/pgf-tan-example.table new file mode 100644 index 00000000000..63beeda4b7a --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/plots/pgf-tan-example.table @@ -0,0 +1,104 @@ + +#Curve 0 of 1, 100 points +#x y type +-3.14100 0.00059 i +-3.07755 0.06413 i +-3.01409 0.12820 i +-2.95064 0.19331 i +-2.88718 0.26005 i +-2.82373 0.32902 i +-2.76027 0.40094 i +-2.69682 0.47663 i +-2.63336 0.55704 i +-2.56991 0.64335 i +-2.50645 0.73701 i +-2.44300 0.83989 i +-2.37955 0.95436 i +-2.31609 1.08360 i +-2.25264 1.23197 i +-2.18918 1.40553 i +-2.12573 1.61314 i +-2.06227 1.86816 i +-1.99882 2.19188 i +-1.93536 2.62036 i +-1.87191 3.22003 o +-1.80845 4.12820 o +-1.74500 5.68222 o +-1.68155 8.99247 o +-1.61809 21.12830 o +-1.55464 -61.87594 o +-1.49118 -12.53398 o +-1.42773 -6.94188 o +-1.36427 -4.77302 o +-1.30082 -3.61357 o +-1.23736 -2.88713 i +-1.17391 -2.38590 i +-1.11045 -2.01664 i +-1.04700 -1.73126 i +-0.98355 -1.50245 i +-0.92009 -1.31351 i +-0.85664 -1.15368 i +-0.79318 -1.01569 i +-0.72973 -0.89443 i +-0.66627 -0.78621 i +-0.60282 -0.68828 i +-0.53936 -0.59856 i +-0.47591 -0.51542 i +-0.41245 -0.43755 i +-0.34900 -0.36390 i +-0.28555 -0.29357 i +-0.22209 -0.22582 i +-0.15864 -0.15998 i +-0.09518 -0.09547 i +-0.03173 -0.03174 i +0.03173 0.03174 i +0.09518 0.09547 i +0.15864 0.15998 i +0.22209 0.22582 i +0.28555 0.29357 i +0.34900 0.36390 i +0.41245 0.43755 i +0.47591 0.51542 i +0.53936 0.59856 i +0.60282 0.68828 i +0.66627 0.78621 i +0.72973 0.89443 i +0.79318 1.01569 i +0.85664 1.15368 i +0.92009 1.31351 i +0.98355 1.50245 i +1.04700 1.73126 i +1.11045 2.01664 i +1.17391 2.38590 i +1.23736 2.88713 i +1.30082 3.61357 o +1.36427 4.77302 o +1.42773 6.94188 o +1.49118 12.53398 o +1.55464 61.87594 o +1.61809 -21.12830 o +1.68155 -8.99247 o +1.74500 -5.68222 o +1.80845 -4.12820 o +1.87191 -3.22003 o +1.93536 -2.62036 i +1.99882 -2.19188 i +2.06227 -1.86816 i +2.12573 -1.61314 i +2.18918 -1.40553 i +2.25264 -1.23197 i +2.31609 -1.08360 i +2.37955 -0.95436 i +2.44300 -0.83989 i +2.50645 -0.73701 i +2.56991 -0.64335 i +2.63336 -0.55704 i +2.69682 -0.47663 i +2.76027 -0.40094 i +2.82373 -0.32902 i +2.88718 -0.26005 i +2.95064 -0.19331 i +3.01409 -0.12820 i +3.07755 -0.06413 i +3.14100 -0.00059 i + diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/texmf.cnf b/Master/texmf-dist/doc/generic/pgf/text-en/texmf.cnf deleted file mode 100644 index 4235f281312..00000000000 --- a/Master/texmf-dist/doc/generic/pgf/text-en/texmf.cnf +++ /dev/null @@ -1,83 +0,0 @@ -% Part 3: Array and other sizes for TeX (and Metafont and MetaPost). -% -% If you want to change some of these sizes only for a certain TeX -% variant, the usual dot notation works, e.g., -% main_memory.hugetex = 20000000 -% -% If a change here appears to be ignored, try redumping the format file -% with fmtutil-sys. - -% Memory. Must be less than 8,000,000 total. -% -% main_memory is relevant only to initex, extra_mem_* only to non-ini. -% Thus, have to redump the .fmt file after changing main_memory; to add -% to existing fmt files, increase extra_mem_*. (To get an idea of how -% much, try \tracingstats=2 in your TeX source file; -% web2c/tests/memtest.tex might also be interesting.) -% -% To increase space for boxes (as might be needed by, e.g., PiCTeX), -% increase extra_mem_bot. -% -% For some xy-pic samples, you may need as much as 700000 words of memory. -% For the vast majority of documents, 60000 or less will do. -% -main_memory = 9000000 % words of inimemory available; also applies to inimf&mp -extra_mem_top = 6000000 % extra high memory for chars, tokens, etc. -extra_mem_bot = 6000000 % extra low memory for boxes, glue, breakpoints, etc. - -% Words of font info for TeX (total size of all TFM files, approximately). -% Must be >= 20000 and <= 4000000 (without tex.ch changes). -%font_mem_size = 1200000 - -% Total number of fonts. Must be >= 50 and <= 2000 (without tex.ch changes). -%font_max = 2000 - -% Extra space for the hash table of control sequences (which allows 10K -% names as distributed). -hash_extra = 200000 - -% Max number of characters in all strings, including all error messages, -% help texts, font names, control sequences. These values apply to TeX and MP. -pool_size = 3850000 -% Minimum pool space after TeX/MP's own strings; must be at least -% 25000 less than pool_size, but doesn't need to be nearly that large. -%string_vacancies = 90000 -% Maximum number of strings. -%max_strings = 100000 -% min pool space left after loading .fmt -%pool_free = 47500 - -% Buffer size. TeX uses the buffer to contain input lines, but macro -% expansion works by writing material into the buffer and reparsing the -% line. As a consequence, certain constructs require the buffer to be -% very large, even though most documents can be handled with a small value. -%buf_size = 200000 - -% Hyphenation trie. The maximum possible is 4194303 (ssup_trie_size in -% the sources), but we don't need that much. The value here suffices -% for all known free hyphenation patterns to be loaded simultaneously -% (as TeX Live does). -% -%trie_size = 400000 - -%hyph_size = 8191 % prime number of hyphenation exceptions, >610, <32767. - % http://primes.utm.edu/curios/page.php/8191.html -%nest_size = 500 % simultaneous semantic levels (e.g., groups) -%max_in_open = 15 % simultaneous input files and error insertions -%param_size = 10000 % simultaneous macro parameters -%save_size = 5000 % for saving values outside current group -save_size=800000 -stack_size = 500000 % simultaneous input sources - - - - -% It's probably inadvisable to change these. At any rate, we must have: -% 45 < error_line < 255; -% 30 < half_error_line < error_line - 15; -% 60 <= max_print_line; -% These apply to Metafont and MetaPost as well. -error_line = 254 -half_error_line = 127 -max_print_line = 32000 - diff --git a/Master/texmf-dist/doc/generic/pgf/version-for-dvipdfm/pgfmanual-dvipdfm.cfg b/Master/texmf-dist/doc/generic/pgf/version-for-dvipdfm/pgfmanual-dvipdfm.cfg index cd6c2322fee..500c76d0058 100644 --- a/Master/texmf-dist/doc/generic/pgf/version-for-dvipdfm/pgfmanual-dvipdfm.cfg +++ b/Master/texmf-dist/doc/generic/pgf/version-for-dvipdfm/pgfmanual-dvipdfm.cfg @@ -8,6 +8,8 @@ % See the file doc/generic/pgf/licenses/LICENSE for more details. +\usepackage[hyphens]{url} + \usepackage[dvipdfm]{graphics} % This will tell everyone which driver we are using. diff --git a/Master/texmf-dist/doc/generic/pgf/version-for-dvipdfmx/en/Makefile b/Master/texmf-dist/doc/generic/pgf/version-for-dvipdfmx/en/Makefile index b0d1d980eec..aa777e23e39 100644 --- a/Master/texmf-dist/doc/generic/pgf/version-for-dvipdfmx/en/Makefile +++ b/Master/texmf-dist/doc/generic/pgf/version-for-dvipdfmx/en/Makefile @@ -12,6 +12,7 @@ pgfmanual.ind: pgfmanual.idx makeindex $(doc).idx pgfmanual.pdf: $(doc).tex $(doc).ind + mkdir -p plots (TEXINPUTS="$(TEXINPUTS)" $(latex) $(doc).tex) || true (egrep -q $(rerun) $(doc).log && TEXINPUTS="$(TEXINPUTS)" $(latex) $(doc).tex) || true dvipdfmx -p a4 $(doc) diff --git a/Master/texmf-dist/doc/generic/pgf/version-for-dvipdfmx/en/pgfmanual-test.tex b/Master/texmf-dist/doc/generic/pgf/version-for-dvipdfmx/en/pgfmanual-test.tex new file mode 100644 index 00000000000..c4d74a3e8da --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/version-for-dvipdfmx/en/pgfmanual-test.tex @@ -0,0 +1,25 @@ +% Copyright 2006 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\documentclass[a4paper]{ltxdoc} + +% pgf version is defined in \pgfversion in file +% generic/pgf/utilities/pgfrcs.code.tex + +\input{../pgfmanual-dvipdfmx.cfg} +\input{../../text-en/pgfmanual-en-main-preamble.tex} + +\begin{document} + +\hypertarget{foo}{Bar} +\hyperlink{foo}{to bar} + +\tikz [transparency group] \node {Smoking}; + +\end{document} diff --git a/Master/texmf-dist/doc/generic/pgf/version-for-dvipdfmx/pgfmanual-dvipdfmx.cfg b/Master/texmf-dist/doc/generic/pgf/version-for-dvipdfmx/pgfmanual-dvipdfmx.cfg index 7d619800b1b..2303efdbf5a 100644 --- a/Master/texmf-dist/doc/generic/pgf/version-for-dvipdfmx/pgfmanual-dvipdfmx.cfg +++ b/Master/texmf-dist/doc/generic/pgf/version-for-dvipdfmx/pgfmanual-dvipdfmx.cfg @@ -7,6 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. +\usepackage[hyphens]{url} \usepackage[dvipdfmx]{graphicx} % This will tell everyone which driver we are using. diff --git a/Master/texmf-dist/doc/generic/pgf/version-for-dvips/pgfmanual-dvips.cfg b/Master/texmf-dist/doc/generic/pgf/version-for-dvips/pgfmanual-dvips.cfg index 9051b2b3bfd..9f5e7f82c8a 100644 --- a/Master/texmf-dist/doc/generic/pgf/version-for-dvips/pgfmanual-dvips.cfg +++ b/Master/texmf-dist/doc/generic/pgf/version-for-dvips/pgfmanual-dvips.cfg @@ -8,6 +8,7 @@ % See the file doc/generic/pgf/licenses/LICENSE for more details. +\usepackage[hyphens]{url} \usepackage[dvips]{graphics} \usepackage{hyperref} diff --git a/Master/texmf-dist/doc/generic/pgf/version-for-luatex/en/Makefile b/Master/texmf-dist/doc/generic/pgf/version-for-luatex/en/Makefile new file mode 100644 index 00000000000..685f3468037 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/version-for-luatex/en/Makefile @@ -0,0 +1,45 @@ +rerun = "(There were undefined references|Rerun to get (cross-references|the bars) right)" +doc = pgfmanual +latex = lualatex +TEXINPUTS := ../../text-en:../../images:$(TEXINPUTS) + +all: $(doc).pdf + +dist: FORCE + $(latex) --jobname=pgfmanual '\def\pgfautoxrefs{1}\pdfminorversion=5 \pdfobjcompresslevel=2 \input{$(doc)}' + makeindex $(doc).idx + @echo "$(doc).pdf remade with auto-xref support. Check if auto-xrefs work and rerun make dist if not." + +pgfmanual.idx: + touch pgfmanual.idx + +pgfmanual.ind: pgfmanual.idx + makeindex $(doc).idx + +pgfmanual.pdf: $(doc).tex $(doc).ind + TEXINPUTS="$(TEXINPUTS)" $(latex) '$(linkcode)' $(doc).tex + (egrep -q $(rerun) $(doc).log && TEXINPUTS="$(TEXINPUTS)" $(latex) $(doc).tex) || true + @echo "Use 'make dist' to generate auto-xrefs." + +test: $(doc)-test.tex $(doc).ind + TEXINPUTS="$(TEXINPUTS)" $(latex) $(doc)-test.tex + (egrep -q $(rerun) $(doc).log && TEXINPUTS="$(TEXINPUTS)" $(latex) $(doc)-test.tex) || true + @echo "Use 'make dist' to generate auto-xrefs." + +FORCE: + +clean: + rm -f \ + plots/* \ + pgfmanual.out \ + pgfmanual.log \ + pgfmanual.idx \ + pgfmanual.ind \ + pgfmanual.ilg \ + pgfmanual.pdf \ + pgfmanual.toc \ + pgfmanual.bbl \ + pgfmanual.blg \ + pgfmanual.ps \ + pgfmanual.dvi \ + pgfmanual*.aux diff --git a/Master/texmf-dist/doc/generic/pgf/version-for-luatex/en/pgfmanual-test.tex b/Master/texmf-dist/doc/generic/pgf/version-for-luatex/en/pgfmanual-test.tex new file mode 100644 index 00000000000..9827f1a15a1 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/version-for-luatex/en/pgfmanual-test.tex @@ -0,0 +1,33 @@ +% Copyright 2006 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\documentclass[a4paper]{ltxdoc} + +% pgf version is defined in \pgfversion in file +% generic/pgf/utilities/pgfrcs.code.tex + +\input{../pgfmanual-luatex.cfg} +\input{../../text-en/pgfmanual-en-main-preamble.tex} + +\begin{document} + +\begin{key}{/tikz/graph/testy} + foo +\end{key} + +\tikzset{/tikz/testy/.style=} +\tikzset{/tikz/graph/testy/.style=} + +\begin{codeexample}[] + +\tikz \draw [graph/testy,testy] (0,0) -- (1,1); +\end{codeexample} + + +\end{document} diff --git a/Master/texmf-dist/doc/generic/pgf/version-for-luatex/en/pgfmanual.tex b/Master/texmf-dist/doc/generic/pgf/version-for-luatex/en/pgfmanual.tex new file mode 100644 index 00000000000..d1c6389a5c7 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/version-for-luatex/en/pgfmanual.tex @@ -0,0 +1,16 @@ +% Copyright 2006 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\documentclass[a4paper]{ltxdoc} + +% pgf version is defined in \pgfversion in file +% generic/pgf/utilities/pgfrcs.code.tex + +\input{../pgfmanual-luatex.cfg} +\input{../../text-en/pgfmanual-en-main.tex} diff --git a/Master/texmf-dist/doc/generic/pgf/version-for-luatex/pgfmanual-luatex.cfg b/Master/texmf-dist/doc/generic/pgf/version-for-luatex/pgfmanual-luatex.cfg new file mode 100644 index 00000000000..87f7a939757 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/version-for-luatex/pgfmanual-luatex.cfg @@ -0,0 +1,14 @@ +% Copyright 2006 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + +\usepackage[hyphens]{url} +\usepackage[pdfborder={0 0 0}]{hyperref} + +% Just make sure to compile this using lualatex. diff --git a/Master/texmf-dist/doc/generic/pgf/version-for-pdftex/en/Makefile b/Master/texmf-dist/doc/generic/pgf/version-for-pdftex/en/Makefile index 1983d547501..dabca5ae516 100644 --- a/Master/texmf-dist/doc/generic/pgf/version-for-pdftex/en/Makefile +++ b/Master/texmf-dist/doc/generic/pgf/version-for-pdftex/en/Makefile @@ -5,14 +5,8 @@ TEXINPUTS := ../../text-en:../../images:$(TEXINPUTS) all: $(doc).pdf -# make dist will also enable automatic cross references in codeexamples. -# This is disabled by default as it requires higher mem limits. -# -# It employs a 'texmf.cnf' which lies in ../../text-en. dist: FORCE - export TEXMFCNF="../../text-en:$(TEXMFCNF)"; \ - export TEXINPUTS="$(TEXINPUTS)"; \ - $(latex) '\def\pgfautoxrefs{1}\pdfminorversion=5 \pdfobjcompresslevel=2 \input{$(doc)}' + $(latex) --jobname=pgfmanual '\def\pgfautoxrefs{1}\pdfminorversion=5 \pdfobjcompresslevel=2 \input{$(doc)}' makeindex $(doc).idx @echo "$(doc).pdf remade with auto-xref support. Check if auto-xrefs work and rerun make dist if not." diff --git a/Master/texmf-dist/doc/generic/pgf/version-for-pdftex/en/pgfmanual.figlist b/Master/texmf-dist/doc/generic/pgf/version-for-pdftex/en/pgfmanual.figlist deleted file mode 100644 index 5bbdfc855da..00000000000 --- a/Master/texmf-dist/doc/generic/pgf/version-for-pdftex/en/pgfmanual.figlist +++ /dev/null @@ -1,1464 +0,0 @@ -pgfmanual-figure0 -pgfmanual-figure1 -pgfmanual-figure2 -pgfmanual-figure3 -pgfmanual-figure4 -pgfmanual-figure5 -pgfmanual-figure6 -pgfmanual-figure7 -pgfmanual-figure8 -pgfmanual-figure9 -pgfmanual-figure10 -pgfmanual-figure11 -pgfmanual-figure12 -pgfmanual-figure13 -pgfmanual-figure14 -pgfmanual-figure15 -pgfmanual-figure16 -pgfmanual-figure17 -pgfmanual-figure18 -pgfmanual-figure19 -pgfmanual-figure20 -pgfmanual-figure21 -pgfmanual-figure22 -pgfmanual-figure23 -pgfmanual-figure24 -pgfmanual-figure25 -pgfmanual-figure26 -pgfmanual-figure27 -pgfmanual-figure28 -pgfmanual-figure29 -pgfmanual-figure30 -pgfmanual-figure31 -pgfmanual-figure32 -pgfmanual-figure33 -pgfmanual-figure34 -pgfmanual-figure35 -pgfmanual-figure36 -pgfmanual-figure37 -pgfmanual-figure38 -pgfmanual-figure39 -pgfmanual-figure40 -pgfmanual-figure41 -pgfmanual-figure42 -pgfmanual-figure43 -pgfmanual-figure44 -pgfmanual-figure45 -pgfmanual-figure46 -pgfmanual-figure47 -pgfmanual-figure48 -pgfmanual-figure49 -pgfmanual-figure50 -pgfmanual-figure51 -pgfmanual-figure52 -pgfmanual-figure53 -pgfmanual-figure54 -pgfmanual-figure55 -pgfmanual-figure56 -pgfmanual-figure57 -pgfmanual-figure58 -pgfmanual-figure59 -pgfmanual-figure60 -pgfmanual-figure61 -pgfmanual-figure62 -pgfmanual-figure63 -pgfmanual-figure64 -pgfmanual-figure65 -pgfmanual-figure66 -pgfmanual-figure67 -pgfmanual-figure68 -pgfmanual-figure69 -pgfmanual-figure70 -pgfmanual-figure71 -pgfmanual-figure72 -pgfmanual-figure73 -pgfmanual-figure74 -pgfmanual-figure75 -pgfmanual-figure76 -pgfmanual-figure77 -pgfmanual-figure78 -pgfmanual-figure79 -pgfmanual-figure80 -pgfmanual-figure81 -pgfmanual-figure82 -pgfmanual-figure83 -pgfmanual-figure84 -pgfmanual-figure85 -pgfmanual-figure86 -pgfmanual-figure87 -pgfmanual-figure88 -pgfmanual-figure89 -pgfmanual-figure90 -pgfmanual-figure91 -pgfmanual-figure92 -pgfmanual-figure93 -pgfmanual-figure94 -pgfmanual-figure95 -pgfmanual-figure96 -pgfmanual-figure97 -pgfmanual-figure98 -pgfmanual-figure99 -pgfmanual-figure100 -pgfmanual-figure101 -pgfmanual-figure102 -pgfmanual-figure103 -pgfmanual-figure104 -pgfmanual-figure105 -pgfmanual-figure106 -pgfmanual-figure107 -pgfmanual-figure108 -pgfmanual-figure109 -pgfmanual-figure110 -pgfmanual-figure111 -pgfmanual-figure112 -pgfmanual-figure113 -pgfmanual-figure114 -pgfmanual-figure115 -pgfmanual-figure116 -pgfmanual-figure117 -pgfmanual-figure118 -pgfmanual-figure119 -pgfmanual-figure120 -pgfmanual-figure121 -pgfmanual-figure122 -pgfmanual-figure123 -pgfmanual-figure124 -pgfmanual-figure125 -pgfmanual-figure126 -pgfmanual-figure127 -pgfmanual-figure128 -pgfmanual-figure129 -pgfmanual-figure130 -pgfmanual-figure131 -pgfmanual-figure132 -pgfmanual-figure133 -pgfmanual-figure134 -pgfmanual-figure135 -pgfmanual-figure136 -pgfmanual-figure137 -pgfmanual-figure138 -pgfmanual-figure139 -pgfmanual-figure140 -pgfmanual-figure141 -pgfmanual-figure142 -pgfmanual-figure143 -pgfmanual-figure144 -pgfmanual-figure145 -pgfmanual-figure146 -pgfmanual-figure147 -pgfmanual-figure148 -pgfmanual-figure149 -pgfmanual-figure150 -pgfmanual-figure151 -pgfmanual-figure152 -pgfmanual-figure153 -pgfmanual-figure154 -pgfmanual-figure155 -pgfmanual-figure156 -pgfmanual-figure157 -pgfmanual-figure158 -pgfmanual-figure159 -pgfmanual-figure160 -pgfmanual-figure161 -pgfmanual-figure162 -pgfmanual-figure163 -pgfmanual-figure164 -pgfmanual-figure165 -pgfmanual-figure166 -pgfmanual-figure167 -pgfmanual-figure168 -pgfmanual-figure169 -pgfmanual-figure170 -pgfmanual-figure171 -pgfmanual-figure172 -pgfmanual-figure173 -pgfmanual-figure174 -pgfmanual-figure175 -pgfmanual-figure176 -pgfmanual-figure177 -pgfmanual-figure178 -pgfmanual-figure179 -pgfmanual-figure180 -pgfmanual-figure181 -pgfmanual-figure182 -pgfmanual-figure183 -pgfmanual-figure184 -pgfmanual-figure185 -pgfmanual-figure186 -pgfmanual-figure187 -pgfmanual-figure188 -pgfmanual-figure189 -pgfmanual-figure190 -pgfmanual-figure191 -pgfmanual-figure192 -pgfmanual-figure193 -pgfmanual-figure194 -pgfmanual-figure195 -pgfmanual-figure196 -pgfmanual-figure197 -pgfmanual-figure198 -pgfmanual-figure199 -pgfmanual-figure200 -pgfmanual-figure201 -pgfmanual-figure202 -pgfmanual-figure203 -pgfmanual-figure204 -pgfmanual-figure205 -pgfmanual-figure206 -pgfmanual-figure207 -pgfmanual-figure208 -pgfmanual-figure209 -pgfmanual-figure210 -pgfmanual-figure211 -pgfmanual-figure212 -pgfmanual-figure213 -pgfmanual-figure214 -pgfmanual-figure215 -pgfmanual-figure216 -pgfmanual-figure217 -pgfmanual-figure218 -pgfmanual-figure219 -pgfmanual-figure220 -pgfmanual-figure221 -pgfmanual-figure222 -pgfmanual-figure223 -pgfmanual-figure224 -pgfmanual-figure225 -pgfmanual-figure226 -pgfmanual-figure227 -pgfmanual-figure228 -pgfmanual-figure229 -pgfmanual-figure230 -pgfmanual-figure231 -pgfmanual-figure232 -pgfmanual-figure233 -pgfmanual-figure234 -pgfmanual-figure235 -pgfmanual-figure236 -pgfmanual-figure237 -pgfmanual-figure238 -pgfmanual-figure239 -pgfmanual-figure240 -pgfmanual-figure241 -pgfmanual-figure242 -pgfmanual-figure243 -pgfmanual-figure244 -pgfmanual-figure245 -pgfmanual-figure246 -pgfmanual-figure247 -pgfmanual-figure248 -pgfmanual-figure249 -pgfmanual-figure250 -pgfmanual-figure251 -pgfmanual-figure252 -pgfmanual-figure253 -pgfmanual-figure254 -pgfmanual-figure255 -pgfmanual-figure256 -pgfmanual-figure257 -pgfmanual-figure258 -pgfmanual-figure259 -pgfmanual-figure260 -pgfmanual-figure261 -pgfmanual-figure262 -pgfmanual-figure263 -pgfmanual-figure264 -pgfmanual-figure265 -pgfmanual-figure266 -pgfmanual-figure267 -pgfmanual-figure268 -pgfmanual-figure269 -pgfmanual-figure270 -pgfmanual-figure271 -pgfmanual-figure272 -pgfmanual-figure273 -pgfmanual-figure274 -pgfmanual-figure275 -pgfmanual-figure276 -pgfmanual-figure277 -pgfmanual-figure278 -pgfmanual-figure279 -pgfmanual-figure280 -pgfmanual-figure281 -pgfmanual-figure282 -pgfmanual-figure283 -pgfmanual-figure284 -pgfmanual-figure285 -pgfmanual-figure286 -pgfmanual-figure287 -pgfmanual-figure288 -pgfmanual-figure289 -pgfmanual-figure290 -pgfmanual-figure291 -pgfmanual-figure292 -pgfmanual-figure293 -pgfmanual-figure294 -pgfmanual-figure295 -pgfmanual-figure296 -pgfmanual-figure297 -pgfmanual-figure298 -pgfmanual-figure299 -pgfmanual-figure300 -pgfmanual-figure301 -pgfmanual-figure302 -pgfmanual-figure303 -pgfmanual-figure304 -pgfmanual-figure305 -pgfmanual-figure306 -pgfmanual-figure307 -pgfmanual-figure308 -pgfmanual-figure309 -pgfmanual-figure310 -pgfmanual-figure311 -pgfmanual-figure312 -pgfmanual-figure313 -pgfmanual-figure314 -pgfmanual-figure315 -pgfmanual-figure316 -pgfmanual-figure317 -pgfmanual-figure318 -pgfmanual-figure319 -pgfmanual-figure320 -pgfmanual-figure321 -pgfmanual-figure322 -pgfmanual-figure323 -pgfmanual-figure324 -pgfmanual-figure325 -pgfmanual-figure326 -pgfmanual-figure327 -pgfmanual-figure328 -pgfmanual-figure329 -pgfmanual-figure330 -pgfmanual-figure331 -pgfmanual-figure332 -pgfmanual-figure333 -pgfmanual-figure334 -pgfmanual-figure335 -pgfmanual-figure336 -pgfmanual-figure337 -pgfmanual-figure338 -pgfmanual-figure339 -pgfmanual-figure340 -pgfmanual-figure341 -pgfmanual-figure342 -pgfmanual-figure343 -pgfmanual-figure344 -pgfmanual-figure345 -pgfmanual-figure346 -pgfmanual-figure347 -pgfmanual-figure348 -pgfmanual-figure349 -pgfmanual-figure350 -pgfmanual-figure351 -pgfmanual-figure352 -pgfmanual-figure353 -pgfmanual-figure354 -pgfmanual-figure355 -pgfmanual-figure356 -pgfmanual-figure357 -pgfmanual-figure358 -pgfmanual-figure359 -pgfmanual-figure360 -pgfmanual-figure361 -pgfmanual-figure362 -pgfmanual-figure363 -pgfmanual-figure364 -pgfmanual-figure365 -pgfmanual-figure366 -pgfmanual-figure367 -pgfmanual-figure368 -pgfmanual-figure369 -pgfmanual-figure370 -pgfmanual-figure371 -pgfmanual-figure372 -pgfmanual-figure373 -pgfmanual-figure374 -pgfmanual-figure375 -pgfmanual-figure376 -pgfmanual-figure377 -pgfmanual-figure378 -pgfmanual-figure379 -pgfmanual-figure380 -pgfmanual-figure381 -pgfmanual-figure382 -pgfmanual-figure383 -pgfmanual-figure384 -pgfmanual-figure385 -pgfmanual-figure386 -pgfmanual-figure387 -pgfmanual-figure388 -pgfmanual-figure389 -pgfmanual-figure390 -pgfmanual-figure391 -pgfmanual-figure392 -pgfmanual-figure393 -pgfmanual-figure394 -pgfmanual-figure395 -pgfmanual-figure396 -pgfmanual-figure397 -pgfmanual-figure398 -pgfmanual-figure399 -pgfmanual-figure400 -pgfmanual-figure401 -pgfmanual-figure402 -pgfmanual-figure403 -pgfmanual-figure404 -pgfmanual-figure405 -pgfmanual-figure406 -pgfmanual-figure407 -pgfmanual-figure408 -pgfmanual-figure409 -pgfmanual-figure410 -pgfmanual-figure411 -pgfmanual-figure412 -pgfmanual-figure413 -pgfmanual-figure414 -pgfmanual-figure415 -pgfmanual-figure416 -pgfmanual-figure417 -pgfmanual-figure418 -pgfmanual-figure419 -pgfmanual-figure420 -pgfmanual-figure421 -pgfmanual-figure422 -pgfmanual-figure423 -pgfmanual-figure424 -pgfmanual-figure425 -pgfmanual-figure426 -pgfmanual-figure427 -pgfmanual-figure428 -pgfmanual-figure429 -pgfmanual-figure430 -pgfmanual-figure431 -pgfmanual-figure432 -pgfmanual-figure433 -pgfmanual-figure434 -pgfmanual-figure435 -pgfmanual-figure436 -pgfmanual-figure437 -pgfmanual-figure438 -pgfmanual-figure439 -pgfmanual-figure440 -pgfmanual-figure441 -pgfmanual-figure442 -pgfmanual-figure443 -pgfmanual-figure444 -pgfmanual-figure445 -pgfmanual-figure446 -pgfmanual-figure447 -pgfmanual-figure448 -pgfmanual-figure449 -pgfmanual-figure450 -pgfmanual-figure451 -pgfmanual-figure452 -pgfmanual-figure453 -pgfmanual-figure454 -pgfmanual-figure455 -pgfmanual-figure456 -pgfmanual-figure457 -pgfmanual-figure458 -pgfmanual-figure459 -pgfmanual-figure460 -pgfmanual-figure461 -pgfmanual-figure462 -pgfmanual-figure463 -pgfmanual-figure464 -pgfmanual-figure465 -pgfmanual-figure466 -pgfmanual-figure467 -pgfmanual-figure468 -pgfmanual-figure469 -pgfmanual-figure470 -pgfmanual-figure471 -pgfmanual-figure472 -pgfmanual-figure473 -pgfmanual-figure474 -pgfmanual-figure475 -pgfmanual-figure476 -pgfmanual-figure477 -pgfmanual-figure478 -pgfmanual-figure479 -pgfmanual-figure480 -pgfmanual-figure481 -pgfmanual-figure482 -pgfmanual-figure483 -pgfmanual-figure484 -pgfmanual-figure485 -pgfmanual-figure486 -pgfmanual-figure487 -pgfmanual-figure488 -pgfmanual-figure489 -pgfmanual-figure490 -pgfmanual-figure491 -pgfmanual-figure492 -pgfmanual-figure493 -pgfmanual-figure494 -pgfmanual-figure495 -pgfmanual-figure496 -pgfmanual-figure497 -pgfmanual-figure498 -pgfmanual-figure499 -pgfmanual-figure500 -pgfmanual-figure501 -pgfmanual-figure502 -pgfmanual-figure503 -pgfmanual-figure504 -pgfmanual-figure505 -pgfmanual-figure506 -pgfmanual-figure507 -pgfmanual-figure508 -pgfmanual-figure509 -pgfmanual-figure510 -pgfmanual-figure511 -pgfmanual-figure512 -pgfmanual-figure513 -pgfmanual-figure514 -pgfmanual-figure515 -pgfmanual-figure516 -pgfmanual-figure517 -pgfmanual-figure518 -pgfmanual-figure519 -pgfmanual-figure520 -pgfmanual-figure521 -pgfmanual-figure522 -pgfmanual-figure523 -pgfmanual-figure524 -pgfmanual-figure525 -pgfmanual-figure526 -pgfmanual-figure527 -pgfmanual-figure528 -pgfmanual-figure529 -pgfmanual-figure530 -pgfmanual-figure531 -pgfmanual-figure532 -pgfmanual-figure533 -pgfmanual-figure534 -pgfmanual-figure535 -pgfmanual-figure536 -pgfmanual-figure537 -pgfmanual-figure538 -pgfmanual-figure539 -pgfmanual-figure540 -pgfmanual-figure541 -pgfmanual-figure542 -pgfmanual-figure543 -pgfmanual-figure544 -pgfmanual-figure545 -pgfmanual-figure546 -pgfmanual-figure547 -pgfmanual-figure548 -pgfmanual-figure549 -pgfmanual-figure550 -pgfmanual-figure551 -pgfmanual-figure552 -pgfmanual-figure553 -pgfmanual-figure554 -pgfmanual-figure555 -pgfmanual-figure556 -pgfmanual-figure557 -pgfmanual-figure558 -pgfmanual-figure559 -pgfmanual-figure560 -pgfmanual-figure561 -pgfmanual-figure562 -pgfmanual-figure563 -pgfmanual-figure564 -pgfmanual-figure565 -pgfmanual-figure566 -pgfmanual-figure567 -pgfmanual-figure568 -pgfmanual-figure569 -pgfmanual-figure570 -pgfmanual-figure571 -pgfmanual-figure572 -pgfmanual-figure573 -pgfmanual-figure574 -pgfmanual-figure575 -pgfmanual-figure576 -pgfmanual-figure577 -pgfmanual-figure578 -pgfmanual-figure579 -pgfmanual-figure580 -pgfmanual-figure581 -pgfmanual-figure582 -pgfmanual-figure583 -pgfmanual-figure584 -pgfmanual-figure585 -pgfmanual-figure586 -pgfmanual-figure587 -pgfmanual-figure588 -pgfmanual-figure589 -pgfmanual-figure590 -pgfmanual-figure591 -pgfmanual-figure592 -pgfmanual-figure593 -pgfmanual-figure594 -pgfmanual-figure595 -pgfmanual-figure596 -pgfmanual-figure597 -pgfmanual-figure598 -pgfmanual-figure599 -pgfmanual-figure600 -pgfmanual-figure601 -pgfmanual-figure602 -pgfmanual-figure603 -pgfmanual-figure604 -pgfmanual-figure605 -pgfmanual-figure606 -pgfmanual-figure607 -pgfmanual-figure608 -pgfmanual-figure609 -pgfmanual-figure610 -pgfmanual-figure611 -pgfmanual-figure612 -pgfmanual-figure613 -pgfmanual-figure614 -pgfmanual-figure615 -pgfmanual-figure616 -pgfmanual-figure617 -pgfmanual-figure618 -pgfmanual-figure619 -pgfmanual-figure620 -pgfmanual-figure621 -pgfmanual-figure622 -pgfmanual-figure623 -pgfmanual-figure624 -pgfmanual-figure625 -pgfmanual-figure626 -pgfmanual-figure627 -pgfmanual-figure628 -pgfmanual-figure629 -pgfmanual-figure630 -pgfmanual-figure631 -pgfmanual-figure632 -pgfmanual-figure633 -pgfmanual-figure634 -pgfmanual-figure635 -pgfmanual-figure636 -pgfmanual-figure637 -pgfmanual-figure638 -pgfmanual-figure639 -pgfmanual-figure640 -pgfmanual-figure641 -pgfmanual-figure642 -pgfmanual-figure643 -pgfmanual-figure644 -pgfmanual-figure645 -pgfmanual-figure646 -pgfmanual-figure647 -pgfmanual-figure648 -pgfmanual-figure649 -pgfmanual-figure650 -pgfmanual-figure651 -pgfmanual-figure652 -pgfmanual-figure653 -pgfmanual-figure654 -pgfmanual-figure655 -pgfmanual-figure656 -pgfmanual-figure657 -pgfmanual-figure658 -pgfmanual-figure659 -pgfmanual-figure660 -pgfmanual-figure661 -pgfmanual-figure662 -pgfmanual-figure663 -pgfmanual-figure664 -pgfmanual-figure665 -pgfmanual-figure666 -pgfmanual-figure667 -pgfmanual-figure668 -pgfmanual-figure669 -pgfmanual-figure670 -pgfmanual-figure671 -pgfmanual-figure672 -pgfmanual-figure673 -pgfmanual-figure674 -pgfmanual-figure675 -pgfmanual-figure676 -pgfmanual-figure677 -pgfmanual-figure678 -pgfmanual-figure679 -pgfmanual-figure680 -pgfmanual-figure681 -pgfmanual-figure682 -pgfmanual-figure683 -pgfmanual-figure684 -pgfmanual-figure685 -pgfmanual-figure686 -pgfmanual-figure687 -pgfmanual-figure688 -pgfmanual-figure689 -pgfmanual-figure690 -pgfmanual-figure691 -pgfmanual-figure692 -pgfmanual-figure693 -pgfmanual-figure694 -pgfmanual-figure695 -pgfmanual-figure696 -pgfmanual-figure697 -pgfmanual-figure698 -pgfmanual-figure699 -pgfmanual-figure700 -pgfmanual-figure701 -pgfmanual-figure702 -pgfmanual-figure703 -pgfmanual-figure704 -pgfmanual-figure705 -pgfmanual-figure706 -pgfmanual-figure707 -pgfmanual-figure708 -pgfmanual-figure709 -pgfmanual-figure710 -pgfmanual-figure711 -pgfmanual-figure712 -pgfmanual-figure713 -pgfmanual-figure714 -pgfmanual-figure715 -pgfmanual-figure716 -pgfmanual-figure717 -pgfmanual-figure718 -pgfmanual-figure719 -pgfmanual-figure720 -pgfmanual-figure721 -pgfmanual-figure722 -pgfmanual-figure723 -pgfmanual-figure724 -pgfmanual-figure725 -pgfmanual-figure726 -pgfmanual-figure727 -pgfmanual-figure728 -pgfmanual-figure729 -pgfmanual-figure730 -pgfmanual-figure731 -pgfmanual-figure732 -pgfmanual-figure733 -pgfmanual-figure734 -pgfmanual-figure735 -pgfmanual-figure736 -pgfmanual-figure737 -pgfmanual-figure738 -pgfmanual-figure739 -pgfmanual-figure740 -pgfmanual-figure741 -pgfmanual-figure742 -pgfmanual-figure743 -pgfmanual-figure744 -pgfmanual-figure745 -pgfmanual-figure746 -pgfmanual-figure747 -pgfmanual-figure748 -pgfmanual-figure749 -pgfmanual-figure750 -pgfmanual-figure751 -pgfmanual-figure752 -pgfmanual-figure753 -pgfmanual-figure754 -pgfmanual-figure755 -pgfmanual-figure756 -pgfmanual-figure757 -pgfmanual-figure758 -pgfmanual-figure759 -pgfmanual-figure760 -pgfmanual-figure761 -pgfmanual-figure762 -pgfmanual-figure763 -pgfmanual-figure764 -pgfmanual-figure765 -pgfmanual-figure766 -pgfmanual-figure767 -pgfmanual-figure768 -pgfmanual-figure769 -pgfmanual-figure770 -pgfmanual-figure771 -pgfmanual-figure772 -pgfmanual-figure773 -pgfmanual-figure774 -pgfmanual-figure775 -pgfmanual-figure776 -pgfmanual-figure777 -pgfmanual-figure778 -pgfmanual-figure779 -pgfmanual-figure780 -pgfmanual-figure781 -pgfmanual-figure782 -pgfmanual-figure783 -pgfmanual-figure784 -pgfmanual-figure785 -pgfmanual-figure786 -pgfmanual-figure787 -pgfmanual-figure788 -pgfmanual-figure789 -pgfmanual-figure790 -pgfmanual-figure791 -pgfmanual-figure792 -pgfmanual-figure793 -pgfmanual-figure794 -pgfmanual-figure795 -pgfmanual-figure796 -pgfmanual-figure797 -pgfmanual-figure798 -pgfmanual-figure799 -pgfmanual-figure800 -pgfmanual-figure801 -pgfmanual-figure802 -pgfmanual-figure803 -pgfmanual-figure804 -pgfmanual-figure805 -pgfmanual-figure806 -pgfmanual-figure807 -pgfmanual-figure808 -pgfmanual-figure809 -pgfmanual-figure810 -pgfmanual-figure811 -pgfmanual-figure812 -pgfmanual-figure813 -pgfmanual-figure814 -pgfmanual-figure815 -pgfmanual-figure816 -pgfmanual-figure817 -pgfmanual-figure818 -pgfmanual-figure819 -pgfmanual-figure820 -pgfmanual-figure821 -pgfmanual-figure822 -pgfmanual-figure823 -pgfmanual-figure824 -pgfmanual-figure825 -pgfmanual-figure826 -pgfmanual-figure827 -pgfmanual-figure828 -pgfmanual-figure829 -pgfmanual-figure830 -pgfmanual-figure831 -pgfmanual-figure832 -pgfmanual-figure833 -pgfmanual-figure834 -pgfmanual-figure835 -pgfmanual-figure836 -pgfmanual-figure837 -pgfmanual-figure838 -pgfmanual-figure839 -pgfmanual-figure840 -pgfmanual-figure841 -pgfmanual-figure842 -pgfmanual-figure843 -pgfmanual-figure844 -pgfmanual-figure845 -pgfmanual-figure846 -pgfmanual-figure847 -pgfmanual-figure848 -pgfmanual-figure849 -pgfmanual-figure850 -pgfmanual-figure851 -pgfmanual-figure852 -pgfmanual-figure853 -pgfmanual-figure854 -pgfmanual-figure855 -pgfmanual-figure856 -pgfmanual-figure857 -pgfmanual-figure858 -pgfmanual-figure859 -pgfmanual-figure860 -pgfmanual-figure861 -pgfmanual-figure862 -pgfmanual-figure863 -pgfmanual-figure864 -pgfmanual-figure865 -pgfmanual-figure866 -pgfmanual-figure867 -pgfmanual-figure868 -pgfmanual-figure869 -pgfmanual-figure870 -pgfmanual-figure871 -pgfmanual-figure872 -pgfmanual-figure873 -pgfmanual-figure874 -pgfmanual-figure875 -pgfmanual-figure876 -pgfmanual-figure877 -pgfmanual-figure878 -pgfmanual-figure879 -pgfmanual-figure880 -pgfmanual-figure881 -pgfmanual-figure882 -pgfmanual-figure883 -pgfmanual-figure884 -pgfmanual-figure885 -pgfmanual-figure886 -pgfmanual-figure887 -pgfmanual-figure888 -pgfmanual-figure889 -pgfmanual-figure890 -pgfmanual-figure891 -pgfmanual-figure892 -pgfmanual-figure893 -pgfmanual-figure894 -pgfmanual-figure895 -pgfmanual-figure896 -pgfmanual-figure897 -pgfmanual-figure898 -pgfmanual-figure899 -pgfmanual-figure900 -pgfmanual-figure901 -pgfmanual-figure902 -pgfmanual-figure903 -pgfmanual-figure904 -pgfmanual-figure905 -pgfmanual-figure906 -pgfmanual-figure907 -pgfmanual-figure908 -pgfmanual-figure909 -pgfmanual-figure910 -pgfmanual-figure911 -pgfmanual-figure912 -pgfmanual-figure913 -pgfmanual-figure914 -pgfmanual-figure915 -pgfmanual-figure916 -pgfmanual-figure917 -pgfmanual-figure918 -pgfmanual-figure919 -pgfmanual-figure920 -pgfmanual-figure921 -pgfmanual-figure922 -pgfmanual-figure923 -pgfmanual-figure924 -pgfmanual-figure925 -pgfmanual-figure926 -pgfmanual-figure927 -pgfmanual-figure928 -pgfmanual-figure929 -pgfmanual-figure930 -pgfmanual-figure931 -pgfmanual-figure932 -pgfmanual-figure933 -pgfmanual-figure934 -pgfmanual-figure935 -pgfmanual-figure936 -pgfmanual-figure937 -pgfmanual-figure938 -pgfmanual-figure939 -pgfmanual-figure940 -pgfmanual-figure941 -pgfmanual-figure942 -pgfmanual-figure943 -pgfmanual-figure944 -pgfmanual-figure945 -pgfmanual-figure946 -pgfmanual-figure947 -pgfmanual-figure948 -pgfmanual-figure949 -pgfmanual-figure950 -pgfmanual-figure951 -pgfmanual-figure952 -pgfmanual-figure953 -pgfmanual-figure954 -pgfmanual-figure955 -pgfmanual-figure956 -pgfmanual-figure957 -pgfmanual-figure958 -pgfmanual-figure959 -pgfmanual-figure960 -pgfmanual-figure961 -pgfmanual-figure962 -pgfmanual-figure963 -pgfmanual-figure964 -pgfmanual-figure965 -pgfmanual-figure966 -pgfmanual-figure967 -pgfmanual-figure968 -pgfmanual-figure969 -pgfmanual-figure970 -pgfmanual-figure971 -pgfmanual-figure972 -pgfmanual-figure973 -pgfmanual-figure974 -pgfmanual-figure975 -pgfmanual-figure976 -pgfmanual-figure977 -pgfmanual-figure978 -pgfmanual-figure979 -pgfmanual-figure980 -pgfmanual-figure981 -pgfmanual-figure982 -pgfmanual-figure983 -pgfmanual-figure984 -pgfmanual-figure985 -pgfmanual-figure986 -pgfmanual-figure987 -pgfmanual-figure988 -pgfmanual-figure989 -pgfmanual-figure990 -pgfmanual-figure991 -pgfmanual-figure992 -pgfmanual-figure993 -pgfmanual-figure994 -pgfmanual-figure995 -pgfmanual-figure996 -pgfmanual-figure997 -pgfmanual-figure998 -pgfmanual-figure999 -pgfmanual-figure1000 -pgfmanual-figure1001 -pgfmanual-figure1002 -pgfmanual-figure1003 -pgfmanual-figure1004 -pgfmanual-figure1005 -pgfmanual-figure1006 -pgfmanual-figure1007 -pgfmanual-figure1008 -pgfmanual-figure1009 -pgfmanual-figure1010 -pgfmanual-figure1011 -pgfmanual-figure1012 -pgfmanual-figure1013 -pgfmanual-figure1014 -pgfmanual-figure1015 -pgfmanual-figure1016 -pgfmanual-figure1017 -pgfmanual-figure1018 -pgfmanual-figure1019 -pgfmanual-figure1020 -pgfmanual-figure1021 -pgfmanual-figure1022 -pgfmanual-figure1023 -pgfmanual-figure1024 -pgfmanual-figure1025 -pgfmanual-figure1026 -pgfmanual-figure1027 -pgfmanual-figure1028 -pgfmanual-figure1029 -pgfmanual-figure1030 -pgfmanual-figure1031 -pgfmanual-figure1032 -pgfmanual-figure1033 -pgfmanual-figure1034 -pgfmanual-figure1035 -pgfmanual-figure1036 -pgfmanual-figure1037 -pgfmanual-figure1038 -pgfmanual-figure1039 -pgfmanual-figure1040 -pgfmanual-figure1041 -pgfmanual-figure1042 -pgfmanual-figure1043 -pgfmanual-figure1044 -pgfmanual-figure1045 -pgfmanual-figure1046 -pgfmanual-figure1047 -pgfmanual-figure1048 -pgfmanual-figure1049 -pgfmanual-figure1050 -pgfmanual-figure1051 -pgfmanual-figure1052 -pgfmanual-figure1053 -pgfmanual-figure1054 -pgfmanual-figure1055 -pgfmanual-figure1056 -pgfmanual-figure1057 -pgfmanual-figure1058 -pgfmanual-figure1059 -pgfmanual-figure1060 -pgfmanual-figure1061 -pgfmanual-figure1062 -pgfmanual-figure1063 -pgfmanual-figure1064 -pgfmanual-figure1065 -pgfmanual-figure1066 -pgfmanual-figure1067 -pgfmanual-figure1068 -pgfmanual-figure1069 -pgfmanual-figure1070 -pgfmanual-figure1071 -pgfmanual-figure1072 -pgfmanual-figure1073 -pgfmanual-figure1074 -pgfmanual-figure1075 -pgfmanual-figure1076 -pgfmanual-figure1077 -pgfmanual-figure1078 -pgfmanual-figure1079 -pgfmanual-figure1080 -pgfmanual-figure1081 -pgfmanual-figure1082 -pgfmanual-figure1083 -pgfmanual-figure1084 -pgfmanual-figure1085 -pgfmanual-figure1086 -pgfmanual-figure1087 -pgfmanual-figure1088 -pgfmanual-figure1089 -pgfmanual-figure1090 -pgfmanual-figure1091 -pgfmanual-figure1092 -pgfmanual-figure1093 -pgfmanual-figure1094 -pgfmanual-figure1095 -pgfmanual-figure1096 -pgfmanual-figure1097 -pgfmanual-figure1098 -pgfmanual-figure1099 -pgfmanual-figure1100 -pgfmanual-figure1101 -pgfmanual-figure1102 -pgfmanual-figure1103 -pgfmanual-figure1104 -pgfmanual-figure1105 -pgfmanual-figure1106 -pgfmanual-figure1107 -pgfmanual-figure1108 -pgfmanual-figure1109 -pgfmanual-figure1110 -pgfmanual-figure1111 -pgfmanual-figure1112 -pgfmanual-figure1113 -pgfmanual-figure1114 -pgfmanual-figure1115 -pgfmanual-figure1116 -pgfmanual-figure1117 -pgfmanual-figure1118 -pgfmanual-figure1119 -pgfmanual-figure1120 -pgfmanual-figure1121 -pgfmanual-figure1122 -pgfmanual-figure1123 -pgfmanual-figure1124 -pgfmanual-figure1125 -pgfmanual-figure1126 -pgfmanual-figure1127 -pgfmanual-figure1128 -pgfmanual-figure1129 -pgfmanual-figure1130 -pgfmanual-figure1131 -pgfmanual-figure1132 -pgfmanual-figure1133 -pgfmanual-figure1134 -pgfmanual-figure1135 -pgfmanual-figure1136 -pgfmanual-figure1137 -pgfmanual-figure1138 -pgfmanual-figure1139 -pgfmanual-figure1140 -pgfmanual-figure1141 -pgfmanual-figure1142 -pgfmanual-figure1143 -pgfmanual-figure1144 -pgfmanual-figure1145 -pgfmanual-figure1146 -pgfmanual-figure1147 -pgfmanual-figure1148 -pgfmanual-figure1149 -pgfmanual-figure1150 -pgfmanual-figure1151 -pgfmanual-figure1152 -pgfmanual-figure1153 -pgfmanual-figure1154 -pgfmanual-figure1155 -pgfmanual-figure1156 -pgfmanual-figure1157 -pgfmanual-figure1158 -pgfmanual-figure1159 -pgfmanual-figure1160 -pgfmanual-figure1161 -pgfmanual-figure1162 -pgfmanual-figure1163 -pgfmanual-figure1164 -pgfmanual-figure1165 -pgfmanual-figure1166 -pgfmanual-figure1167 -pgfmanual-figure1168 -pgfmanual-figure1169 -pgfmanual-figure1170 -pgfmanual-figure1171 -pgfmanual-figure1172 -pgfmanual-figure1173 -pgfmanual-figure1174 -pgfmanual-figure1175 -pgfmanual-figure1176 -pgfmanual-figure1177 -pgfmanual-figure1178 -pgfmanual-figure1179 -pgfmanual-figure1180 -pgfmanual-figure1181 -pgfmanual-figure1182 -pgfmanual-figure1183 -pgfmanual-figure1184 -pgfmanual-figure1185 -pgfmanual-figure1186 -pgfmanual-figure1187 -pgfmanual-figure1188 -pgfmanual-figure1189 -pgfmanual-figure1190 -pgfmanual-figure1191 -pgfmanual-figure1192 -pgfmanual-figure1193 -pgfmanual-figure1194 -pgfmanual-figure1195 -pgfmanual-figure1196 -pgfmanual-figure1197 -pgfmanual-figure1198 -pgfmanual-figure1199 -pgfmanual-figure1200 -pgfmanual-figure1201 -pgfmanual-figure1202 -pgfmanual-figure1203 -pgfmanual-figure1204 -pgfmanual-figure1205 -pgfmanual-figure1206 -pgfmanual-figure1207 -pgfmanual-figure1208 -pgfmanual-figure1209 -pgfmanual-figure1210 -pgfmanual-figure1211 -pgfmanual-figure1212 -pgfmanual-figure1213 -pgfmanual-figure1214 -pgfmanual-figure1215 -pgfmanual-figure1216 -pgfmanual-figure1217 -pgfmanual-figure1218 -pgfmanual-figure1219 -pgfmanual-figure1220 -pgfmanual-figure1221 -pgfmanual-figure1222 -pgfmanual-figure1223 -pgfmanual-figure1224 -pgfmanual-figure1225 -pgfmanual-figure1226 -pgfmanual-figure1227 -pgfmanual-figure1228 -pgfmanual-figure1229 -pgfmanual-figure1230 -pgfmanual-figure1231 -pgfmanual-figure1232 -pgfmanual-figure1233 -pgfmanual-figure1234 -pgfmanual-figure1235 -pgfmanual-figure1236 -pgfmanual-figure1237 -pgfmanual-figure1238 -pgfmanual-figure1239 -pgfmanual-figure1240 -pgfmanual-figure1241 -pgfmanual-figure1242 -pgfmanual-figure1243 -pgfmanual-figure1244 -pgfmanual-figure1245 -pgfmanual-figure1246 -pgfmanual-figure1247 -pgfmanual-figure1248 -pgfmanual-figure1249 -pgfmanual-figure1250 -pgfmanual-figure1251 -pgfmanual-figure1252 -pgfmanual-figure1253 -pgfmanual-figure1254 -pgfmanual-figure1255 -pgfmanual-figure1256 -pgfmanual-figure1257 -pgfmanual-figure1258 -pgfmanual-figure1259 -pgfmanual-figure1260 -pgfmanual-figure1261 -pgfmanual-figure1262 -pgfmanual-figure1263 -pgfmanual-figure1264 -pgfmanual-figure1265 -pgfmanual-figure1266 -pgfmanual-figure1267 -pgfmanual-figure1268 -pgfmanual-figure1269 -pgfmanual-figure1270 -pgfmanual-figure1271 -pgfmanual-figure1272 -pgfmanual-figure1273 -pgfmanual-figure1274 -pgfmanual-figure1275 -pgfmanual-figure1276 -pgfmanual-figure1277 -pgfmanual-figure1278 -pgfmanual-figure1279 -pgfmanual-figure1280 -pgfmanual-figure1281 -pgfmanual-figure1282 -pgfmanual-figure1283 -pgfmanual-figure1284 -pgfmanual-figure1285 -pgfmanual-figure1286 -pgfmanual-figure1287 -pgfmanual-figure1288 -pgfmanual-figure1289 -pgfmanual-figure1290 -pgfmanual-figure1291 -pgfmanual-figure1292 -pgfmanual-figure1293 -pgfmanual-figure1294 -pgfmanual-figure1295 -pgfmanual-figure1296 -pgfmanual-figure1297 -pgfmanual-figure1298 -pgfmanual-figure1299 -pgfmanual-figure1300 -pgfmanual-figure1301 -pgfmanual-figure1302 -pgfmanual-figure1303 -pgfmanual-figure1304 -pgfmanual-figure1305 -pgfmanual-figure1306 -pgfmanual-figure1307 -pgfmanual-figure1308 -pgfmanual-figure1309 -pgfmanual-figure1310 -pgfmanual-figure1311 -pgfmanual-figure1312 -pgfmanual-figure1313 -pgfmanual-figure1314 -pgfmanual-figure1315 -pgfmanual-figure1316 -pgfmanual-figure1317 -pgfmanual-figure1318 -pgfmanual-figure1319 -pgfmanual-figure1320 -pgfmanual-figure1321 -pgfmanual-figure1322 -pgfmanual-figure1323 -pgfmanual-figure1324 -pgfmanual-figure1325 -pgfmanual-figure1326 -pgfmanual-figure1327 -pgfmanual-figure1328 -pgfmanual-figure1329 -pgfmanual-figure1330 -pgfmanual-figure1331 -pgfmanual-figure1332 -pgfmanual-figure1333 -pgfmanual-figure1334 -pgfmanual-figure1335 -pgfmanual-figure1336 -pgfmanual-figure1337 -pgfmanual-figure1338 -pgfmanual-figure1339 -pgfmanual-figure1340 -pgfmanual-figure1341 -pgfmanual-figure1342 -pgfmanual-figure1343 -pgfmanual-figure1344 -pgfmanual-figure1345 -pgfmanual-figure1346 -pgfmanual-figure1347 -pgfmanual-figure1348 -pgfmanual-figure1349 -pgfmanual-figure1350 -pgfmanual-figure1351 -pgfmanual-figure1352 -pgfmanual-figure1353 -pgfmanual-figure1354 -pgfmanual-figure1355 -pgfmanual-figure1356 -pgfmanual-figure1357 -pgfmanual-figure1358 -pgfmanual-figure1359 -pgfmanual-figure1360 -pgfmanual-figure1361 -pgfmanual-figure1362 -pgfmanual-figure1363 -pgfmanual-figure1364 -pgfmanual-figure1365 -pgfmanual-figure1366 -pgfmanual-figure1367 -pgfmanual-figure1368 -pgfmanual-figure1369 -pgfmanual-figure1370 -pgfmanual-figure1371 -pgfmanual-figure1372 -pgfmanual-figure1373 -pgfmanual-figure1374 -pgfmanual-figure1375 -pgfmanual-figure1376 -pgfmanual-figure1377 -pgfmanual-figure1378 -pgfmanual-figure1379 -pgfmanual-figure1380 -pgfmanual-figure1381 -pgfmanual-figure1382 -pgfmanual-figure1383 -pgfmanual-figure1384 -pgfmanual-figure1385 -pgfmanual-figure1386 -pgfmanual-figure1387 -pgfmanual-figure1388 -pgfmanual-figure1389 -pgfmanual-figure1390 -pgfmanual-figure1391 -pgfmanual-figure1392 -pgfmanual-figure1393 -pgfmanual-figure1394 -pgfmanual-figure1395 -pgfmanual-figure1396 -pgfmanual-figure1397 -pgfmanual-figure1398 -pgfmanual-figure1399 -pgfmanual-figure1400 -pgfmanual-figure1401 -pgfmanual-figure1402 -pgfmanual-figure1403 -pgfmanual-figure1404 -pgfmanual-figure1405 -pgfmanual-figure1406 -pgfmanual-figure1407 -pgfmanual-figure1408 -pgfmanual-figure1409 -pgfmanual-figure1410 -pgfmanual-figure1411 -pgfmanual-figure1412 -pgfmanual-figure1413 -pgfmanual-figure1414 -pgfmanual-figure1415 -pgfmanual-figure1416 -pgfmanual-figure1417 -pgfmanual-figure1418 -pgfmanual-figure1419 -pgfmanual-figure1420 -pgfmanual-figure1421 -pgfmanual-figure1422 -pgfmanual-figure1423 -pgfmanual-figure1424 -pgfmanual-figure1425 -pgfmanual-figure1426 -pgfmanual-figure1427 -pgfmanual-figure1428 -pgfmanual-figure1429 -pgfmanual-figure1430 -pgfmanual-figure1431 -pgfmanual-figure1432 -pgfmanual-figure1433 -pgfmanual-figure1434 -pgfmanual-figure1435 -pgfmanual-figure1436 -pgfmanual-figure1437 -pgfmanual-figure1438 -pgfmanual-figure1439 -pgfmanual-figure1440 -pgfmanual-figure1441 -pgfmanual-figure1442 -pgfmanual-figure1443 -pgfmanual-figure1444 -pgfmanual-figure1445 -pgfmanual-figure1446 -pgfmanual-figure1447 -pgfmanual-figure1448 -pgfmanual-figure1449 -pgfmanual-figure1450 -pgfmanual-figure1451 -pgfmanual-figure1452 -pgfmanual-figure1453 -pgfmanual-figure1454 -pgfmanual-figure1455 -pgfmanual-figure1456 -pgfmanual-figure1457 -pgfmanual-figure1458 -pgfmanual-figure1459 -pgfmanual-figure1460 -pgfmanual-figure1461 -pgfmanual-figure1462 -pgfmanual-figure1463 diff --git a/Master/texmf-dist/doc/generic/pgf/version-for-pdftex/pgfmanual-pdftex.cfg b/Master/texmf-dist/doc/generic/pgf/version-for-pdftex/pgfmanual-pdftex.cfg index 25c46a965a9..0beedab340c 100644 --- a/Master/texmf-dist/doc/generic/pgf/version-for-pdftex/pgfmanual-pdftex.cfg +++ b/Master/texmf-dist/doc/generic/pgf/version-for-pdftex/pgfmanual-pdftex.cfg @@ -8,6 +8,7 @@ % See the file doc/generic/pgf/licenses/LICENSE for more details. +\usepackage[hyphens]{url} \usepackage[pdfborder={0 0 0}]{hyperref} % Just make sure to compile this using pdfelatex. diff --git a/Master/texmf-dist/doc/generic/pgf/version-for-vtex/pgfmanual-vtex.cfg b/Master/texmf-dist/doc/generic/pgf/version-for-vtex/pgfmanual-vtex.cfg index 6b959370d1a..166b2c1111f 100644 --- a/Master/texmf-dist/doc/generic/pgf/version-for-vtex/pgfmanual-vtex.cfg +++ b/Master/texmf-dist/doc/generic/pgf/version-for-vtex/pgfmanual-vtex.cfg @@ -7,6 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. +\usepackage[hyphens]{url} \usepackage[vtex]{graphics} \usepackage{hyperref} diff --git a/Master/texmf-dist/doc/generic/pgf/version-for-xetex/pgfmanual-xetex.cfg b/Master/texmf-dist/doc/generic/pgf/version-for-xetex/pgfmanual-xetex.cfg index 0466c698f54..d61e6c3365e 100644 --- a/Master/texmf-dist/doc/generic/pgf/version-for-xetex/pgfmanual-xetex.cfg +++ b/Master/texmf-dist/doc/generic/pgf/version-for-xetex/pgfmanual-xetex.cfg @@ -7,6 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. +\usepackage[hyphens]{url} \usepackage[xetex]{graphics} % This will tell everyone which driver we are using. diff --git a/Master/texmf-dist/doc/latex/pgf/README b/Master/texmf-dist/doc/latex/pgf/README deleted file mode 100644 index de59b6dede9..00000000000 --- a/Master/texmf-dist/doc/latex/pgf/README +++ /dev/null @@ -1,12 +0,0 @@ -pgf -- A Portable Graphic Format for TeX - -See the directory doc/generic/pgf for more information. See the file -doc/generic/pgf/pgfmanual.pdf for a manual. This -documentation also explains the installation. See the file -doc/generic/pgf/license/LICENSE for license details. - -Please go to http://sourceforge.net/projects/pgf/ -to submit bug reports, request new features, etc. - - - diff --git a/Master/texmf-dist/source/generic/pgf/c/INSTALL b/Master/texmf-dist/source/generic/pgf/c/INSTALL new file mode 100644 index 00000000000..0690faba7d2 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/INSTALL @@ -0,0 +1,28 @@ +In order to use the C code in these directories, you should first +modify / setup the file config/LocalMakefileConfig.mk, which is +included by the main Makefiles and allows you to overwrite the +settings from config/Makefile.mk. + +Once this is done, run make. + +You must then use the install targets to copy / link the resulting +shared libraries with their full paths into the "luatex/lib" +subdirectory of the directory where your TeX executable resides. For +instance, if the luatex program is in + +/usr/texbin + +then you would put SimpleDemoC.so into + +/usr/texbin/lib/luatex/lua/pgf/gd/examples/c + + +Due to bugs in the LuaTeX code, you currently need to append the paths +of the libraries to their name as done in the Makefiles. + +Note that, currently, the Makefile will link the Lua library +statically into the shared graph drawing library (at least on +MacOS). This is conceptually wrong and, indeed, a lot of effort was +need to avoid having LuaTeX crash on a TeX run because of two Lua +libraries being used simultaneously. It works, but hopefully, in the +fututure, this will be fixed.
\ No newline at end of file diff --git a/Master/texmf-dist/source/generic/pgf/c/Makefile b/Master/texmf-dist/source/generic/pgf/c/Makefile new file mode 100644 index 00000000000..a71312aeaf5 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/Makefile @@ -0,0 +1,35 @@ +.PHONY : all clean examples ogdf + +all: + $(MAKE) -C graphdrawing/pgf/gd/interface/c + $(MAKE) -C graphdrawing/pgf/gd/examples/c + $(MAKE) -C graphdrawing/pgf/gd/ogdf/c + +install_all: + $(MAKE) -C graphdrawing/pgf/gd/interface/c install + $(MAKE) -C graphdrawing/pgf/gd/examples/c install + $(MAKE) -C graphdrawing/pgf/gd/ogdf/c install + +examples: + $(MAKE) -C graphdrawing/pgf/gd/interface/c + $(MAKE) -C graphdrawing/pgf/gd/examples/c + +install_examples: + $(MAKE) -C graphdrawing/pgf/gd/interface/c install + $(MAKE) -C graphdrawing/pgf/gd/examples/c install + +ogdf: + $(MAKE) -C graphdrawing/pgf/gd/interface/c + $(MAKE) -C graphdrawing/pgf/gd/ogdf/c + +install_ogdf: + $(MAKE) -C graphdrawing/pgf/gd/interface/c install + $(MAKE) -C graphdrawing/pgf/gd/ogdf/c install + + + +clean: + $(MAKE) -C graphdrawing/pgf/gd/interface/c clean + $(MAKE) -C graphdrawing/pgf/gd/examples/c clean + $(MAKE) -C graphdrawing/pgf/gd/ogdf/c clean + diff --git a/Master/texmf-dist/source/generic/pgf/c/config/ExampleLocalMakefileConfig.mk b/Master/texmf-dist/source/generic/pgf/c/config/ExampleLocalMakefileConfig.mk new file mode 100644 index 00000000000..b42f097f545 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/config/ExampleLocalMakefileConfig.mk @@ -0,0 +1,7 @@ +MYCFLAGS=-isysroot/Developer/SDKs/MacOSX10.7.sdk +MYLDFLAGS= + +ARCHFLAGS=-arch x86_64 + +SHAREDFLAGS=-undefined dynamic_lookup -bundle -llua -L$(LUALIBPATH) + diff --git a/Master/texmf-dist/source/generic/pgf/c/config/MakefileConfig.mk b/Master/texmf-dist/source/generic/pgf/c/config/MakefileConfig.mk new file mode 100644 index 00000000000..25310b6987b --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/config/MakefileConfig.mk @@ -0,0 +1,45 @@ + +# Where Lua is installed +LUAPATH=/usr/local/lua52 + +LUAINCLUDES = $(LUAPATH)/include +LUALIBPATH = $(LUAPATH)/lib + + +# Where ogdf is installed +OGDFPATH=/usr/local/ogdf + +OGDFINCLUDES = $(OGDFPATH) +OGDFLIBPATH = $(OGDFPATH)/_release + + +# Where the pgf C includes are found +PGFINCLUDES=../../../.. + + +# Where the shared libraries should be installed (base dir) +INSTALLDIR=/usr/texbin/lib/luatex/lua + + +# If you need special flags: +MYCFLAGS= +MYLDFLAGS= + +# Link flags for building a shared library +SHAREDFLAGS= + +# Link flags for linking against the shared Lua lib +LINKSHAREDLUA= + +# Architecture flags: +ARCHFLAGS= + +# The to-be-used compiler +CC=gcc + + +# Now read local definition, which may overwrite the above +-include $(CONFIGDIR)/LocalMakefileConfig.mk + + + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/examples/c/Makefile b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/examples/c/Makefile new file mode 100644 index 00000000000..320969d1909 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/examples/c/Makefile @@ -0,0 +1,35 @@ +CONFIGDIR=../../../../../config +include $(CONFIGDIR)/MakefileConfig.mk + +FLAGS=$(MYCFLAGS) $(ARCHFLAGS) -O2 -Wall -I$(LUAINCLUDES) -I$(PGFINCLUDES) + + +all: SimpleDemoC.so SimpleDemoCPlusPlus.so + +clean: + rm *.o *.so + +install: SimpleDemoC.so SimpleDemoCPlusPlus.so + mkdir -p $(INSTALLDIR)/pgf/gd/examples/c + cp SimpleDemoC.so $(INSTALLDIR)/pgf/gd/examples/c/pgf_gd_examples_c_SimpleDemoC.so + cp SimpleDemoCPlusPlus.so $(INSTALLDIR)/pgf/gd/examples/c/pgf_gd_examples_c_SimpleDemoCPlusPlus.so + +SimpleDemoC.so: SimpleDemoC.o + $(CC) $(FLAGS) $(SHAREDFLAGS) $(MYLDFLAGS) \ + $(LINKSHAREDLUA) \ + -o SimpleDemoC.so \ + SimpleDemoC.o ../../interface/c/InterfaceFromC.o + +SimpleDemoC.o: SimpleDemoC.c + $(CC) $(FLAGS) -c -o SimpleDemoC.o SimpleDemoC.c + + +SimpleDemoCPlusPlus.so: SimpleDemoCPlusPlus.o ../../interface/c/InterfaceFromC++.o ../../interface/c/InterfaceFromC.o + $(CC) $(FLAGS) $(SHAREDFLAGS) $(MYLDFLAGS) \ + $(LINKSHAREDLUA) \ + -o SimpleDemoCPlusPlus.so \ + SimpleDemoCPlusPlus.o ../../interface/c/InterfaceFromC++.o ../../interface/c/InterfaceFromC.o + +SimpleDemoCPlusPlus.o: SimpleDemoCPlusPlus.c++ ../../interface/c/InterfaceFromC++.h ../../interface/c/InterfaceFromC.h + g++ $(FLAGS) -c -o SimpleDemoCPlusPlus.o SimpleDemoCPlusPlus.c++ + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/examples/c/SimpleDemoC.c b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/examples/c/SimpleDemoC.c new file mode 100644 index 00000000000..18e5889ad17 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/examples/c/SimpleDemoC.c @@ -0,0 +1,42 @@ +#include <pgf/gd/interface/c/InterfaceFromC.h> +#include <math.h> + +static void fast_hello_world (pgfgd_SyntacticDigraph* graph, void* v) { + double angle = 6.28318530718 / graph->vertices.length; + double radius = pgfgd_tonumber(graph->options, "fast simple demo radius"); + + int i; + for (i = 0; i < graph->vertices.length; i++) { + pgfgd_Vertex* v = graph->vertices.array[i]; + v->pos.x = cos(angle*i) * radius; + v->pos.y = sin(angle*i) * radius; + } +} + +int luaopen_pgf_gd_examples_c_SimpleDemoC (struct lua_State *state) { + pgfgd_Declaration* d; + + // The main layout key + d = pgfgd_new_key ("fast simple demo layout"); + pgfgd_key_summary (d, "The C version of the hello world of graph drawing."); + pgfgd_key_algorithm (d, fast_hello_world, 0); + pgfgd_key_documentation (d, + "Just like the |SimpleDemo| algorithm, this algorithm arranges \ + the nodes of a graph in a circle (without paying heed to the sizes of the \ + nodes or to the edges). Its main purpose is to show how C code \ + can access the Lua representation of graphs. See \ + Section~\ref{section-algorithms-in-c} of the manual for detais."); + pgfgd_key_add_precondition (d, "connected"); + pgfgd_declare (state, d); + pgfgd_free_key (d); + + // The radius key + d = pgfgd_new_key ("fast simple demo radius"); + pgfgd_key_summary (d, "A radius value for the hello world of graph drawing"); + pgfgd_key_type (d, "length"); + pgfgd_key_initial (d, "1cm"); + pgfgd_declare (state, d); + pgfgd_free_key (d); + + return 0; +} diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/examples/c/SimpleDemoCPlusPlus.c++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/examples/c/SimpleDemoCPlusPlus.c++ new file mode 100644 index 00000000000..0c810d25709 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/examples/c/SimpleDemoCPlusPlus.c++ @@ -0,0 +1,47 @@ +#include <pgf/gd/interface/c/InterfaceFromC++.h> +#include <pgf/gd/interface/c/InterfaceFromC.h> + +#include <math.h> + + +struct FastLayout : scripting::declarations, scripting::runner { + + void run () { + pgfgd_SyntacticDigraph* graph = parameters->syntactic_digraph; + + double angle = 6.28318530718 / graph->vertices.length; + double radius = parameters->option<double>("fast simple demo radius c++"); + + for (int i = 0; i < graph->vertices.length; i++) { + pgfgd_Vertex* v = graph->vertices.array[i]; + v->pos.x = cos(angle*i) * radius; + v->pos.y = sin(angle*i) * radius; + } + } + + void declare(scripting::script s) { + using namespace scripting; + + s.declare(key ("fast simple demo layout c++") + .summary ("The C++ version of the hello world of graph drawing") + .precondition ("connected") + .precondition ("tree") + .algorithm (this)); + + s.declare(key ("fast simple demo radius c++") + .summary ("A radius value for the hello world of graph drawing") + .type ("length") + .initial ("1cm")); + } + +}; + +extern "C" int luaopen_pgf_gd_examples_c_SimpleDemoCPlusPlus (struct lua_State *state) { + + scripting::script s (state); + + s.declare (new FastLayout); + + return 0; +} + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/InterfaceFromC++.c++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/InterfaceFromC++.c++ new file mode 100644 index 00000000000..11c1f99dee0 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/InterfaceFromC++.c++ @@ -0,0 +1,215 @@ + +// Own header: +#include <pgf/gd/interface/c/InterfaceFromC++.h> + +extern "C" { + +// Own C header: +#include <pgf/gd/interface/c/InterfaceFromC.h> + +// Lua stuff: +#include <lauxlib.h> + +} + + +namespace { + + void cpp_caller(pgfgd_SyntacticDigraph* g, void* f) + { + using namespace scripting; + + run_parameters p; + p.syntactic_digraph = g; + + runner* algo = static_cast<runner*> (f); + + algo->prepare(&p); + algo->bridge(); + algo->run(); + algo->unbridge(); + } + +} + + +namespace scripting { + + // The key class + + key::key(const char* key) : d (pgfgd_new_key(key)) {} + key::key(struct pgfgd_Declaration* dec) : d (dec) {} + key::~key() {pgfgd_free_key(d); } + + const key& key::summary (const char* x) const { + pgfgd_key_summary(d, x); + return *this; + } + + const key& key::initial (const char* x) const { + pgfgd_key_initial(d, x); + return *this; + } + + const key& key::initial (factory_base* fac) const { + pgfgd_key_initial_user(d, static_cast<void*>(fac)); + return *this; + } + + const key& key::type (const char* x) const { + pgfgd_key_type(d, x); + return *this; + } + + const key& key::module_type () const { + pgfgd_key_type(d, "user value"); + return *this; + } + + const key& key::default_value (const char* x) const { + pgfgd_key_default(d, x); + return *this; + } + + const key& key::alias (const char* x) const { + pgfgd_key_alias(d, x); + return *this; + } + + const key& key::alias_function (const char* x) const { + pgfgd_key_alias_function(d, x); + return *this; + } + + const key& key::documentation (const char* x) const { + pgfgd_key_documentation(d, x); + return *this; + } + + const key& key::documentation_in (const char* x) const { + pgfgd_key_documentation_in(d, x); + return *this; + } + + const key& key::phase (const char* x) const { + pgfgd_key_phase(d, x); + return *this; + } + + const key& key::set_key (const char* k, const char* v) const { + pgfgd_key_add_use(d, k, v); + return *this; + } + + const key& key::set_module (const char* k, factory_base* fac) const { + pgfgd_key_add_use_user(d, k, static_cast<void*>(fac)); + return *this; + } + + const key& key::example (const char* x) const { + pgfgd_key_add_example(d, x); + return *this; + } + + const key& key::precondition (const char* x) const { + pgfgd_key_add_precondition(d, x); + return *this; + } + + const key& key::postcondition (const char* x) const { + pgfgd_key_add_postcondition(d, x); + return *this; + } + + const key& key::algorithm (runner* a) const { + pgfgd_key_algorithm(d, cpp_caller, static_cast<void*>(a)); + return *this; + } + + + // The script class + + script::script (struct lua_State* s) : state(s) {} + + void script::declare (const key& k) { + pgfgd_declare(state, k.d); + } + + void script::declare (declarations* d) { + d->declare(*this); + } + + void script::declare (declarations& d) { + d.declare(*this); + } + + + // The run_parameters class + + namespace { + + // Helpers: + template <class T> + bool fromnumber (pgfgd_SyntacticDigraph* g, const char* k, T& t) + { + if (pgfgd_isnumber(g->options, k)) { + t = static_cast<T>(pgfgd_tonumber(g->options, k)); + return true; + } + return false; + } + + }; + + template <> bool run_parameters::option<bool> (const char* k, bool& t) + { + if (pgfgd_isboolean(syntactic_digraph->options, k)) { + t = static_cast<bool>(pgfgd_toboolean(syntactic_digraph->options, k)); + return true; + } + return false; + } + + template <> bool run_parameters::option<char*> (const char* k, char*& t) + { + if (pgfgd_isstring(syntactic_digraph->options, k)) { + t = pgfgd_tostring(syntactic_digraph->options, k); + return true; + } + return false; + } + + template <> bool run_parameters::option<short> (const char* k, short& t) + { return fromnumber<short> (syntactic_digraph, k, t); } + + template <> bool run_parameters::option<unsigned short> (const char* k, unsigned short& t) + { return fromnumber<unsigned short> (syntactic_digraph, k, t); } + + template <> bool run_parameters::option<int> (const char* k, int& t) + { return fromnumber<int> (syntactic_digraph, k, t); } + + template <> bool run_parameters::option<unsigned int> (const char* k, unsigned int& t) + { return fromnumber<unsigned int> (syntactic_digraph, k, t); } + + template <> bool run_parameters::option<long> (const char* k, long& t) + { return fromnumber<long> (syntactic_digraph, k, t); } + + template <> bool run_parameters::option<unsigned long> (const char* k, unsigned long& t) + { return fromnumber<unsigned long> (syntactic_digraph, k, t); } + + template <> bool run_parameters::option<float> (const char* k, float& t) + { return fromnumber<float> (syntactic_digraph, k, t); } + + template <> bool run_parameters::option<double> (const char* k, double& t) + { return fromnumber<double> (syntactic_digraph, k, t); } + + void* run_parameters::invoke_void_factory_for (const char* k) + { + if (pgfgd_isuser (syntactic_digraph->options, k)) { + factory_base* user = static_cast<factory_base *>(pgfgd_touser (syntactic_digraph->options, k)); + return user->make_void(this); + } + return 0; + } + +} diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/InterfaceFromC++.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/InterfaceFromC++.h new file mode 100644 index 00000000000..40cccb78846 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/InterfaceFromC++.h @@ -0,0 +1,190 @@ +#ifndef PGF_GD_INTERFACE_C_INTERFACEFROMCPP_H +#define PGF_GD_INTERFACE_C_INTERFACEFROMCPP_H + +/** \file pgf/gd/interface/c/InterfaceFromC++.h + + The C++-header file that should be used by algorithms written + in C++ for graph drawing in Lua. +*/ + + +struct lua_State; +struct pgfgd_Declaration; +struct pgfgd_SyntacticDigraph; + +namespace scripting { + + // Forward; + class script; + class run_parameters; + + + class runner { + public: + + void prepare (run_parameters* p) { parameters = p; } + + virtual void bridge () {} + virtual void run () = 0; + virtual void unbridge () {} + + virtual ~runner () {} + + protected: + + run_parameters* parameters; + + }; + + class factory_base { + public: + virtual void* make_void (run_parameters*) = 0; + virtual ~factory_base () {} + }; + + template <class T> class factory : public factory_base { + virtual void* make_void (run_parameters*r) { return static_cast<void*>(make(r)); } + virtual T* make (run_parameters*) { return new T(); } + }; + + class key { + public: + + key (const char*); + key (struct pgfgd_Declaration*); + ~key (); + + const key& summary (const char*) const; + const key& initial (const char*) const; + const key& initial (factory_base*) const; + const key& type (const char*) const; + const key& module_type () const; + const key& default_value (const char*) const; + const key& alias (const char*) const; + const key& alias_function (const char*) const; + const key& documentation (const char*) const; + const key& documentation_in (const char*) const; + const key& phase (const char*) const; + const key& set_key (const char*, const char*) const; + const key& set_module (const char*, factory_base*) const; + const key& example (const char*) const; + const key& precondition (const char*) const; + const key& postcondition (const char*) const; + const key& algorithm (runner*) const; + + private: + + struct pgfgd_Declaration* d; + friend class script; + + key (const key& k); // Not implemented. + key& operator = (const key& k); // Not implemented. + + }; + + + // Declarations are useful for scripting: + + class declarations { + + public: + + virtual void declare (script) = 0; + virtual ~declarations () {} + + }; + + + // The script class + + class script { + + public: + + script (struct lua_State*); + + // Declares a key + void declare (const key&); + void declare (declarations&); + void declare (declarations*); + + private: + + struct lua_State* state; + + }; + + + + // Declaring algorithms defined in a function + + class function_runner : public runner { + public: + function_runner (void (*f) (run_parameters&)) : fun(f) {} + virtual void run () { fun(*parameters); } + + private: + void (*fun) (run_parameters&); + }; + + + // Configuring a class + + class run_parameters { + public: + + struct pgfgd_SyntacticDigraph* syntactic_digraph; + + template <class Layout, class T> + void configure_option (const char*, void (Layout::*) (T), Layout&); + + template <class Layout, class T> + void configure_module (const char*, void (Layout::*) (T*), Layout&); + + template <class T> bool option (const char*, T&); + template <class T> T option (const char*); + template <class T> bool option_is_set (const char*); + + template <class T> T* make (const char*); + + protected: + void* invoke_void_factory_for (const char*); + }; + + template <class T> + T run_parameters::option (const char* k) + { + T t; + option (k, t); + return t; + } + + template <class T> + bool run_parameters::option_is_set (const char* k) + { + T t; + return option(k, t); + } + + template <class Layout, class T> + void run_parameters::configure_option (const char* k, void (Layout::*f) (T), Layout& l) + { + T t; + if (option<T> (k, t)) + (l.*f) (t); + } + + template <class Layout, class T> + void run_parameters::configure_module (const char* k, void (Layout::*f) (T*), Layout& l) + { + if (void* obj = invoke_void_factory_for(k)) + (l.*f) (static_cast<T*> (obj)); + } + + template <class T> + T* run_parameters::make (const char* k) { return static_cast<T*>(invoke_void_factory_for(k)); } + +} + + +#endif diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/InterfaceFromC.c b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/InterfaceFromC.c new file mode 100644 index 00000000000..8a49947b950 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/InterfaceFromC.c @@ -0,0 +1,1187 @@ + +// Own header: +#include <pgf/gd/interface/c/InterfaceFromC.h> + +// Lua stuff: +#include <lauxlib.h> + +// C stuff: +#include <stdlib.h> +#include <string.h> + + +// The following is a hack to avoid a problem with the Lua lib being linked twice. +// When this happens, two version of "dummynode" exist in Lua and we must ensure that +// we never create a table using such a dummynode while using a second lib. +// The following should later be set to 0 and replaced everywhere, once this is fixed. +#define MIN_HASH_SIZE_FIX 1 + + + +// Help functions + +static void set_field (lua_State* L, const char* what, const char* where) +{ + if (what) { + lua_pushstring(L, what); + lua_setfield(L, -2, where); + } +} + + +static void init_vertex_array(pgfgd_Vertex_array* a, int count) +{ + a->length = count; + a->array = (pgfgd_Vertex**) calloc(count, sizeof(pgfgd_Vertex*)); +} + +static void init_edge_array(pgfgd_Edge_array* a, int count) +{ + a->length = count; + a->array = (pgfgd_Edge**) calloc(count, sizeof(pgfgd_Edge*)); +} + +static void init_arcs_array(pgfgd_Arc_array* arcs, int length) +{ + arcs->length = length; + arcs->tails = (int*) calloc(length, sizeof(int)); + arcs->heads = (int*) calloc(length, sizeof(int)); +} + +static void init_path(pgfgd_Path* a, int count) +{ + a->length = count; + a->coordinates = (pgfgd_Coordinate*) calloc(count, sizeof(pgfgd_Coordinate)); + a->strings = (char**) calloc(count, sizeof(char*)); +} + +static void clear_path(pgfgd_Path* p) +{ + int i; + for (i=0; i < p->length; i++) + free(p->strings[i]); + + free(p->strings); + free(p->coordinates); + + p->length = 0; + p->strings = 0; + p->coordinates = 0; +} + + + +// Option handling + +struct pgfgd_OptionTable { + lua_State* state; + + int kind; + int index; +}; + +// These are the indices of the parameters during a run of the main +// algorithm: +#define GRAPH_INDEX 1 +#define VERTICES_INDEX 2 +#define EDGES_INDEX 3 +#define ALGORITHM_INDEX 4 + +// This is the index of a special table mapping vertices back to the +// index they have. It is created in the C code, but stays on the +// stack during the computations. +#define BACKINDEX_STORAGE_INDEX 5 + +// These are the positions of different upvalues for the C closure of +// a C algorithm. +#define FUNCTION_UPVALUE 1 +#define USER_UPVALUE 2 +#define DIGRAPH_OBJECT_UPVALUE 3 + + +static pgfgd_OptionTable* make_option_table(lua_State* L, int kind, int index) +{ + pgfgd_OptionTable* t = (pgfgd_OptionTable*) malloc(sizeof(pgfgd_OptionTable)); + + t->state = L; + t->kind = kind; + t->index = index; + + return t; +} + +static void push_option_table(pgfgd_OptionTable* t) +{ + switch (t->kind) { + case GRAPH_INDEX: + lua_getfield(t->state, GRAPH_INDEX, "options"); + break; + case VERTICES_INDEX: + lua_rawgeti(t->state, VERTICES_INDEX, t->index); + lua_getfield(t->state, -1, "options"); + lua_replace(t->state, -2); + break; + case EDGES_INDEX: + lua_rawgeti(t->state, EDGES_INDEX, t->index); + lua_getfield(t->state, -1, "options"); + lua_replace(t->state, -2); + break; + } +} + +int pgfgd_isset(pgfgd_OptionTable* t, const char* key) +{ + push_option_table(t); + lua_getfield(t->state, -1, key); + int is_nil = lua_isnil(t->state, -1); + lua_pop(t->state, 2); + return !is_nil; +} + +int pgfgd_isnumber(pgfgd_OptionTable* t, const char* key) +{ + push_option_table(t); + lua_getfield(t->state, -1, key); + int is_number = lua_isnumber(t->state, -1); + lua_pop(t->state, 2); + return is_number; +} + +int pgfgd_isboolean(pgfgd_OptionTable* t, const char* key) +{ + push_option_table(t); + lua_getfield(t->state, -1, key); + int is_bool = lua_isboolean(t->state, -1); + lua_pop(t->state, 2); + return is_bool; +} + +int pgfgd_isstring(pgfgd_OptionTable* t, const char* key) +{ + push_option_table(t); + lua_getfield(t->state, -1, key); + int is_string = lua_isstring(t->state, -1); + lua_pop(t->state, 2); + return is_string; +} + +int pgfgd_isuser(pgfgd_OptionTable* t, const char* key) +{ + push_option_table(t); + lua_getfield(t->state, -1, key); + int is_user = lua_isuserdata(t->state, -1); + lua_pop(t->state, 2); + return is_user; +} + + +double pgfgd_tonumber(pgfgd_OptionTable* t, const char* key) +{ + push_option_table(t); + lua_getfield(t->state, -1, key); + double d = lua_tonumber(t->state, -1); + lua_pop(t->state, 2); + return d; +} + +int pgfgd_toboolean(pgfgd_OptionTable* t, const char* key) +{ + push_option_table(t); + lua_getfield(t->state, -1, key); + int d = lua_toboolean(t->state, -1); + lua_pop(t->state, 2); + return d; +} + +char* pgfgd_tostring(pgfgd_OptionTable* t, const char* key) +{ + push_option_table(t); + lua_getfield(t->state, -1, key); + const char* s = lua_tostring(t->state, -1); + char* copy = strcpy((char*) malloc(strlen(s)+1), s); + lua_pop(t->state, 2); + return copy; +} + +void* pgfgd_touser(pgfgd_OptionTable* t, const char* key) +{ + push_option_table(t); + lua_getfield(t->state, -1, key); + void* d = lua_touserdata(t->state, -1); + lua_pop(t->state, 2); + return d; +} + + +// Handling algorithms + +struct pgfgd_SyntacticDigraph_internals { + lua_State* state; +}; + +static char* make_string_from(lua_State* L, const char* name) +{ + lua_getfield(L, -1, name); + if (lua_isnil(L, -1)) { + // Field not set; return emtpy string. + lua_pop(L, 1); + return (char*) calloc(1, sizeof(char)); + } + else { + const char* s = lua_tostring(L, -1); + char* copy = strcpy((char*) malloc(strlen(s)+1), s); + lua_pop(L, 1); + return copy; + } +} + +static void make_coordinate(lua_State* L, pgfgd_Coordinate* c) +{ + lua_getfield(L, -1, "x"); + c->x = lua_tonumber(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "y"); + c->y = lua_tonumber(L, -1); + lua_pop(L, 1); +} + +static pgfgd_Path* make_empty_path(lua_State* L) +{ + return (pgfgd_Path*) calloc(1, sizeof(pgfgd_Path)); +} + +static pgfgd_Path* make_path(lua_State* L) +{ + /* Path object must be on top of stack. */ + pgfgd_Path* p = make_empty_path(L); + + // Fill path: + int path_length = lua_rawlen(L, -1); + if (path_length > 0) { + init_path(p, path_length); + int i; + for (i = 0; i < path_length; i++) { + lua_rawgeti(L, -1, i+1); + if (lua_isstring(L, -1)) { + const char* s = lua_tostring(L, -1); + p->strings[i] = strcpy((char*) malloc(strlen(s)+1), s); + } else { + lua_getfield(L, -1, "x"); + p->coordinates[i].x = lua_tonumber(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "y"); + p->coordinates[i].y = lua_tonumber(L, -1); + lua_pop(L, 1); + } + lua_pop(L, 1); + } + } + + return p; +} + +static void construct_digraph(lua_State* L, pgfgd_SyntacticDigraph* d) +{ + d->internals = (pgfgd_SyntacticDigraph_internals*) calloc(1, sizeof(pgfgd_SyntacticDigraph_internals)); + d->internals->state = L; + + // Create the options table: + d->options = make_option_table(L, GRAPH_INDEX, 0); + + // Create the vertex table + init_vertex_array(&d->vertices, lua_rawlen(L, VERTICES_INDEX)); + + // Create the vertices + int i; + for (i=0; i<d->vertices.length; i++) { + pgfgd_Vertex* v = (pgfgd_Vertex*) calloc(1, sizeof(pgfgd_Vertex)); + + // Push the vertex onto the Lua stack: + lua_rawgeti(L, VERTICES_INDEX, i+1); + + // Fill v with information: + v->name = make_string_from(L, "name"); + v->shape = make_string_from(L, "shape"); + v->kind = make_string_from(L, "kind"); + + // Options: + v->options = make_option_table(L, VERTICES_INDEX, i+1); + + // Index: + v->array_index = i; + + // Setup pos field + lua_getfield(L, -1, "pos"); + make_coordinate(L, &v->pos); + lua_pop(L, 1); + + // Setup path array: + lua_getfield(L, -1, "path"); + v->path = make_path(L); + lua_pop(L, 1); + + // Pop the vertex + lua_pop(L, 1); + + d->vertices.array[i] = v; + } + + // Construct the edges: + init_edge_array(&d->syntactic_edges, lua_rawlen(L, EDGES_INDEX)); + + int edge_index; + for (edge_index = 0; edge_index < d->syntactic_edges.length; edge_index++) { + pgfgd_Edge* e = (pgfgd_Edge*) calloc(1, sizeof(pgfgd_Edge)); + + lua_rawgeti(L, EDGES_INDEX, edge_index+1); + + e->direction = make_string_from(L, "direction"); + e->options = make_option_table(L, EDGES_INDEX, edge_index+1); + + // Index: + e->array_index = edge_index; + + // Compute the tail vertex index: + lua_getfield(L, -1, "tail"); + lua_gettable(L, VERTICES_INDEX); + e->tail = d->vertices.array[lua_tointeger(L, -1) - 1]; + lua_pop(L, 1); + + lua_getfield(L, -1, "head"); + lua_gettable(L, VERTICES_INDEX); + e->head = d->vertices.array[lua_tointeger(L, -1) - 1]; + lua_pop(L, 1); + + // Fill path: + e->path = make_empty_path(L); + e->path->length = -1; // Means that a default path should be created. + + // Pop the edge form the Lua stack: + lua_pop(L, 1); + + d->syntactic_edges.array[edge_index] = e; + } +} + + +static void sync_digraph(lua_State* L, pgfgd_SyntacticDigraph* d) +{ + // Writes back the computed position information to the digraph: + int i; + for (i=0; i<d->vertices.length; i++) { + + // Push pos field of vertex: + lua_rawgeti(L, VERTICES_INDEX, i+1); + lua_getfield(L, -1, "pos"); + + // Set x and y coordinates: + pgfgd_Vertex* v = d->vertices.array[i]; + lua_pushnumber(L, v->pos.x); + lua_setfield(L, -2, "x"); + lua_pushnumber(L, v->pos.y); + lua_setfield(L, -2, "y"); + + // pop pos and vertex + lua_pop(L, 2); + } + + // Write back the paths + + int tos = lua_gettop(L); + + // First, get "Coordinate.new" as a "local" + lua_getglobal(L, "require"); + lua_pushstring(L, "pgf.gd.model.Path"); + lua_call(L, 1, 1); + int Path_index = lua_gettop(L); + + lua_getglobal(L, "require"); + lua_pushstring(L, "pgf.gd.model.Coordinate"); + lua_call(L, 1, 1); + lua_getfield(L, -1, "new"); + + int Coordinate_new_index = lua_gettop(L); + + for (i=0; i < d->syntactic_edges.length; i++) { + pgfgd_Edge* e = d->syntactic_edges.array[i]; + + lua_rawgeti(L, EDGES_INDEX, i+1); + + if (e->path->length == -1) { + // Create default path + pgfgd_path_append_moveto_tail(e); + pgfgd_path_append_lineto_head(e); + } + + lua_createtable(L, e->path->length ? e->path->length : 1, MIN_HASH_SIZE_FIX); + lua_pushvalue(L, Path_index); + lua_setmetatable(L, -2); + + int j; + for (j=0; j<e->path->length; j++) { + if (e->path->strings[j]) { + lua_pushstring(L, e->path->strings[j]); + lua_rawseti(L, -2, j+1); + } else { + lua_pushvalue(L, Coordinate_new_index); + lua_pushnumber(L, e->path->coordinates[j].x); + lua_pushnumber(L, e->path->coordinates[j].y); + lua_call(L, 2, 1); + + lua_rawseti(L, -2, j+1); + } + } + + lua_setfield(L, -2, "path"); + lua_pop(L, 1); // The edge object + } + + lua_settop(L, tos); // Cleanup +} + + +static void free_digraph(pgfgd_SyntacticDigraph* digraph) +{ + int i; + for (i=0; i < digraph->vertices.length; i++) { + pgfgd_Vertex* v = digraph->vertices.array[i]; + + clear_path(v->path); + free(v->path); + free(v->name); + free(v->shape); + free(v->kind); + free(v->options); + free(v->incoming.array); + free(v->outgoing.array); + free(v); + } + + for (i=0; i < digraph->syntactic_edges.length; i++) { + pgfgd_Edge* e = digraph->syntactic_edges.array[i]; + + clear_path(e->path); + free(e->path); + free(e->direction); + free(e->options); + free(e); + } + + free(digraph->vertices.array); + free(digraph->syntactic_edges.array); + free(digraph->options); + free(digraph->internals); + free(digraph); +} + +static int algorithm_dispatcher(lua_State* L) +{ + // Create the back index table. It will be at index BACKINDEX_STORAGE_INDEX + lua_createtable(L, 0, MIN_HASH_SIZE_FIX); + + // The actual function is stored in an upvalue. + pgfgd_SyntacticDigraph* digraph = (pgfgd_SyntacticDigraph*) calloc(1, sizeof(pgfgd_SyntacticDigraph)); + + construct_digraph(L, digraph); + + pgfgd_algorithm_fun fun = lua_touserdata(L, lua_upvalueindex(FUNCTION_UPVALUE)); + fun(digraph, lua_touserdata(L, lua_upvalueindex(USER_UPVALUE))); + + sync_digraph(L, digraph); + + free_digraph(digraph); + + return 0; +} + + +int pgfgd_vertex_anchor(pgfgd_Vertex* v, const char* anchor, double* x, double* y) +{ + lua_State* L = v->options->state; + + // Ok, first, find the vertex: + lua_rawgeti(L, VERTICES_INDEX, v->array_index+1); + + // Find the anchor function: + lua_getfield(L, -1, "anchor"); + lua_pushvalue(L, -2); + lua_pushstring(L, anchor); + + // Find the anchor: + lua_call(L, 2, 1); + + if (lua_isnil(L, -1)) { + // Failed. Cleanup! + lua_pop(L, 2); + *x = 0; + *y = 0; + return 0; + } else { + lua_getfield(L, -1, "x"); + *x = lua_tonumber(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "y"); + *y = lua_tonumber(L, -1); + lua_pop(L, 1); + + lua_pop(L, 2); + return 1; + } + return 0; +} + + + +void pgfgd_path_clear(pgfgd_Edge* e) +{ + clear_path (e->path); +} + +static void path_add_segment(pgfgd_Edge* edge, const char* s, int num, double a, double b, double c, double d, double e, double f) +{ + if (edge->path->length == -1) + pgfgd_path_clear(edge); + + int start = edge->path->length; + + edge->path->length += num + 1; + edge->path->strings = (char **) + realloc(edge->path->strings, edge->path->length*sizeof(char*)); + edge->path->coordinates = (pgfgd_Coordinate*) + realloc(edge->path->coordinates, edge->path->length*sizeof(pgfgd_Coordinate)); + + edge->path->coordinates[start].x = 0; + edge->path->coordinates[start].y = 0; + edge->path->strings[start] = strcpy((char*) malloc(strlen(s)+1), s); + + if (num > 0) { + edge->path->coordinates[start+1].x = a; + edge->path->coordinates[start+1].y = b; + edge->path->strings[start+1] = 0; + } + + if (num > 1) { + edge->path->coordinates[start+2].x = c; + edge->path->coordinates[start+2].y = d; + edge->path->strings[start+2] = 0; + } + + if (num > 2) { + edge->path->coordinates[start+3].x = e; + edge->path->coordinates[start+3].y = f; + edge->path->strings[start+3] = 0; + } +} + + +void pgfgd_path_append_moveto(pgfgd_Edge* e, double x, double y) +{ + path_add_segment(e, "moveto", 1, x, y, 0, 0, 0, 0); +} + +void pgfgd_path_append_moveto_tail (pgfgd_Edge* e) +{ + double x, y; + char* tail_anchor = pgfgd_tostring(e->tail->options, "tail anchor"); + + pgfgd_vertex_anchor(e->tail, tail_anchor, &x, &y); + x += e->tail->pos.x; + y += e->tail->pos.y; + + pgfgd_path_append_moveto(e, x, y); + free(tail_anchor); +} + +void pgfgd_path_append_lineto(pgfgd_Edge* e, double x, double y) +{ + path_add_segment(e, "lineto", 1, x, y, 0, 0, 0, 0); +} + +void pgfgd_path_append_lineto_head (pgfgd_Edge* e) +{ + double x, y; + char* head_anchor = pgfgd_tostring(e->head->options, "head anchor"); + + pgfgd_vertex_anchor(e->head, head_anchor, &x, &y); + x += e->head->pos.x; + y += e->head->pos.y; + + pgfgd_path_append_lineto(e, x, y); + free(head_anchor); +} + +void pgfgd_path_append_curveto(pgfgd_Edge* edge, double a, double b, double c, double d, double e, double f) +{ + path_add_segment(edge, "curveto", 3, a, b, c, d, e, f); +} + +void pgfgd_path_append_closepath(pgfgd_Edge* e) +{ + path_add_segment(e, "closepath", 0, 0, 0, 0, 0, 0, 0); +} + + + +// Handling digraphs + +struct pgfgd_Digraph { + lua_State* state; + const char* name; + pgfgd_SyntacticDigraph* syntactic_digraph; +}; + + +pgfgd_Digraph* pgfgd_get_digraph (pgfgd_SyntacticDigraph* g, const char* graph_name) +{ + lua_State* L = g->internals->state; + + lua_getfield(L, ALGORITHM_INDEX, graph_name); + if (lua_isnil(L, -1)) + luaL_error(L, "digraph named %s not found in algorithm class", graph_name); + lua_pop(L, 1); + + pgfgd_Digraph* new = (pgfgd_Digraph*) calloc(1, sizeof(pgfgd_Digraph)); + + new->state = L; + new->name = graph_name; + new->syntactic_digraph = g; + + return new; +} + +int pgfgd_digraph_num_vertices (pgfgd_Digraph* g) +{ + lua_getfield(g->state, ALGORITHM_INDEX, g->name); + lua_getfield(g->state, -1, "vertices"); + int num = lua_rawlen(g->state, -1); + lua_pop(g->state, 2); + + return num; +} + +static void push_digraph_and_backindex(pgfgd_Digraph* g) +{ + lua_State* L = g->state; + + // Get digraph + lua_getfield(L, ALGORITHM_INDEX, g->name); + int digraph_pos = lua_gettop(L); + + // Get entry in back index table + lua_pushvalue(L, digraph_pos); + lua_gettable(L, BACKINDEX_STORAGE_INDEX); + int backtable_pos = lua_gettop(L); + if (lua_isnil(L, backtable_pos)) { + // Aha. We need to install a new table: + lua_pop(L, 1); // Get rid of nil + + lua_createtable(L, 0, MIN_HASH_SIZE_FIX); + + lua_pushvalue(L, digraph_pos); // The digraph object + lua_pushvalue(L, backtable_pos); // The new table + lua_settable(L, BACKINDEX_STORAGE_INDEX); + + // Fill the table: + lua_getfield(L, digraph_pos, "vertices"); + int vertex_pos = lua_gettop(L); + int i; + int n = lua_rawlen(L, -1); + for (i = 1; i <= n; i++) { + lua_rawgeti(L, vertex_pos, i); + lua_pushinteger(L, i); + lua_settable(L, backtable_pos); + } + lua_pop(L, 1); + } +} + +static pgfgd_Arc_array* build_c_array_of_arcs_from_lua_array_of_arcs(pgfgd_Digraph* g) +{ + lua_State* L = g->state; + + pgfgd_Arc_array* arcs = (pgfgd_Arc_array*) calloc(1, sizeof(pgfgd_Arc_array)); + + int array_pos = lua_gettop(L); + + push_digraph_and_backindex(g); + int backtable_pos = lua_gettop(L); + + // Get number of arcs: + init_arcs_array(arcs, lua_rawlen(L, array_pos)); + int i; + for (i = 1; i<=arcs->length; i++) { + lua_rawgeti(L, array_pos, i); // Get arcs[i] + + // The tail field: + lua_getfield(L, -1, "tail"); + lua_gettable(L, backtable_pos); + + arcs->tails[i-1] = lua_tointeger(L, -1); + lua_pop(L, 1); // The number + + // The head field: + lua_getfield(L, -1, "head"); + lua_gettable(L, backtable_pos); + arcs->heads[i-1] = lua_tointeger(L, -1); + lua_pop(L, 1); // The number + + lua_pop(L, 1); // Pop arcs[i] + } + + lua_settop(L, array_pos); + + return arcs; +} + + +pgfgd_Arc_array* pgfgd_digraph_arcs (pgfgd_Digraph* g) +{ + lua_getfield(g->state, ALGORITHM_INDEX, g->name); + lua_getfield(g->state, -1, "arcs"); + + pgfgd_Arc_array* a = build_c_array_of_arcs_from_lua_array_of_arcs(g); + + lua_pop(g->state, 2); + + return a; +} + + +pgfgd_Vertex* pgfgd_digraph_syntactic_vertex (pgfgd_Digraph* g, int v) +{ + int tos = lua_gettop(g->state); + pgfgd_Vertex* return_me = 0; + + lua_getfield(g->state, ALGORITHM_INDEX, g->name); + lua_getfield(g->state, -1, "vertices"); + lua_rawgeti(g->state, -1, v); + + lua_gettable(g->state, VERTICES_INDEX); + if (lua_isnumber(g->state, -1)) { + return_me = g->syntactic_digraph->vertices.array[lua_tointeger(g->state, -1)-1]; + } + + lua_settop(g->state, tos); + return return_me; +} + + +int pgfgd_digraph_isarc (pgfgd_Digraph* g, int tail, int head) +{ + lua_State* L = g->state; + int is_arc = 0; + + lua_getfield(L, ALGORITHM_INDEX, g->name); + int digraph_pos = lua_gettop(L); + + lua_getfield(L, digraph_pos, "vertices"); + int vertices_pos = lua_gettop(L); + + // Call digraph:connected(tail, head) + lua_pushvalue(L, lua_upvalueindex(DIGRAPH_OBJECT_UPVALUE)); + lua_getfield(L, -1, "arc"); + lua_pushvalue(L, digraph_pos); + lua_rawgeti(L, vertices_pos, tail); + lua_rawgeti(L, vertices_pos, head); + lua_call(L, 3, 1); + + is_arc = !lua_isnil(L, -1); + + lua_settop(L, digraph_pos-1); + + return is_arc; +} + +pgfgd_Arc_array* pgfgd_digraph_incoming (pgfgd_Digraph* g, int v) +{ + lua_State* L = g->state; + + lua_getfield(L, ALGORITHM_INDEX, g->name); + int digraph_pos = lua_gettop(L); + + lua_getfield(L, digraph_pos, "vertices"); + int vertices_pos = lua_gettop(L); + + // Call digraph:connected(tail, head) + lua_pushvalue(L, lua_upvalueindex(DIGRAPH_OBJECT_UPVALUE)); + lua_getfield(L, -1, "incoming"); + lua_pushvalue(L, digraph_pos); + lua_rawgeti(L, vertices_pos, v); + lua_call(L, 2, 1); + + pgfgd_Arc_array* a = build_c_array_of_arcs_from_lua_array_of_arcs(g); + + lua_settop(L, digraph_pos-1); + + return a; +} + +pgfgd_Arc_array* pgfgd_digraph_outgoing (pgfgd_Digraph* g, int v) +{ + lua_State* L = g->state; + + lua_getfield(L, ALGORITHM_INDEX, g->name); + int digraph_pos = lua_gettop(L); + + lua_getfield(L, digraph_pos, "vertices"); + int vertices_pos = lua_gettop(L); + + // Call digraph:connected(tail, head) + lua_pushvalue(L, lua_upvalueindex(DIGRAPH_OBJECT_UPVALUE)); + lua_getfield(L, -1, "outgoing"); + lua_pushvalue(L, digraph_pos); + lua_rawgeti(L, vertices_pos, v); + lua_call(L, 2, 1); + + pgfgd_Arc_array* a = build_c_array_of_arcs_from_lua_array_of_arcs(g); + + lua_settop(L, digraph_pos-1); + + return a; +} + +pgfgd_Edge_array* pgfgd_digraph_syntactic_edges (pgfgd_Digraph* g, int tail, int head) +{ + pgfgd_Edge_array* edges = (pgfgd_Edge_array*) calloc(1, sizeof(pgfgd_Edge_array)); + + // First, get the arc in the syntatic digraph. + lua_State* L = g->state; + int tos = lua_gettop(L); + + lua_getfield(L, ALGORITHM_INDEX, g->name); + int digraph_pos = lua_gettop(L); + + lua_getfield(L, digraph_pos, "vertices"); + int vertices_pos = lua_gettop(L); + + // Call digraph:arc(tail, head) + lua_pushvalue(L, lua_upvalueindex(DIGRAPH_OBJECT_UPVALUE)); + int digraph_class_index = lua_gettop(L); + + lua_getfield(L, digraph_class_index, "arc"); + lua_pushvalue(L, digraph_pos); + lua_rawgeti(L, vertices_pos, tail); + lua_rawgeti(L, vertices_pos, head); + lua_call(L, 3, 1); + + if (!lua_isnil(L, -1)) { + // Get syntactic_digraph of the arc: + lua_getfield(L, -1, "syntactic_digraph"); + + // Call syntactic_digraph:arc(tail, head) + lua_getfield(L, digraph_class_index, "arc"); + lua_pushvalue(L, -2); + lua_rawgeti(L, vertices_pos, tail); + lua_rawgeti(L, vertices_pos, head); + lua_call(L, 3, 1); + + if (!lua_isnil(L, -1)) { + lua_getfield(L, -1, "syntactic_edges"); + int syntactic_edges_index = lua_gettop(L); + + int n = lua_rawlen(L, syntactic_edges_index); + init_edge_array(edges, n); + int i; + for (i=1; i<=n; i++) { + lua_rawgeti(L, syntactic_edges_index, i); + lua_gettable(L, EDGES_INDEX); + if (!lua_isnumber(L, -1)) { + pgfgd_digraph_free_edge_array(edges); + luaL_error(L, "syntactic edge index not found"); + } + int p = lua_tonumber(L, -1); + edges->array[i-1] = g->syntactic_digraph->syntactic_edges.array[p-1]; + } + } + } + + lua_settop(L, tos); + + return edges; +} + + + +void pgfgd_digraph_free (pgfgd_Digraph* g) +{ + free(g); +} + +void pgfgd_digraph_free_arc_array (pgfgd_Arc_array* arcs) +{ + free (arcs->tails); + free (arcs->heads); + free (arcs); +} + +void pgfgd_digraph_free_edge_array (pgfgd_Edge_array* edges) +{ + free (edges->array); + free (edges); +} + + + +// Handling declarations + + +struct pgfgd_Declaration { + const char* key; + const char* summary; + const char* type; + const char* initial; + void* initial_user; + const char* default_value; + const char* alias; + const char* alias_function_string; + const char* documentation; + const char* documentation_in; + pgfgd_algorithm_fun algorithm; + void* algorithm_user; + const char* phase; + + int use_length; + const char** use_keys; + const char** use_values_strings; + void** use_values_user; + + int examples_length; + const char** examples; + + int pre_length; + const char** pre; + + int post_length; + const char** post; +}; + + +pgfgd_Declaration* pgfgd_new_key (const char* key) +{ + pgfgd_Declaration* d = (pgfgd_Declaration*) calloc(1, sizeof(pgfgd_Declaration)); + + d->key = key; + + return d; +} + +void pgfgd_declare(struct lua_State* state, pgfgd_Declaration* d) +{ + if (d && d->key) { + int tos = lua_gettop(state); + + lua_gc(state, LUA_GCSTOP, 0); // BUG: Remove once linking against dynamic Lua lib works! + + // Find declare function: + lua_getglobal(state, "require"); + lua_pushstring(state, "pgf.gd.interface.InterfaceToAlgorithms"); + lua_call(state, 1, 1); + lua_getfield(state, -1, "declare"); + + // Build a Lua table: + lua_createtable(state, 0, 11); + + set_field (state, d->key, "key"); + set_field (state, d->summary, "summary"); + set_field (state, d->type, "type"); + set_field (state, d->initial, "initial"); + set_field (state, d->documentation, "documentation"); + set_field (state, d->documentation_in, "documentation_in"); + set_field (state, d->default_value, "default"); + set_field (state, d->alias, "alias"); + set_field (state, d->alias_function_string, "alias_function_string"); + set_field (state, d->phase, "phase"); + + if (d->initial_user) { + lua_pushlightuserdata(state, d->initial_user); + lua_setfield(state, -2, "initial"); + } + + if (d->use_length > 0) { + lua_createtable(state, d->use_length, MIN_HASH_SIZE_FIX); + int i; + for (i=0; i < d->use_length; i++) { + lua_createtable(state, 0, 2); + set_field(state, d->use_keys[i], "key"); + if (d->use_values_strings[i]) + set_field(state, d->use_values_strings[i], "value"); + if (d->use_values_user[i]) { + lua_pushlightuserdata(state, d->use_values_user[i]); + lua_setfield(state, -2, "value"); + } + lua_rawseti(state, -2, i+1); + } + lua_setfield(state, -2, "use"); + } + + if (d->pre) { + lua_createtable(state, 0, d->pre_length); + int i; + for (i=0; i < d->pre_length; i++) { + lua_pushboolean(state, 1); + lua_setfield(state, -2, d->pre[i]); + } + lua_setfield(state, -2, "preconditions"); + } + + if (d->post) { + lua_createtable(state, 0, d->post_length); + int i; + for (i=0; i < d->post_length; i++) { + lua_pushboolean(state, 1); + lua_setfield(state, -2, d->post[i]); + } + lua_setfield(state, -2, "postconditions"); + } + + if (d->examples) { + lua_createtable(state, d->examples_length, MIN_HASH_SIZE_FIX); + int i; + for (i=0; i < d->examples_length; i++) { + lua_pushstring(state, d->examples[i]); + lua_rawseti(state, -2, i+1); + } + lua_setfield(state, -2, "examples"); + } + + if (d->algorithm) { + // The algorithm function and the user data is stored as lightuserdate upvalue + lua_pushlightuserdata(state, (void *) d->algorithm); + lua_pushlightuserdata(state, (void *) d->algorithm_user); + + // Find the Digraph.arc function and store it as the second upvalue: + lua_getglobal(state, "require"); + lua_pushstring(state, "pgf.gd.model.Digraph"); + lua_call(state, 1, 1); + + lua_pushcclosure(state, algorithm_dispatcher, 3); + lua_setfield(state, -2, "algorithm_written_in_c"); + } + + // Call the declare function: + lua_call(state, 1, 0); + + // Cleanup: + lua_settop(state, tos); + + lua_gc(state, LUA_GCRESTART, 0); + } +} + +void pgfgd_key_add_use(pgfgd_Declaration* d, const char* key, const char* value) +{ + d->use_length++; + d->use_keys = (const char **) realloc(d->use_keys, d->use_length*sizeof(const char*)); + d->use_values_strings = (const char **) realloc(d->use_values_strings, d->use_length*sizeof(const char*)); + d->use_values_user = (void **) realloc(d->use_values_user, d->use_length*sizeof(void*)); + + d->use_keys [d->use_length-1] = key; + d->use_values_strings[d->use_length-1] = value; + d->use_values_user [d->use_length-1] = 0; +} + +void pgfgd_key_add_use_user(pgfgd_Declaration* d, const char* key, void* value) +{ + d->use_length++; + d->use_keys = (const char **) realloc(d->use_keys, d->use_length*sizeof(const char*)); + d->use_values_strings = (const char **) realloc(d->use_values_strings, d->use_length*sizeof(const char*)); + d->use_values_user = (void **) realloc(d->use_values_user, d->use_length*sizeof(void*)); + + d->use_keys [d->use_length-1] = key; + d->use_values_strings[d->use_length-1] = 0; + d->use_values_user [d->use_length-1] = value; +} + +void pgfgd_key_add_example(pgfgd_Declaration* d, const char* s) +{ + d->examples_length++; + d->examples = (const char **) realloc(d->examples, d->examples_length*sizeof(const char*)); + + d->examples[d->examples_length-1] = s; +} + +void pgfgd_key_add_precondition(pgfgd_Declaration* d, const char* s) +{ + d->pre_length++; + d->pre = (const char **) realloc(d->pre, d->pre_length*sizeof(const char*)); + + d->pre[d->pre_length-1] = s; +} + +void pgfgd_key_add_postcondition(pgfgd_Declaration* d, const char* s) +{ + d->post_length++; + d->post = (const char **) realloc(d->post, d->post_length*sizeof(const char*)); + + d->post[d->post_length-1] = s; +} + +void pgfgd_key_summary(pgfgd_Declaration* d, const char* s) +{ + d->summary = s; +} + +void pgfgd_key_type(pgfgd_Declaration* d, const char* s) +{ + d->type = s; +} + +void pgfgd_key_initial(pgfgd_Declaration* d, const char* s) +{ + d->initial = s; +} + +void pgfgd_key_initial_user(pgfgd_Declaration* d, void* s) +{ + d->initial_user = s; +} + +void pgfgd_key_default(pgfgd_Declaration* d, const char* s) +{ + d->default_value = s; +} + +void pgfgd_key_alias(pgfgd_Declaration* d, const char* s) +{ + d->alias = s; +} + +void pgfgd_key_alias_function(pgfgd_Declaration* d, const char* s) +{ + d->alias_function_string = s; +} + +void pgfgd_key_documentation(pgfgd_Declaration* d, const char* s) +{ + d->documentation = s; +} + +void pgfgd_key_documentation_in(pgfgd_Declaration* d, const char* s) +{ + d->documentation_in = s; +} + +void pgfgd_key_phase(pgfgd_Declaration* d, const char* s) +{ + d->phase = s; +} + +void pgfgd_key_algorithm(pgfgd_Declaration* d, pgfgd_algorithm_fun f, void* user_data) +{ + d->algorithm = f; + d->algorithm_user = user_data; +} + +void pgfgd_free_key(pgfgd_Declaration* d) +{ + if (d) { + free(d->examples); + free(d->use_keys); + free(d->use_values_user); + free(d->use_values_strings); + free(d); + } +} diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/InterfaceFromC.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/InterfaceFromC.h new file mode 100644 index 00000000000..40495dbdc29 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/InterfaceFromC.h @@ -0,0 +1,613 @@ +#ifndef PGF_GD_INTERFACE_C_INTERFACEFROMC_H +#define PGF_GD_INTERFACE_C_INTERFACEFROMC_H + +/** \file pgf/gd/interface/c/InterfaceFromC.h + + The C-header file that should be used by algorithms written + in C for graph drawing in Lua. +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + + + +// Option handling + +/** Abstraction of a Lua option table. + You cannot access it directly, but only through the function + pgfgd_isset and so on. Note that pointers to such option tables + will only be valid during a run of the algorithm; you cannot store + a point to an option table past the run of an algorithm. +*/ + +typedef struct pgfgd_OptionTable pgfgd_OptionTable; + + +/** Returns 1 if the key is actually set in the option table to any + non-nil value; otherwise 0. */ +int pgfgd_isset(pgfgd_OptionTable* t, const char* key); + +/** Returns 1 if the key is a number (or can be converted to a + number) in the option table. */ +int pgfgd_isnumber(pgfgd_OptionTable* t, const char* key); + +/** Returns 1 if the key is a string in the option table. */ +int pgfgd_isstring(pgfgd_OptionTable* t, const char* key); + +/** Returns 1 if the key is a Boolean value in the option table. */ +int pgfgd_isboolean(pgfgd_OptionTable* t, const char* key); + +/** Returns 1 if the key is a user value in the option table. */ +int pgfgd_isuser(pgfgd_OptionTable* t, const char* key); + +/** Provided that pgfgd_isnumber returns 1 for the key, this funciton + will return the number stored in the key (otherwise, the function + may crash). Note that integers are also retrieved through this function. */ +double pgfgd_tonumber(pgfgd_OptionTable* t, const char* key); + +/** Provided that pgfgd_isstring returns 1 for this key, this function + returns a copy of the string stored in the key. You must free the + returned string yourself. */ +char* pgfgd_tostring(pgfgd_OptionTable* t, const char* key); + +/** Provided that pgfgd_isboolean returns 1 for this key, the function + returns this Boolean value. */ +int pgfgd_toboolean(pgfgd_OptionTable* t, const char* key); + +/** Provided that pgfgd_isuser returns 1 for this key, the function + returns this user value. */ +void* pgfgd_touser(pgfgd_OptionTable* t, const char* key); + + + +// Graph model + +/** An abstraction of a pgf.gd.model.Coordinate object. */ +typedef struct pgfgd_Coordinate { + double x; + double y; +} pgfgd_Coordinate; + + +/** Used to pass around arrays of Coordinate objects. The main purpose + of the structure is to provide access to the length of the + array. Note that numbering starts with 0. +*/ +typedef struct pgfgd_Coordinate_array { + int length; + pgfgd_Coordinate* array; +} pgfgd_Coordinate_array; + + +typedef struct pgfgd_Edge pgfgd_Edge; + +/** An array of Edge objects. */ +typedef struct pgfgd_Edge_array { + + int length; + pgfgd_Edge** array; + +} pgfgd_Edge_array; + + +/** This struct is used to model a Lua Path. In Lua, a path is an + array where each entry is either a Coordinate object or a + string. This is modeled on the C layer by having + two arrays and for each position, either the coordinates array or + the strings array is set (the strings + array is set at position i if, and only if, it is not null). + + Graph drawing functions may wish to modify Edge paths, namely + whenever they wish to setup a special routing for an edge. In this + case, you may not directly modify the object, but, rather, you + must use the functions pgfgd_path_xxx to modify the path + field. When the graph drawing function is done, the values stored + in the the path fields of the Edges of the syntactic digraph are + copied back to Lua. + + Note that numbering starts at 0. Also note that you have to set + the path field for each syntactic edge individually. + + The |length| field will be |-1| for the ``default path'' of an + edge. The actual path (a straight line from the tail to the head + vertex) is generated only when the graph is written back, because + only then the coordinates of the nodes will be known. +*/ + +typedef struct pgfgd_Path { + + /** Both arrays of this struct will have this length, except when + this field is set to -1, indicating that a default path should + be generated when this path is written back to the graph. */ + int length; + + /** An array of coordinates. Not all entries of this array are + relevant, namely only those for which the strings array is null + at the some position. + */ + pgfgd_Coordinate* coordinates; + + /** An array of strings. Whenever an entry in this array is not + null, the entry in the coordinates array at the same position is + ignored. */ + char** strings; + +} pgfgd_Path; + + + +/** An abstraction of a pgf.gd.model.Vertex. These objects are + managed by the library (including creation and deletion), you + should not create them yourself or modify them, except for the pos + field, which you should modify (indeed, this is the whole purpose + of your graph drawing algorithm). +*/ + +typedef struct pgfgd_Vertex { + + /** The name field of the Lua Vertex class. */ + char* name; + + /** The path field of the Lua Vertex class. */ + pgfgd_Path* path; + + /** The shape field of the Lua Vertex class. */ + char* shape; + + /** The kind field of the Lua Vertex class. */ + char* kind; + + /** The pos field of the Lua Vertex class. Unlike the other fields + of this struct, you can write pos.x and pos.y. When the graph + drawing function returns, the values stored in theses fields + will be written back to the Lua layer. + */ + pgfgd_Coordinate pos; + + /** The options fields of the Lua Vertex class. Note that you do + not have direct access to theses options. Rather, all access to + them must go through functions like pgfgd_isset that take a + pgfgd_OptionsTable* as input. Also note that you cannot store a + pointer to an options table: At the end of the graph drawing + function, all option table pointers will loose their + meaning. If you really wish to store an options table, you need + to retrieve all information stored in it while the point is + still active and then store the retrieved information in your + own table. + */ + pgfgd_OptionTable* options; + + /** Similar to the incoming field of the Lua Vertex class, but it + stores abstractions of the syntactic Edges objects of the + syntactic digraph, rather than the table of Arc objects that are + really stored in a Vertex. Also note that in a Lua Vertex + object, the incoming and outgoing arcs depend on the graph, + while a pgfgd_Vertex always only stores the incoming and + outgoing edges of the syntactic digraph. The order of the edges + in the incoming array will be the same as on the Lua layer, but + numbering starts with 0 (since these are C arrays). + */ + pgfgd_Edge_array incoming; + + /** Like the incoming fields. */ + pgfgd_Edge_array outgoing; + + /** The index of this vertex in the array entry of the syntactic + digraph. */ + int array_index; + +} pgfgd_Vertex; + + + +/** Used to pass around arrays of Vertex objects (more precisely, of + arrays of pointers to pgfgd_Vertex objects). Note that numbering + starts with 0. +*/ + +typedef struct pgfgd_Vertex_array { + int length; + pgfgd_Vertex** array; +} pgfgd_Vertex_array; + + + +/** This function allows you to query an anchor of a vertex (like a + call to |Vertex:anchor|). The function returns + |1| if there is such an anchor, otherwise |0| is returned and + both |x| and |y| will be set to 0. */ +extern int pgfgd_vertex_anchor(pgfgd_Vertex* v, const char* anchor, double* x, double* y); + + + +/** An abstraction of pgf.gd.model.Edge. */ + +struct pgfgd_Edge { + + /** The tail field of the Lua Edge class. */ + pgfgd_Vertex* tail; + + /** The head field of the Lua Edge class. */ + pgfgd_Vertex* head; + + /** The direction field of the Lua Edge class. */ + char* direction; + + /** The path field of the Lua Edge class. You can read this field + directly, but you can write it only through the function whose + names start with pgfgd_path. + + For each pgfgd_Edge object, at the end of the graph drawing + routinge, the value stored in this field will be written back to + the path field of the original syntactic edge. + */ + pgfgd_Path* path; + + /** A pointer to the options table of the Edge. This works like the + options table of pgdgd_Vertex and the same restrictions apply. + */ + pgfgd_OptionTable* options; + + /** The index of this edge in the array entry of the syntactic + digraph. */ + int array_index; + +}; + + +typedef struct pgfgd_SyntacticDigraph_internals pgfgd_SyntacticDigraph_internals; + + +/** The class pgf.gd.model.Digraph is modeled using two different C + structs: First, we have pgfgd_SyntacticDigraph and, second, we + have pgfgd_Digraph. The first is used, only, to model the (single) + syntactic digraph that is passed to the graph drawing function, + while the second is used to model different, more light weight + digraphs that are computed be the graph drawing system prior to + the call of the graph drawing routine. For instance, the spanning + tree computed by the graph drawing system for algorithms whose + preconditions included "tree" will be modeled as a pgfgd_Digraph. + + There is only one pgfgd_SyntacticDigraph during a call of + the graph drawing routine and you can access its properties + directly by accessing the fields of the struct. You cannot, + however, modify the syntactic digraph, except for setting the pos + fields of the vertices and for setting the path field arrays of + the syntactic edges (through the pgfgd_path_xxx functions). When + the graph drawing function is done, the modifications will be + written back to the Lua layer. + + Note that the syntactic digraph only stores the syntactic edges, + not the Arc objects. In particular, when you write + |graph { a <- b }| on the TikZ layer, you will get one syntactic + edge from a to b (not the other way round) with its direction + field set to "<-" in the syntactic digraph object. + */ + +typedef struct pgfgd_SyntacticDigraph { + + /** The vertices field of a Lua (syntactic) digraph. You may not + modify this array, except for changing the pos fields of the + vertices. */ + pgfgd_Vertex_array vertices; + + /** All syntactic edges of the graph. You cannot modify this array, + but you can use the pgfgd_path_xxx funtion to change the routing + of the edges stored here. Note that, since you get access to + syntactic edges, the direction of these edges may not be what + you expect and there may be several syntactic edges between the + same vertices. + */ + pgfgd_Edge_array syntactic_edges; + + /** The syntactic digraph's options field. Like all options fields, + it will go out of scope at the end of the graph drawing + routine. + */ + pgfgd_OptionTable* options; + + pgfgd_SyntacticDigraph_internals* internals; + +} pgfgd_SyntacticDigraph; + + + + +// Modifying edge bend paths + +/** You can apply this function to an Edge to clear the routing path + stored in it. +*/ +extern void pgfgd_path_clear (pgfgd_Edge* e); + +/** This function adds a moveto at the end of a path. */ +extern void pgfgd_path_append_moveto (pgfgd_Edge* e, double x, double y); + +/** This function adds a moveto to the |tail anchor| of the tail of + the edge. This call is useful for ``starting'' a path. This + function is a ``service function,'' you can achieve the same + effect by directly reading the option table of the tail vertex + and then using the pgfgd_vertex_anchor method. */ +extern void pgfgd_path_append_moveto_tail (pgfgd_Edge* e); + +/** This function adds a lineto at the end of a path. */ +extern void pgfgd_path_append_lineto (pgfgd_Edge* e, double x, double y); + +/** This function adds a linto to the |head anchor| of the head of + the edge. This call is useful for ``ending'' a path. */ +extern void pgfgd_path_append_lineto_head (pgfgd_Edge* e); + +/** This function adds a closepath at the end of a path. */ +extern void pgfgd_path_append_closepath (pgfgd_Edge* e); + +/** This function adds a curevto at the end of a path. */ +extern void pgfgd_path_append_curveto (pgfgd_Edge* e, double x1, double y1, double x2, double y2, double x, double y); + + + + +// Querying graphs other than the syntactic digraph + +/** A pgfgd_Digraph is a light-weight abstraction of a Lua Digraph + object. Unlike a pgfgd_SyntacticDigraph, you cannot access the + fields such an object directly, rather, all information is + retrieved through functions starting with pgfgd_digraph. + + When the graph drawing function is called, the graph drawing + system will already have computed a number of special digraphs in + addition to the syntactic digraph passed to the function. For + instance, there is always the "ugraph", which is the undirected + graph underlying the syntactic digraph. To access these special + graphs, you first call pgfgd_get_digraph and then use the + pgfgd_digraph_xxx function to retrieve information about them. + + Unlike the pgfgd_SyntacticDigraph object, which is managed by the + library, you must free pgfgd_Digraph objects yourself through the + pgfgd_digraph_free function. +*/ + +typedef struct pgfgd_Digraph pgfgd_Digraph; + +/** There is no abstraction of an Arc object on the C layer. Rather, + an arc is simply the index of the tail vertex plus the index of + the head vertex, where the indices are relative to the array of + vertices making up the digraph under consideration. + + You may wonder why we store indices rather than pointers to + pgfgd_Vertex objects. The reason is that a pgfgd_Digraph may + actually contain vertices that are not present in the syntactic + digraph (for instance, dummy vertices in a spanning tree) and for + which no pgfgd_Vertex obejct exists. For this reason, we only use + indices and there is a special function + (pgfgd_digraph_syntactic_vertex) that can be used to retrieve the + pgfgd_Vertex object, provided it exists. + + Note that the numbers stored in the tails and heads arrays, which + refer to positions inside a Lua vertices array, start numbering + with 1. The arrays themselves, however, start numbering with + 0. So, tails[0] == 1 and heads[0] == 2 would mean that there is an + Arc from the first to the second vertex. You can pass the numbers + stored in these arrays directly to the pgfgd_digraph_xxx + functions. + + You must free pgfgd_Arc_array objects yourself via + pgfgd_digraph_free_arc_array. + */ +typedef struct pgfgd_Arc_array { + + /** The length of both arrays. */ + int length; + + /** The array of the numbers of the tail vertices of the arcs. The + array itself starts numbering with 0, but its entries refer to + positions inside Lua array, so their numbering starts with 1. */ + int* tails; + + /** Like tails. */ + int* heads; + +} pgfgd_Arc_array; + + +/** In order to access special digraphs like the |ugraph| or the + |spanning_tree| computed by the graph drawing system, you first + need to call this function. In detail, the graph_name must be the + name of a field of the Lua algorithm object and this field must + store a |Digraph| object. Examples are "digraph" or "ugraph". The + function will then return a handle to this digraph which you can + subsequently access. The handle will become invalid at the end of + the graph drawing funciton and you must free it explicitly using + pgfgd_digraph_free. + */ +extern pgfgd_Digraph* pgfgd_get_digraph (pgfgd_SyntacticDigraph* g, const char* graph_name); + +/** Returns the number of vertices in the digraph. Note that this + number needs not be the same as the number of vertices in the + syntactic digraph and that the ordering need not be the + same as in the syntactic digraph. */ +extern int pgfgd_digraph_num_vertices (pgfgd_Digraph* g); + +/** Returns a newly allocated array of all arcs present in the + digraph. You must free this array explicitly using + pgfgd_digraph_free_arc_array. +*/ +extern pgfgd_Arc_array* pgfgd_digraph_arcs (pgfgd_Digraph* g); + +/** This function allows you to retrieve the syntatic vertex that + corresponds to a given index in the digraph. Normally, the first + vertex of a digraph like the ugraph will also be the first entry + of the vertices field of the syntactic digraph, but this need not + always be the case. For instance, for a spanning_tree digraph, + there will be more vertices in the graph than there are syntactic + vertices and the order may be quite different. For theses reaons, + you must use this function to convert a vertex index into the + digraph g into a pgfgd_Vertex object. It may happen that the index + does not refer to any syntactic vertex, in this case 0 is + returned. + + Note that v is an index into a Lua array and, thus, numbering + starts with 1. +*/ +extern pgfgd_Vertex* pgfgd_digraph_syntactic_vertex (pgfgd_Digraph* g, int v); + +/** Tests whether there is an arc between two vertices in the digraph + g. The tail and head are indices starting with 1. This operation + takes time $O(1)$. +*/ +extern int pgfgd_digraph_isarc (pgfgd_Digraph* g, int tail, int head); + +/** Returns an array of all syntactic edges present between two + vertices (whose indices are given as input). You must free the + returned array explicitly using + pgfgd_digraph_free_edge_array. Typically, this array will have at + most one entry, but it may happen that the user has specified + several syntatic edges between the same vertices, in which case + you get a larger array here. + + Note that tail and head are indices (starting with 1) into the + digraph's vertices array, which the return value is an array of + syntactic edges present in the syntactic digraph between the + vertices corresponding to these indices. In particular, if the + vertices do not correspond to syntactic vertices, the returned + array will always be empty. +*/ +extern pgfgd_Edge_array* pgfgd_digraph_syntactic_edges (pgfgd_Digraph* g, int tail, int head); + +/** Returns an array of all incoming arcs of the given vertex. (As + always, the vertex is coded as an index starting with 1 into the + vertices array of the digraph.) You must free this array + yourself using pgfgd_digraph_free_arc_array. In the returned + array, all entries of the head array will equal v. + */ +extern pgfgd_Arc_array* pgfgd_digraph_incoming (pgfgd_Digraph* g, int v); + +/** Like pgfgd_digraph_incoming. */ +extern pgfgd_Arc_array* pgfgd_digraph_outgoing (pgfgd_Digraph* g, int v); + +/** Frees a pgfgd_Digraph object previously allocated by the + pgfgd_get_digraph function. */ +extern void pgfgd_digraph_free (pgfgd_Digraph* d); + +/** Frees a pgfgd_Arc_array object; in particular, the arrays stored + inside it are freed. You should call this function once at some + point for all objects of this kind returned by any library function. +*/ +extern void pgfgd_digraph_free_arc_array (pgfgd_Arc_array* arcs); + +/** Like pgfgd_digraph_free_arc_array, but for the Edge arrays + returned by pgfgd_digraph_syntactic_edges. Do not call this + function for the syntactic_edges field of a syntactic digraph. +*/ +extern void pgfgd_digraph_free_edge_array (pgfgd_Edge_array* edges); + + + +// Declarations + +struct lua_State; +typedef void (*pgfgd_algorithm_fun) (pgfgd_SyntacticDigraph* component, void* user_data); +typedef struct pgfgd_Declaration pgfgd_Declaration; + + +/** Each declaration of a new option starts with a call to this + function. The function returns an object whose properties you can + set subsequently through the pgfgd_key_xxx function. Once all + properties of the key have been set, you call pgfgd_declare to + make Lua aware of the option. Then, you need to call + pgfgd_free_key on it. + */ + +extern pgfgd_Declaration* pgfgd_new_key (const char* key); + +/** Sets the summary field of the key. You should always call this + function. */ +extern void pgfgd_key_summary (pgfgd_Declaration* d, const char* s); + +/** Sets the type field of the key. */ +extern void pgfgd_key_type (pgfgd_Declaration* d, const char* s); + +/** Sets the initial field of the key to a string. */ +extern void pgfgd_key_initial (pgfgd_Declaration* d, const char* s); + +/** Sets the initial field of the key to void* value (a light userdata + in Lua-speak). */ +extern void pgfgd_key_initial_user (pgfgd_Declaration* d, void* v); + +/** Sets the default field of the key. */ +extern void pgfgd_key_default (pgfgd_Declaration* d, const char* s); + +/** Sets the alias field of the key. */ +extern void pgfgd_key_alias (pgfgd_Declaration* d, const char* s); + +/** Sets the alias_function_string field of the key. */ +extern void pgfgd_key_alias_function (pgfgd_Declaration* d, const char* s); + +/** Sets the documentation field of the key. */ +extern void pgfgd_key_documentation (pgfgd_Declaration* d, const char* s); + +/** Sets the documentation_in field of the key. */ +extern void pgfgd_key_documentation_in (pgfgd_Declaration* d, const char* s); + +/** Sets the phase field of the key. */ +extern void pgfgd_key_phase (pgfgd_Declaration* d, const char* s); + +/** Sets the algorithm field of the key. The function f must conform + to the function prototype pgfgd_algorithm_fun, which prescribes + that the function takes a syntactic digraph as input + (pgfgd_SyntacticDigraph*) and some user data and does not return + anything. The user data that is passed to the function is the + datum passed here. + + Whenever the key is now used on the Lua layer, the graph drawing + system will run the normal layout pipeline on the graph. Then, at + some point, it would call the actual Lua graph drawing + algorithm. At that point, the function f is called instead. The + parameter of this function will be a representation of the + to-be-drawn syntatic digraph as a C pgfgd_SyntacticDigraph. +*/ +extern void pgfgd_key_algorithm (pgfgd_Declaration* d, + pgfgd_algorithm_fun f, + void* user_data); + +/** Adds a use to the key. This means that whenever the key is used, + the given key--value pairs will also be set. This is used, in + particular, to create aliases for keys (but is not to be confused + with the |alias| field, whose semantics are slightly different). + */ +extern void pgfgd_key_add_use (pgfgd_Declaration* d, const char* key, const char* value); + +/** Adds a use to the key, but with the value being a user value in + Lua-speak. + */ +extern void pgfgd_key_add_use_user (pgfgd_Declaration* d, const char* key, void* value); + +/** Adds an example to the examples field of the key. */ +extern void pgfgd_key_add_example (pgfgd_Declaration* d, const char* s); + +/** Adds a precondition (the field s of the precondition table is set + to true) to the key. */ +extern void pgfgd_key_add_precondition (pgfgd_Declaration* d, const char* s); + +/** Adds a postcondition to the key. */ +extern void pgfgd_key_add_postcondition (pgfgd_Declaration* d, const char* s); + +/** After all properties of an option key have been set, call this + function once to actually declare the key inside the state that + your graph drawing library's main function gets + passed by the Lua dynamic linkage code. */ +extern void pgfgd_declare (struct lua_State* s, pgfgd_Declaration* d); + +/** Frees the memory used by the key object. */ +extern void pgfgd_free_key (pgfgd_Declaration* d); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/Makefile b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/Makefile new file mode 100644 index 00000000000..898e841aa40 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/interface/c/Makefile @@ -0,0 +1,17 @@ +CONFIGDIR=../../../../../config +include $(CONFIGDIR)/MakefileConfig.mk + +FLAGS=$(MYCFLAGS) $(ARCHFLAGS) -O2 -Wall -I$(LUAINCLUDES) -I$(PGFINCLUDES) + +all: InterfaceFromC.o InterfaceFromC++.o + +clean: + rm *.o + +install: + +InterfaceFromC.o: InterfaceFromC.c InterfaceFromC.h + $(CC) $(FLAGS) -c -o InterfaceFromC.o InterfaceFromC.c + +InterfaceFromC++.o: InterfaceFromC++.h InterfaceFromC.h InterfaceFromC++.c++ + $(CC) $(FLAGS) -c -o InterfaceFromC++.o InterfaceFromC++.c++ diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/InterfaceFromOGDF.c++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/InterfaceFromOGDF.c++ new file mode 100644 index 00000000000..248ee0b19e1 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/InterfaceFromOGDF.c++ @@ -0,0 +1,105 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <pgf/gd/interface/c/InterfaceFromC.h> + +#include <ogdf/basic/geometry.h> + + +using namespace ogdf; + +namespace scripting { + + + void ogdf_runner::bridge () + { + graph = Graph(); + graph_attributes = GraphAttributes (graph, + GraphAttributes::nodeGraphics | + GraphAttributes::edgeGraphics | + GraphAttributes::nodeLevel | + GraphAttributes::edgeIntWeight | + GraphAttributes::edgeDoubleWeight | + GraphAttributes::nodeWeight); + + pgfgd_SyntacticDigraph* g = parameters->syntactic_digraph; + + int n = g->vertices.length; + int m = g->syntactic_edges.length; + + node* nodes = new node [n]; + + for (int i=0; i < n; i++) { + nodes[i] = graph.newNode(); + + // Compute width and height + double x1, x2,y1,y2; + x1 = x2 = y1 = y2 = 0; + + int first = 1; + + pgfgd_Path* path = g->vertices.array[i]->path; + + for (int j = 1; j < path->length; j++) + if (!path->strings[j]) { + double x = path->coordinates[j].x; + double y = path->coordinates[j].y; + + if (first) { + x1 = x2 = x; + y1 = y2 = y; + first = 0; + } else { + x1 = x < x1 ? x : x1; + x2 = x > x2 ? x : x2; + y1 = y < y1 ? y : y1; + y2 = y > y2 ? y : y2; + } + } + + graph_attributes.width(nodes[i]) = x2-x1; + graph_attributes.height(nodes[i]) = y2-y1; + } + + for (int i=0; i < m; i++) { + int tail = g->syntactic_edges.array[i]->tail->array_index; + int head = g->syntactic_edges.array[i]->head->array_index; + + graph.newEdge(nodes[tail], nodes[head]); + } + } + + void ogdf_runner::unbridge () + { + pgfgd_SyntacticDigraph* g = parameters->syntactic_digraph; + + node v; + int i; + for (i = 0, v = graph.firstNode(); v; v=v->succ(), i++) { + g->vertices.array[i]->pos.x = graph_attributes.x(v); + g->vertices.array[i]->pos.y = graph_attributes.y(v); + } + + edge e; + for (i = 0, e = graph.firstEdge(); e; e=e->succ(), i++) { + pgfgd_Edge* ed = g->syntactic_edges.array[i]; + + DPolyline bend = graph_attributes.bends(e); + + if (bend.begin().valid()) { + bend.unify(); + bend.normalize(); + + // We start with a moveto: + pgfgd_path_clear (ed); + + pgfgd_path_append_moveto_tail(ed); + + for (List<DPoint>::iterator it = bend.begin(); it.valid(); it++) + pgfgd_path_append_lineto(ed, (*it).m_x, (*it).m_y); + + // We end with a lineto: + pgfgd_path_append_lineto_head(ed); + } + } + } + +} diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/InterfaceFromOGDF.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/InterfaceFromOGDF.h new file mode 100644 index 00000000000..bd742eb1610 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/InterfaceFromOGDF.h @@ -0,0 +1,45 @@ +#ifndef PGF_GD_INTERFACE_C_INTERFACEFROMOGDF_H +#define PGF_GD_INTERFACE_C_INTERFACEFROMOGDF_H + +/** \file pgf/gd/interface/c/InterfaceFromOGDF.h + + The C++-header file that should be used by algorithms written + for the OGFD library when the algorithm should be included in Lua. +*/ + +#include <pgf/gd/interface/c/InterfaceFromC++.h> +#include <ogdf/basic/Graph.h> +#include <ogdf/basic/GraphAttributes.h> + +namespace scripting { + + class ogdf_runner : public runner { + public: + + void bridge (); + void unbridge (); + + protected: + + ogdf::Graph graph; + ogdf::GraphAttributes graph_attributes; + + }; + + + class ogdf_function_runner : public ogdf_runner { + public: + typedef void (*function) (run_parameters&, + ogdf::Graph&, + ogdf::GraphAttributes&); + + ogdf_function_runner (function f) : fun(f) {} + virtual void run () { fun(*parameters, graph, graph_attributes); } + + private: + function fun; + }; +} + + +#endif diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/Makefile b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/Makefile new file mode 100644 index 00000000000..7ebf338f20f --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/Makefile @@ -0,0 +1,56 @@ +CONFIGDIR=../../../../../config +include $(CONFIGDIR)/MakefileConfig.mk + +FLAGS=$(MYCFLAGS) $(ARCHFLAGS) -O2 -Wall -I$(LUAINCLUDES) -I$(PGFINCLUDES) -I$(OGDFINCLUDES) + +all: ogdf_script.so SimpleDemoOGDF.so + +clean: + rm *.o *.so + +install: ogdf_script.so SimpleDemoOGDF.so + mkdir -p $(INSTALLDIR)/pgf/gd/ogdf/c + cp SimpleDemoOGDF.so $(INSTALLDIR)/pgf/gd/ogdf/c/pgf_gd_ogdf_c_SimpleDemoOGDF.so + cp ogdf_script.so $(INSTALLDIR)/pgf/gd/ogdf/c/pgf_gd_ogdf_c_ogdf_script.so + + +ogdf_script.so: ogdf_script.o InterfaceFromOGDF.o ../../interface/c/InterfaceFromC++.o ../../interface/c/InterfaceFromC.o + $(CC) $(FLAGS) $(SHAREDFLAGS) $(MYLDFLAGS) \ + -L$(OGDFLIBPATH) -lOGDF \ + $(LINKSHAREDLUA) \ + -o ogdf_script.so \ + ogdf_script.o \ + InterfaceFromOGDF.o \ + ../../interface/c/InterfaceFromC.o \ + ../../interface/c/InterfaceFromC++.o + +ogdf_script.o: ogdf_script.c++ \ + InterfaceFromOGDF.h \ + ../../interface/c/InterfaceFromC++.h \ + ../../interface/c/InterfaceFromC.h Makefile + $(CC) $(FLAGS) -c -o ogdf_script.o ogdf_script.c++ + + +SimpleDemoOGDF.so: SimpleDemoOGDF.o \ + InterfaceFromOGDF.o \ + ../../interface/c/InterfaceFromC++.o \ + ../../interface/c/InterfaceFromC.o Makefile + $(CC) $(FLAGS) $(SHAREDFLAGS) $(MYLDFLAGS) \ + $(LINKSHAREDLUA) \ + -L$(OGDFLIBPATH) -lOGDF \ + -o SimpleDemoOGDF.so \ + SimpleDemoOGDF.o ../../interface/c/InterfaceFromC++.o ../../interface/c/InterfaceFromC.o \ + InterfaceFromOGDF.o + +SimpleDemoOGDF.o: SimpleDemoOGDF.c++ \ + InterfaceFromOGDF.h \ + ../../interface/c/InterfaceFromC++.h \ + ../../interface/c/InterfaceFromC.h + $(CC) $(FLAGS) -I$(OGDFINCLUDES) -c -o SimpleDemoOGDF.o SimpleDemoOGDF.c++ + + + +InterfaceFromOGDF.o: ../../interface/c/InterfaceFromC++.h ../../interface/c/InterfaceFromC.h \ + InterfaceFromOGDF.c++ InterfaceFromOGDF.h + $(CC) $(FLAGS) -c -o InterfaceFromOGDF.o InterfaceFromOGDF.c++ + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/SimpleDemoOGDF.c++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/SimpleDemoOGDF.c++ new file mode 100644 index 00000000000..b7d914c5207 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/SimpleDemoOGDF.c++ @@ -0,0 +1,43 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> + +#include <math.h> + +using namespace ogdf; +using namespace scripting; + +struct FastLayoutOGDF : declarations, ogdf_runner { + + void run () { + double angle = 6.28318530718 / graph.numberOfNodes(); + double radius = parameters->option<double>("my radius ogdf"); + + int i = 0; + for (node v = graph.firstNode(); v; v=v->succ(), i++) { + graph_attributes.x(v) = cos(angle*i) * radius; + graph_attributes.y(v) = sin(angle*i) * radius; + } + } + + void declare(script s) { + using namespace scripting; + + s.declare(key ("fast simple demo layout ogdf") + .summary ("The OGDF version of the hello world of graph drawing") + .precondition ("connected") + .algorithm (this)); + + s.declare(key ("my radius ogdf") + .summary ("A radius value for the hello world of graph drawing") + .type ("length") + .initial ("1cm")); + } + +}; + +extern "C" int luaopen_pgf_gd_ogdf_c_SimpleDemoOGDF (struct lua_State *state) { + + script (state).declare (new FastLayoutOGDF); + + return 0; +} + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/FMMMLayout_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/FMMMLayout_script.h new file mode 100644 index 00000000000..bdaf26bf672 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/FMMMLayout_script.h @@ -0,0 +1,44 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/FMMMLayout.h> + +struct FMMMLayout_script : + scripting::declarations, + scripting::ogdf_runner +{ + void run () { + using namespace ogdf; + FMMMLayout layout; + + layout.newInitialPlacement(false); + layout.qualityVersusSpeed(FMMMLayout::qvsGorgeousAndEfficient); + + parameters->configure_option ("FMMMLayout.unitEdgeLength", + &FMMMLayout::unitEdgeLength, layout); + parameters->configure_option ("FMMMLayout.randSeed", + &FMMMLayout::randSeed, layout); + + layout.call (graph_attributes); + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + s.declare (key ("FMMMLayout") + .precondition ("connected") + .algorithm (this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.FMMMLayout")); + + s.declare (key ("FMMMLayout.randSeed") + .type ("number") + .initial ("42") + .alias ("random seed") + .documentation_in ("pgf.gd.doc.ogdf.energybased.FMMMLayout")); + + s.declare (key ("FMMMLayout.unitEdgeLength") + .type ("length") + .initial ("1cm") + .alias_function ("function (o) return o['node pre sep'] + o['node post sep'] end") + .documentation_in ("pgf.gd.doc.ogdf.energybased.FMMMLayout")); + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/FastMultipoleEmbedder_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/FastMultipoleEmbedder_script.h new file mode 100644 index 00000000000..38d9b032c9e --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/FastMultipoleEmbedder_script.h @@ -0,0 +1,51 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/FastMultipoleEmbedder.h> + +struct FastMultipoleEmbedder_script : + scripting::declarations, + scripting::factory<ogdf::FastMultipoleEmbedder> +{ + ogdf::FastMultipoleEmbedder* make (scripting::run_parameters* parameters) { + using namespace ogdf; + FastMultipoleEmbedder* r = new FastMultipoleEmbedder; + + parameters->configure_option ("FastMultipoleEmbedder.numIterations", + &FastMultipoleEmbedder::setNumIterations, *r); + parameters->configure_option ("FastMultipoleEmbedder.multipolePrec", + &FastMultipoleEmbedder::setMultipolePrec, *r); + parameters->configure_option ("FastMultipoleEmbedder.defaultEdgeLength", + &FastMultipoleEmbedder::setDefaultEdgeLength, *r); + parameters->configure_option ("FastMultipoleEmbedder.defaultNodeSize", + &FastMultipoleEmbedder::setDefaultNodeSize, *r); + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("FastMultipoleEmbedder") + .set_module ("LayoutModule", this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.FastMultipoleEmbedder")); + + s.declare (key ("FastMultipoleEmbedder.numIterations") + .type ("number") + .documentation_in ("pgf.gd.doc.ogdf.energybased.FastMultipoleEmbedder")); + + s.declare (key ("FastMultipoleEmbedder.multipolePrec") + .type ("number") + .documentation_in ("pgf.gd.doc.ogdf.energybased.FastMultipoleEmbedder")); + + s.declare (key ("FastMultipoleEmbedder.defaultEdgeLength") + .type ("length") + .alias_function ("function (o) return o['node pre sep'] + o['node post sep'] end") + .documentation_in ("pgf.gd.doc.ogdf.energybased.FastMultipoleEmbedder")); + + s.declare (key ("FastMultipoleEmbedder.defaultNodeSize") + .type ("number") + .documentation_in ("pgf.gd.doc.ogdf.energybased.FastMultipoleEmbedder")); + + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/GEMLayout_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/GEMLayout_script.h new file mode 100644 index 00000000000..7b4fda7e68a --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/GEMLayout_script.h @@ -0,0 +1,101 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/GEMLayout.h> + +struct GEMLayout_script : + scripting::declarations, + scripting::factory<ogdf::GEMLayout> +{ + ogdf::GEMLayout* make (scripting::run_parameters* parameters) { + using namespace ogdf; + GEMLayout* r = new GEMLayout; + + parameters->configure_option ("GEMLayout.numberOfRounds", + &GEMLayout::numberOfRounds, *r); + parameters->configure_option ("GEMLayout.minimalTemperature", + &GEMLayout::minimalTemperature, *r); + parameters->configure_option ("GEMLayout.initialTemperature", + &GEMLayout::initialTemperature, *r); + parameters->configure_option ("GEMLayout.gravitationalConstant", + &GEMLayout::gravitationalConstant, *r); + parameters->configure_option ("GEMLayout.desiredLength", + &GEMLayout::desiredLength, *r); + parameters->configure_option ("GEMLayout.maximalDisturbance", + &GEMLayout::maximalDisturbance, *r); + parameters->configure_option ("GEMLayout.rotationAngle", + &GEMLayout::rotationAngle, *r); + parameters->configure_option ("GEMLayout.oscillationAngle", + &GEMLayout::oscillationAngle, *r); + parameters->configure_option ("GEMLayout.rotationSensitivity", + &GEMLayout::rotationSensitivity, *r); + parameters->configure_option ("GEMLayout.oscillationSensitivity", + &GEMLayout::oscillationSensitivity, *r); + parameters->configure_option ("GEMLayout.attractionFormula", + &GEMLayout::attractionFormula, *r); + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("GEMLayout") + .set_module ("LayoutModule", this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.GEMLayout")); + + s.declare (key ("GEMLayout.numberOfRounds") + .type ("number") + .initial ("20000") + .documentation_in ("pgf.gd.doc.ogdf.energybased.GEMLayout")); + + s.declare (key ("GEMLayout.minimalTemperature") + .type ("number") + .initial ("0.005") + .documentation_in ("pgf.gd.doc.ogdf.energybased.GEMLayout")); + + s.declare (key ("GEMLayout.initialTemperature") + .type ("number") + .initial ("10") + .documentation_in ("pgf.gd.doc.ogdf.energybased.GEMLayout")); + + s.declare (key ("GEMLayout.gravitationalConstant") + .type ("number") + .initial ("0.0625") + .documentation_in ("pgf.gd.doc.ogdf.energybased.GEMLayout")); + + s.declare (key ("GEMLayout.desiredLength") + .type ("length") + .alias_function ("function (o) return o['node pre sep'] + o['node post sep'] end") + .documentation_in ("pgf.gd.doc.ogdf.energybased.GEMLayout")); + + s.declare (key ("GEMLayout.maximalDisturbance") + .type ("number") + .initial ("0") + .documentation_in ("pgf.gd.doc.ogdf.energybased.GEMLayout")); + + s.declare (key ("GEMLayout.rotationAngle") + .type ("number") + .documentation_in ("pgf.gd.doc.ogdf.energybased.GEMLayout")); + + s.declare (key ("GEMLayout.oscillationAngle") + .type ("number") + .documentation_in ("pgf.gd.doc.ogdf.energybased.GEMLayout")); + + s.declare (key ("GEMLayout.rotationSensitivity") + .type ("number") + .initial ("0.01") + .documentation_in ("pgf.gd.doc.ogdf.energybased.GEMLayout")); + + s.declare (key ("GEMLayout.oscillationSensitivity") + .type ("number") + .initial ("0.3") + .documentation_in ("pgf.gd.doc.ogdf.energybased.GEMLayout")); + + s.declare (key ("GEMLayout.attractionFormula") + .type ("number") + .initial ("1") + .documentation_in ("pgf.gd.doc.ogdf.energybased.GEMLayout")); + + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/MultilevelLayout_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/MultilevelLayout_script.h new file mode 100644 index 00000000000..091ab9766ce --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/MultilevelLayout_script.h @@ -0,0 +1,33 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/MultilevelLayout.h> + +struct MultilevelLayout_script : + scripting::declarations, + scripting::ogdf_runner +{ + void run () { + using namespace ogdf; + MultilevelLayout layout; + + parameters->configure_module ("LayoutModule", + &MultilevelLayout::setLayout, layout); + parameters->configure_module ("MultilevelBuilder", + &MultilevelLayout::setMultilevelBuilder, layout); + parameters->configure_module ("InitialPlacer", + &MultilevelLayout::setPlacer, layout); + + layout.call (graph_attributes); + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("MultilevelLayout") + .precondition ("connected") + .algorithm (this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.MultilevelLayout")); + + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/SpringEmbedderFRExact_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/SpringEmbedderFRExact_script.h new file mode 100644 index 00000000000..4e9fbfb3f17 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/SpringEmbedderFRExact_script.h @@ -0,0 +1,66 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/SpringEmbedderFRExact.h> + +struct SpringEmbedderFRExact_script : + scripting::declarations, + scripting::ogdf_runner +{ + void run () { + using namespace ogdf; + SpringEmbedderFRExact layout; + + parameters->configure_option ("SpringEmbedderFRExact.iterations", + &SpringEmbedderFRExact::iterations, layout); + parameters->configure_option ("SpringEmbedderFRExact.noise", + &SpringEmbedderFRExact::noise, layout); + parameters->configure_option ("SpringEmbedderFRExact.idealEdgeLength", + &SpringEmbedderFRExact::idealEdgeLength, layout); + parameters->configure_option ("SpringEmbedderFRExact.convTolerance", + &SpringEmbedderFRExact::convTolerance, layout); + + char* s = 0; + + if (parameters->option("SpringEmbedderFRExact.coolingFunction", s)) { + if (strcmp(s, "factor") == 0) + layout.coolingFunction(SpringEmbedderFRExact::cfFactor); + else if (strcmp(s, "logarithmic") == 0) + layout.coolingFunction(SpringEmbedderFRExact::cfLogarithmic); + + free(s); + } + + layout.call (graph_attributes); + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("SpringEmbedderFRExact") + .precondition ("connected") + .algorithm (this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.SpringEmbedderFRExact")); + + s.declare (key ("SpringEmbedderFRExact.iterations") + .type ("number") + .documentation_in ("pgf.gd.doc.ogdf.energybased.SpringEmbedderFRExact")); + + s.declare (key ("SpringEmbedderFRExact.noise") + .type ("boolean") + .documentation_in ("pgf.gd.doc.ogdf.energybased.SpringEmbedderFRExact")); + + s.declare (key ("SpringEmbedderFRExact.coolingFunction") + .type ("string") + .documentation_in ("pgf.gd.doc.ogdf.energybased.SpringEmbedderFRExact")); + + s.declare (key ("SpringEmbedderFRExact.idealEdgeLength") + .type ("number") + .documentation_in ("pgf.gd.doc.ogdf.energybased.SpringEmbedderFRExact")); + + s.declare (key ("SpringEmbedderFRExact.convTolerance") + .type ("number") + .documentation_in ("pgf.gd.doc.ogdf.energybased.SpringEmbedderFRExact")); + + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/SpringEmbedderFR_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/SpringEmbedderFR_script.h new file mode 100644 index 00000000000..5ae182e5898 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/SpringEmbedderFR_script.h @@ -0,0 +1,45 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/SpringEmbedderFR.h> + +struct SpringEmbedderFR_script : + scripting::declarations, + scripting::ogdf_runner +{ + void run () { + using namespace ogdf; + SpringEmbedderFR layout; + + parameters->configure_option ("SpringEmbedderFR.iterations", + &SpringEmbedderFR::iterations, layout); + parameters->configure_option ("SpringEmbedderFR.noise", + &SpringEmbedderFR::noise, layout); + parameters->configure_option ("SpringEmbedderFR.scaleFunctionFactor", + &SpringEmbedderFR::scaleFunctionFactor, layout); + + layout.call (graph_attributes); + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("SpringEmbedderFR") + .precondition ("connected") + .algorithm (this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.SpringEmbedderFR")); + + s.declare (key ("SpringEmbedderFR.iterations") + .type ("number") + .documentation_in ("pgf.gd.doc.ogdf.energybased.SpringEmbedderFR")); + + s.declare (key ("SpringEmbedderFR.noise") + .type ("boolean") + .documentation_in ("pgf.gd.doc.ogdf.energybased.SpringEmbedderFR")); + + s.declare (key ("SpringEmbedderFR.scaleFunctionFactor") + .type ("number") + .documentation_in ("pgf.gd.doc.ogdf.energybased.SpringEmbedderFR")); + + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/SpringEmbedderKK_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/SpringEmbedderKK_script.h new file mode 100644 index 00000000000..2b1586a5461 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/SpringEmbedderKK_script.h @@ -0,0 +1,39 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/SpringEmbedderKK.h> + +struct SpringEmbedderKK_script : + scripting::declarations, + scripting::ogdf_runner +{ + void run () { + using namespace ogdf; + SpringEmbedderKK layout; + + parameters->configure_option ("SpringEmbedderKK.stopTolerance", + &SpringEmbedderKK::setStopTolerance, layout); + parameters->configure_option ("SpringEmbedderKK.desLength", + &SpringEmbedderKK::setDesLength, layout); + + layout.call (graph_attributes); + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("SpringEmbedderKK") + .precondition ("connected") + .algorithm (this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.SpringEmbedderKK")); + + s.declare (key ("SpringEmbedderKK.stopTolerance") + .type ("number") + .documentation_in ("pgf.gd.doc.ogdf.energybased.SpringEmbedderKK")); + + s.declare (key ("SpringEmbedderKK.desLength") + .type ("length") + .documentation_in ("pgf.gd.doc.ogdf.energybased.SpringEmbedderKK")); + + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/energybased_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/energybased_script.h new file mode 100644 index 00000000000..fdcd92565e7 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/energybased_script.h @@ -0,0 +1,31 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> + +#include "FMMMLayout_script.h" +#include "GEMLayout_script.h" +#include "FastMultipoleEmbedder_script.h" + +#include "SpringEmbedderFR_script.h" +#include "SpringEmbedderFRExact_script.h" +#include "SpringEmbedderKK_script.h" + +#include "MultilevelLayout_script.h" + +#include "multilevelmixer/multilevelmixer_script.h" + +struct energybased_script : + scripting::declarations +{ + void declare (scripting::script s) { + s.declare (new FMMMLayout_script); + s.declare (new GEMLayout_script); + s.declare (new FastMultipoleEmbedder_script); + + s.declare (new SpringEmbedderFR_script); + s.declare (new SpringEmbedderFRExact_script); + s.declare (new SpringEmbedderKK_script); + + s.declare (new MultilevelLayout_script); + + s.declare (new multilevelmixer_script); + } +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/BarycenterPlacer_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/BarycenterPlacer_script.h new file mode 100644 index 00000000000..19ac75d3147 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/BarycenterPlacer_script.h @@ -0,0 +1,32 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/multilevelmixer/BarycenterPlacer.h> + +struct BarycenterPlacer_script : + scripting::declarations, + scripting::factory<ogdf::BarycenterPlacer> +{ + ogdf::BarycenterPlacer* make (scripting::run_parameters* parameters) { + using namespace ogdf; + BarycenterPlacer* r = new BarycenterPlacer; + + parameters->configure_option ("BarycenterPlacer.weightedPositionPriority", + &BarycenterPlacer::weightedPositionPriority, *r); + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("BarycenterPlacer") + .set_module ("InitialPlacer", this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.BarycenterPlacer")); + + s.declare (key ("BarycenterPlacer.weightedPositionPriority") + .type ("boolean") + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.BarycenterPlacer")); + + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/CirclePlacer_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/CirclePlacer_script.h new file mode 100644 index 00000000000..f208dbdecff --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/CirclePlacer_script.h @@ -0,0 +1,56 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/multilevelmixer/CirclePlacer.h> + +struct CirclePlacer_script : + scripting::declarations, + scripting::factory<ogdf::CirclePlacer> +{ + ogdf::CirclePlacer* make (scripting::run_parameters* parameters) { + using namespace ogdf; + CirclePlacer* r = new CirclePlacer; + + parameters->configure_option ("CirclePlacer.circleSize", + &CirclePlacer::setCircleSize, *r); + parameters->configure_option ("CirclePlacer.radiusFixed", + &CirclePlacer::setRadiusFixed, *r); + + + char* s = 0; + + if (parameters->option("CirclePlacer.nodeSelection", s)) { + if (strcmp(s, "new") == 0) + r->setNodeSelection(CirclePlacer::nsNew); + else if (strcmp(s, "old") == 0) + r->setNodeSelection(CirclePlacer::nsOld); + else if (strcmp(s, "all") == 0) + r->setNodeSelection(CirclePlacer::nsAll); + + free(s); + } + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("CirclePlacer") + .set_module ("InitialPlacer", this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.CirclePlacer")); + + s.declare (key ("CirclePlacer.circleSize") + .type ("number") + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.CirclePlacer")); + + s.declare (key ("CirclePlacer.radiusFixed") + .type ("boolean") + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.CirclePlacer")); + + s.declare (key ("CirclePlacer.nodeSelection") + .type ("string") + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.CirclePlacer")); + + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/EdgeCoverMerger_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/EdgeCoverMerger_script.h new file mode 100644 index 00000000000..cb91637d5da --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/EdgeCoverMerger_script.h @@ -0,0 +1,32 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/multilevelmixer/EdgeCoverMerger.h> + +struct EdgeCoverMerger_script : + scripting::declarations, + scripting::factory<ogdf::EdgeCoverMerger> +{ + ogdf::EdgeCoverMerger* make (scripting::run_parameters* parameters) { + using namespace ogdf; + EdgeCoverMerger* r = new EdgeCoverMerger; + + parameters->configure_option ("EdgeCoverMerger.factor", + &EdgeCoverMerger::setFactor, *r); + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("EdgeCoverMerger") + .set_module ("MultilevelBuilder", this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.EdgeCoverMerger")); + + s.declare (key ("EdgeCoverMerger.factor") + .type ("number") + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.EdgeCoverMerger")); + + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/IndependentSetMerger_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/IndependentSetMerger_script.h new file mode 100644 index 00000000000..2d950f8b9c8 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/IndependentSetMerger_script.h @@ -0,0 +1,32 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/multilevelmixer/IndependentSetMerger.h> + +struct IndependentSetMerger_script : + scripting::declarations, + scripting::factory<ogdf::IndependentSetMerger> +{ + ogdf::IndependentSetMerger* make (scripting::run_parameters* parameters) { + using namespace ogdf; + IndependentSetMerger* r = new IndependentSetMerger; + + parameters->configure_option ("IndependentSetMerger.searchDepthBase", + &IndependentSetMerger::setSearchDepthBase, *r); + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("IndependentSetMerger") + .set_module ("MultilevelBuilder", this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.IndependentSetMerger")); + + s.declare (key ("IndependentSetMerger.searchDepthBase") + .type ("number") + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.IndependentSetMerger")); + + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/LocalBiconnectedMerger_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/LocalBiconnectedMerger_script.h new file mode 100644 index 00000000000..898822e0c02 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/LocalBiconnectedMerger_script.h @@ -0,0 +1,32 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/multilevelmixer/LocalBiconnectedMerger.h> + +struct LocalBiconnectedMerger_script : + scripting::declarations, + scripting::factory<ogdf::LocalBiconnectedMerger> +{ + ogdf::LocalBiconnectedMerger* make (scripting::run_parameters* parameters) { + using namespace ogdf; + LocalBiconnectedMerger* r = new LocalBiconnectedMerger; + + parameters->configure_option ("LocalBiconnectedMerger.factor", + &LocalBiconnectedMerger::setFactor, *r); + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("LocalBiconnectedMerger") + .set_module ("MultilevelBuilder", this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.LocalBiconnectedMerger")); + + s.declare (key ("LocalBiconnectedMerger.factor") + .type ("number") + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.LocalBiconnectedMerger")); + + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/MatchingMerger_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/MatchingMerger_script.h new file mode 100644 index 00000000000..1d50c273cdb --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/MatchingMerger_script.h @@ -0,0 +1,32 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/multilevelmixer/MatchingMerger.h> + +struct MatchingMerger_script : + scripting::declarations, + scripting::factory<ogdf::MatchingMerger> +{ + ogdf::MatchingMerger* make (scripting::run_parameters* parameters) { + using namespace ogdf; + MatchingMerger* r = new MatchingMerger; + + parameters->configure_option ("MatchingMerger.selectByNodeMass", + &MatchingMerger::selectByNodeMass, *r); + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("MatchingMerger") + .set_module ("MultilevelBuilder", this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.MatchingMerger")); + + s.declare (key ("MatchingMerger.selectByNodeMass") + .type ("boolean") + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.MatchingMerger")); + + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/MedianPlacer_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/MedianPlacer_script.h new file mode 100644 index 00000000000..4670554393c --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/MedianPlacer_script.h @@ -0,0 +1,26 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/multilevelmixer/MedianPlacer.h> + +struct MedianPlacer_script : + scripting::declarations, + scripting::factory<ogdf::MedianPlacer> +{ + ogdf::MedianPlacer* make (scripting::run_parameters* parameters) { + using namespace ogdf; + MedianPlacer* r = new MedianPlacer; + + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("MedianPlacer") + .set_module ("InitialPlacer", this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.MedianPlacer")); + + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/RandomMerger_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/RandomMerger_script.h new file mode 100644 index 00000000000..8acc53bbeff --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/RandomMerger_script.h @@ -0,0 +1,32 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/multilevelmixer/RandomMerger.h> + +struct RandomMerger_script : + scripting::declarations, + scripting::factory<ogdf::RandomMerger> +{ + ogdf::RandomMerger* make (scripting::run_parameters* parameters) { + using namespace ogdf; + RandomMerger* r = new RandomMerger; + + parameters->configure_option ("RandomMerger.factor", + &RandomMerger::setFactor, *r); + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("RandomMerger") + .set_module ("MultilevelBuilder", this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.RandomMerger")); + + s.declare (key ("RandomMerger.factor") + .type ("number") + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.RandomMerger")); + + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/RandomPlacer_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/RandomPlacer_script.h new file mode 100644 index 00000000000..a92873ff478 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/RandomPlacer_script.h @@ -0,0 +1,32 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/multilevelmixer/RandomPlacer.h> + +struct RandomPlacer_script : + scripting::declarations, + scripting::factory<ogdf::RandomPlacer> +{ + ogdf::RandomPlacer* make (scripting::run_parameters* parameters) { + using namespace ogdf; + RandomPlacer* r = new RandomPlacer; + + parameters->configure_option ("RandomPlacer.circleSize", + &RandomPlacer::setCircleSize, *r); + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("RandomPlacer") + .set_module ("InitialPlacer", this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.RandomPlacer")); + + s.declare (key ("RandomPlacer.circleSize") + .type ("number") + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.RandomPlacer")); + + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/SolarMerger_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/SolarMerger_script.h new file mode 100644 index 00000000000..8453241bd63 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/SolarMerger_script.h @@ -0,0 +1,36 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/multilevelmixer/SolarMerger.h> + +struct SolarMerger_script : + scripting::declarations, + scripting::factory<ogdf::SolarMerger> +{ + ogdf::SolarMerger* make (scripting::run_parameters* parameters) { + using namespace ogdf; + SolarMerger* r = new SolarMerger (parameters->option<bool>("SolarMerger.simple"), + parameters->option<bool>("SolarMerger.massAsNodeRadius")); + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("SolarMerger") + .set_module ("MultilevelBuilder", this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.SolarMerger")); + + s.declare (key ("SolarMerger.simple") + .type ("boolean") + .initial ("false") + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.SolarMerger")); + + s.declare (key ("SolarMerger.massAsNodeRadius") + .type ("boolean") + .initial ("false") + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.SolarMerger")); + + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/SolarPlacer_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/SolarPlacer_script.h new file mode 100644 index 00000000000..5f9191251ce --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/SolarPlacer_script.h @@ -0,0 +1,26 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/multilevelmixer/SolarPlacer.h> + +struct SolarPlacer_script : + scripting::declarations, + scripting::factory<ogdf::SolarPlacer> +{ + ogdf::SolarPlacer* make (scripting::run_parameters* parameters) { + using namespace ogdf; + SolarPlacer* r = new SolarPlacer; + + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("SolarPlacer") + .set_module ("InitialPlacer", this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.SolarPlacer")); + + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/ZeroPlacer_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/ZeroPlacer_script.h new file mode 100644 index 00000000000..255ac34bd8c --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/ZeroPlacer_script.h @@ -0,0 +1,32 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/energybased/multilevelmixer/ZeroPlacer.h> + +struct ZeroPlacer_script : + scripting::declarations, + scripting::factory<ogdf::ZeroPlacer> +{ + ogdf::ZeroPlacer* make (scripting::run_parameters* parameters) { + using namespace ogdf; + ZeroPlacer* r = new ZeroPlacer; + + parameters->configure_option ("ZeroPlacer.randomRange", + &ZeroPlacer::setRandomRange, *r); + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("ZeroPlacer") + .set_module ("InitialPlacer", this) + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.ZeroPlacer")); + + s.declare (key ("ZeroPlacer.randomRange") + .type ("number") + .documentation_in ("pgf.gd.doc.ogdf.energybased.multilevelmixer.ZeroPlacer")); + + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/multilevelmixer_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/multilevelmixer_script.h new file mode 100644 index 00000000000..499406bc335 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/energybased/multilevelmixer/multilevelmixer_script.h @@ -0,0 +1,33 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> + +#include "BarycenterPlacer_script.h" +#include "IndependentSetMerger_script.h" +#include "MedianPlacer_script.h" +#include "SolarMerger_script.h" +#include "CirclePlacer_script.h" +#include "LocalBiconnectedMerger_script.h" +#include "RandomMerger_script.h" +#include "SolarPlacer_script.h" +#include "EdgeCoverMerger_script.h" +#include "MatchingMerger_script.h" +#include "RandomPlacer_script.h" +#include "ZeroPlacer_script.h" + +struct multilevelmixer_script : + scripting::declarations +{ + void declare (scripting::script s) { + s.declare (new BarycenterPlacer_script); + s.declare (new IndependentSetMerger_script); + s.declare (new MedianPlacer_script); + s.declare (new SolarMerger_script); + s.declare (new CirclePlacer_script); + s.declare (new LocalBiconnectedMerger_script); + s.declare (new RandomMerger_script); + s.declare (new SolarPlacer_script); + s.declare (new EdgeCoverMerger_script); + s.declare (new MatchingMerger_script); + s.declare (new RandomPlacer_script); + s.declare (new ZeroPlacer_script); + } +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/BarycenterHeuristic_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/BarycenterHeuristic_script.h new file mode 100644 index 00000000000..709e91d3de4 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/BarycenterHeuristic_script.h @@ -0,0 +1,20 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/layered/BarycenterHeuristic.h> + +struct BarycenterHeuristic_script : + scripting::declarations, + scripting::factory<ogdf::BarycenterHeuristic> +{ + + ogdf::BarycenterHeuristic* make (scripting::run_parameters* parameters) { + return new ogdf::BarycenterHeuristic; + } + + void declare (scripting::script s) { + using namespace scripting; + s.declare (key ("BarycenterHeuristic") + .documentation_in ("pgf.gd.doc.ogdf.layered.BarycenterHeuristic") + .set_module ("TwoLayerCrossMin", this)); + } +}; + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/CoffmanGrahamRanking_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/CoffmanGrahamRanking_script.h new file mode 100644 index 00000000000..d8cb01a771d --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/CoffmanGrahamRanking_script.h @@ -0,0 +1,34 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/layered/CoffmanGrahamRanking.h> + +struct CoffmanGrahamRanking_script : + scripting::declarations, + scripting::factory<ogdf::CoffmanGrahamRanking> +{ + + ogdf::CoffmanGrahamRanking* make (scripting::run_parameters* parameters) { + using namespace ogdf; + CoffmanGrahamRanking* r = new CoffmanGrahamRanking; + + parameters->configure_option ("CoffmanGrahamRanking.width", + &CoffmanGrahamRanking::width, *r); + parameters->configure_module ("AcyclicSubgraphModule", + &CoffmanGrahamRanking::setSubgraph, *r); + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + s.declare (key ("CoffmanGrahamRanking") + .documentation_in ("pgf.gd.doc.ogdf.layered.CoffmanGrahamRanking") + .set_module ("RankingModule", this)); + + s.declare (key ("CoffmanGrahamRanking.width") + .type ("number") + .initial ("3") + .documentation_in ("pgf.gd.doc.ogdf.layered.CoffmanGrahamRanking")); + } +}; + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/DfsAcyclicSubgraph_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/DfsAcyclicSubgraph_script.h new file mode 100644 index 00000000000..0d784ff3f5b --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/DfsAcyclicSubgraph_script.h @@ -0,0 +1,20 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/layered/DfsAcyclicSubgraph.h> + +struct DfsAcyclicSubgraph_script : + scripting::declarations, + scripting::factory<ogdf::DfsAcyclicSubgraph> +{ + + ogdf::DfsAcyclicSubgraph* make (scripting::run_parameters* parameters) { + return new ogdf::DfsAcyclicSubgraph; + } + + void declare (scripting::script s) { + using namespace scripting; + s.declare (key ("DfsAcyclicSubgraph") + .documentation_in ("pgf.gd.doc.ogdf.layered.DfsAcyclicSubgraph") + .set_module ("AcyclicSubgraphModule", this)); + } +}; + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/FastHierarchyLayout_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/FastHierarchyLayout_script.h new file mode 100644 index 00000000000..c8063e063af --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/FastHierarchyLayout_script.h @@ -0,0 +1,48 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/layered/FastHierarchyLayout.h> + +struct FastHierarchyLayout_script : + scripting::declarations, + scripting::factory<ogdf::FastHierarchyLayout> +{ + + ogdf::FastHierarchyLayout* make (scripting::run_parameters* parameters) { + using namespace ogdf; + FastHierarchyLayout* r = new FastHierarchyLayout; + + parameters->configure_option ("FastHierarchyLayout.fixedLayerDistance", + &FastHierarchyLayout::fixedLayerDistance, *r); + parameters->configure_option ("FastHierarchyLayout.layerDistance", + &FastHierarchyLayout::layerDistance, *r); + parameters->configure_option ("FastHierarchyLayout.nodeDistance", + &FastHierarchyLayout::nodeDistance, *r); + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("FastHierarchyLayout") + .documentation_in ("pgf.gd.doc.ogdf.layered.FastHierarchyLayout") + .set_module ("HierarchyLayoutModule", this)); + + s.declare (key ("FastHierarchyLayout.fixedLayerDistance") + .type ("boolean") + .initial ("false") + .documentation_in ("pgf.gd.doc.ogdf.layered.FastHierarchyLayout")); + + s.declare (key ("FastHierarchyLayout.layerDistance") + .type ("length") + .alias_function ("function (o) return o['level pre sep'] + o['level post sep'] end") + .documentation_in ("pgf.gd.doc.ogdf.layered.FastHierarchyLayout")); + + s.declare (key ("FastHierarchyLayout.nodeDistance") + .type ("length") + .alias_function ("function (o) return o['sibling pre sep'] + o['sibling post sep'] end") + .documentation_in ("pgf.gd.doc.ogdf.layered.FastHierarchyLayout")); + } +}; + + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/FastSimpleHierarchyLayout_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/FastSimpleHierarchyLayout_script.h new file mode 100644 index 00000000000..37c6c94bc05 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/FastSimpleHierarchyLayout_script.h @@ -0,0 +1,41 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/layered/FastSimpleHierarchyLayout.h> + +struct FastSimpleHierarchyLayout_script : + scripting::declarations, + scripting::factory<ogdf::FastSimpleHierarchyLayout> +{ + + ogdf::FastSimpleHierarchyLayout* make (scripting::run_parameters* parameters) { + using namespace ogdf; + + FastSimpleHierarchyLayout* r = new FastSimpleHierarchyLayout + ( + parameters->option<int> ("FastSimpleHierarchyLayout.siblingDistance"), + parameters->option<int> ("FastSimpleHierarchyLayout.layerDistance") + ); + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("FastSimpleHierarchyLayout") + .documentation_in ("pgf.gd.doc.ogdf.layered.FastSimpleHierarchyLayout") + .set_module ("HierarchyLayoutModule", this)); + + s.declare (key ("FastSimpleHierarchyLayout.layerDistance") + .type ("length") + .alias ("level distance") + .documentation_in ("pgf.gd.doc.ogdf.layered.FastSimpleHierarchyLayout")); + + s.declare (key ("FastSimpleHierarchyLayout.siblingDistance") + .type ("length") + .alias ("sibling distance") + .documentation_in ("pgf.gd.doc.ogdf.layered.FastSimpleHierarchyLayout")); + } +}; + + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/GreedyCycleRemoval_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/GreedyCycleRemoval_script.h new file mode 100644 index 00000000000..74616981414 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/GreedyCycleRemoval_script.h @@ -0,0 +1,20 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/layered/GreedyCycleRemoval.h> + +struct GreedyCycleRemoval_script : + scripting::declarations, + scripting::factory<ogdf::GreedyCycleRemoval> +{ + + ogdf::GreedyCycleRemoval* make (scripting::run_parameters* parameters) { + return new ogdf::GreedyCycleRemoval; + } + + void declare (scripting::script s) { + using namespace scripting; + s.declare (key ("GreedyCycleRemoval") + .documentation_in ("pgf.gd.doc.ogdf.layered.GreedyCycleRemoval") + .set_module ("AcyclicSubgraphModule", this)); + } +}; + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/GreedyInsertHeuristic_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/GreedyInsertHeuristic_script.h new file mode 100644 index 00000000000..4ab2675b5aa --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/GreedyInsertHeuristic_script.h @@ -0,0 +1,20 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/layered/GreedyInsertHeuristic.h> + +struct GreedyInsertHeuristic_script : + scripting::declarations, + scripting::factory<ogdf::GreedyInsertHeuristic> +{ + + ogdf::GreedyInsertHeuristic* make (scripting::run_parameters* parameters) { + return new ogdf::GreedyInsertHeuristic; + } + + void declare (scripting::script s) { + using namespace scripting; + s.declare (key ("GreedyInsertHeuristic") + .documentation_in ("pgf.gd.doc.ogdf.layered.GreedyInsertHeuristic") + .set_module ("TwoLayerCrossMin", this)); + } +}; + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/LongestPathRanking_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/LongestPathRanking_script.h new file mode 100644 index 00000000000..ca2e6344850 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/LongestPathRanking_script.h @@ -0,0 +1,50 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/layered/LongestPathRanking.h> + +struct LongestPathRanking_script : + scripting::declarations, + scripting::factory<ogdf::LongestPathRanking> +{ + + ogdf::LongestPathRanking* make (scripting::run_parameters* parameters) { + using namespace ogdf; + LongestPathRanking* r = new LongestPathRanking; + + parameters->configure_option ("LongestPathRanking.separateDeg0Layer", + &LongestPathRanking::separateDeg0Layer, *r); + parameters->configure_option ("LongestPathRanking.separateMultiEdges", + &LongestPathRanking::separateMultiEdges, *r); + parameters->configure_option ("LongestPathRanking.optimizeEdgeLength", + &LongestPathRanking::optimizeEdgeLength, *r); + + parameters->configure_module ("AcyclicSubgraphModule", + &LongestPathRanking::setSubgraph, *r); + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + s.declare (key ("LongestPathRanking") + .documentation_in ("pgf.gd.doc.ogdf.layered.LongestPathRanking") + .set_module ("RankingModule", this)); + + s.declare (key ("LongestPathRanking.separateDeg0Layer") + .type ("boolean") + .initial ("true") + .documentation_in ("pgf.gd.doc.ogdf.layered.LongestPathRanking")); + + s.declare (key ("LongestPathRanking.separateMultiEdges") + .type ("boolean") + .initial ("true") + .documentation_in ("pgf.gd.doc.ogdf.layered.LongestPathRanking")); + + s.declare (key ("LongestPathRanking.optimizeEdgeLength") + .type ("boolean") + .initial ("true") + .documentation_in ("pgf.gd.doc.ogdf.layered.LongestPathRanking")); + } +}; + + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/MedianHeuristic_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/MedianHeuristic_script.h new file mode 100644 index 00000000000..8ce4a610e7d --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/MedianHeuristic_script.h @@ -0,0 +1,20 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/layered/MedianHeuristic.h> + +struct MedianHeuristic_script : + scripting::declarations, + scripting::factory<ogdf::MedianHeuristic> +{ + + ogdf::MedianHeuristic* make (scripting::run_parameters* parameters) { + return new ogdf::MedianHeuristic; + } + + void declare (scripting::script s) { + using namespace scripting; + s.declare (key ("MedianHeuristic") + .documentation_in ("pgf.gd.doc.ogdf.layered.MedianHeuristic") + .set_module ("TwoLayerCrossMin", this)); + } +}; + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/OptimalRanking_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/OptimalRanking_script.h new file mode 100644 index 00000000000..f35fc67da79 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/OptimalRanking_script.h @@ -0,0 +1,34 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/layered/OptimalRanking.h> + +struct OptimalRanking_script : + scripting::declarations, + scripting::factory<ogdf::OptimalRanking> +{ + + ogdf::OptimalRanking* make (scripting::run_parameters* parameters) { + using namespace ogdf; + OptimalRanking* r = new OptimalRanking; + + parameters->configure_option ("OptimalRanking.separateMultiEdges", + &OptimalRanking::separateMultiEdges, *r); + parameters->configure_module ("AcyclicSubgraphModule", + &OptimalRanking::setSubgraph, *r); + + return r; + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + s.declare (key ("OptimalRanking") + .documentation_in ("pgf.gd.doc.ogdf.layered.OptimalRanking") + .set_module ("RankingModule", this)); + + s.declare (key ("OptimalRanking.separateMultiEdges") + .type ("boolean") + .initial ("true") + .documentation_in ("pgf.gd.doc.ogdf.layered.OptimalRanking")); + } +}; + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/SiftingHeuristic_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/SiftingHeuristic_script.h new file mode 100644 index 00000000000..653432f52b5 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/SiftingHeuristic_script.h @@ -0,0 +1,40 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/layered/SiftingHeuristic.h> + +struct SiftingHeuristic_script : + scripting::declarations, + scripting::factory<ogdf::SiftingHeuristic> +{ + + ogdf::SiftingHeuristic* make (scripting::run_parameters* parameters) { + using namespace ogdf; + + SiftingHeuristic* h = new SiftingHeuristic; + + char* strategy = 0; + + if (parameters->option("SiftingHeuristic.strategy", strategy)) { + if (strcmp(strategy, "left_to_right") == 0) + h->strategy(SiftingHeuristic::left_to_right); + else if (strcmp(strategy, "desc_degree") == 0) + h->strategy(SiftingHeuristic::desc_degree); + else if (strcmp(strategy, "random") == 0) + h->strategy(SiftingHeuristic::random); + + free(strategy); + } + return h; + } + + void declare (scripting::script s) { + using namespace scripting; + s.declare (key ("SiftingHeuristic") + .documentation_in ("pgf.gd.doc.ogdf.layered.SiftingHeuristic") + .set_module ("TwoLayerCrossMin", this)); + + s.declare (key ("SiftingHeuristic.strategy") + .type ("string") + .documentation_in ("pgf.gd.doc.ogdf.layered.SiftingHeuristic")); + } +}; + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/SplitHeuristic_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/SplitHeuristic_script.h new file mode 100644 index 00000000000..6799be36e92 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/SplitHeuristic_script.h @@ -0,0 +1,20 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/layered/SplitHeuristic.h> + +struct SplitHeuristic_script : + scripting::declarations, + scripting::factory<ogdf::SplitHeuristic> +{ + + ogdf::SplitHeuristic* make (scripting::run_parameters* parameters) { + return new ogdf::SplitHeuristic; + } + + void declare (scripting::script s) { + using namespace scripting; + s.declare (key ("SplitHeuristic") + .documentation_in ("pgf.gd.doc.ogdf.layered.SplitHeuristic") + .set_module ("TwoLayerCrossMin", this)); + } +}; + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/SugiyamaLayout_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/SugiyamaLayout_script.h new file mode 100644 index 00000000000..c9cf0973732 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/SugiyamaLayout_script.h @@ -0,0 +1,54 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/layered/SugiyamaLayout.h> + +struct SugiyamaLayout_script : + scripting::declarations, + scripting::ogdf_runner +{ + void run () { + using namespace ogdf; + SugiyamaLayout layout; + + parameters->configure_option ("SugiyamaLayout.runs", + &SugiyamaLayout::runs, layout); + parameters->configure_option ("SugiyamaLayout.transpose", + &SugiyamaLayout::transpose, layout); + parameters->configure_option ("SugiyamaLayout.fails", + &SugiyamaLayout::fails, layout); + + parameters->configure_module ("RankingModule", + &SugiyamaLayout::setRanking, layout); + parameters->configure_module ("TwoLayerCrossMin", + &SugiyamaLayout::setCrossMin, layout); + parameters->configure_module ("HierarchyLayoutModule", + &SugiyamaLayout::setLayout, layout); + + layout.call (graph_attributes); + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + s.declare (key ("SugiyamaLayout") + .precondition ("connected") + .postcondition ("upward_oriented_swapped") + .algorithm (this) + .documentation_in ("pgf.gd.doc.ogdf.layered.SugiyamaLayout")); + + s.declare (key ("SugiyamaLayout.runs") + .type ("number") + .initial ("15") + .documentation_in ("pgf.gd.doc.ogdf.layered.SugiyamaLayout")); + + s.declare (key ("SugiyamaLayout.transpose") + .type ("boolean") + .initial ("true") + .documentation_in ("pgf.gd.doc.ogdf.layered.SugiyamaLayout")); + + s.declare (key ("SugiyamaLayout.fails") + .type ("number") + .initial ("4") + .documentation_in ("pgf.gd.doc.ogdf.layered.SugiyamaLayout")); + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/layered_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/layered_script.h new file mode 100644 index 00000000000..8a117f1fc6f --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/layered/layered_script.h @@ -0,0 +1,46 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> + +#include "SugiyamaLayout_script.h" + +#include "LongestPathRanking_script.h" +#include "OptimalRanking_script.h" +#include "CoffmanGrahamRanking_script.h" + +#include "DfsAcyclicSubgraph_script.h" +#include "GreedyCycleRemoval_script.h" + +#include "BarycenterHeuristic_script.h" +#include "GreedyInsertHeuristic_script.h" +#include "SiftingHeuristic_script.h" +#include "MedianHeuristic_script.h" +#include "SplitHeuristic_script.h" + +#include "FastHierarchyLayout_script.h" +#include "FastSimpleHierarchyLayout_script.h" + +struct layered_script : + scripting::declarations +{ + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (new SugiyamaLayout_script); + + s.declare (new LongestPathRanking_script); + s.declare (new OptimalRanking_script); + s.declare (new CoffmanGrahamRanking_script); + + s.declare (new DfsAcyclicSubgraph_script); + s.declare (new GreedyCycleRemoval_script); + + s.declare (new BarycenterHeuristic_script); + s.declare (new GreedyInsertHeuristic_script); + s.declare (new SiftingHeuristic_script); + s.declare (new MedianHeuristic_script); + s.declare (new SplitHeuristic_script); + + s.declare (new FastHierarchyLayout_script); + s.declare (new FastSimpleHierarchyLayout_script); + } +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/misclayout/BalloonLayout_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/misclayout/BalloonLayout_script.h new file mode 100644 index 00000000000..311bee3e092 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/misclayout/BalloonLayout_script.h @@ -0,0 +1,32 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/misclayout/BalloonLayout.h> + +struct BalloonLayout_script : + scripting::declarations, + scripting::ogdf_runner +{ + void run () { + using namespace ogdf; + BalloonLayout layout; + + parameters->configure_option ("BalloonLayout.evenAngles", + &BalloonLayout::setEvenAngles, layout); + + layout.call (graph_attributes); + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("BalloonLayout") + .precondition ("connected") + .algorithm (this) + .documentation_in ("pgf.gd.doc.ogdf.misclayout.BalloonLayout")); + + s.declare (key ("BalloonLayout.evenAngles") + .type ("boolean") + .documentation_in ("pgf.gd.doc.ogdf.misclayout.BalloonLayout")); + } +}; + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/misclayout/CircularLayout_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/misclayout/CircularLayout_script.h new file mode 100644 index 00000000000..d0840e64f6b --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/misclayout/CircularLayout_script.h @@ -0,0 +1,47 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/misclayout/CircularLayout.h> + +struct CircularLayout_script : + scripting::declarations, + scripting::ogdf_runner +{ + void run () { + using namespace ogdf; + CircularLayout layout; + + parameters->configure_option ("CircularLayout.minDistCircle", + &CircularLayout::minDistCircle, layout); + parameters->configure_option ("CircularLayout.minDistLevel", + &CircularLayout::minDistLevel, layout); + parameters->configure_option ("CircularLayout.minDistSibling", + &CircularLayout::minDistSibling, layout); + + layout.call (graph_attributes); + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + + s.declare (key ("CircularLayout") + .precondition ("connected") + .algorithm (this) + .documentation_in ("pgf.gd.doc.ogdf.misclayout.CircularLayout")); + + s.declare (key ("CircularLayout.minDistCircle") + .type ("length") + .alias_function ("function (o) return o['part pre sep'] + o['part post sep'] end") + .documentation_in ("pgf.gd.doc.ogdf.layered.CircularLayout")); + + s.declare (key ("CircularLayout.minDistLevel") + .type ("length") + .alias_function ("function (o) return o['level pre sep'] + o['level post sep'] end") + .documentation_in ("pgf.gd.doc.ogdf.layered.CircularLayout")); + + s.declare (key ("CircularLayout.minDistSibling") + .type ("length") + .alias_function ("function (o) return o['sibling pre sep'] + o['sibling post sep'] end") + .documentation_in ("pgf.gd.doc.ogdf.layered.CircularLayout")); + } +}; + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/misclayout/misclayout_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/misclayout/misclayout_script.h new file mode 100644 index 00000000000..22ac039b7f3 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/misclayout/misclayout_script.h @@ -0,0 +1,13 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> + +#include "BalloonLayout_script.h" +#include "CircularLayout_script.h" + +struct misclayout_script : + scripting::declarations +{ + void declare (scripting::script s) { + s.declare (new BalloonLayout_script); + s.declare (new CircularLayout_script); + } +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/module/module_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/module/module_script.h new file mode 100644 index 00000000000..97579ecdd92 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/module/module_script.h @@ -0,0 +1,27 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> + +struct module_script : scripting::declarations { + void declare (scripting::script s) + { + using namespace scripting; + + s.declare (key ("RankingModule") + .module_type ()); + + s.declare (key ("AcyclicSubgraphModule") + .module_type ()); + + s.declare (key ("HierarchyLayoutModule") + .module_type ()); + + s.declare (key ("TwoLayerCrossMin") + .module_type ()); + + s.declare (key ("InitialPlacer") + .module_type ()); + + s.declare (key ("MultilevelBuilder") + .module_type ()); + } +}; + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/ogdf_script.c++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/ogdf_script.c++ new file mode 100644 index 00000000000..12a5f6bfeb0 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/ogdf_script.c++ @@ -0,0 +1,23 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> + +#include "module/module_script.h" + +#include "layered/layered_script.h" +#include "energybased/energybased_script.h" +#include "misclayout/misclayout_script.h" +#include "planarity/planarity_script.h" + + +extern "C" int luaopen_pgf_gd_ogdf_c_ogdf_script (struct lua_State *state) { + + scripting::script s (state); + + s.declare (new module_script); + s.declare (new layered_script); + s.declare (new energybased_script); + s.declare (new misclayout_script); + s.declare (new planarity_script); + + return 0; +} + diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/planarity/PlanarizationLayout_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/planarity/PlanarizationLayout_script.h new file mode 100644 index 00000000000..4fa89d5d190 --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/planarity/PlanarizationLayout_script.h @@ -0,0 +1,43 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> +#include <ogdf/planarity/PlanarizationLayout.h> + +struct PlanarizationLayout_script : + scripting::declarations, + scripting::ogdf_runner +{ + + void run () { + using namespace ogdf; + PlanarizationLayout layout; + + parameters->configure_option ("PlanarizationLayout.preprocessCliques", + &PlanarizationLayout::preprocessCliques, layout); + parameters->configure_option ("PlanarizationLayout.minCliqueSize", + &PlanarizationLayout::minCliqueSize, layout); + + // .. TODO: configure modules + + layout.call (graph_attributes); + } + + void declare (scripting::script s) { + using namespace scripting; + using namespace ogdf; + s.declare (key ("PlanarizationLayout") + .precondition ("connected") + .postcondition ("fixed") + .algorithm (this) + .documentation_in ("pgf.gd.doc.ogdf.planarity.PlanarizationLayout")); + + s.declare (key ("PlanarizationLayout.preprocessCliques") + .type ("boolean") + .initial ("false") + .documentation_in ("pgf.gd.doc.ogdf.planarity.PlanarizationLayout")); + + s.declare (key ("PlanarizationLayout.minCliqueSize") + .type ("number") + .initial ("10") + .documentation_in ("pgf.gd.doc.ogdf.planarity.PlanarizationLayout")); + } + +}; diff --git a/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/planarity/planarity_script.h b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/planarity/planarity_script.h new file mode 100644 index 00000000000..dd337fcc0ee --- /dev/null +++ b/Master/texmf-dist/source/generic/pgf/c/graphdrawing/pgf/gd/ogdf/c/planarity/planarity_script.h @@ -0,0 +1,11 @@ +#include <pgf/gd/ogdf/c/InterfaceFromOGDF.h> + +#include "PlanarizationLayout_script.h" + +struct planarity_script : + scripting::declarations +{ + void declare (scripting::script s) { + s.declare (new PlanarizationLayout_script); + } +}; diff --git a/Master/texmf-dist/source/latex/pgf/testsuite/external/Makefile b/Master/texmf-dist/source/generic/pgf/testsuite/external/Makefile index 0ba43c08570..0ba43c08570 100644 --- a/Master/texmf-dist/source/latex/pgf/testsuite/external/Makefile +++ b/Master/texmf-dist/source/generic/pgf/testsuite/external/Makefile diff --git a/Master/texmf-dist/source/latex/pgf/testsuite/external/tikzexternaltest.code.tex b/Master/texmf-dist/source/generic/pgf/testsuite/external/tikzexternaltest.code.tex index 8a200fcf991..8a200fcf991 100644 --- a/Master/texmf-dist/source/latex/pgf/testsuite/external/tikzexternaltest.code.tex +++ b/Master/texmf-dist/source/generic/pgf/testsuite/external/tikzexternaltest.code.tex diff --git a/Master/texmf-dist/source/latex/pgf/testsuite/external/tikzexternaltest.sharedpreamble.tex b/Master/texmf-dist/source/generic/pgf/testsuite/external/tikzexternaltest.sharedpreamble.tex index 87e94f899eb..87e94f899eb 100644 --- a/Master/texmf-dist/source/latex/pgf/testsuite/external/tikzexternaltest.sharedpreamble.tex +++ b/Master/texmf-dist/source/generic/pgf/testsuite/external/tikzexternaltest.sharedpreamble.tex diff --git a/Master/texmf-dist/source/latex/pgf/testsuite/external/tikzexternaltest.tex b/Master/texmf-dist/source/generic/pgf/testsuite/external/tikzexternaltest.tex index 2aaef55effe..2aaef55effe 100644 --- a/Master/texmf-dist/source/latex/pgf/testsuite/external/tikzexternaltest.tex +++ b/Master/texmf-dist/source/generic/pgf/testsuite/external/tikzexternaltest.tex diff --git a/Master/texmf-dist/source/latex/pgf/testsuite/external/tikzexternaltestmakefile.tex b/Master/texmf-dist/source/generic/pgf/testsuite/external/tikzexternaltestmakefile.tex index 232489823ec..232489823ec 100644 --- a/Master/texmf-dist/source/latex/pgf/testsuite/external/tikzexternaltestmakefile.tex +++ b/Master/texmf-dist/source/generic/pgf/testsuite/external/tikzexternaltestmakefile.tex diff --git a/Master/texmf-dist/source/latex/pgf/testsuite/mathtest/pgfmathtestsuite.tex b/Master/texmf-dist/source/generic/pgf/testsuite/mathtest/pgfmathtestsuite.tex index 7ae80434c2d..0497f0d095b 100644 --- a/Master/texmf-dist/source/latex/pgf/testsuite/mathtest/pgfmathtestsuite.tex +++ b/Master/texmf-dist/source/generic/pgf/testsuite/mathtest/pgfmathtestsuite.tex @@ -11,7 +11,7 @@ \def\pgfsysdriver{pgfsys-dvipdfm.def} \usepackage[dvipdfm]{hyperref} \fi -\usepackage{pgf} +\usepackage{tikz} \usepackage{fp} \makeatletter @@ -480,6 +480,88 @@ } \onecolumn +\testsection{Pretty printing using the relative style} +{ +\long\def\TESTIT#1#2{% + \gdef\temptable{\begin{tabular}}% + \gdef\header{l}% + \def\n{\noexpand\n}% + \foreach \number in {#2} {% + \xdef\header{\header c}% + }% + \toks0=\expandafter{\temptable}% + \xdef\temptable{\the\toks0 {\header}\n}% + % + \toks0=\expandafter{\temptable}% + \toks1={}% + \xdef\temptable{\the\toks0 \the\toks1}% + \foreach \number in {#2} {% + \toks0=\expandafter{\temptable}% + \toks1=\expandafter{\number}% + \xdef\temptable{\the\toks0 & \noexpand\texttt{\the\toks1}}% + }% + \toks0=\expandafter{\temptable}% + \xdef\temptable{\the\toks0 \noexpand\\\n}% + % + \toks0=\expandafter{\temptable}% + \toks1={With actual config:}% + \xdef\temptable{\the\toks0 \the\toks1}% + \foreach \number in {#2} {% + \toks0=\expandafter{\temptable}% + \toks1=\expandafter{\number}% + \xdef\temptable{\the\toks0 & \noexpand\pgfmathprintnumber{\the\toks1}}% + }% + \toks0=\expandafter{\temptable}% + \xdef\temptable{\the\toks0 \noexpand\\\n}% + % + \foreach \relativeto in {#1} {% + \toks0=\expandafter{\temptable}% + \xdef\temptable{\the\toks0 Relative to $10^{\relativeto}$:}% + \foreach \number in {#2} {% + \toks0=\expandafter{\temptable}% + \toks1=\expandafter{\number}% + \xdef\temptable{\the\toks0 & \noexpand\pgfmathprintnumber[relative={\relativeto}]{\the\toks1}}% + }% + \toks0=\expandafter{\temptable}% + \xdef\temptable{\the\toks0 \noexpand\\\n}% + }% + % + % + \toks0=\expandafter{\temptable}% + \toks1={\end{tabular}\n}% + \xdef\temptable{\the\toks0 \the\toks1}% + % + \def\n{^^J}% +%\message{TEMP-TABLE: \n\meaning\temptable\n}% + % + \let\n=\relax + \noindent + \temptable +}% +%\tracingmacros=2 \tracingcommands=2 + +\TESTIT{1,3}{1e-16,0,15,17,20} + +\TESTIT{0,1,3,4,5,6,7,8,9}{-100.123456,1e-16,1431,2000.1234,123456789.1234} + + + +\TESTIT{-4,-3,-2,-1,0,1,2,3}{0.0001,0.00012678,0.00013678,0.00016678,1.23,2.345,123.4,1234.5} + +{ +\subsection*{every relative/.style={sci}} +\pgfkeys{/pgf/number format/every relative/.style={sci}} +\TESTIT{-4,-3,-2,-1,0,1,2,3}{0.0001,0.00012678,0.00013678,0.00016678,1.23,2.345,123.4,1234.5} +} + +\TESTIT{-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9}{-123.123456,123.1234565} +{ +\subsection*{precision=4} +\pgfkeys{/pgf/number format/precision=4} +\TESTIT{-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9}{-123.123456,123.1234565} +} +} + \begingroup \testsection{testing pgfmathfloatadd} \def\testfloataddnonsymmetric#1#2{% @@ -732,6 +814,25 @@ \[ #1 / #2 = \showlowlevelfloatmacro\result = \pgfmathresult \] }% \tests + +% #1/#2 expected #3 +\def\pgfmathfloattest#1#2#3{% + \pgfmathfloatparsenumber{#1}% + \let\argumenta=\pgfmathresult + \pgfmathfloatparsenumber{#2}% + \let\argumentb=\pgfmathresult + \pgfmathfloatparsenumber{#3}% + \let\reference=\pgfmathresult + \message{computing (#1/#2)}% + \pgfmathfloatdivide\argumenta\argumentb% + \let\resultfloat=\pgfmathresult + \pgfmathfloattosci\pgfmathresult + \let\result=\pgfmathresult + \pgfmathfloatrelerror\resultfloat\reference + \pgfmathfloattosci\pgfmathresult + \[ #1/#2 = \result\quad (\text{error/r to }#3 = \pgfmathprintnumber\pgfmathresult)\] +}% +\pgfmathfloattest{83407811.0}{166815640.0}{0.499999946048224} \endgroup diff --git a/Master/texmf-dist/source/latex/pgf/incoming/GrzegorzMurzynowski/pgfdatabasearrows.pdf b/Master/texmf-dist/source/latex/pgf/incoming/GrzegorzMurzynowski/pgfdatabasearrows.pdf Binary files differdeleted file mode 100644 index d386670f931..00000000000 --- a/Master/texmf-dist/source/latex/pgf/incoming/GrzegorzMurzynowski/pgfdatabasearrows.pdf +++ /dev/null diff --git a/Master/texmf-dist/source/latex/pgf/incoming/GrzegorzMurzynowski/pgfdatabasearrows.sty b/Master/texmf-dist/source/latex/pgf/incoming/GrzegorzMurzynowski/pgfdatabasearrows.sty deleted file mode 100644 index 8b76c5f24eb..00000000000 --- a/Master/texmf-dist/source/latex/pgf/incoming/GrzegorzMurzynowski/pgfdatabasearrows.sty +++ /dev/null @@ -1,147 +0,0 @@ -% A~definition of some database entity diagram arrow tips for -% pgf (tikz) based on arrow declaration tips in the Till Tantau's pgf -% manual for v1.10 p.\ 254. -% -% author: Natror (Grzegorz Murzynowski), natror at o2.pl -% 2006/12/16 -% -% This file is a~draft version intended to be possibly adjusted by the -% tikz package developer(s) and included into the tikz bundle -% on the Gnu Public License. -% -% -% - -\NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{pgfdatabasearrows} - -\RequirePackage{tikz} -\RequirePackage{pgflibraryarrows} - - -\newdimen\arrowsize - -% nulla -\pgfarrowsdeclare{nulla}{nulla} -{ - \arrowsize=0.2pt - \advance\arrowsize by .5\pgflinewidth - \pgfarrowsleftextend{-.5\pgflinewidth} - \pgfarrowsrightextend{3\arrowsize+.5\pgflinewidth} -} -{ - \arrowsize=0.2pt - \advance\arrowsize by .5\pgflinewidth - \pgfsetdash{}{0pt} % do not dash - \pgfsetroundjoin - \pgfsetroundcap - \pgfpathmoveto{\pgfpointorigin} - \pgfpathlineto{\pgfpoint{3\arrowsize}{0\arrowsize}} - \pgfusepathqstroke -} - -% nulla = dbplain -\pgfarrowsdeclarealias{dbplain}{dbplain}{nulla}{nulla} - - -% nullalonga -\pgfarrowsdeclare{nullalonga}{nullalonga} -{ - \arrowsize=0.2pt - \advance\arrowsize by .5\pgflinewidth - \pgfarrowsleftextend{-.5\pgflinewidth} - \pgfarrowsrightextend{5.5\arrowsize+.5\pgflinewidth} -} -{ - \arrowsize=0.2pt - \advance\arrowsize by .5\pgflinewidth - \pgfsetdash{}{0pt} % do not dash - \pgfsetroundjoin - \pgfsetroundcap - \pgfpathmoveto{\pgfpointorigin} - \pgfpathlineto{\pgfpoint{5.5\arrowsize}{0\arrowsize}} - \pgfusepathqstroke -} - -% nullalonga = dbplainlong -\pgfarrowsdeclarealias{dbplainlong}{dbplainlong}{nullalonga}{nullalonga} - - -% dboshortt -\pgfarrowsdeclarecombine*[-.5\pgflinewidth]%offset -{dboshortt}{dboshortt}{o}{o}{nulla}{nulla} - -% dboshort -\pgfarrowsdeclarecombine*[-.5\pgflinewidth]%offset -{dboshort}{dboshort}{o}{o}{nullalonga}{nullalonga} - -% dbo -\pgfarrowsdeclarecombine*[-1\pgflinewidth]%offset -{dbo}{dbo}{dboshort}{dboshort}{nulla}{nulla} - -% dbolong -\pgfarrowsdeclarecombine*[-1\pgflinewidth]%offset -{dbolong}{dbolong}{dboshort}{dboshort}{nullalonga}{nullalonga} - -% dbbar for nice combining -\pgfarrowsdeclare{dbbar}{dbbar} -{ - \arrowsize=0.2pt - \advance\arrowsize by .5\pgflinewidth - \pgfarrowsleftextend{-.5\pgflinewidth} - \pgfarrowsrightextend{.5\pgflinewidth} -} -{ - \arrowsize=0.2pt - \advance\arrowsize by .5\pgflinewidth - \pgfsetdash{}{0pt} % do not dash - \pgfsetroundjoin - \pgfsetroundcap - \pgfpathmoveto{\pgfpoint{0\arrowsize}{6\arrowsize}} - \pgfpathlineto{\pgfpoint{0\arrowsize}{-6\arrowsize}} - \pgfusepathqstroke -} - -% db1 -\pgfarrowsdeclarecombine*[-.5\pgflinewidth]%offset -{db1}{db1}{dbbar}{dbbar}{nulla}{nulla} - -% dbo1, starred to avoid stroking the o -\pgfarrowsdeclarecombine*[-.5\pgflinewidth]%offset -{dbo1}{dbo1}{dboshortt}{dboshortt}{db1}{db1} - -% db1o, * not to stroke |- in tight curves -\pgfarrowsdeclarecombine*[-.5\pgflinewidth]%offset -{db1o}{db1o}{db1}{db1}{dboshortt}{dboshortt} - -% dbmany -\pgfarrowsdeclare{dbmany}{dbmany} -{ - \arrowsize=0.2pt - \advance\arrowsize by .5\pgflinewidth - \pgfarrowsleftextend{-.5\pgflinewidth} - \pgfarrowsrightextend{10.4\arrowsize+.5\pgflinewidth} -} -{ - \arrowsize=0.2pt - \advance\arrowsize by .5\pgflinewidth - \pgfsetdash{}{0pt} % do not dash - \pgfsetroundjoin - \pgfsetroundcap - \pgfpathmoveto{\pgfpointorigin} - \pgfpathlineto{\pgfpoint{10.4\arrowsize}{6\arrowsize}} - \pgfusepathqstroke - \pgfpathmoveto{\pgfpointorigin} - \pgfpathlineto{\pgfpoint{10.4\arrowsize}{0\arrowsize}} - \pgfusepathqstroke - \pgfpathmoveto{\pgfpointorigin} - \pgfpathlineto{\pgfpoint{10.4\arrowsize}{-6\arrowsize}} - \pgfusepathqstroke -} - -% dbomany -\pgfarrowsdeclarecombine*[-1.5\pgflinewidth]%offset -{dbomany}{dbomany}{dboshortt}{dboshortt}{dbmany}{dbmany} - - -\endinput
\ No newline at end of file diff --git a/Master/texmf-dist/source/latex/pgf/incoming/GrzegorzMurzynowski/pgfdatabasearrows.tex b/Master/texmf-dist/source/latex/pgf/incoming/GrzegorzMurzynowski/pgfdatabasearrows.tex deleted file mode 100644 index c7fe6b8f5dd..00000000000 --- a/Master/texmf-dist/source/latex/pgf/incoming/GrzegorzMurzynowski/pgfdatabasearrows.tex +++ /dev/null @@ -1,131 +0,0 @@ -\documentclass[11pt]{article} -\usepackage{pgfdatabasearrows} -\usepackage{array} -\usepackage[margin=2.5cm]{geometry} - -\begin{document} -\pagestyle{empty} -\raggedright -\parskip\smallskipamount - -\noindent\hfill Warszawa,\\ -\noindent\hfill March 16, 2006,\\ -\noindent\hfill December 16, 2006 (next try). - -\medskip - -Prof.\ Dr.\ \textbf{Till Tantau}\\ -\texttt{tantau at users.sourceforge.net} - -\bigskip\bigskip -Dear Sir, - -\medskip -Here are some arrow tips for drawing database entity -diagrams. - -\medskip -(The first attempt to send you them I~made on March 16, 2006 but the -mail was rejected due to overfull of your mailbox.) - -(At \emph{this} attempt the \textsf{sourceforge.net} server rejects -mails with .zip attachments :-)) - -(At the project's site I~didn't see any encouragement for contributions -other than becoming a~Developer which is not the case here, I~suppose. - -I~mean, if you'd be interested in these arrow tips and wanted me to -describe them a~bit more, I'd still remain just a~\textsf{tikz} user.) - - -\bigskip -\newcommand*\dbarrowtest[2]{% - #1 & \raisebox{.5ex}{\tikz[thick] \draw[#2-#2] (0,0.2) -- - (2,0.2);\ \ \tikz[thin] \draw[#2-#2] (0,0.2) -- - (2,0.2);}\\} - - -\begin{tabular}{>{\ttfamily}r@{:\ \ }l} - -\dbarrowtest{dbplain {\normalfont alias} nulla}{nulla} -\dbarrowtest{dbplainlong {\normalfont alias} nullalonga}{nullalonga} - -\dbarrowtest{dboshortt}{dboshortt} -\dbarrowtest{dboshort}{dboshort} -\dbarrowtest{dbo}{dbo} -\dbarrowtest{dbolong}{dbolong} - -\dbarrowtest{dbbar {\normalfont (for combining)}}{dbbar} -\dbarrowtest{db1}{db1} -\dbarrowtest{dbo1}{dbo1} -\dbarrowtest{db1o}{db1o} -\dbarrowtest{dbmany}{dbmany} -\dbarrowtest{dbomany}{dbomany} -\end{tabular} -% -\quad -% -\begin{minipage}{.3\textwidth} - -And with curves: - -\medskip -\newcommand*\dbarrowtestic[1]{\tikz\draw[rotate=-90,thin,#1-#1] (1,1) .. controls -(0.4,1) and (0.6,0) .. (0,0);\ } - -\dbarrowtestic{nulla} -\dbarrowtestic{nullalonga} -\dbarrowtestic{dboshortt} -\dbarrowtestic{dboshort} - -\dbarrowtestic{dbo} -\dbarrowtestic{dbolong} -\dbarrowtestic{dbbar} -\dbarrowtestic{db1} - -\dbarrowtestic{dbo1} -\dbarrowtestic{db1o} -\dbarrowtestic{dbmany} -\dbarrowtestic{dbomany} - -\tikz\draw[rotate=-90,thin,angle 60-angle 60] (0.5,1) .. controls -(0.3,1) and (0.2,0) .. (0,0); - -\end{minipage} - -\bigskip - -I~think they may be useful for someone else. -If there's no such arrow tips defined yet -it would be an honour for me to see this humble package included into -the \textsf{pgf} bundle. - -\medskip -\noindent\leftline{\textbf{The `nulla' arrow tip advisability}} -I~think something like \texttt{nulla} arrow would be useful in general -(like Zero or Null are sometimes useful ;-) e.g., to straighten an -ending of a~curve (compare my arrows with \texttt{angle 60} drawn last -above). - -\medskip -I~think there could be some standard arrow tips defined with a~straight -segment in their middle so that they not look like last arrowcurve -above but like this: -% -\tikz\draw[rotate=-90,thin,angle 60-angle 60] (0.5,.5) -- ++(-.1,0) .. controls -+(-.2,0) and +(0.2,0) .. (.1,0) -- (0,0); - -\medskip -Once again thanks for a~good work. - -\medskip -Yours sincerely and \TeX nically,\\ -\emph{Natror (Grzegorz Murzynowski)}\\ -\texttt{natror at o2.pl} - -\end{document} - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: t -%%% End: diff --git a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/basics.pdf b/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/basics.pdf Binary files differdeleted file mode 100644 index 7e2a07930b2..00000000000 --- a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/basics.pdf +++ /dev/null diff --git a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/basics.tex b/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/basics.tex deleted file mode 100644 index f194c9eaf56..00000000000 --- a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/basics.tex +++ /dev/null @@ -1,125 +0,0 @@ -% Some basic examples for signal flow diagrams. -% -% Author: Dr. Karlheinz Ochs, Ruhr-University of Bochum, Germany -% Version: 0.1 -% Date: 2007/01/05 -\documentclass{article} -\usepackage{signalflowdiagram} - -\begin{document} - -% -% Basic definitions of the symbols used in a signal flow diagram -% - -% - input terminal -\begin{signalflow}{Input terminal} - \node[input] (in) {$x(t)$}; - \node[coordinate] (c) [right from=in] {}; - % signal path - \path[r>] (in) -- (c); -\end{signalflow} - -% - output terminal -\begin{signalflow}{Output terminal} - \node[output] (out) {$y(t)$}; - \node[coordinate] (c) [left from=out] {}; - % signal path - \path[r>] (c) -- (out); -\end{signalflow} - -% - branching node -\begin{signalflow}{Branching node} - \node[input] (in) {$x(t)$}; - \node[node] (nd) [right from=in] {}; - \node[output] (out1) [above right from=nd] {$x(t)$}; - \node[output] (out2) [below right from=nd] {$x(t)$}; - % signal paths - \path[r>] (in) -- (nd); - \path[r>] (nd) |- (out1); - \path[r>] (nd) |- (out2); -\end{signalflow} - -% - multiplier -\begin{signalflow}{Multiplier} - \node[input] (in) {$x(t)$}; - \node[multiplier] (mul) [right from=in] {\nodepart{above}{$\alpha$}}; - \node[output] (out) [right from=mul] {$\alpha x(t)$}; - % signal paths - \path[r>] (in) -- (mul); - \path[r>] (mul) -- (out); -\end{signalflow} - -% - adder -\begin{signalflow}{Adder} - \node[adder] (add) {}; - \node[input] (in1) [above left from=add] {$x_1(t)$}; - \node[input] (in2) [below left from=add] {$x_2(t)$}; - \node[output] (out) [right from=add] {$x_1(t)+x_2(t)$}; - % signal paths - \path[r>] (in1) -| (add); - \path[r>] (in2) -| (add); - \path[r>] (add) -- (out); -\end{signalflow} - -% - modulator -\begin{signalflow}{Modulator} - \node[modulator] (mul) {}; - \node[input] (in1) [above left from=mul] {$x_1(t)$}; - \node[input] (in2) [below left from=mul] {$x_2(t)$}; - \node[output] (out) [right from=mul] {$x_1(t)x_2(t)$}; - % signal paths - \path[r>] (in1) -| (mul); - \path[r>] (in2) -| (mul); - \path[r>] (mul) -- (out); -\end{signalflow} - -% - delay element -\begin{signalflow}{Delay element} - \node[input] (in) {$x(t)$}; - \node[delay] (del) [right from=in] {$T$}; - \node[output] (out) [right from=del] {$x(t-T)$}; - % signal paths - \path[r>] (in) -- (del); - \path[r>] (del) -- (out); -\end{signalflow} - -% - filter -\begin{signalflow}{Filter} - \node[input] (in) {$x(t)$}; - \node[filter] (fil) [right from=in] {$q(t)$}; - \node[output] (out) [right from=fil] {$x(t)\ast q(t)$}; - % signal paths - \path[r>] (in) -- (fil); - \path[r>] (fil) -- (out); -\end{signalflow} - -% - building block -\begin{signalflow}{Building block of a minimum shift keying modulator} - \node[input] (in) {$x(t)$}; - \node[block] (msk) [right from=in] {Minimum shift keying modulator}; - \node[output](out) [right from=msk] {$z(t)$}; - % signal paths - \path[r>] (in) -- (msk); - \path[r>] (msk) -- (out); -\end{signalflow} - -% - MSK symbol encoder -\begin{signalflow}{Minimum shift keying symbol encoder} - \node[input] (in) {$x(t)$}; - \node[modulator] (mod) [right from=in] {}; - \node[multiplier] (mul) [below from=mod] {$\mathrm{j}$}; - \node[delay] (del) [right from=mod] {$T$}; - \node[node] (nd) [right from=del] {}; - \node[output] (out) [right from=nd] {$y(t)$}; - % signal paths - \path[c>] (in) -- (mod); - \path[c>] (mod) -- (del); - \path[c>] (del) -- (nd); - \path[c>] (nd) |- (mul); - \path[c>] (mul) -- (mod); - \path[c>] (nd) -- (out); -\end{signalflow} - - -\end{document} diff --git a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/fir.pdf b/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/fir.pdf Binary files differdeleted file mode 100644 index f9719f7e450..00000000000 --- a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/fir.pdf +++ /dev/null diff --git a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/fir.tex b/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/fir.tex deleted file mode 100644 index 4a8af171c61..00000000000 --- a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/fir.tex +++ /dev/null @@ -1,61 +0,0 @@ -% Example for an interconnection of signal flow diagrams. -% -% Author: Dr. Karlheinz Ochs, Ruhr-University of Bochum, Germany -% Version: 0.1 -% Date: 2007/01/05 -\documentclass{article} -\usepackage{signalflowdiagram} - -\begin{document} - -% An FIR filter -\begin{signalflow}[node distance=9mm]{Finite impulse response filter of order $n$}% - % building blocks - \tikzgrid{ - \node[input] (in) {$x(t)$} & - \node[node] (n0) {} & - \node[delay] (d1) {$T$} & - \node[node] (n1) {} & - \node[delay] (d2) {$T$} & - \node[node] (n2) {} & - \node[coordinate] (c1) {} & - \node[coordinate] (c3) {} & - \node[delay] (dn) {$T$} & - \\ & - \node[multiplier] (m0) {$\alpha_0$} & & - \node[multiplier] (m1) {$\alpha_1$} & & - \node[multiplier] (m2) {$\alpha_2$} & & & & - \node[multiplier] (mn) {$\alpha_n$} - \\ & & & - \node[adder] (a1) {} & & - \node[adder] (a2) {} & - \node[coordinate] (c2) {} & - \node[coordinate] (c4) {} & & - \node[adder] (an) {} & - \node[output] (out) {$y(t)$} - } - % signal paths - \path[r>] (in) -- (n0); - \path[r>] (n0) -- (d1); - \path[r>] (d1) -- (n1); - \path[r>] (n1) -- (d2); - \path[r>] (d2) -- (n2); - \path[r>] (n2) -- (c1); % continuation - \path[r.] (c1) -- (c3); % continuation - \path[r>] (c3) -- (dn); % continuation - \path[r>] (n0) -- (m0); - \path[r>] (n1) -- (m1); - \path[r>] (n2) -- (m2); - \path[r>] (dn) -| (mn); - \path[r>] (m0) |- (a1); - \path[r>] (m1) -- (a1); - \path[r>] (m2) -- (a2); - \path[r>] (mn) -- (an); - \path[r>] (a1) -- (a2); - \path[r>] (a2) -- (c2); % continuation - \path[r.] (c2) -- (c4); % continuation - \path[r>] (c4) -- (an); % continuation - \path[r>] (an) -- (out); -\end{signalflow} - -\end{document} diff --git a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/interconnection.pdf b/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/interconnection.pdf Binary files differdeleted file mode 100644 index 1092c9ba2d6..00000000000 --- a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/interconnection.pdf +++ /dev/null diff --git a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/interconnection.tex b/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/interconnection.tex deleted file mode 100644 index 1bc3072d70d..00000000000 --- a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/interconnection.tex +++ /dev/null @@ -1,25 +0,0 @@ -% Example for an interconnection of signal flow diagrams. -% -% Author: Dr. Karlheinz Ochs, Ruhr-University of Bochum, Germany -% Version: 0.1 -% Date: 2007/01/05 -\documentclass{article} -\usepackage{signalflowdiagram} -\usepackage{macros} - -\begin{document} - -% interconnection of an MSK symbol encoder with a pulse shaper -\begin{signalflow}{Minimum shift keying modulator}% - \node[input] (in) {$x(t)$}; - \mskCoder {mC} {right from=in} {}; - \pulseShaper {pS} {right from=mC-out} {}; - \node[output] (out) [right from=pS-out] {$z(t)$}; - % signal paths - \path[c>] (in) -- (mC-in); - \path[c>] (mC-out) -- (pS-in); - \path[c>] (pS-out) -- (out); - \textaboveof{mC-out}{$y(t)$} -\end{signalflow} - -\end{document} diff --git a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/macros.sty b/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/macros.sty deleted file mode 100644 index 024b248cc76..00000000000 --- a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/macros.sty +++ /dev/null @@ -1,46 +0,0 @@ -% Some macros for signal flow diagrams. -% -% Author: Dr. Karlheinz Ochs, Ruhr-University of Bochum, Germany -% Version: 0.1 -% Date: 2007/01/05 - -\NeedsTeXFormat{LaTeX2e} -\RequirePackage{tikz} -\RequirePackage{signalflowdiagram} -\ProvidesPackage{macros} - [2007/01/05 v0.1 Some user-defined macros for signal flow diagrams] - -% -% Creates the signal flow diagram of a minimum shift keying coder. -% -% #1 = global label -% #2 = parameter for placement -\newcommand{\mskCoder}[3]{% - % building blocks - \node[modulator] (#1-in) [#2] {}; - \node[multiplier] (mul) [below from=#1-in] {$\mathrm{j}$}; - \node[delay] (del) [right from=#1-in] {$T$}; - \node[node] (#1-out) [right from=del] {}; - % signal paths - \path[c>] (#1-in) -- (del); - \path[c>] (del) -- (#1-out); - \path[c>] (#1-out) |- (mul); - \path[c>] (mul) -- (#1-in); -}% - - -% Creates the signal flow diagram of a pulse shaper. -% -% #1 = global label -% #2 = parameter for placement -\newcommand{\pulseShaper}[4]{% - % building blocks - \node[modulator] (#1-in) [#2] {}; - \node[coordinate] (pam) - [above from = #1-in, - label=above:$\sum\limits_{\nu=-\infty}^{\infty} \delta(t-t_\nu)$] {}; - \node[filter] (#1-out) [right from = #1-in] {$q(t)$}; - % signal paths - \path[r>] (pam) -- (#1-in); - \path[c>] (#1-in) -- (#1-out); -}% diff --git a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/pgflibrarytikzsignalflowarrows.code.tex b/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/pgflibrarytikzsignalflowarrows.code.tex deleted file mode 100644 index da8a6ea3848..00000000000 --- a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/pgflibrarytikzsignalflowarrows.code.tex +++ /dev/null @@ -1,31 +0,0 @@ -% pgf/tikz library -% for signal flow diagrams -% -% Author: Dr. Karlheinz Ochs, Ruhr-University of Bochum, Germany -% Version: 0.1 -% Date: 2007/01/05 - - -% Styles for real and complex signal tips. -\newcommand{\pgfarrowsextend}[1]{% - \pgfsetcolor{\pathdrawcolor}% - \@tempdima=#1\pgflinewidth% - \pgfarrowsleftextend{-2\@tempdima} - \pgfarrowsrightextend{2\@tempdima} -} -\newcommand{\pgfarrowsarrowtip}[1]{% - \pgfsetcolor{\pathdrawcolor}% - \@tempdima=#1\pgflinewidth% - \pgfpathmoveto{\pgfpoint{2\@tempdima}{0pt}} - \pgfpathlineto{\pgfpoint{-\@tempdima}{\@tempdima}} - \pgfpathlineto{\pgfpointorigin} - \pgfpathlineto{\pgfpoint{-\@tempdima}{-\@tempdima}} - \pgfusepathqfill -} -\pgfarrowsdeclare{real tip}{real tip}{\pgfarrowsextend{3}}{\pgfarrowsarrowtip{3}} -\pgfarrowsdeclarereversed{real tip reversed}{real tip reversed}{real tip}{real tip} -\pgfarrowsdeclare{complex tip}{complex tip}{\pgfarrowsextend{1}}{\pgfarrowsarrowtip{1}} -\pgfarrowsdeclarereversed{complex tip reversed}{complex tip reversed}{complex tip}{complex tip} - - -\endinput diff --git a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/pgflibrarytikzsignalflowblocks.code.tex b/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/pgflibrarytikzsignalflowblocks.code.tex deleted file mode 100644 index 0a7410cc443..00000000000 --- a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/pgflibrarytikzsignalflowblocks.code.tex +++ /dev/null @@ -1,469 +0,0 @@ -% pgf/tikz library -% for signal flow diagrams -% -% Author: Dr. Karlheinz Ochs, Ruhr-University of Bochum, Germany -% Version: 0.1 -% Date: 2007/01/05 - -% Known bugs: - Anchors of source shape are not precisely positioned. -% - Anchor border of source shape is a rectangle. -% - The bounding box of standard text label is ignored. - - -% -% Styles for nodes, terminals, and operators. -% -% - building blocks -\tikzstyle{block color}% - = [draw=\blockdrawcolor, - fill=\blockfillcolor] -\tikzstyle{block style}% - = [block color, - line width=\blocklinewidth, - text centered] -\tikzstyle{block}% - = [rectangle, - block style, - minimum width=\blockwidth, - minimum height=\blockheight, - text width=\blocktextwidth] -\tikzstyle{filter}% - = [rectangle, - block style, - minimum width=\filterwidth, - minimum height=\filterheight, - text width=\filtertextwidth] -\tikzstyle{source}% - = [source shape, - operator style] -\tikzstyle{serial parallel converter}% - = [serial parallel converter shape, - block style, - minimum width=10mm, - minimum height=20mm, - inner sep=2mm] -\tikzstyle{parallel serial converter}% - = [parallel serial converter shape, - block style, - minimum width=10mm, - minimum height=20mm, - inner sep=2mm] -\tikzstyle{symbol mapper}% - = [symbol mapper shape, - block style, - text centered, - minimum size=20mm, - text width=18mm] -\tikzstyle{inverse symbol mapper}% - = [inverse symbol mapper shape, - block style, - text centered, - minimum size=20mm, - text width=18mm] - - -% -% Shape of a source. -% -\newbox\pgfnodeparttextbox -\pgfdeclareshape{source shape} -{ - \savedanchor\westpoint{ - \pgf@x=\wd\pgfnodeparttextbox% - \advance\pgf@x by\pgfshapeouterxsep% - \pgf@y=.5\ht\pgfnodeparttextbox% - \advance\pgf@y by-.5\dp\pgfnodeparttextbox% - } - \saveddimen\radius{ - \setlength\pgf@x{\pgfshapeminwidth} - } - \anchor{west}{\westpoint} - \anchor{north west}{ - \pgf@process{\westpoint} - \advance\pgf@y by\radius - } - \anchor{north}{% - \pgf@process{\westpoint} - \pgf@xa=\radius\advance\pgf@x by+0.5\pgf@xa - \pgf@ya=\radius\advance\pgf@y by+0.866025\pgf@ya - } - \anchor{north east}{% - \pgf@process{\westpoint} - \pgf@xa=\radius\advance\pgf@x by+0.866025\pgf@xa - \pgf@ya=\radius\advance\pgf@y by+0.5\pgf@ya - } - \anchor{east}{ - \pgf@process{\westpoint} - \advance\pgf@x by\radius - \advance\pgf@x by0.5\pgflinewidth - } - \anchor{south east}{% - \pgf@process{\westpoint} - \pgf@xa=\radius\advance\pgf@x by+0.866025\pgf@xa - \pgf@ya=\radius\advance\pgf@y by-0.5\pgf@ya - } - \anchor{south}{% - \pgf@process{\westpoint} - \pgf@xa=\radius\advance\pgf@x by+0.5\pgf@xa - \pgf@ya=\radius\advance\pgf@y by-0.866025\pgf@ya - } - \anchor{south west}{ - \pgf@process{\westpoint} - \advance\pgf@y by-\radius - } - \anchor{center}{ - \pgf@process{\westpoint} - \pgf@xa=\radius\advance\pgf@x by+0.5\pgf@xa - } - % node part - \nodeparts{text} - \anchor{text}{ - \pgf@process{\westpoint} - \pgf@xa=\radius - \advance\pgf@y by-.5\ht\pgfnodeparttextbox% - \advance\pgf@x by-\wd\pgfnodeparttextbox% - \advance\pgf@x by-0.5mm - } - \anchorborder{% - \pgf@xb=\pgf@x% xb/yb is target - \pgf@yb=\pgf@y% - % southwest - \westpoint\advance\pgf@y by-\radius - \pgf@xa=\pgf@x% xa/ya is se - \pgf@ya=\pgf@y% - % northeast - \westpoint\advance\pgf@x by\radius\advance\pgf@y by\radius% - \advance\pgf@x by-\pgf@xa% - \advance\pgf@y by-\pgf@ya% - \pgf@xc=.5\pgf@x% x/y is half width/height - \pgf@yc=.5\pgf@y% - \advance\pgf@xa by\pgf@xc% xa/ya becomes center - \advance\pgf@ya by\pgf@yc% - \edef\pgf@marshal{% - \noexpand\pgfpointborderrectangle - {\noexpand\pgfpoint{\the\pgf@xb}{\the\pgf@yb}} - {\noexpand\pgfpoint{\the\pgf@xc}{\the\pgf@yc}}% - }% - \pgf@process{\pgf@marshal}% - \advance\pgf@x by\pgf@xa% - \advance\pgf@y by\pgf@ya% - } - % Background path - \backgroundpath{ - {\pgftransformreset{\pgfnodeparttextbox}} - \westpoint \pgf@xa=\pgf@x \pgf@ya=\pgf@y - \advance\pgf@y by\radius - \pgfmoveto{\pgfpoint{\pgf@x}{\pgf@y}} - \pgfpatharc{90}{-90}{\radius} - \pgfclosepath - } -} - - -% -% Shape of a serial to parallel converter. -% -\newbox\pgfnodepartSbox -\newbox\pgfnodepartPbox -\pgfdeclareshape{serial parallel converter shape} -{ - % inherit from rectangle - \inheritsavedanchors[from=rectangle] - \inheritanchor[from=rectangle]{center} - \inheritanchor[from=rectangle]{north} - \inheritanchor[from=rectangle]{north east} - \inheritanchor[from=rectangle]{east} - \inheritanchor[from=rectangle]{south east} - \inheritanchor[from=rectangle]{south} - \inheritanchor[from=rectangle]{south west} - \inheritanchor[from=rectangle]{west} - \inheritanchor[from=rectangle]{north west} - \inheritanchorborder[from=rectangle] - \inheritanchorborder[from=rectangle] - \inheritbackgroundpath[from=rectangle] - % terminal anchors - \anchor{in}{% - \northeast - \pgf@ya=0.5\pgf@y - \southwest - \pgf@y=0.5\pgf@y - \advance\pgf@y by+\pgf@ya% - } - \anchor{out1}{ - \southwest - \pgf@ya=0.9\pgf@y - \northeast - \pgf@y=0.1\pgf@y - \advance\pgf@y by\pgf@ya% - } - \anchor{out2}{ - \southwest - \pgf@ya=0.7\pgf@y - \northeast - \pgf@y=0.3\pgf@y - \advance\pgf@y by\pgf@ya% - } - \anchor{outl}{ - \southwest - \pgf@ya=0.1\pgf@y - \northeast - \pgf@y=0.9\pgf@y - \advance\pgf@y by\pgf@ya% - } - \anchor{dots}{ - \southwest - \pgf@ya=0.4\pgf@y - \northeast - \pgf@y=0.6\pgf@y - \advance\pgf@y by\pgf@ya% - \setlength{\pgf@xa}{\xspace} - \advance\pgf@x by.5\pgf@xa% - } - % node parts - \nodeparts{S,P} - \anchor{S}{ - \southwest - \pgf@xa=\pgf@x - \northeast - \pgf@x=\pgf@xa - \advance\pgf@y by-\ht\pgfnodepartSbox% - \advance\pgf@y by-.5\dp\pgfnodepartSbox% - \advance\pgf@x by+\pgfshapeinnerxsep% - \advance\pgf@y by-\pgfshapeinnerysep% - } - \anchor{P}{ - \northeast - \pgf@xa=\pgf@x - \southwest - \pgf@x=\pgf@xa - \advance\pgf@x by-\wd\pgfnodepartPbox% - \advance\pgf@x by-\pgfshapeinnerxsep% - \advance\pgf@y by+\pgfshapeinnerysep% - } - % diagonal line S/P - \foregroundpath{% - \pgfpathmoveto{\pgfpointadd{\southwest}{\pgfpoint{\pgfshapeouterxsep}{\pgfshapeouterysep}}} - \pgfpathlineto{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfshapeouterxsep}{\pgfshapeouterysep}}}} - } -} - -% -% Shape of a parallel to serial converter. -% -\newbox\pgfnodepartSbox -\newbox\pgfnodepartPbox -\pgfdeclareshape{parallel serial converter shape} -{ - % inherit from rectangle - \inheritsavedanchors[from=rectangle] - \inheritanchor[from=rectangle]{center} - \inheritanchor[from=rectangle]{north} - \inheritanchor[from=rectangle]{north east} - \inheritanchor[from=rectangle]{east} - \inheritanchor[from=rectangle]{south east} - \inheritanchor[from=rectangle]{south} - \inheritanchor[from=rectangle]{south west} - \inheritanchor[from=rectangle]{west} - \inheritanchor[from=rectangle]{north west} - \inheritanchorborder[from=rectangle] - \inheritanchorborder[from=rectangle] - \inheritbackgroundpath[from=rectangle] - % terminal anchors - \anchor{out}{% - \southwest - \pgf@ya=0.5\pgf@y - \northeast - \pgf@y=0.5\pgf@y - \advance\pgf@y by+\pgf@ya% - } - \anchor{in1}{ - \northeast - \pgf@ya=0.1\pgf@y - \southwest - \pgf@y=0.9\pgf@y - \advance\pgf@y by\pgf@ya% - } - \anchor{in2}{ - \northeast - \pgf@ya=0.3\pgf@y - \southwest - \pgf@y=0.7\pgf@y - \advance\pgf@y by\pgf@ya% - } - \anchor{inl}{ - \northeast - \pgf@ya=0.9\pgf@y - \southwest - \pgf@y=0.1\pgf@y - \advance\pgf@y by\pgf@ya% - } - \anchor{dots}{ - \northeast - \pgf@ya=0.6\pgf@y - \southwest - \pgf@y=0.4\pgf@y - \advance\pgf@y by\pgf@ya% - \setlength{\pgf@xa}{\xspace} - \advance\pgf@x by-.5\pgf@xa% - } - % node parts - \nodeparts{P,S} - \anchor{P}{ - \southwest - \pgf@xa=\pgf@x - \northeast - \pgf@x=\pgf@xa - \advance\pgf@y by-\ht\pgfnodepartPbox% - \advance\pgf@y by-.5\dp\pgfnodepartPbox% - \advance\pgf@x by+\pgfshapeinnerxsep% - \advance\pgf@y by-\pgfshapeinnerysep% - } - \anchor{S}{ - \northeast - \pgf@xa=\pgf@x - \southwest - \pgf@x=\pgf@xa - \advance\pgf@x by-\wd\pgfnodepartSbox% - \advance\pgf@x by-\pgfshapeinnerxsep% - \advance\pgf@y by+\pgfshapeinnerysep% - } - % diagonal line S/P - \foregroundpath{% - \pgfpathmoveto{\pgfpointadd{\southwest}{\pgfpoint{\pgfshapeouterxsep}{\pgfshapeouterysep}}} - \pgfpathlineto{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfshapeouterxsep}{\pgfshapeouterysep}}}} - } -} - - -% -% Shape of a symbol mapper. -% -\pgfdeclareshape{symbol mapper shape} -{ - % rectangle anchors - \inheritsavedanchors[from=rectangle] - \inheritanchor[from=rectangle]{center} - \inheritanchor[from=rectangle]{north} - \inheritanchor[from=rectangle]{north east} - \inheritanchor[from=rectangle]{east} - \inheritanchor[from=rectangle]{south east} - \inheritanchor[from=rectangle]{south} - \inheritanchor[from=rectangle]{south west} - \inheritanchor[from=rectangle]{west} - \inheritanchor[from=rectangle]{north west} - \inheritanchorborder[from=rectangle] - % terminal anchors - \anchor{out}{% - \southwest - \pgf@ya=0.5\pgf@y - \northeast - \pgf@y=0.5\pgf@y - \advance\pgf@y by+\pgf@ya% - } - \anchor{in1}{ - \northeast - \pgf@ya=0.1\pgf@y - \southwest - \pgf@y=0.9\pgf@y - \advance\pgf@y by\pgf@ya% - } - \anchor{in2}{ - \northeast - \pgf@ya=0.3\pgf@y - \southwest - \pgf@y=0.7\pgf@y - \advance\pgf@y by\pgf@ya% - } - \anchor{dots}{ - \northeast - \pgf@ya=0.6\pgf@y - \southwest - \pgf@y=0.4\pgf@y - \advance\pgf@y by\pgf@ya% - \setlength{\pgf@xa}{\xspace} - \advance\pgf@x by-.5\pgf@xa% - } - \anchor{inl}{ - \northeast - \pgf@ya=0.9\pgf@y - \southwest - \pgf@y=0.1\pgf@y - \advance\pgf@y by\pgf@ya% - } - % rectangle shaped frame - \backgroundpath{ - \pgfpathrectanglecorners - {\pgfpointadd{\southwest}{\pgfpoint{\pgfshapeouterxsep}{\pgfshapeouterysep}}} - {\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfshapeouterxsep}{\pgfshapeouterysep}}}} - } - - \inheritbackgroundpath[from=rectangle] -} - - -% -% Shape of an inverse symbol mapper. -% -\pgfdeclareshape{inverse symbol mapper shape} -{ - % rectangle anchors - \inheritsavedanchors[from=rectangle] - \inheritanchor[from=rectangle]{center} - \inheritanchor[from=rectangle]{north} - \inheritanchor[from=rectangle]{north east} - \inheritanchor[from=rectangle]{east} - \inheritanchor[from=rectangle]{south east} - \inheritanchor[from=rectangle]{south} - \inheritanchor[from=rectangle]{south west} - \inheritanchor[from=rectangle]{west} - \inheritanchor[from=rectangle]{north west} - \inheritanchorborder[from=rectangle] - % terminal anchors - \anchor{in}{% - \northeast - \pgf@ya=0.5\pgf@y - \southwest - \pgf@y=0.5\pgf@y - \advance\pgf@y by+\pgf@ya% - } - \anchor{out1}{ - \southwest - \pgf@ya=0.9\pgf@y - \northeast - \pgf@y=0.1\pgf@y - \advance\pgf@y by\pgf@ya% - } - \anchor{out2}{ - \southwest - \pgf@ya=0.7\pgf@y - \northeast - \pgf@y=0.3\pgf@y - \advance\pgf@y by\pgf@ya% - } - \anchor{outl}{ - \southwest - \pgf@ya=0.1\pgf@y - \northeast - \pgf@y=0.9\pgf@y - \advance\pgf@y by\pgf@ya% - } - \anchor{dots}{ - \southwest - \pgf@ya=0.4\pgf@y - \northeast - \pgf@y=0.6\pgf@y - \advance\pgf@y by\pgf@ya% - \setlength{\pgf@xa}{\xspace} - \advance\pgf@x by.5\pgf@xa% - } - % rectangle shaped frame - \backgroundpath{ - \pgfpathrectanglecorners - {\pgfpointadd{\southwest}{\pgfpoint{\pgfshapeouterxsep}{\pgfshapeouterysep}}} - {\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfshapeouterxsep}{\pgfshapeouterysep}}}} - } - - \inheritbackgroundpath[from=rectangle] -} - -\endinput diff --git a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/pgflibrarytikzsignalflowdiagram.code.tex b/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/pgflibrarytikzsignalflowdiagram.code.tex deleted file mode 100644 index 37e3608ac8d..00000000000 --- a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/pgflibrarytikzsignalflowdiagram.code.tex +++ /dev/null @@ -1,60 +0,0 @@ -% pgf/tikz library -% for signal flow diagrams -% -% Author: Dr. Karlheinz Ochs, Ruhr-University of Bochum, Germany -% Version: 0.1 -% Date: 2007/01/05 - -% -% Extended general shape options, cf. tikz.code.tex -% -% #1 = source node -% Remark: The node distance is used -% for the distance between the borders of two nodes -\tikzoption{below from}{\tikz@from{#1}{1}{-90}{south}{north}}% -\tikzoption{right from}{\tikz@from{#1}{1}{0}{east}{west}}% -\tikzoption{above from}{\tikz@from{#1}{1}{90}{north}{south}}% -\tikzoption{left from}{\tikz@from{#1}{1}{180}{west}{east}}% -\tikzoption{below left from}{\tikz@from{#1}{1.414214}{-135}{south west}{north east}}% -\tikzoption{below right from}{\tikz@from{#1}{1.414214}{-45}{south east}{north west}}% -\tikzoption{above right from}{\tikz@from{#1}{1.414214}{45}{north east}{south west}}% -\tikzoption{above left from}{\tikz@from{#1}{1.414214}{135}{north west}{south east}}% -\def\tikz@from#1#2#3#4#5{% - \def\tikz@anchor{#5}% - \let\tikz@do@auto@anchor=\relax% - \tikz@addtransform{\pgftransformshift{\pgfpointscale{#2}{\pgfpointpolar{#3}{\tikz@node@distance}}}}% - \def\tikz@node@at{\pgfpointanchor{#1}{#4}}} - - -% -% Styles for real and complex signal paths. -% -\tikzstyle{dotted path} - = [loosely dotted, - shorten >= 2mm, - shorten <= 2mm] -\tikzstyle{r} - = [line width=\pathlinewidth, - >= real tip, - draw] -\tikzstyle{r>} - = [r,->] -\tikzstyle{<r} - = [r,<-] -\tikzstyle{r.} - = [r,dotted path] -\tikzstyle{c} - = [line width=\pathlinewidth, - double=\pathfillcolor, - double distance=\pathlinewidth, - >= complex tip, - draw,shorten <=-\pathlineextend] -\tikzstyle{c>} - = [c,->] -\tikzstyle{<c} - = [c,<-] -\tikzstyle{c.} - = [c,dotted path] - - -\endinput diff --git a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/pgflibrarytikzsignalflowoperators.code.tex b/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/pgflibrarytikzsignalflowoperators.code.tex deleted file mode 100644 index f94f0a8f8a7..00000000000 --- a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/pgflibrarytikzsignalflowoperators.code.tex +++ /dev/null @@ -1,259 +0,0 @@ -% pgf/tikz library -% for signal flow diagrams -% -% Author: Dr. Karlheinz Ochs, Ruhr-University of Bochum, Germany -% Version: 0.1 -% Date: 2007/01/05 - - -% -% Styles for nodes, terminals, and operators. -% -% - nodes and terminals -\tikzstyle{node style}% - = [draw=\pathdrawcolor, - fill=\pathdrawcolor, - minimum size=\nodesize] -\tikzstyle{terminal style}% - = [draw=\pathdrawcolor, - fill=\pathfillcolor, - line width=\pathlinewidth, - minimum size=\terminalsize] -\tikzstyle{node}% - = [node shape, - node style] -\tikzstyle{input}% - = [input terminal shape, - terminal style] -\tikzstyle{output}% - = [output terminal shape, - terminal style] -% - operators -\tikzstyle{operator color}% - = [draw=\operatordrawcolor, - fill=\operatorfillcolor] -\tikzstyle{operator style}% - = [operator color, - line width=\operatorlinewidth, - minimum size=\operatorsize] -\tikzstyle{multiplier}% - = [multiplier shape, - operator style] -\tikzstyle{modulator}% - = [modulator shape, - operator style] -\tikzstyle{adder}% - = [adder shape, - operator style] -\tikzstyle{delay}% - = [rectangle, - operator style, - minimum size=\delaysize] - - -% -% Circular shapes of operator symbols. -% -% #1 = additional inner symbol -\newcommand{\circularshape}[1]{% - \savedanchor\centerpoint{\pgfpointorigin} - % radius is half of maximum of \pgfshapeminwidth and \pgfshapeminheight - \saveddimen\radius{% - \setlength{\pgf@xa}{\pgfshapeminwidth} - \setlength{\pgf@ya}{\pgfshapeminheight} - \ifdim\pgf@xa>\pgf@ya - \pgf@x=.5\pgf@xa - \else - \pgf@x=.5\pgf@ya - \fi - } - \inheritanchor[from=circle]{center} - \inheritanchorborder[from=circle] - \inheritanchor[from=circle]{north} - \inheritanchor[from=circle]{north east} - \inheritanchor[from=circle]{east} - \inheritanchor[from=circle]{south east} - \inheritanchor[from=circle]{south} - \inheritanchor[from=circle]{south west} - \inheritanchor[from=circle]{west} - \inheritanchor[from=circle]{north west} - \inheritanchor[from=circle]{mid} - \inheritanchor[from=circle]{mid west} - \inheritanchor[from=circle]{mid east} - \inheritanchor[from=circle]{base} - \inheritanchor[from=circle]{base west} - \inheritanchor[from=circle]{base east} - % circular shaped frame - \inheritbackgroundpath[from=circle] - % additional inner symbol - \foregroundpath{ - \centerpoint% - \pgf@xc=\pgf@x% - \pgf@yc=\pgf@y% - \@tempdima=\radius% - #1 - } - % no text - \nodeparts{} -} - - -% -% Anchors for default text box, see below. -% -\newcommand{\stdaboveanchor}{% - \anchor{text}{% - \centerpoint - \advance\pgf@x by-0.5\wd\pgfnodeparttextbox% - \advance\pgf@y by\radius - \advance\pgf@y by+0.5mm - } -} -\newcommand{\stdrightanchor}{% - \anchor{text}{% - \centerpoint - \advance\pgf@x by\radius - \advance\pgf@x by+0.5mm - \advance\pgf@y by-0.5\ht\pgfnodeparttextbox% - \advance\pgf@y by+0.5\dp\pgfnodeparttextbox% - } -} -\newcommand{\stdbelowanchor}{% - \anchor{text}{% - \centerpoint - \advance\pgf@x by-0.5\wd\pgfnodeparttextbox% - \advance\pgf@y by-\ht\pgfnodeparttextbox% - \advance\pgf@y by-\radius - \advance\pgf@y by-0.5mm - } -} -\newcommand{\stdleftanchor}{% - \anchor{text}{% - \centerpoint - \advance\pgf@x by-\radius - \advance\pgf@x by-\wd\pgfnodeparttextbox% - \advance\pgf@x by-0.5mm - \advance\pgf@y by-0.5\ht\pgfnodeparttextbox% - \advance\pgf@y by+0.5\dp\pgfnodeparttextbox% - } -} - - -% -% Circular shapes of operator symbols with default text box. -% -% #1 = place of the default text box -\newbox\pgfnodepartabovebox -\newbox\pgfnodepartrightbox -\newbox\pgfnodepartbelowbox -\newbox\pgfnodepartleftbox -\newcommand{\labelledcircularshape}[1]{% - % node parts - \nodeparts{text,above,right,below,left} - % anchors - \savedanchor\centerpoint{\pgfpointorigin} - % radius is half of maximum of \pgfshapeminwidth and \pgfshapeminheight - \saveddimen\radius{% - \setlength{\pgf@xa}{\pgfshapeminwidth} - \setlength{\pgf@ya}{\pgfshapeminheight} - \ifdim\pgf@xa>\pgf@ya - \pgf@x=.5\pgf@xa - \else - \pgf@x=.5\pgf@ya - \fi - } - \inheritanchor[from=circle]{center} - \inheritanchorborder[from=circle] - \inheritanchor[from=circle]{north} - \inheritanchor[from=circle]{north east} - \inheritanchor[from=circle]{east} - \inheritanchor[from=circle]{south east} - \inheritanchor[from=circle]{south} - \inheritanchor[from=circle]{south west} - \inheritanchor[from=circle]{west} - \inheritanchor[from=circle]{north west} - \inheritanchor[from=circle]{mid} - \inheritanchor[from=circle]{mid west} - \inheritanchor[from=circle]{mid east} - \inheritanchor[from=circle]{base} - \inheritanchor[from=circle]{base west} - \inheritanchor[from=circle]{base east} - #1 - \anchor{above}{% - \centerpoint - \advance\pgf@x by-0.5\wd\pgfnodepartabovebox% - \advance\pgf@y by\radius - \advance\pgf@y by+0.5mm - } - \anchor{right}{% - \centerpoint - \advance\pgf@x by\radius - \advance\pgf@x by+0.5mm - \advance\pgf@y by-0.5\ht\pgfnodepartrightbox% - \advance\pgf@y by+0.5\dp\pgfnodeparttextbox% - } - \anchor{below}{% - \centerpoint - \advance\pgf@x by-0.5\wd\pgfnodepartbelowbox% - \advance\pgf@y by-\ht\pgfnodepartbelowbox% - \advance\pgf@y by-\radius - \advance\pgf@y by-0.5mm - } - \anchor{left}{% - \centerpoint - \advance\pgf@x by-\radius - \advance\pgf@x by-\wd\pgfnodepartleftbox% - \advance\pgf@x by-0.5mm - \advance\pgf@y by-0.5\ht\pgfnodepartleftbox% - \advance\pgf@y by+0.5\dp\pgfnodeparttextbox% - } - % circular shaped frame - \inheritbackgroundpath[from=circle] -} - - -% -% Shape of a node. -% -\pgfdeclareshape{node shape}{\labelledcircularshape{\stdaboveanchor}}% - -% -% Shape of an input terminal. -% -\pgfdeclareshape{input terminal shape}{\labelledcircularshape{\stdleftanchor}}% -% -% Shape of an output terminal. -% -\pgfdeclareshape{output terminal shape}{\labelledcircularshape{\stdrightanchor}}% -% -% Shape of a multiplier. -% -\pgfdeclareshape{multiplier shape}{\labelledcircularshape{\stdleftanchor}}% -% -% Shape of a modulator. -% -\pgfdeclareshape{modulator shape}{\circularshape{% - \pgfpathmoveto{\pgfpointadd{\pgfpoint{\pgf@xc}{\pgf@yc}} - {\pgfpoint{-0.707107\@tempdima}{-0.707107\@tempdima}}} - \pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xc}{\pgf@yc}} - {\pgfpoint{0.707107\@tempdima}{0.707107\@tempdima}}} - \pgfpathmoveto{\pgfpointadd{\pgfpoint{\pgf@xc}{\pgf@yc}} - {\pgfpoint{0.707107\@tempdima}{-0.707107\@tempdima}}} - \pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xc}{\pgf@yc}} - {\pgfpoint{-0.707107\@tempdima}{0.707107\@tempdima}}} -}}% -% -% Shape of an adder. -% -\pgfdeclareshape{adder shape}{\circularshape{% - \pgfpathmoveto{\pgfpointadd{\pgfpoint{\pgf@xc}{\pgf@yc}} - {\pgfpoint{-0.5\@tempdima}{0\@tempdima}}} - \pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xc}{\pgf@yc}} - {\pgfpoint{0.5\@tempdima}{0\@tempdima}}} - \pgfpathmoveto{\pgfpointadd{\pgfpoint{\pgf@xc}{\pgf@yc}} - {\pgfpoint{0\@tempdima}{-0.5\@tempdima}}} - \pgfpathlineto{\pgfpointadd{\pgfpoint{\pgf@xc}{\pgf@yc}} - {\pgfpoint{0\@tempdima}{0.5\@tempdima}}} -}}% - -\endinput diff --git a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/placement.pdf b/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/placement.pdf Binary files differdeleted file mode 100644 index c06b5d79f08..00000000000 --- a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/placement.pdf +++ /dev/null diff --git a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/placement.tex b/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/placement.tex deleted file mode 100644 index ec65a53b7d0..00000000000 --- a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/placement.tex +++ /dev/null @@ -1,28 +0,0 @@ -% Placement example of from command, -% which is an extension of the of command, -% cf. tikz.code.tex of Till Tantau. -% -% Author: Dr. Karlheinz Ochs, Ruhr-University of Bochum, Germany -% Version: 0.1 -% Date: 2007/01/05 -\documentclass{article} -\usepackage{signalflowdiagram} -\usepackage{macros} - -\begin{document} - -% -% Basic placement example using my "from" command. -% -\begin{signalflow}{Placement example} - \node[block] (bc) {center}; - \node[block] (bl) [left from=bc] {left}; - \node[block] (br) [right from=bc] {right}; - \node[block] (ba) [above from=bc] {above}; - \node[block] (bb) [below from=bc] {below}; - \node[block] (bal) [above left from=bc] {above\\left}; - \node[block] (bbl) [below left from=bc] {below\\left}; - \node[block] (bal) [above right from=bc] {above\\right}; - \node[block] (bbl) [below right from=bc] {below\\right}; -\end{signalflow} -\end{document} diff --git a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/signalflowdiagram.sty b/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/signalflowdiagram.sty deleted file mode 100644 index c258eb7a9d9..00000000000 --- a/Master/texmf-dist/source/latex/pgf/incoming/KarlheinzOchs/signalflowdiagram.sty +++ /dev/null @@ -1,138 +0,0 @@ -% A simple library for signal flow diagrams -% based on the pgf/tikz package of Till Tantau -% -% Author: Dr. Karlheinz Ochs, Ruhr-University of Bochum, Germany -% Version: 0.1 -% Date: 2007/01/05 -\NeedsTeXFormat{LaTeX2e} -\RequirePackage{tikz} -\ProvidesPackage{signalflowdiagram} - [2006/12/30 v0.1 Signal flow diagrams] - -% -% Libraries for signal flow diagrams. -% -\usetikzlibrary{signalflowdiagram,signalflowarrows,signalflowoperators,signalflowblocks} - - -% -% Colors -% -\newcommand{\pathdrawcolor}{\blockdrawcolor} % draw color of signal paths -\newcommand{\pathfillcolor}{\blockfillcolor} % fill color of signal paths -\newcommand{\operatordrawcolor}{\blockdrawcolor} % draw color of operators -\newcommand{\operatorfillcolor}{\blockfillcolor} % fill color of operators -\newcommand{\blockdrawcolor}{black} % draw color of blocks -\newcommand{\blockfillcolor}{white} % fill color of blocks - -% -% line widths of -% -\newcommand{\diagramlinewidth}{0.5mm} % signal flow diagram frames -\newcommand{\pathlinewidth}{0.3mm} % signal paths -\newcommand{\operatorlinewidth}{0.3mm} % operator frames -\newcommand{\blocklinewidth}{0.5mm} % building block styles - -% -% line widths, sizes, etc. -% -\newcommand{\nodesize}{1.5mm} % size of nodes -\newcommand{\terminalsize}{\nodesize} % size of terminals -\newcommand{\operatorsize}{3mm} % size of circular shaped operator symbols -\newcommand{\delaysize}{6mm} % minimum size of delay elements -\newcommand{\blockwidth}{24mm} % minimum width of blocks -\newcommand{\blockheight}{12mm} % minimum height of blocks -\newcommand{\blocktextwidth}{22mm} % minimum text width of blocks -\newcommand{\filterwidth}{12mm} % minimum width of filters -\newcommand{\filterheight}{8mm} % minimum height of filters -\newcommand{\filtertextwidth}{6mm} % minimum text width of filters - -% -% misc. -% -\newcommand{\pathlineextend}{0.025mm} % shortens the end of the signal paths -\newcommand{\vbullets}[1]{% vertical bullets -\node[rectangle,anchor=center,at=(#1),text width=2ex]{% -$\bullet$\\[-1ex] $\bullet$\\[-1ex] $\bullet$} -}% - - -% -% Signal flow diagram. -% -% #1 = optional parameter(s) -% #2 = title text -\tikzstyle{signal flow diagram} = - [rectangle, - sharp corners, - line width=\diagramlinewidth, - draw=black, - inner sep=3mm] -\newenvironment{signalflow}[2][]{% -\begin{center} - \begin{tikzpicture} - \node[% title - signal flow diagram, - fill=blue!90!black, - text=white] (title) {#2};% title text - \node at (title.south west) [% - signal flow diagram, - fill=blue!20!white, - anchor=north west, - yshift=\pgflinewidth] - \bgroup - \begin{minipage}{0.9\textwidth} - \centering - \begin{tikzpicture}[% - node distance=8mm, - pin distance=8mm, - label distance=-0.5mm, - inner sep=1mm, - anchor=center, - text centered, - #1]% optional parameter(s) -}{% - \end{tikzpicture} - \end{minipage} - \egroup; - \end{tikzpicture} -\end{center} -}% - - -% -% Positioning of node text. -% -% #1 = node label -% #2 = label text -\newcommand{\textaboveof}[2]{\pgftext[bottom,at=\pgfpointanchor{#1}{north},y=+1mm]{#2}}% -\newcommand{\textrightof}[2]{\pgftext[left, at=\pgfpointanchor{#1}{east}, x=+1mm]{#2}}% -\newcommand{\textbelowof}[2]{\pgftext[top ,at=\pgfpointanchor{#1}{south},y=-1mm]{#2}}% -\newcommand{\textleftof} [2]{\pgftext[right, at=\pgfpointanchor{#1}{west}, x=-1mm]{#2}}% - -\makeatletter -\newcounter{r} -\newcommand{\tikzgrid}{% - \pgfsetxvec{\pgfpoint{\tikz@node@distance}{0mm}}% - \pgfsetyvec{\pgfpoint{0mm}{\tikz@node@distance}}% - \tikz@matrix% -} -\newcommand{\tikz@matrix}[1]{\tikz@@matrix#1@}% -\def\tikz@@matrix#1@{\do@rows#1\\@\\}% -\def\do@rows#1\\{% - \ifx#1@% - \else% - \setcounter{r}{0}% - \do@columns#1&@&% - \pgftransformshift{\pgfpointxy{-\ther}{-1}}% - \expandafter\do@rows% - \fi}% -\def\do@columns#1&{% - \if#1@% - \else% - \stepcounter{r}% - \pgftransformshift{\pgfpointxy{1}{0}}% - #1;% - \expandafter\do@columns% - \fi}% -\makeatother diff --git a/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgf.tex b/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgf.tex index eab81dec5b4..333d7c3d14a 100644 --- a/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgf.tex +++ b/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgf.tex @@ -10,6 +10,10 @@ % ConTeXt module pgf. +\writestatus{loading}{ConTeXt User Module / pgf} + +\unprotect + \ifx\pgfdefined\undefined \let\pgfdefined=\relax @@ -24,4 +28,7 @@ \fi -\endinput
\ No newline at end of file +\stopmodule + +\protect +\endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgfbim.tex b/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgfbim.tex index 7e1cad0623f..943a34cf833 100644 --- a/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgfbim.tex +++ b/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgfbim.tex @@ -9,7 +9,14 @@ % ConTeXt module pgfbaseimage. +\writestatus{loading}{ConTeXt User Module / pgfbim} + +\unprotect + \PackageWarning{pgf}{This module is obsolete and no longer needed} -\endinput
\ No newline at end of file +\stopmodule + +\protect +\endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgfcor.tex b/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgfcor.tex index 172019d86da..975bfc252ca 100644 --- a/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgfcor.tex +++ b/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgfcor.tex @@ -9,6 +9,10 @@ % ConTeXt module pgfcore. +\writestatus{loading}{ConTeXt User Module / pgfcor} + +\unprotect + \ifx\pgfcoredefined\undefined @@ -50,4 +54,7 @@ \fi +\stopmodule + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/frontendlayer/t-tikz.tex b/Master/texmf-dist/tex/context/third/pgf/frontendlayer/t-tikz.tex index d3fc269d385..85c6fcf2f0b 100644 --- a/Master/texmf-dist/tex/context/third/pgf/frontendlayer/t-tikz.tex +++ b/Master/texmf-dist/tex/context/third/pgf/frontendlayer/t-tikz.tex @@ -9,6 +9,10 @@ % ConTeXt module tikz. +\writestatus{loading}{ConTeXt User Module / tikz} + +\unprotect + % \input xkeyval.tex % no longer used/needed @@ -31,4 +35,7 @@ \let\starttikzpicture=\tikzpicture \let\stoptikzpicture=\endtikzpicture -\endinput
\ No newline at end of file +\stopmodule + +\protect +\endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/math/t-pgfmat.tex b/Master/texmf-dist/tex/context/third/pgf/math/t-pgfmat.tex index 45fc7606906..bdc8e6569de 100644 --- a/Master/texmf-dist/tex/context/third/pgf/math/t-pgfmat.tex +++ b/Master/texmf-dist/tex/context/third/pgf/math/t-pgfmat.tex @@ -9,6 +9,10 @@ % ConTeXt module pgfmath. +\writestatus{loading}{ConTeXt User Module / pgfmath} + +\unprotect + \ifx\pgfmathdefined\undefined \let\pgfmathdefined=\relax @@ -28,4 +32,7 @@ \fi -\endinput
\ No newline at end of file +\stopmodule + +\protect +\endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/systemlayer/t-pgfsys.tex b/Master/texmf-dist/tex/context/third/pgf/systemlayer/t-pgfsys.tex index 8b2453b094f..5d78653282e 100644 --- a/Master/texmf-dist/tex/context/third/pgf/systemlayer/t-pgfsys.tex +++ b/Master/texmf-dist/tex/context/third/pgf/systemlayer/t-pgfsys.tex @@ -9,6 +9,10 @@ % ConTeXt module pgfsys. +\writestatus{loading}{ConTeXt User Module / pgfsys} + +\unprotect + \ifx\pgfsysdefined\undefined \let\pgfsysdefined=\relax @@ -32,4 +36,7 @@ \fi -\endinput
\ No newline at end of file +\stopmodule + +\protect +\endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfcal.tex b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfcal.tex index 8d74ee6db5a..4651a99cf96 100644 --- a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfcal.tex +++ b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfcal.tex @@ -8,6 +8,10 @@ % See the file doc/generic/pgf/licenses/LICENSE for more details. % ConTeXt module pgfcalendar. +\writestatus{loading}{ConTeXt User Module / pgfcalendar} + +\unprotect + \ifx\pgfcalendardefined\undefined \let\pgfcalendardefined=\relax @@ -26,4 +30,7 @@ \fi +\stopmodule + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgffor.tex b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgffor.tex index 8fea962d972..390e9dccde2 100644 --- a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgffor.tex +++ b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgffor.tex @@ -8,6 +8,10 @@ % See the file doc/generic/pgf/licenses/LICENSE for more details. % ConTeXt module pgffor. +\writestatus{loading}{ConTeXt User Module / pgffor} + +\unprotect + \ifx\pgffordefined\undefined \let\pgffordefined=\relax @@ -27,4 +31,7 @@ \fi -\endinput
\ No newline at end of file +\stopmodule + +\protect +\endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfkey.tex b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfkey.tex index dbc393a8276..291384bc58f 100644 --- a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfkey.tex +++ b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfkey.tex @@ -8,6 +8,10 @@ % See the file doc/generic/pgf/licenses/LICENSE for more details. % ConTeXt module pgfkeys. +\writestatus{loading}{ConTeXt User Module / pgfkey} + +\unprotect + \ifx\pgfkeysdefined\undefined \let\pgfkeysdefined=\relax @@ -24,4 +28,7 @@ \fi -\endinput
\ No newline at end of file +\stopmodule + +\protect +\endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfmod.tex b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfmod.tex index ab7b456f5c7..d8c0fa39c8d 100644 --- a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfmod.tex +++ b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfmod.tex @@ -8,6 +8,10 @@ % See the file doc/generic/pgf/licenses/LICENSE for more details. +\writestatus{loading}{ConTeXt User Module / pgfmodules} + +\unprotect + % ConTeXt module pgfmodules. @@ -41,4 +45,7 @@ \fi -\endinput
\ No newline at end of file +\stopmodule + +\protect +\endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfrcs.tex b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfrcs.tex index a0a12dd47be..b4bb290b164 100644 --- a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfrcs.tex +++ b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfrcs.tex @@ -8,6 +8,10 @@ % See the file doc/generic/pgf/licenses/LICENSE for more details. % ConTeXt module pgfrcs. +\writestatus{loading}{ConTeXt User Module / pgfrcs} + +\unprotect + \ifx\pgfrcsdefined\undefined \let\pgfrcsdefined=\relax @@ -32,4 +36,7 @@ \fi -\endinput
\ No newline at end of file +\stopmodule + +\protect +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex index 19e73e0b44e..d0fdab957aa 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex @@ -1,4 +1,4 @@ -% Copyright 2006 by Till Tantau +% Copyright 2006, 2013 by Till Tantau % % This file may be distributed and/or modified % @@ -7,406 +7,1061 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorearrows.code.tex,v 1.11 2008/04/23 14:59:01 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorearrows.code.tex,v 1.40 2013/11/07 15:45:46 tantau Exp $ -% Sets the end arrow + +% Define a new (meta) arrow or a shorthand % -% #1 = An arrow name +% #1 = key--value pairs % -% Example: +% Description: % -% \pgfsetarrowsend{stealth} - -\def\pgfsetarrowsend#1{\pgf@arrowset{end}{#1}} -\def\pgf@arrowset#1#2{% - \pgfutil@ifundefined{pgf@arrow@code@#2} - {\PackageError{pgf}{Arrow #1 type ``#2'' unknown}{}} - {% - \edef\pgf@arrow@temp{#2}% - \ifx\pgf@arrow@temp\pgfutil@empty% ah. clear! - \expandafter\let\csname pgf@#1arrow\endcsname=\pgfutil@empty% - \expandafter\let\csname pgf@shorten@#1\endcsname=\pgfutil@empty% +% This command is used to define a new arrow tip kind. For more +% details on the description of the keys, please see the pgfmanual. +% +% name = Name of the arrow. If the name contains a dash +% (hyphen), the text before the hyphen is the start name +% and the text behind it the end name. +% +% means = If set, none of the below options may be +% given. The effect is that whenever the arrow is +% used, it gets replaced by this "text", which is +% parsed by the parser. +% +% setup code = Code that does "precomputations". These will be +% executed only once for each combination of the +% dependencies. At the end of this code, you can use +% \savethe and \save to "save" computed values, which +% will then be available inside the "code". Values needed +% only for the "... end" keys and the convex hull do not +% need to be saved since these are also executed only +% once. +% drawing code = Code for drawing the arrow. When the cache key is set to +% true, which is the default, the code will be protocolled +% and the resulting code is inserted using \pgflowlevelobj. +% cache = Boolean that decides whether the arrow can be cached. The +% default is true, so you have to say cache=false to switch +% caching off. In this case, each time the arrow is drawn, +% its code is simply executed. This allows you to put things +% like text or shadings in arrow tips. +% bending mode = Can be set to "orthogonal", "polar", or +% "none". Defaults to "orthogonal". +% defaults = A list of "default" options for the arrow tip. These +% are executed as if they were given to the arrow tip in +% brackets. This is useful for setting up default values. +% parameters = A list of comma-separated macro names on whose values +% the appearance of the arrow tip depends. When an arrow +% tip is used, these macros are expanded. If an +% arrow tip was already installed with the same macro +% names (and caching is true), the cached code is +% used. Note that when you use dimensions here, add \the. +% +% Inside the setup code, the following macros are available: +% +% \pgfarrowsettipend +% The code should draw an arrow pointing "right along the x +% axis". The "tip" key specifies how far the arrow goes +% along the x axis, that is, it should be the x coordinate +% of the very tip of the arrow. In previous versions this +% was called the "right extend". The value passed to this +% key should be some code that sets the dimension +% "\pgfarrowresult", which is \let to be equal to +% \pgf@x. A \relax will be added after the code provided +% here, so you can write things like "\pgfarrowresult=1pt". +% \pgfarrowsetbackend +% The leftmost x-coordinate that is still part of the +% arrow tip (the "back end" of the arrow"). This coordinate +% will be used when multiple arrow tips are +% composed. Defaults to 0pt. +% \pgfarrowsetlineend +% The x-coordinate where a line should stop inside the arrow +% tip so that it gets "obscured" by the arrow. Defaults to 0pt. +% \pgfarrowsetvisualtipend +% When the arrow tip is drawn in flex mode, it is rotated +% such that the x-coordinates of "visual tip end" and "visual +% back end" lie on the path. Defaults to \pgfarrowsettipend. +% \pgfarrowsetvisualbackend +% See above. Defaults to \pgfarrowsetbackend + +\def\pgfdeclarearrow#1{% + \let\pgf@decl@arrow@defaults\pgfutil@empty% + \let\pgf@decl@arrow@means\relax% + \let\pgf@decl@arrow@code\relax% + \pgfkeys{/pgf/@arrows decl/.cd, + name=, + setup code=, + cache=true, + bending mode=orthogonal, + parameters=,% + #1% + }% + \ifx\pgf@decl@arrow@name@end\pgfutil@empty% + \pgferror{Declaring unnamed arrow}% + \else% + \pgf@arrow@letter{name@end}% + \pgf@arrow@letter{name@start}% + \expandafter\let\csname pgf@ar@start@\pgf@decl@arrow@name@start\endcsname\pgf@decl@arrow@name@end% + \expandafter\let\expandafter\pgf@old@code\csname pgf@ar@code@\pgf@decl@arrow@name@end\endcsname% + \expandafter\let\expandafter\pgf@old@means\csname pgf@ar@means@\pgf@decl@arrow@name@end\endcsname% + \ifx\pgf@decl@arrow@code\relax% + \ifx\pgf@decl@arrow@means\relax% + \pgferror{You must set either the 'means' or the drawing code' keys for arrow tip '\pgf@decl@arrow@name@end'}% + \else% + \ifx\pgf@old@code\relax% + \let\pgf@arrow@tip@sequence\pgfutil@empty% + \let\pgf@arrow@translate\relax% + \expandafter\let\expandafter\pgf@arrows@direct\csname pgf@arrows@direct@name@end@\pgf@decl@arrow@means\endcsname% + \ifx\pgf@arrows@direct\relax% + \let\pgf@arrows@options\pgfutil@empty% + \expandafter\pgfarrows@initial@parser\pgf@decl@arrow@means[]\pgf@stop% + \else% + \let\pgf@arrow@tip@sequence\pgf@arrows@direct% + \fi% + \pgf@arrow@letter@\pgf@arrow@tip@sequence{means}% + \expandafter\let\csname pgf@ar@code@\pgf@decl@arrow@name@end\endcsname\relax% + \else% + \pgferror{Arrow tip '\pgf@decl@arrow@name@end' was already + defined with key 'drawing code' previously and you cannot change this}% + \fi% + \fi% \else% - %\pgf@arrow@prepare{#2}% - \expandafter\def\csname pgf@#1arrow\endcsname{\pgf@arrow@call{#2}}% - \expandafter\edef\csname pgf@shorten@#1\endcsname{\expandafter\noexpand\csname pgf@arrow@right@#2\endcsname}% + \ifx\pgf@decl@arrow@means\relax% + \ifx\pgf@old@means\relax% + \pgf@arrow@letter{code}% + \pgf@arrow@letter{defaults}% + \pgf@arrow@letter{setup}% + \pgf@arrow@letter{bending@mode}% + \pgf@arrow@letter{par}% + \expandafter\let\csname pgf@ar@do@cache@\pgf@decl@arrow@name@end\endcsname\pgf@decl@arrow@cache% + \else% + \pgferror{Arrow tip '\pgf@decl@arrow@name@end' was already + defined with key 'means' previously and you cannot change this}% + \fi% + \else% + \pgferror{You cannot set both the 'means' and also the 'drawing code' + keys for arrow tip '\pgf@decl@arrow@name@end'}% + \fi% \fi% + \fi% +} + +\def\pgf@arrow@letter#1{% + \expandafter\pgf@arrow@letter@\expandafter{\csname pgf@decl@arrow@#1\endcsname}{#1}% +} +\def\pgf@arrow@letter@#1#2{% + \expandafter\let\csname pgf@ar@#2@\pgf@decl@arrow@name@end\endcsname#1% +} + +\pgfkeys{ + /pgf/@arrows decl/.cd, + name/.code={% + \pgfutil@in@-{#1}% + \ifpgfutil@in@% + \pgf@arrows@name@decomp#1\pgf@stop% + \else% + \def\pgf@decl@arrow@name@end{#1}\let\pgf@decl@arrow@name@start\pgf@decl@arrow@name@end% + \fi}, + means/.store in=\pgf@decl@arrow@means, + setup code/.store in=\pgf@decl@arrow@setup, + drawing code/.store in=\pgf@decl@arrow@code, + cache/.store in=\pgf@decl@arrow@cache, + bending mode/.is choice, + bending mode/none/.code=\let\pgf@decl@arrow@bending@mode\pgfutil@empty, + bending mode/orthogonal/.code=\def\pgf@decl@arrow@bending@mode{\pgfpointcurvilinearbezierorthogonal}, + bending mode/polar/.code=\def\pgf@decl@arrow@bending@mode{\pgfpointcurvilinearbezierpolar}, + parameters/.store in=\pgf@decl@arrow@par, + defaults/.code={% + \let\pgf@arrows@options\pgfutil@empty% + \pgfkeys{/pgf/arrow keys/.cd,#1}% + \let\pgf@decl@arrow@defaults\pgf@arrows@options% + } +} + +\def\pgf@arrows@name@decomp#1-#2\pgf@stop{% + \def\pgf@decl@arrow@name@start{#1}% + \def\pgf@decl@arrow@name@end{#2}% +} + + +% Handler for defining arrow tips: +% +% Description: +% +% When you write "my name/.tip = arrow spec", this has the same +% effect as writeing \pgfdeclarearrow{name = my name, means = arrow spec}. + +\pgfkeys{/handlers/.tip/.code=% + \expandafter\expandafter\expandafter\pgf@arrows@unravel\pgfkeyscurrentpath/\pgf@stop% + \expandafter\pgf@arrows@key@call\expandafter{\pgf@arrows@unravelled}{#1}} +\def\pgf@arrows@unravel#1/{\pgfutil@ifnextchar\pgf@stop{\def\pgf@arrows@unravelled{#1}\pgfutil@gobble}{\pgf@arrows@unravel}} +\def\pgf@arrows@key@call#1#2{\pgfdeclarearrow{name={#1},means={#2}}} + + + + +% Draw an arrow +% +% #1 = arrow specification +% +% Description: +% +% Draws the arrow in the given specification (and "end" +% specification). The arrow will be drawn such that it touches the +% origin "from the left", that is, the arrow will lie completely in +% the half plane with negative $x$ values and the tip will end exactly +% at the origin. + +\def\pgfarrowdraw#1{% + {% + \pgfsetarrowsend{#1}% + \pgf@arrow@compute@shortening\pgf@end@tip@sequence% + \pgf@arrow@draw@arrow\pgf@end@tip@sequence\pgf@xb% }% } -% Sets the start arrow -% -% #1 = An arrow name -% -% Example: -% -% \pgfsetarrowsstart{stealth} -\def\pgfsetarrowsstart#1{\pgf@arrowset{start}{\csname pgf@arrows@invert#1\endcsname}} +% Compute the length of an arrow +% +% #1 = arrow specification +% +% Description: +% +% In \pgf@x, this will return the total length of the arrow given as +% #1, in \pgf@xa it will return the distance from the tip to the line +% end. + +\def\pgfarrowtotallength#1{% + {% + \pgfsetarrowsend{#1}% + \pgf@arrow@compute@shortening\pgf@end@tip@sequence% + \expandafter\expandafter\expandafter% + }% + \expandafter\expandafter\expandafter\pgf@x\expandafter\the\expandafter\pgf@xb\expandafter\pgf@xa\the\pgf@xa% +} -\def\pgf@arrows@invname#1#2{\expandafter\def\csname pgf@arrows@invert#1\endcsname{#2}} -\pgf@arrows@invname{}{} -% Sets arrows +% Sets the end arrow tip % -% #1 = An arrow specification of the form ``left''-``right''. The last -% and right should be arrow types that have been defined using -% the \pgfarrowsdef command +% #1 = An arrow specification % -% Example: +% Description: +% +% An "arrow specification" is a sequence of names of meta arrow tips +% together with options in brackets. In detail: +% +% In #1, consider the text from the start up to the first bracket. If +% this text is the name of a (meta) arrow tip, we use this arrow tip +% with the provided options. If it is the name of a arrow tip +% shorthand, this shorthand is expanded and the options are applied to +% each arrow tip inside the shorthand. If the text is neither or the +% above, the first letter of text is treated as a shorthand without +% options. +% +% The special arrow tip "." is used to indicate the end of the line. % -% \pgfsetarrows{-to} +% \pgfsetarrowsend{stealth[reversed]} +% \pgfsetarrowsend{stealth[length=1pt] . stealth[length=2pt]} +% \pgfsetarrowsend{>>>} +% \pgfsetarrowsend{>.>} + +\def\pgfsetarrowsend#1{% + \let\pgf@arrow@tip@sequence\pgfutil@empty% + \pgf@arrows@translatefalse% + \expandafter\let\expandafter\pgf@arrows@direct\csname pgf@arrows@direct@name@end@#1\endcsname% + \ifx\pgf@arrows@direct\relax% + \edef\pgf@marshal{\noexpand\pgfarrows@initial@parser#1[]\noexpand\pgf@stop}% + \pgf@marshal% + \else% + \let\pgf@arrow@tip@sequence\pgf@arrows@direct% + \fi% + \let\pgf@end@tip@sequence\pgf@arrow@tip@sequence% +} -\def\pgfsetarrows#1{\pgf@arrows#1\pgf@stop} -\def\pgf@arrows#1-#2\pgf@stop{% - \pgfsetarrowsstart{#1} - \pgfsetarrowsend{#2} +\newif\ifpgf@arrows@translate + +\def\pgfarrows@initial@parser{% + \pgfutil@ifnextchar[\pgfarrows@initial@parser@{\pgfarrows@initial@parser@[]}}%} + +\def\pgfarrows@initial@parser@[#1]{% + \let\pgf@arrows@options\pgfutil@empty% + \pgfkeys{/pgf/arrow keys/.cd,#1}% + \let\pgf@arrows@options@initial\pgf@arrows@options% + \pgfarrows@parser% } -\def\pgf@arrows@checked#1#2#3{% - \pgfutil@ifundefined{pgf@arrow@code@#2}% - {% - \PackageError{pgf}{Arrow end type ``#2'' unknown}{}}% - {% - \pgfutil@ifundefined{pgf@arrow@code@\csname pgf@arrows@invert#1\endcsname} - {\PackageError{pgf}{Arrow start type ``#1'' unknown}{}}% - {#3}% - }% +\def\pgfarrows@parser#1[{% + \pgfkeys@spdef\pgf@temp{#1}% + \ifx\pgf@temp\pgfutil@empty% + \let\pgf@next\pgf@arrows@empty% + \else% + \ifx\pgf@temp\pgf@dot@text% + \let\pgf@next\pgf@arrows@dot@parsed% + \else% + \let\pgf@untranslated\pgf@temp% + \ifpgf@arrows@translate% + \pgf@arrow@swapper% + \fi% + % Now, let's see what we do with this... + \expandafter\ifx\csname pgf@ar@code@\pgf@temp\endcsname\relax + \expandafter\ifx\csname pgf@ar@means@\pgf@temp\endcsname\relax + % #1 should start with a single-char shorthands + \let\pgf@next\pgf@arrows@single@char@parser% + \let\pgf@temp\pgf@untranslated% + \else% + % #1 is a shorthand! + \let\pgf@next\pgf@arrows@shorthand@parsed% + \fi% + \else% + % #1 is a meta arrow! + \let\pgf@next\pgf@arrows@meta@parsed% + \fi% + \fi% + \fi% + \expandafter\pgf@next\pgf@temp[% +} + +\def\pgf@arrows@empty[#1]{% + \pgfutil@ifnextchar\pgf@stop\pgf@arrows@parser@done\pgfarrows@parser% +} + +\def\pgf@arrows@single@char@parser#1{% + \def\pgf@temp{#1}% + \ifx\pgf@temp\pgf@dot@text% + \let\pgf@next\pgf@arrows@dot@parsed% + \else% + \let\pgf@untranslated\pgf@temp% + \ifpgf@arrows@translate% + \pgf@arrow@swapper% + \fi% + \expandafter\ifx\csname pgf@ar@code@\pgf@temp\endcsname\relax + \expandafter\ifx\csname pgf@ar@means@\pgf@temp\endcsname\relax + \let\pgf@temp\pgf@untranslated% + \let\pgf@next\pgf@arrows@unknown% + \else% + \let\pgf@next\pgf@arrows@shorthand@parsed% + \fi% + \else% + \let\pgf@next\pgf@arrows@meta@parsed% + \fi + \fi + \expandafter\pgf@next\pgf@temp[]% +} +\def\pgf@arrows@unknown#1[]#2[#3]{% + \pgferror{Unknown arrow tip kind '#1#2'}% } -\def\pgf@arrows@check@already#1#2#3{% - \pgfutil@ifundefined{pgf@arrow@code@#2} - {#3}% - {\PackageError{pgf}{Arrow end type ``#2'' already defined}{}}% +\def\pgf@arrows@meta@parsed#1[#2]{% + % Ok, run the keys #2. This will add commands to \pgf@arrows@options: + % + \let\pgf@arrows@options\pgf@arrows@options@initial% + \pgfkeys{/pgf/arrow keys/.cd,#2}% + % Append the arrow and its options to the arrow tip sequence: + \expandafter\pgf@arrows@meta@set\expandafter{\pgf@arrows@options}{#1}{\pgf@arrow@handle}% + \pgfutil@ifnextchar\pgf@stop\pgf@arrows@parser@done\pgfarrows@parser% } +\def\pgf@arrows@parser@done#1{% +} -% Called when an arrow needs to be rendered +\def\pgf@arrows@dot@parsed#1[#2]{% + \pgf@arrows@append@to@tips{\pgf@arrow@handle@dot}% + \pgfutil@ifnextchar\pgf@stop\pgf@arrows@parser@done\pgfarrows@parser% +} -\def\pgf@arrow@call#1{% - \expandafter\ifx\csname\pgf@arrow@full@name{#1}\endcsname\relax% - \pgfsysprotocol@getcurrentprotocol\pgf@arrow@temp% - {% - \pgfinterruptpath% - \let\pgfusepath=\pgf@nousepath@here% - \pgf@relevantforpicturesizefalse% - \pgftransformreset% - \pgfsysprotocol@setcurrentprotocol\pgfutil@empty% - \pgfsysprotocol@bufferedtrue% - \pgfsys@beginscope% - \csname pgf@arrow@code@#1\endcsname% - \pgfsys@endscope% - \pgfsysprotocol@getcurrentprotocol\pgf@@arrow@temp% - \global\let\pgf@@arrow@temp=\pgf@@arrow@temp% - \endpgfinterruptpath% - \expandafter\def\expandafter\pgf@temp\expandafter{\expandafter\pgfsys@invoke\expandafter{\pgf@@arrow@temp}}% - \expandafter\global\expandafter\let\csname\pgf@arrow@full@name{#1}\endcsname=\pgf@temp% - }% - \pgfsysprotocol@setcurrentprotocol\pgf@arrow@temp% +\def\pgf@arrows@meta@set#1#2#3{% + \pgf@arrows@append@to@tips{#3{#2}{#1}}% +} +\def\pgf@arrows@append@to@tips#1{% + \let\pgf@tempa\pgf@arrow@tip@sequence% + \def\pgf@tempb{#1}% + \ifpgf@arrows@translate% + \let\pgf@tempa\pgf@tempb% + \let\pgf@tempb\pgf@arrow@tip@sequence% + \fi% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgf@arrow@tip@sequence% + \expandafter\expandafter\expandafter{\expandafter\pgf@tempa\pgf@tempb}% +} + +\def\pgf@arrows@shorthand@parsed#1[#2]{% + \let\pgf@arrows@options\pgf@arrows@options@initial% + \pgfkeys{/pgf/arrow keys/.cd,#2}% + \ifx\pgf@arrows@options\pgfutil@empty% + \expandafter\pgf@arrows@append@to@tips\expandafter{% + \expandafter\pgf@arrow@handle@shorthand@empty\expandafter{\csname pgf@ar@means@#1\endcsname}}% + \else% + \expandafter\expandafter\expandafter\pgf@arrows@meta@set\expandafter\expandafter\expandafter{% + \expandafter\pgf@arrows@options\expandafter}\expandafter{\csname pgf@ar@means@#1\endcsname}{\pgf@arrow@handle@shorthand}% \fi% - \csname\pgf@arrow@full@name{#1}\endcsname% -} + \pgfutil@ifnextchar\pgf@stop\pgf@arrows@parser@done\pgfarrows@parser% +} + -\def\pgf@arrow@full@name#1{pgf@arrow@prot@#1@\the\pgflinewidth @\pgfinnerlinewidth @\pgfgetarrowoptions{#1}} +% General handler: -\def\pgf@arrow@code@{} % dummy +\def\pgf@arrow@handle@shorthand@empty#1{#1} -\def\pgf@nousepath@here#1{% - \PackageError{pgf}{The definition of an arrow may not use \string\pgfusepath}{} +\def\pgf@arrow@handle@shorthand#1#2{% + \def\pgf@temp@opt{#2}% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgf@arrows@nested@options@temp% + \expandafter\expandafter\expandafter{\expandafter\pgf@temp@opt\pgf@arrows@nested@options}% + \expandafter\let\expandafter\pgf@arrows@nested@options\expandafter\pgf@arrows@nested@options@temp% + \expandafter#1% all these expandafters to avoid creating groups, but having the options nest + \expandafter\def\expandafter\pgf@arrows@nested@options\expandafter{\pgf@arrows@nested@options}% } +\let\pgf@arrows@nested@options\pgfutil@empty + + -% Get options for an arrow + +% Sets the start arrow tip % -% #1 = arrow tip name +% #1 = An arrow specification % % Description: +% +% This works like \pgfsetarrowsend, only the order of the tips in the +% arrow specification is reversed and the "reversed names" are used. % -% For every arrow tip certain options can be set, which may influence -% the appearance of the arrow tip. How the options are used is up the -% arrow tip code. This command will expand to the current value of -% the options for this tip. The default is 0. +% \pgfsetarrowsend{<<} +% \pgfsetarrowsend{>.>} + +\def\pgfsetarrowsstart#1{% + \let\pgf@arrow@tip@sequence\pgfutil@empty% + \pgf@arrows@translatetrue% + \expandafter\let\expandafter\pgf@arrows@direct\csname pgf@arrows@direct@name@start@#1\endcsname% + \ifx\pgf@arrows@direct\relax% + \edef\pgf@marshal{\noexpand\pgfarrows@initial@parser#1[]\noexpand\pgf@stop}% + \pgf@marshal% + \else% + \let\pgf@arrow@tip@sequence\pgf@arrows@direct% + \fi% + \let\pgf@start@tip@sequence\pgf@arrow@tip@sequence% +} -\def\pgfgetarrowoptions#1{% - \expandafter\ifx\csname pgf@arrow@opt@#1\endcsname\relax0\else\csname pgf@arrow@opt@#1\endcsname\fi% +\def\pgf@arrow@swapper{% + \expandafter\let\expandafter\pgf@temp\csname pgf@ar@start@\pgf@temp\endcsname% + \ifx\pgf@temp\relax% + \def\pgf@temp{undefined}% + \fi% } +\let\pgf@start@tip@sequence\pgfutil@empty +\let\pgf@end@tip@sequence\pgfutil@empty + + +\expandafter\def\csname pgf@arrows@direct@name@start@\endcsname{} +\expandafter\def\csname pgf@arrows@direct@name@end@\endcsname{} + + +% Predefined lengths and ifs + +\newdimen\pgfarrowsep + +\newif\ifpgfarrowswap +\newif\ifpgfarrowreversed +\newif\ifpgfarrowharpoon +\newif\ifpgfarrowopen + +\let\pgf@arrows@stroke@color\pgfutil@empty +\let\pgf@arrows@fill@color\pgfutil@empty + +\def\pgfarrows@length@scale{1} +\def\pgfarrows@width@scale{1} +\def\pgfarrows@slant{0} + +\let\pgfarrows@scale@list\pgfutil@empty +\def\pgfarrowsaddtolengthscalelist#1{\expandafter\def\expandafter\pgfarrows@scale@list\expandafter{\pgfarrows@scale@list#1\pgfarrows@length@scale#1}} +\def\pgfarrowsaddtowidthscalelist#1{\expandafter\def\expandafter\pgfarrows@scale@list\expandafter{\pgfarrows@scale@list#1\pgfarrows@width@scale#1}} + +\pgfkeys{ + /pgf/arrow keys/.cd, + scale/.code={% + \pgfmathparse{#1}% + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@length@scale\expandafter{\pgfmathresult}}% + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@width@scale\expandafter{\pgfmathresult}}% + }, + scale length/.code={\pgfmathparse{#1}\expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@length@scale\expandafter{\pgfmathresult}}}, + scale width/.code={\pgfmathparse{#1}\expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@width@scale\expandafter{\pgfmathresult}}}, + slant/.code={\pgfmathparse{#1}\expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@slant\expandafter{\pgfmathresult}}}, + sep/.code={ + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\pgfarrowslinewidthdependent\pgfarrowstheparameters\pgfarrowsep\pgf@x}% + }, + sep/.default=0.88pt .3 1, + % + swap/.code=\pgfarrowsaddtooptions{\ifpgfarrowswap\pgfarrowswapfalse\else\pgfarrowswaptrue\fi}, + reversed/.code=\pgfarrowsaddtooptions{\ifpgfarrowreversed\pgfarrowreversedfalse\else\pgfarrowreversedtrue\fi}, + harpoon/.is choice, + harpoon/.default=true, + harpoon/true/.code=\pgfarrowsaddtooptions{\pgfarrowharpoontrue}, + harpoon/false/.code=\pgfarrowsaddtooptions{\pgfarrowharpoonfalse}, + left/.style={harpoon}, + right/.style={harpoon,swap}, + % + color/.code=\pgfarrowsaddtooptions{\def\pgf@arrows@stroke@color{#1}}, + fill/.code={% + \def\pgf@temp{#1}% + \ifx\pgf@temp\pgf@nonetext% + \pgfarrowsaddtooptions{\pgfarrowopentrue} + \else + \pgfarrowsaddtooptions{\pgfarrowopenfalse\def\pgf@arrows@fill@color{#1}} + \fi + }, + fill/.value required, + open/.style={fill=none}, + .unknown/.code={ + \expandafter\pgfutil@in@\expandafter!\expandafter{\pgfkeyscurrentname}% + \ifpgfutil@in@% + % this is a color! + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgf@arrows@stroke@color\expandafter{\pgfkeyscurrentname}}% + \else% + \pgfutil@doifcolorelse{\pgfkeyscurrentname} + {% + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgf@arrows@stroke@color\expandafter{\pgfkeyscurrentname}}% + } + {% + \edef\pgf@temp{\pgfkeyscurrentname}% + \pgfkeys{/errors/unknown key/.expand once=\expandafter{\pgf@temp}{#1}}% + } + \fi + } +} +\def\pgf@nonetext{none} -% Set options for an arrow -% -% #1 = arrow tip name -% #2 = options -% -% Description: -% -% Sets the arrow tip options for an arrow. The options should be a -% normal string and will be used to detect whether an arrow should be -% recached. For instance, when you set the arrow tip options of -% "myarrow" to "1", the arrow will be rendered in a certain way. Then, -% when you set the options to "2", the arrow will be rerendered. +\def\pgfarrowsaddtooptions#1{\expandafter\def\expandafter\pgf@arrows@options\expandafter{\pgf@arrows@options#1}} +\def\pgfarrowsaddtolateoptions#1{\expandafter\def\expandafter\pgf@arrows@options\expandafter{\pgf@arrows@options\pgf@arrows@add@to@late@options{#1}}} +\def\pgf@arrows@add@to@late@options#1{\expandafter\def\expandafter\pgf@arrows@late@options\expandafter{\pgf@arrows@late@options#1}} -\def\pgfsetarrowoptions#1#2{% - \expandafter\def\csname pgf@arrow@opt@#1\endcsname{#2}% + + +\def\pgfarrowsthreeparameters#1{% + \pgfarrowsthreeparameters@#1 +0 +0 +0 \pgf@stop% +} +\def\pgfarrowsthreeparameters@#1 #2 #3 #4\pgf@stop{% + \pgfmathsetlength\pgf@x{#1}% + \pgfmathsetmacro\pgf@temp@a{#2}% + \pgfmathsetmacro\pgf@temp@b{#3}% + \edef\pgfarrowstheparameters{{\the\pgf@x}{\pgf@temp@a}{\pgf@temp@b}}% } +\def\pgfarrowsfourparameters#1{% + \pgfarrowsfourparameters@#1 +0 +0 +0 \pgf@stop% +} +\def\pgfarrowsfourparameters@#1:#2 #3 #4 #5\pgf@stop{% + \pgfmathsetmacro\pgf@temp@z{#1}% + \pgfmathsetlength\pgf@x{#2}% + \pgfmathsetmacro\pgf@temp@a{#3}% + \pgfmathsetmacro\pgf@temp@b{#4}% + \edef\pgfarrowstheparameters{{\pgf@temp@z}{\the\pgf@x}{\pgf@temp@a}{\pgf@temp@b}}% +} +\def\pgfarrows@angle@setup#1#2#3#4{% + \pgfarrowslinewidthdependent{#2}{#3}{#4} + \pgf@xc\pgf@x + \pgf@yc#1 pt% + \pgf@yc.5\pgf@yc% + \pgfpointpolar{\pgf@yc}{\pgf@xc} + \pgfarrowlength\pgf@x% + \pgf@y2\pgf@y% + \expandafter\pgf@arrows@add@to@late@options\expandafter{\expandafter\pgfarrowwidth\the\pgf@y}% +} +\def\pgfarrows@angle@setup@prime#1{% + \pgf@yc#1 pt% + \pgfmathtan@{.5\pgf@yc}% + \pgfarrowwidth\pgfmathresult\pgfarrowlength% + \pgfarrowwidth2\pgfarrowwidth% +} -% Define an arrow type. -% -% #1 = name or mnemonic for arrow when used at the start (examples: ``to'' or ``<'') -% #2 = name or mnemonic for arrow when used at the end (examples: ``to'' or ``>'') -% #3 = code to setup the left and right extend of the arrow. To set -% the left extend, call \pgfarrowsleftextend, for the right \pgfarrowsrightextend. -% #4 = protocolable code -% -% Description: -% -% When you define an arrow using this command, you must give two -% names. The first is used for the arrow when it is ``at the start'', -% the other when it is at the end. For example, a simple arrow might -% have the names ``<'' and ``>'', though these particular names are -% not used by pgf and left for the user. -% -% The code should be ``protocolable'' code. This means that it uses -% only pretty simple commands. -% -% The arrow code will be protocolled once for each line width at which -% the arrow is used. Thus, the code can (and often should) depend on -% the line width. -% -% The arrow should ``point right'' in the coordinate system. The end -% of the line at which the arrow should be drawn will be at the origin -% of the coordinate system. The coordinate system will be scaled and -% rotated appropriately before the arrow is drawn. -% -% The right extend of the arrow should be set to how much the arrow -% ``protrudes over the right''. Prior to drawing the arrow, the line -% will be shortened by this amount so that the arrow tip will exactly -% touch the original right end of the unshortened line. -% -% The left extend specifies the leftmost point of the arrow. This is -% important only if you use the swapping command, when this end is -% used to compute the shortening. -% -% The definition of an arrow should normally take care of the fact -% that the line cap of the main line may be a butt cap, a round cap or -% a rect cap. In all cases, the arrow should ``cover'' the cap -% completely or not at all. -% -% Example: -% -% \pgfarrowsdeclare{stealth}{stealth} -% { -% \pgfarrowsleftextend{-6\pgflinewidth} -% \pgfarrowsrightextend{2\pgflinewidth} -% { -% \pgfpathmoveto{\pgfpoint{2\pgflinewidth}{0pt}} -% \pgfpathlineto{\pgfpoint{-6\pgflinewidth}{4\pgflinewidth}} -% \pgfpathlineto{\pgfpoint{-3\pgflinewidth}{0pt}} -% \pgfpathlineto{\pgfpoint{-6\pgflinewidth}{-4\pgflinewidth}} -% \pgfusepathqfill -% } +\def\pgfarrowslinewidthdependent#1#2#3{% + \pgf@x#1% + \ifdim\pgfinnerlinewidth>0pt% + \pgf@arrows@inner@line@width@dep{#2}{#3}% + \else% + \advance\pgf@x by#2\pgflinewidth% + \fi% +} +\def\pgf@arrows@inner@line@width@dep#1#2{% + % #1*((1-#2/2)*full line width - (#2/2) * inner line width) + % Compute "real" line width + \pgf@xa\pgflinewidth% + \pgf@xb-.5\pgflinewidth% + \pgf@xb#2\pgf@xb% + \advance\pgf@xa by\pgf@xb% + \pgf@xb\pgfinnerlinewidth% + \pgf@xb-.5\pgf@xb + \advance\pgf@xa by#2\pgf@xb% + \advance\pgf@x by#1\pgf@xa% +} -\def\pgfarrowsdeclare#1#2#3#4{% - \pgf@arrows@check@already{#1}{#2} - {% - \expandafter\def\csname pgf@arrow@code@#2\endcsname{#4}% - \expandafter\def\csname pgf@arrow@left@#2\endcsname{#3\advance\pgf@x by-\pgf@xa}% - \expandafter\def\csname pgf@arrow@right@#2\endcsname{#3\advance\pgf@x by\pgf@xb}% - \pgf@arrows@invname{#1}{#2}% - }% + +\def\pgfarrowslengthdependent#1#2#3#4{% + #4#1% + \advance#4by#2\pgfarrowlength% + \advance#4by#3\pgflinewidth% } -\def\pgfarrowsleftextend#1{\pgfmathsetlength\pgf@xa{#1}} -\def\pgfarrowsrightextend#1{\pgfmathsetlength\pgf@xb{#1}} -\def\pgf@arrows@repeat#1#2{% - \edef\pgf@arrows@marshal{\noexpand\let\expandafter\noexpand\csname#2\endcsname=\expandafter\noexpand\csname#1\endcsname}% - \pgf@arrows@marshal} +% Build the full name: +\def\pgf@arrow@fullname#1{pgf@@ar@#1@\the\pgflinewidth @\pgfinnerlinewidth @\ifpgfarrowreversed r\fi @\pgf@arrows@stroke@color @\pgf@arrows@fill@color @\csname pgf@ar@par@#1\endcsname} +\def\pgf@arrow@id@count{0}% -% Declare a new arrow type to be the same as another one. -% -% #1 = name of new start -% #2 = name or new end -% #3 = name or old start -% #4 = name or old end -% -% Example: -% -% \pgfarrowsdeclarealias{<}{>}{to}{to} +% Compute the arrow id of an arrow +% +% #1 = arrow name +% #2 = options +% +% Description: +% +% Returns the an id in \pgf@arrow@id that identifies the instantiation +% of the given arrow. If the arrow was not instantiated, this happens now. + +\def\pgfarrows@getid#1#2{% + % Execute options: + \let\pgf@arrows@late@options\pgfutil@empty% + % 1. Defaults: + \csname pgf@ar@defaults@#1\endcsname% + % 2. Scope: + \pgf@arrows@options@scope + % 3. Local: + #2\relax% + % 4. Nested: + \pgf@arrows@nested@options% + % 5. Last options: + \pgf@arrows@late@options% + % 6. Scaling: + \pgfarrows@scale@list% + % Now, test: + \expandafter\global\expandafter\let\expandafter\pgf@arrow@id\csname\pgf@arrow@fullname{#1}\endcsname\relax% + \ifx\pgf@arrow@id\relax% + \pgf@arrows@instantiate{#1} + \fi% +} -\def\pgfarrowsdeclarealias#1#2#3#4{% - \pgf@arrows@check@already{#1}{#2} +\def\pgf@arrows@instantiate#1{% + % Not defined. Rats! + % Allocate new id: + \pgfutil@tempcnta\pgf@arrow@id@count\relax% + \advance\pgfutil@tempcnta by1\relax% + \xdef\pgf@arrow@id@count{\the\pgfutil@tempcnta}% + \expandafter\global\expandafter\let\csname\pgf@arrow@fullname{#1}\endcsname\pgf@arrow@id@count% + \global\let\pgf@arrow@id\pgf@arrow@id@count% {% - \pgf@arrows@checked{#3}{#4}% - {% - \pgf@arrows@repeat{pgf@arrow@code@#4}{pgf@arrow@code@#2}% - \pgf@arrows@repeat{pgf@arrow@left@#4}{pgf@arrow@left@#2}% - \pgf@arrows@repeat{pgf@arrow@right@#4}{pgf@arrow@right@#2}% - \pgf@arrows@invname{#1}{#2}% + \csname pgf@ar@setup@#1\endcsname% + % Handle reversal + \ifpgfarrowreversed% + % Compute transformation: + \pgf@arrows@handle@reverse% + \fi% + % Save computed values + \expandafter\global\expandafter\let\csname pgf@ar@saves@\pgf@arrow@id\endcsname\pgf@arrows@saves% + \expandafter\global\expandafter\let\csname pgf@ar@hull@\pgf@arrow@id\endcsname\pgf@arrows@convexhull% + \expandafter\xdef\csname pgf@ar@ends@\pgf@arrow@id\endcsname{{\pgf@arrows@the@tipend}{\pgf@arrows@the@backend}{\pgf@arrows@the@lineend}}% + \expandafter\xdef\csname pgf@ar@visual@\pgf@arrow@id\endcsname{{\pgf@arrows@the@visualtipend}{\pgf@arrows@the@visualbackend}{}}% + % Save code (needed for bending) + \edef\pgf@arrow@code{% + \ifpgfarrowreversed\noexpand\pgftransformxscale{-1}\fi% + \expandafter\noexpand\csname pgf@ar@code@#1\endcsname% }% + \expandafter\global\expandafter\let\csname pgf@ar@inst@code@\pgf@arrow@id\endcsname\pgf@arrow@code% + % Should we cache? + \expandafter\ifx\csname pgf@ar@do@cache@#1\endcsname\pgf@truetext% + \pgfsysprotocol@getcurrentprotocol\pgf@arrow@temp% + {% + \pgfinterruptpath% + \let\pgfusepath=\pgf@nousepath@here% + \pgf@relevantforpicturesizefalse% + \pgftransformreset% + \pgfsysprotocol@setcurrentprotocol\pgfutil@empty% + \pgfsysprotocol@bufferedtrue% + \pgfscope% + \pgf@arrow@code% + \endpgfscope% + \pgfsysprotocol@getcurrentprotocol\pgf@@arrow@temp% + \expandafter\gdef\expandafter\pgf@arrow@code\expandafter{\expandafter\pgfsysprotocol@literal\expandafter{\pgf@@arrow@temp}}% + \endpgfinterruptpath% + }% + \pgfsysprotocol@setcurrentprotocol\pgf@arrow@temp% + \fi% + \expandafter\global\expandafter\let\csname pgf@ar@cache@\pgf@arrow@id\endcsname\pgf@arrow@code% }% } +\def\pgf@truetext{true} + +% Ok, now run setup: +\def\pgf@arrows@copy@tipend{\pgf@arrows@the@tipend} +\def\pgf@arrows@copy@backend{\pgf@arrows@the@backend} +\def\pgf@arrows@copy@lineend{\pgf@arrows@the@lineend} +\def\pgf@arrows@zeropt{0pt}% + +\let\pgf@arrows@saves\pgfutil@empty% +\let\pgf@arrows@convexhull\pgfutil@empty% +\let\pgf@arrows@the@tipend\pgf@arrows@zeropt% +\let\pgf@arrows@the@backend\pgf@arrows@zeropt% +\let\pgf@arrows@the@lineend\pgf@arrows@zeropt% +\let\pgf@arrows@the@visualtipend\pgf@arrows@copy@tipend% +\let\pgf@arrows@the@visualbackend\pgf@arrows@copy@backend% + + +\def\pgf@arrows@handle@reverse{% + \pgf@x\pgf@arrows@the@visualtipend\pgf@x-\pgf@x% + \pgf@y\pgf@arrows@the@visualbackend\pgf@y-\pgf@y + \edef\pgf@arrows@the@visualtipend{\the\pgf@y}% + \edef\pgf@arrows@the@visualbackend{\the\pgf@x}% + \pgf@x\pgf@arrows@the@tipend\pgf@x-\pgf@x% + \pgf@y\pgf@arrows@the@backend\pgf@y-\pgf@y + \edef\pgf@arrows@the@tipend{\the\pgf@y}% + \edef\pgf@arrows@the@backend{\the\pgf@x}% + \pgf@x\pgf@arrows@the@lineend\pgf@x-\pgf@x\edef\pgf@arrows@the@lineend{\the\pgf@x}% + \let\pgf@temp\pgf@arrows@convexhull% + \let\pgf@arrows@convexhull\pgfutil@empty% + \let\pgf@arrow@hull@point\pgf@arrow@hull@point@reverse% + \pgf@temp% +} +\def\pgf@arrow@hull@point@reverse#1#2{% + \pgf@x#1% + \pgfarrowshullpoint{-\pgf@x}{#2}% +} + +\def\pgf@nousepath@here#1{\pgferror{The definition of an arrow may not use \string\pgfusepath}} + +\def\pgfarrowssavethe#1{% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgf@arrows@saves% + \expandafter\expandafter\expandafter{\expandafter\pgf@arrows@saves\expandafter#1\the#1\relax} +} +\def\pgfarrowssave#1{% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgf@arrows@saves% + \expandafter\expandafter\expandafter{\expandafter\pgf@arrows@saves\expandafter\def\expandafter#1\expandafter{#1}} +} +\def\pgfarrowshullpoint#1#2{% + \pgf@x#1\relax% + \pgf@y#2\relax% + \edef\pgf@arrows@temp{\noexpand\pgf@arrows@convexhull\noexpand\pgf@arrow@hull@point{\the\pgf@x}{\the\pgf@y}}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@arrows@convexhull\expandafter\expandafter\expandafter{\pgf@arrows@temp}% +} +\def\pgfarrowsupperhullpoint#1#2{% + \pgf@x#1\relax% + \pgf@y#2\relax% + \ifdim\pgf@y>0pt + \edef\pgf@arrows@temp{\noexpand\pgf@arrows@convexhull\noexpand\pgf@arrow@hull@point{\the\pgf@x}{\the\pgf@y}\ifpgfarrowharpoon\else\noexpand\pgf@arrow@hull@point{\the\pgf@x}{-\the\pgf@y}\fi}% + \else + \edef\pgf@arrows@temp{\noexpand\pgf@arrows@convexhull\noexpand\pgf@arrow@hull@point{\the\pgf@x}{\the\pgf@y}}% + \fi + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@arrows@convexhull\expandafter\expandafter\expandafter{\pgf@arrows@temp}% +} -% Creates a new arrows by ``swapping'' an existing arrow. -% -% #1 = name of new start -% #2 = name of new end -% #3 = name of old start -% #4 = name of old end -% -% Example: -% -% \pgfarrowsdeclarealias{]}{[}{[}{]} +\def\pgfarrowssettipend#1{\pgf@x#1\edef\pgf@arrows@the@tipend{\the\pgf@x}} +\def\pgfarrowssetbackend#1{\pgf@x#1\edef\pgf@arrows@the@backend{\the\pgf@x}} +\def\pgfarrowssetlineend#1{\pgf@x#1\edef\pgf@arrows@the@lineend{\the\pgf@x}} +\def\pgfarrowssetvisualtipend#1{\pgf@x#1\edef\pgf@arrows@the@visualtipend{\the\pgf@x}} +\def\pgfarrowssetvisualbackend#1{\pgf@x#1\edef\pgf@arrows@the@visualbackend{\the\pgf@x}} -\def\pgfarrowsdeclarereversed#1#2#3#4{% - \pgf@arrows@check@already{#1}{#2}% - {% - \pgf@arrows@checked{#3}{#4}% - {% - \expandafter\def\csname pgf@arrow@code@#2\endcsname{% - \pgflowlevel{\pgftransformxscale{-1}}% - \csname pgf@arrow@code@#4\endcsname}% - \pgf@arrows@repeat{pgf@arrow@right@#4}{pgf@arrow@left@#2}% - \pgf@arrows@repeat{pgf@arrow@left@#4}{pgf@arrow@right@#2}% - \pgf@arrows@invname{#1}{#2}% - }% - }% + +% Internal computatin of the line end (shortening) for an arrow +% +% #1 = arrow tip list +% +% Description: +% +% \pgf@xa will contain the necessary path shortening for the given +% arrow tip list, \pgf@xb will contain the total length of the arrow +% tip list (sum of the differences between tip end and back end plus +% the seps). + +\def\pgf@arrow@compute@shortening#1{% + \let\pgf@arrow@handle\pgf@arrow@compute@shortening@ + \let\pgf@arrow@handle@dot\pgf@arrow@after@line@endtrue% + \pgf@arrow@after@line@endfalse% + \pgf@xa0pt% + \pgf@xb0pt% + #1% +} +\newif\ifpgf@arrow@after@line@end + +\def\pgf@arrow@compute@shortening@#1#2{% + {\pgfarrows@getid{#1}{#2}\ifnum\pgf@arrow@flex@mode>0\relax\global\pgf@precise@shorteningtrue\fi\expandafter}\expandafter\pgf@x\the\pgfarrowsep% + \expandafter\expandafter\expandafter\pgf@arrow@cont@short\csname pgf@ar@ends@\pgf@arrow@id\endcsname% +} +\def\pgf@dot@text{.} + +\def\pgf@arrow@cont@short#1#2#3{% tip end, back end, line end, sep + \advance\pgf@xb by#1% + \pgf@xc#2% + \advance\pgf@xb by-\pgf@xc% + \advance\pgf@xb by\pgf@x% + \ifpgf@arrow@after@line@end% + \advance\pgf@xa by#1% + \advance\pgf@xa by\pgf@x% + \pgf@xc#2% + \advance\pgf@xa by-\pgf@xc% + \else% + \pgf@xa#1% + \advance\pgf@xa by\pgf@x% + \pgf@xc#3% + \advance\pgf@xa by-\pgf@xc% + \fi% } -% Creates new arrows by combining two existing arrows. -% -% #1 = optional additional space -% #2 = name of new start -% #3 = name of new end -% #4 = name of second (innermost) start -% #5 = name of second end -% #6 = name of first (outermost) start -% #7 = name of first end -% -% In the star form, the line will end at the innermost arrows, -% otherwise the line will end at the outermost arrows. -% -% Example: -% -% \pgfarrowsdeclarecombine*{|<}{>|}{|}{|}{<}{>} -% \pgfarrowsdeclarecombine{<<}{>>}{<}{>}{<}{>} -\def\pgfarrowsdeclarecombine{\pgfutil@ifnextchar*{\pgfarrowsdeclarecombine@star}{\pgf@@arrowsdeclarecombine}} +% Draw an arrow +% +% #1 = arrow tip list +% #2 = total length of the arrow (the value of \pgf@xb computed by +% \pgf@arrow@compute@shortening) +% +% Description: +% +% Draws an arrow tip list. The coordinate system must have been +% transformed so that the to-be-drawn arrow points right and should +% "end" at the origin. -\def\pgf@@arrowsdeclarecombine{\pgfutil@ifnextchar[{\pgf@arrowsdeclarecombine}{\pgf@arrowsdeclarecombine[0pt]}} -\def\pgf@arrowsdeclarecombine[#1]#2#3#4#5#6#7{% - \pgf@arrows@check@already{#2}{#3}% +\def\pgf@arrow@draw@arrow#1#2{% {% - \pgf@arrows@checked{#4}{#5}% - {% - \pgf@arrows@checked{#6}{#7}% - {% - \expandafter\edef\csname pgf@arrow@code@#3\endcsname{% - \noexpand\pgfscope% - {\expandafter\noexpand\csname pgf@arrow@code@#7\endcsname}% - \noexpand\endpgfscope% - {% - \noexpand\pgfmathsetlength\pgf@x{#1}% - \noexpand\pgf@process{\expandafter\noexpand\csname pgf@arrow@left@#7\endcsname}% - \noexpand\pgf@process{\expandafter\noexpand\csname pgf@arrow@right@#5\endcsname}% - \pgf@x=-\pgf@x% - \noexpand\pgflowlevel{\noexpand\pgftransformxshift{\pgf@x}}% - \expandafter\noexpand\csname pgf@arrow@code@#5\endcsname}% - }% - \pgf@arrows@repeat{pgf@arrow@right@#7}{pgf@arrow@right@#3}% - \expandafter\def\csname pgf@arrow@left@#3\endcsname{% - \pgf@process{% - \pgfmathsetlength\pgf@y{#1}% - \advance\pgf@x by\pgf@y% - \pgf@process{\csname pgf@arrow@left@#7\endcsname}% - \pgf@process{\csname pgf@arrow@right@#5\endcsname}% - \pgf@process{\csname pgf@arrow@left@#5\endcsname}% - }% - }% - \pgf@arrows@invname{#2}{#3}% - }% - }% + \pgf@xb=#2% + \pgftransformxshift{-\pgf@xb}% + \let\pgf@arrow@handle\pgf@arrow@drawer + \let\pgf@arrow@handle@dot\relax% + #1% }% } -\def\pgfarrowsdeclarecombine@star*{\pgfutil@ifnextchar[{\pgf@arrowsdeclarecombine@star}{\pgf@arrowsdeclarecombine@star[0pt]}} -\def\pgf@arrowsdeclarecombine@star[#1]#2#3#4#5#6#7{% - \pgf@arrows@check@already{#2}{#3}% + +\def\pgf@arrow@drawer#1#2{% + % Prepare: {% - \pgf@arrows@checked{#4}{#5}% + \pgfarrows@getid{#1}{#2}% + % Do shift: + \expandafter\expandafter\expandafter\pgf@arrow@drawer@shift\csname pgf@ar@ends@\pgf@arrow@id\endcsname% + % Do slant: + \ifdim\pgfarrows@slant pt=0pt% + \else% + \pgftransformxslant{\pgfarrows@slant}% + \fi% + % do swap: + \ifpgfarrowswap% + \pgftransformyscale{-1}% + \fi% {% - \pgf@arrows@checked{#6}{#7}% - {% - \expandafter\edef\csname pgf@arrow@code@#3\endcsname{% - \noexpand\pgfscope% - {% - \noexpand\pgfmathsetlength\pgf@x{#1}% - \pgf@process{\expandafter\noexpand\csname pgf@arrow@left@#7\endcsname}% - \pgf@process{\expandafter\noexpand\csname pgf@arrow@right@#5\endcsname}% - \noexpand\pgflowlevel{\noexpand\pgftransformxshift{\pgf@x}}% - }% - {\expandafter\noexpand\csname pgf@arrow@code@#7\endcsname}% - \noexpand\endpgfscope% - \expandafter\noexpand\csname pgf@arrow@code@#5\endcsname% - }% - \pgf@arrows@repeat{pgf@arrow@left@#7}{pgf@arrow@left@#3}% - \expandafter\def\csname pgf@arrow@right@#3\endcsname{% - \pgf@process{% - \pgfmathsetlength\pgf@y{#1}% - \advance\pgf@x by\pgf@y% - \pgf@process{\csname pgf@arrow@left@#7\endcsname}% - \pgf@process{\csname pgf@arrow@right@#5\endcsname}% - \pgf@process{\csname pgf@arrow@right@#7\endcsname}% - }% - }% - \pgf@arrows@invname{#2}{#3}% - }% - }% - }% + \csname pgf@ar@saves@\pgf@arrow@id\endcsname% + \pgfscope% + \pgf@arrows@color@setup% + \pgflowlevelsynccm\csname pgf@ar@cache@\pgf@arrow@id\endcsname% + \endpgfscope% + \pgf@arrows@rigid@hull% + }% + \expandafter}% + % Transform to next tip: + \expandafter\pgftransformxshift\expandafter{\the\pgf@xc}% +} + +\def\pgf@arrows@color@setup{% + \ifx\pgf@arrows@stroke@color\pgfutil@empty\else\pgfsetstrokecolor{\pgf@arrows@stroke@color}\fi% + \ifx\pgf@arrows@fill@color\pgfutil@empty% + \expandafter\expandafter\expandafter\ifx% + \expandafter\csname\expandafter\string\expandafter\color@pgfstrokecolor\expandafter\endcsname\csname\string\color@pgffillcolor\endcsname% + \else + \pgfsetfillcolor{pgfstrokecolor}% + \fi% + \else% + \pgfsetfillcolor{\pgf@arrows@fill@color}% + \fi% +} + +\def\pgf@arrow@drawer@shift#1#2#3{% tip end, back end, line end, sep + \pgf@xb#2\pgftransformxshift{-\pgf@xb}% + \pgf@xc#1% + \advance\pgf@xc by\pgfarrowsep% + \advance\pgf@xc by-\pgf@xb% +} + +\def\pgf@arrows@rigid@hull{% + \ifpgf@relevantforpicturesize% + % Do bb update: + \expandafter\let\expandafter\pgf@temp\csname pgf@ar@hull@\pgf@arrow@id\endcsname% + \ifx\pgf@temp\pgfutil@empty\else% + \let\pgf@arrow@hull@point\pgf@arrow@hull@point@first% + \pgf@temp% + \pgf@arrow@update@bb% + \fi% + \fi +} + + +% Convex hull stuff: + +\def\pgf@arrow@hull@point@first#1#2{% +% {\pgfsys@beginscope\pgfpathcircle{\pgfqpoint{#1}{#2}}{0.5pt}\pgfusepathqfill\pgfsys@endscope}% + \pgf@x#1\pgf@y#2% + \pgf@xa\pgf@pt@aa\pgf@x% + \advance\pgf@xa by\pgf@pt@ba\pgf@y% + \pgf@ya\pgf@pt@ab\pgf@x% + \advance\pgf@ya by\pgf@pt@bb\pgf@y% + \pgf@xb\pgf@xa\pgf@yb\pgf@ya% + \let\pgf@arrow@hull@point\pgf@arrow@hull@point@other% +} +\def\pgf@arrow@hull@point@other#1#2{% +% {\pgfsys@beginscope\pgfpathcircle{\pgfqpoint{#1}{#2}}{0.5pt}\pgfusepathqfill\pgfsys@endscope}% + \pgfutil@tempdima#1\pgfutil@tempdimb#2% + \pgf@x\pgf@pt@aa\pgfutil@tempdima% + \advance\pgf@x by\pgf@pt@ba\pgfutil@tempdimb% + \pgf@y\pgf@pt@ab\pgfutil@tempdima% + \advance\pgf@y by\pgf@pt@bb\pgfutil@tempdimb% + \ifdim\pgf@x<\pgf@xa\pgf@xa\pgf@x\else\ifdim\pgf@x>\pgf@xb\pgf@xb\pgf@x\fi\fi% + \ifdim\pgf@y<\pgf@ya\pgf@ya\pgf@y\else\ifdim\pgf@y>\pgf@yb\pgf@yb\pgf@y\fi\fi% } +\def\pgf@arrow@update@bb{% + \advance\pgf@xa by\pgf@pt@x% + \advance\pgf@ya by\pgf@pt@y% + \advance\pgf@xb by\pgf@pt@x% + \advance\pgf@yb by\pgf@pt@y% + \ifdim\pgf@picmaxx=-16000pt\relax% + \global\pgf@picminx\pgf@xa% + \global\pgf@picmaxx\pgf@xb% + \global\pgf@picminy\pgf@ya% + \global\pgf@picmaxy\pgf@yb% + \else% + \ifdim\pgf@xa<\pgf@picminx\global\pgf@picminx\pgf@xa\fi% + \ifdim\pgf@ya<\pgf@picminy\global\pgf@picminy\pgf@ya\fi% + \ifdim\pgf@xb>\pgf@picmaxx\global\pgf@picmaxx\pgf@xb\fi% + \ifdim\pgf@yb>\pgf@picmaxy\global\pgf@picmaxy\pgf@yb\fi% + \fi% +} -% Creates new arrows by doubling/tripling existing arrows. +% Sets arrows % -% #1 = optional additional space in multiples of line width -% #2 = name of new start -% #3 = name of new end -% #4 = name of old start -% #5 = name of old end +% #1 = An arrow specification of the form +% <start spec>-<end spec>. This will call \pgfsetstartarrow{start +% spec} and \pgfsetendarrow{end spec}. +% +% Alternatively, it may be of the form [options]. In this case, +% the arrow options are set for the local scope and all arrows in +% the current scope will have these options set. % % Example: % -% \pgfarrowsdeclaredouble{<<}{>>}{<}{>} +% \pgfsetarrows{-to} -\def\pgfarrowsdeclaredouble{\pgfutil@ifnextchar[{\pgf@arrowsdeclaredouble}{\pgf@arrowsdeclaredouble[0pt]}} -\def\pgf@arrowsdeclaredouble[#1]#2#3#4#5{\pgfarrowsdeclarecombine[#1]{#2}{#3}{#4}{#5}{#4}{#5}} -\def\pgfarrowsdeclaretriple{\pgfutil@ifnextchar[{\pgf@arrowsdeclaretriple}{\pgf@arrowsdeclaretriple[0pt]}} -\def\pgf@arrowsdeclaretriple[#1]#2#3#4#5{% - \pgfarrowsdeclarecombine[#1]{pgf@trip@#2}{pgf@trip@#3}{#4}{#5}{#4}{#5}% - \pgfarrowsdeclarecombine[#1]{#2}{#3}{pgf@trip@#2}{pgf@trip@#3}{#4}{#5}% +\def\pgfsetarrows#1{\pgf@arrows#1\pgf@stop} +\def\pgf@arrows{\pgfutil@ifnextchar[\pgf@arrows@test@opt\pgf@arrows@}%} +\def\pgf@arrows@#1-#2\pgf@stop{% + \pgfsetarrowsstart{#1}% + \pgfsetarrowsend{#2}% +} +\def\pgf@arrows@test@opt[{% + \pgfutil@ifnextchar-{\pgf@arrows@[}%} go back to normal reading for compat. reasons. + \pgf@arrows@test@opt@% +} +\def\pgf@arrows@test@opt@#1]{% + \pgfutil@ifnextchar\pgf@stop{% + \let\pgf@arrows@options\pgf@arrows@options@scope% + \pgfkeys{/pgf/arrow keys/.cd,#1}% + \let\pgf@arrows@options@scope\pgf@arrows@options% + % Ok, setup the options + \pgfutil@gobble% + }{% + \pgf@arrows@[#1]% Oops: go back to normal mode + }% } +\let\pgf@arrows@options@scope\pgfutil@empty + + + + -% A stealth-fighter-like pointed arrow -% -% Example: % -% \pgfsetarrows{-stealth} +% Predefined arrows: +% + + +% A dot is used to indicate the end of the line: + +\pgfdeclarearrow{ + name = ., + drawing code = +} + + +% An underscore adds a space as in >_> or >_Â >. However, it will be +% faster to say ">[sep] >" or ">[sep=2pt] >". + +\pgfdeclarearrow{ + name = _, + defaults = {sep}, + drawing code = +} + + + +% Default shorthands: + +\pgfdeclarearrow{ name = To, means = } % forward declaration +\pgfdeclarearrow{ name = Bar, means = } % forward declaration +\pgfkeys{ + <-> /.tip = {To}, + >-< /.tip = {>[reversed]}, + | /.tip = {Bar} +} + + + +% Compatibility with old arrow system: + +\pgfkeys {} + +\def\pgf@arrows@direct@def#1#2{\expandafter\pgf@arrows@direct@def@\expandafter{\csname pgf@ar@means@#2\endcsname}{#1}} +\def\pgf@arrows@direct@def@#1#2{\expandafter\def\csname pgf@arrows@direct@name@#2\endcsname{\pgf@arrow@handle@shorthand@empty{#1}}} +\pgf@arrows@direct@def{start@[}{]} +\pgf@arrows@direct@def{start@]}{[} +\pgf@arrows@direct@def{start@spaced [}{spaced ]} +\pgf@arrows@direct@def{start@spaced ]}{spaced [} +\pgf@arrows@direct@def{end@[}{[} +\pgf@arrows@direct@def{end@]}{]} +\pgf@arrows@direct@def{end@spaced [}{spaced [} +\pgf@arrows@direct@def{end@spaced ]}{spaced ]} + +\def\pgfsetarrowoptions#1#2{\expandafter\def\csname pgf@arrow@compat@opt@#1\endcsname{#2}} +\def\pgfgetarrowoptions#1{\csname pgf@arrow@compat@opt@#1\endcsname} +\def\pgfarrowsdeclare#1#2#3#4{% + \pgfdeclarearrow{ name ={#1}-{#2}, setup code ={#3}, drawing code={#4}, parameters/.expand once={\csname pgf@arrow@compat@opt@#2\endcsname}} + \expandafter\def\csname pgf@arrow@compat@opt@#2\endcsname{0}} +\def\pgfarrowsleftextend#1{\pgfmathsetlength\pgf@xa{#1}\pgfarrowssetbackend{\pgf@xa}} +\def\pgfarrowsrightextend#1{\pgfmathsetlength\pgf@xb{#1}\pgfarrowssettipend{\pgf@xb}} +\def\pgfarrowsdeclarealias#1#2#3#4{\pgfdeclarearrow{ name ={#1}-{#2}, means ={#4} } } +\def\pgfarrowsdeclarereversed#1#2#3#4{\pgfdeclarearrow{ name ={#1}-{#2}, means={{#4}[reversed]}}} +\def\pgfarrowsdeclarecombine{\pgfutil@ifnextchar*{\pgfarrowsdeclarecombine@star}{\pgf@@arrowsdeclarecombine}} +\def\pgf@@arrowsdeclarecombine{\pgfutil@ifnextchar[{\pgf@arrowsdeclarecombine}{\pgf@arrowsdeclarecombine[0pt]}} +\def\pgf@arrowsdeclarecombine[#1]#2#3#4#5#6#7{\def\pgf@@temp{#1}\ifx\pgf@@temp\pgf@linewidthtext\def\pgf@@temp{+0pt 1}\fi% + \pgfdeclarearrow{name ={#2}-{#3}, means={#5[sep/.expand once=\pgf@@temp]#6}}} +\def\pgf@linewidth@text{\pgflinewidth} +\def\pgfarrowsdeclarecombine@star*{\pgfutil@ifnextchar[{\pgf@arrowsdeclarecombine@star}{\pgf@arrowsdeclarecombine@star[0pt]}} +\def\pgf@arrowsdeclarecombine@star[#1]#2#3#4#5#6#7{\def\pgf@@temp{#1}\ifx\pgf@@temp\pgf@linewidthtext\def\pgf@@temp{+0pt 1}\fi% + \pgfdeclarearrow{name ={#2}-{#3}, means={#5[sep/.expand once=\pgf@@temp].#6}}} +\def\pgfarrowsdeclaredouble{\pgfutil@ifnextchar[{\pgf@arrowsdeclaredouble}{\pgf@arrowsdeclaredouble[0pt]}} +\def\pgf@arrowsdeclaredouble[#1]#2#3#4#5{\pgfarrowsdeclarecombine[#1]{#2}{#3}{#4}{#5}{#4}{#5}} +\def\pgfarrowsdeclaretriple{\pgfutil@ifnextchar[{\pgf@arrowsdeclaretriple}{\pgf@arrowsdeclaretriple[0pt]}} +\def\pgf@arrowsdeclaretriple[#1]#2#3#4#5{ \pgfarrowsdeclarecombine[#1]{pgf@trip@#2}{pgf@trip@#3}{#4}{#5}{#4}{#5}% + \pgfarrowsdeclarecombine[#1]{#2}{#3}{pgf@trip@#2}{pgf@trip@#3}{#4}{#5}} +\def\pgf@linewidthtext{\pgflinewidth} \pgfarrowsdeclare{stealth}{stealth} { @@ -432,16 +1087,7 @@ \pgfpathlineto{\pgfqpoint{-3\pgfutil@tempdima}{-4\pgfutil@tempdima}} \pgfusepathqfill } - \pgfarrowsdeclarereversed{stealth reversed}{stealth reversed}{stealth}{stealth} - - -% An arrow similar to the $\to$ arrow -% -% Example: -% -% \pgfsetarrow{-to} - \pgfarrowsdeclare{to}{to} { \pgfutil@tempdima=-0.84pt% @@ -469,7 +1115,7 @@ {\pgfqpoint{-3\pgfutil@tempdima}{-4\pgfutil@tempdima}} \pgfusepathqstroke } - +\pgfkeys{To /.tip = to} \pgfarrowsdeclare{to reversed}{to reversed} { \pgfutil@tempdima=-0.21pt% @@ -497,15 +1143,6 @@ {\pgfqpoint{3.5\pgfutil@tempdima}{-4\pgfutil@tempdima}} \pgfusepathqstroke } - - - -% LaTeX's orginal arrow type -% -% Example: -% -% \pgfsetarrows{-latex} - \pgfarrowsdeclare{latex}{latex} { \pgfutil@tempdima=0.28pt% @@ -537,16 +1174,7 @@ \pgfusepathqfill } \pgfarrowsdeclarereversed{latex reversed}{latex reversed}{latex}{latex} - - - -% A bar shaped arrow -% -% Example: -% -% \pgfsetarrows{-|} - -\pgfarrowsdeclare{|}{|} +\pgfarrowsdeclare{@bar}{@bar} { \pgfarrowsleftextend{+-0.25\pgflinewidth} \pgfarrowsrightextend{+.75\pgflinewidth} @@ -560,17 +1188,7 @@ \pgfpathlineto{\pgfqpoint{0.25\pgflinewidth}{\pgfutil@tempdima}} \pgfusepathqstroke } - - -% A space arrow -% -% This arrow can be combined with other arrows to add "space" around -% them. -% -% Example: -% -% \pgfarrowsdeclarecombine{my<}{my>}{<}{>}{space}{space} - +\pgfkeys{Bar /.tip = @bar} \pgfarrowsdeclare{space}{space} { \pgfutil@tempdima=0.88pt% @@ -583,3 +1201,5 @@ \endinput + + diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreexternal.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreexternal.code.tex index d8eaca5aee7..75789f2d16c 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreexternal.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreexternal.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoreexternal.code.tex,v 1.17 2010/09/01 08:56:40 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoreexternal.code.tex,v 1.20 2013/07/15 12:05:31 tantau Exp $ @@ -107,10 +107,32 @@ \ifpgfexternal@aux@in@dpth \csname newwrite\endcsname\w@pgfexternal@auxout \fi + \pgfexternal@geometry@compatibility \fi% \gdef\pgfrealjobname##1{}% avoid multiple calls. } +\def\pgfexternal@geometry@compatibility{% + % check if \usepackage{geometry} is loaded: + \pgfutil@ifundefined{geometry}{% + }{% + % The geometry package hooks into \begin{document}, evaluates + % its driver -- and generates \special instructions to set the + % paper size. + % + % Unfortunately, this confuses dvips utterly - and perhaps + % other drivers as well. + % + % Thus, if we currently about to generate some external + % graphics, we WANT to disable geometry (it has no purpose in + % this context anyway). + % + % This here works well: + \immediate\write16{Package TikZ externalization: calling \string\geometry{driver=none} during externalization.^^J}% + \geometry{driver=none}% + }% +}% + \def\pgfexternal@nofiles{% % replace \relax. The \nofiles macros does % \let\makeglossary=\relax @@ -158,7 +180,7 @@ % This will be overwritten by the tikz external lib if it is loaded. \def\pgfexternal@error@no@shipout{% - \PackageError{pgf}{Sorry, image externalization failed: the resulting image was EMPTY. I tried to externalize '\pgfactualjobname'. Perhaps there was a typo somewhere? Please check that your document contains '\string\beginpgfgraphicnamed{\pgfactualjobname} ... \string\endpgfgraphicnamed'}% + \pgferror{Sorry, image externalization failed: the resulting image was EMPTY. I tried to externalize '\pgfactualjobname'. Perhaps there was a typo somewhere? Please check that your document contains '\string\beginpgfgraphicnamed{\pgfactualjobname} ... \string\endpgfgraphicnamed'}% }% @@ -238,13 +260,23 @@ \endgroup } -% Defines \pgfexternaldepth to be the depth of the external picture -% '#1' and \pgfexternaltrimleft / \pgfexternaltrimright to be the 'hbaseline' shift. -% +% Reads the .dpth file which contains meta data of the external +% picture. +% +% This command handles the following stuff: +% - it defines \pgfexternaldepth . The macro contains the contents of +% a line which does not start with a control sequence (for example a +% line containing '50pt') +% - it defines \pgfexternaltrimleft and \pgfexternaltrimright +% - it checks if the .dpth file contains content stored by means of +% \pgfexternalstorecommand. If so, the argument of +% \pgfexternalstorecommand will be restored. +% - anything else will be appended to the main .aux file, assuming that +% it contains \label or \ref information (only if the LaTeX switch +% \if@filesw is \iftrue). % -% Furthermore, it handles any auxiliary information stored in the -% .dpth file (it appends it to the main aux file). % +% #1: the image file name (such that #1.dpth exists) \def\pgfexternalreaddpth#1{% % no \begingroup. Handle that manually: \edef\pgfexternalreaddpth@restore{% @@ -291,6 +323,10 @@ % the .aux file. % \expandafter\ifx\pgf@first\pgfexternal@restore + % if the first line in the .dpth file starts with the + % magic string \pgfexternal@restore, the complete line + % will be executed as-is. Example: + % \pgfexternal@restore{\def\somevalue{1}} #1% \else % do NOT execute #1! many LaTeX commands don't support it (\label for example) diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex index eeb6c3e8635..81b39f34659 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex,v 1.9 2008/04/22 17:03:26 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex,v 1.11 2013/09/19 22:34:34 tantau Exp $ % Globals @@ -123,13 +123,15 @@ % \pgfsetstrokecolor{red} \def\pgfsetstrokecolor#1{% - \pgfutil@colorlet{pgf@tempcolor}{#1}% - \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgf@tempcolor}}% - \expandafter\expandafter\expandafter\pgf@setstrokecolor\csname\string\color@pgf@tempcolor\endcsname% + \pgfutil@colorlet{pgfstrokecolor}{#1}% + \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgfstrokecolor}}% + \expandafter\expandafter\expandafter\global% + \expandafter\expandafter\expandafter\let\expandafter\csname\expandafter\string\expandafter\color@pgfstrokecolor\expandafter\endcsname\csname\string\color@pgfstrokecolor\endcsname% + \expandafter\expandafter\expandafter\pgf@setstrokecolor\csname\string\color@pgfstrokecolor\endcsname% } \def\pgf@setstrokecolor#1#2#3#4#5{% \expandafter\ifx\csname pgfsys@color@#4@stroke\endcsname\relax% - \PackageError{pgfbase}{Unsupported color model `#4'. Sorry}{}% + \pgferror{Unsupported color model `#4'. Sorry}% \else% \edef\pgf@colmarshal{\expandafter\noexpand\csname pgfsys@color@#4@stroke\endcsname}% \pgf@uncomma#5,,% @@ -155,13 +157,15 @@ % \pgfsetfillcolor{gray} \def\pgfsetfillcolor#1{% - \pgfutil@colorlet{pgf@tempcolor}{#1}% - \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgf@tempcolor}}% - \expandafter\expandafter\expandafter\pgf@setfillcolor\csname\string\color@pgf@tempcolor\endcsname% + \pgfutil@colorlet{pgffillcolor}{#1}% + \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgffillcolor}}% + \expandafter\expandafter\expandafter\global% + \expandafter\expandafter\expandafter\let\expandafter\csname\expandafter\string\expandafter\color@pgffillcolor\expandafter\endcsname\csname\string\color@pgffillcolor\endcsname% + \expandafter\expandafter\expandafter\pgf@setfillcolor\csname\string\color@pgffillcolor\endcsname% } \def\pgf@setfillcolor#1#2#3#4#5{% \expandafter\ifx\csname pgfsys@color@#4@fill\endcsname\relax% - \PackageError{pgfbase}{Unsupported color model `#4'. Sorry}{}% + \pgferror{Unsupported color model `#4'. Sorry}% \else% \edef\pgf@colmarshal{\expandafter\noexpand\csname pgfsys@color@#4@fill\endcsname}% \pgf@uncomma#5,,% @@ -177,13 +181,17 @@ % \pgfsetcolor{blue} \def\pgfsetcolor#1{% - \pgfutil@colorlet{pgf@tempcolor}{#1}% - \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgf@tempcolor}}% - \expandafter\expandafter\expandafter\pgf@setcolor\csname\string\color@pgf@tempcolor\endcsname% + \pgfutil@colorlet{pgfstrokecolor}{#1}% + \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgfstrokecolor}}% + \expandafter\expandafter\expandafter\global% + \expandafter\expandafter\expandafter\let\expandafter\csname\expandafter\string\expandafter\color@pgfstrokecolor\expandafter\endcsname\csname\string\color@pgfstrokecolor\endcsname% + \expandafter\expandafter\expandafter\global% + \expandafter\expandafter\expandafter\let\expandafter\csname\expandafter\string\expandafter\color@pgffillcolor\expandafter\endcsname\csname\string\color@pgfstrokecolor\endcsname% + \expandafter\expandafter\expandafter\pgf@setcolor\csname\string\color@pgfstrokecolor\endcsname% } \def\pgf@setcolor#1#2#3#4#5{% \expandafter\ifx\csname pgfsys@color@#4\endcsname\relax% - \PackageError{pgfbase}{Unsupported color model `#4'. Sorry}{}% + \pgferror{Unsupported color model `#4'. Sorry}% \else% \edef\pgf@colmarshal{\expandafter\noexpand\csname pgfsys@color@#4\endcsname}% \pgf@uncomma#5,,% diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreimage.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreimage.code.tex index 59a3699f70d..1f2d6ea5d17 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreimage.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreimage.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoreimage.code.tex,v 1.16 2010/03/25 20:57:13 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoreimage.code.tex,v 1.18 2013/07/15 15:41:24 tantau Exp $ @@ -44,8 +44,8 @@ \pgfkeys{/pgf/images/page=}% make page empty \fi% \ifx\pgf@filename\pgfutil@empty% - \PackageWarning{pgf}% - {File "#3" not found when defining image "#2".\MessageBreak + \pgfwarning% + {File "#3" not found when defining image "#2". Tried all extensions in "\pgfsys@imagesuffixlist"}% \pgf@declaredraftimage{#2}{#3}% \else% @@ -66,13 +66,14 @@ \pgfkeys{/pgf/images/height/.estore in=\pgf@imageheight} \pgfkeys{/pgf/images/page/.estore in=\pgf@imagepage} \pgfkeys{/pgf/images/interpolate/.cd,.code=\edef\pgf@imageinterpolate{#1},.default=true} +\let\pgf@imageinterpolate\pgfutil@empty \pgfkeys{/pgf/images/mask/.code=% {% \edef\pgf@imagemask{#1}% \ifx\pgf@imagemask\pgfutil@empty% \else% \pgfutil@ifundefined{pgf@mask@#1}% - {\PackageError{pgf}{Undefined mask "#1".}{}% + {\pgferror{Undefined mask "#1".}% \edef\pgf@imagemask{}}% {\edef\pgf@imagemask{\csname pgf@mask@#1\endcsname}% }% @@ -92,11 +93,11 @@ % #2: file name \def\pgf@declaredraftimage#1#2{% \ifx\pgf@imagewidth\pgfutil@empty% - \PackageWarning{pgf}{Missing width for image "#1" ("#2") in draft mode.\MessageBreak Using 1cm instead}% + \pgfwarning{Missing width for image "#1" ("#2") in draft mode. Using 1cm instead}% \edef\pgf@imagewidth{1cm}% \fi% \ifx\pgf@imageheight\pgfutil@empty% - \PackageWarning{pgf}{Missing height for image "#1" ("#2") in draft mode.\MessageBreak Using 1cm instead}% + \pgfwarning{Missing height for image "#1" ("#2") in draft mode. Using 1cm instead}% \edef\pgf@imageheight{1cm}% \fi% \ifx\pgf@imagepage\pgfutil@empty\else\edef\pgf@imagepagetext{ page \pgf@imagepage}\fi% @@ -105,7 +106,7 @@ \vrule\kern-0.4pt% \vbox to \pgf@imageheight{% \hrule\vfil% - \hbox to \pgf@imagewidth{\hskip-10cm\hfil\noexpand\tiny#2\pgf@imagepage\hfil\hskip-10cm}% + \hbox to \pgf@imagewidth{\hskip-10cm\hfil\noexpand\pgfutil@font@tiny#2\pgf@imagepage\hfil\hskip-10cm}% \vfil\hrule}% \kern-0.4pt\vrule}% }% @@ -141,8 +142,8 @@ \gdef\pgf@filename{}% \expandafter\pgf@findfile\pgfsys@imagesuffixlist:+{#3}% \ifx\pgf@filename\pgfutil@empty% - \PackageWarning{pgf}% - {File "#3" not found when defining mask "#2".\MessageBreak + \pgfwarning% + {File "#3" not found when defining mask "#2". Tried all extensions in "\pgfsys@imagesuffixlist"}% \else% \pgfsys@definemask{#2}% @@ -183,7 +184,7 @@ \def\pgf@imagename{pgf@image@#1}% \pgf@tryextensions{\pgf@imagename}{\pgfalternateextension}% \expandafter\pgfutil@ifundefined\expandafter{\pgf@imagename}% - {\PackageError{pgf}{Undefined image "#1"}{}}% + {\pgferror{Undefined image "#1"}}% {{\leavevmode\csname\pgf@imagename\endcsname}}} \def\pgf@tryextensions#1#2{% diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorelayers.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorelayers.code.tex index e18aea0cde9..880b41c4a30 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorelayers.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorelayers.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorelayers.code.tex,v 1.2 2010/08/27 12:51:47 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorelayers.code.tex,v 1.7 2013/07/18 17:07:38 tantau Exp $ % Creates a new pgf layer @@ -21,8 +21,10 @@ % \pgfdeclarelayer{background} \def\pgfdeclarelayer#1{% - \expandafter\pgf@newbox\csname pgf@layerbox@#1\endcsname% - \expandafter\pgf@newbox\csname pgf@layerboxsaved@#1\endcsname% + \pgfutil@ifundefined{pgf@layerbox@#1}{% + \expandafter\expandafter\csname pgf@newbox\endcsname\csname pgf@layerbox@#1\endcsname% + \expandafter\expandafter\csname pgf@newbox\endcsname\csname pgf@layerboxsaved@#1\endcsname% + }{}% } \let\pgf@newbox=\newbox % avoid plain TeX outer problem @@ -35,6 +37,9 @@ % Sets the list of layers that make up the picture. The layers will be % put on top of each other in the order given. % +% This command can also be given inside of a picture in which case it +% applies only to that very picture. +% % Example: % % \pgfsetlayers{background,main} @@ -42,8 +47,6 @@ \def\pgfsetlayers#1{\edef\pgf@layerlist{#1}} \pgfsetlayers{main} - - % Adds code to a layer % % #1 = layer name @@ -58,30 +61,80 @@ % \fill[red] (0,0) -- (1,1); % \end{pgfonlayer} +\def\pgfonlayer@name{main} + \def\pgfonlayer#1{% \pgfutil@ifundefined{pgf@layerbox@#1}{% - \PackageError{pgf}{Sorry, the requested layer '#1' could not be found. Maybe you misspelled it?}{}% - \bgroup - \begingroup + \pgferror{Sorry, the requested layer '#1' could not be found. Maybe you misspelled it?}% + \bgroup + \begingroup }{% - \expandafter\global\expandafter% - \setbox\csname pgf@layerbox@#1\endcsname=\hbox to 0pt% - \bgroup% - \expandafter\box\csname pgf@layerbox@#1\endcsname% - \begingroup% + \begingroup + \edef\pgf@temp{#1}% + \ifx\pgf@temp\pgfonlayer@name + % we are already on this layer. + \def\pgf@temp{% + \bgroup + \begingroup + }% + \else + \let\pgfonlayer@name=\pgf@temp + \pgfonlayer@assert@is@active + \def\pgf@temp{% + \expandafter\global\expandafter% + \setbox\csname pgf@layerbox@#1\endcsname=\hbox to 0pt% + \bgroup% + \expandafter\box\csname pgf@layerbox@#1\endcsname% + \begingroup% + }% + \fi + \pgfsetlinewidth{0.4pt}% always reset the line width + \pgf@temp }% } \def\endpgfonlayer{% \endgroup% \hss \egroup% + \endgroup } \let\startpgfonlayer=\pgfonlayer \let\stoppgfonlayer=\endpgfonlayer - - +\def\pgfdiscardlayername{discard} + +\def\pgfonlayer@assert@is@active{% + \ifx\pgfonlayer@name\pgfdiscardlayername + % this special layer name can be used as /dev/null without + % warning. + \else + \begingroup + \def\pgfonlayer@isactive{0}% + \expandafter\pgf@assert@layer@is@active@loop\pgf@layerlist,,\relax% + \if0\pgfonlayer@isactive + \pgfonlayer@assert@fail + \fi + \endgroup + \fi +}% +\def\pgfonlayer@assert@fail{% + \pgferror{Sorry, the requested layer '\pgfonlayer@name' is not + part of the layer list. Please verify that you provided + \string\pgfsetlayers\space and that '\pgfonlayer@name' is part of this list}% +}% +\def\pgf@assert@layer@is@active@loop#1,#2,\relax{% + \edef\pgf@test{#1}% + \ifx\pgf@test\pgfonlayer@name + \def\pgfonlayer@isactive{1}% + \else + \def\pgf@test{#2}% + \ifx\pgf@test\pgfutil@empty% + \else% + \pgf@assert@layer@is@active@loop#2,\relax% + \fi% + \fi +} % Hooks into the scoping: diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex index db62f73b6bf..60cede3f006 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex,v 1.24 2010/08/03 12:27:36 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex,v 1.29 2013/10/07 15:51:46 tantau Exp $ \newdimen\pgf@path@lastx @@ -16,6 +16,8 @@ \let\pgfgetpath=\pgfsyssoftpath@getcurrentpath \let\pgfsetpath=\pgfsyssoftpath@setcurrentpath + + % Replace corners by arcs. % % #1 = in-size of arc @@ -75,6 +77,36 @@ } + +% The following protocol the passed sizes and all the corresponding +% softpath commands. The nonlinear transformation (nlt) module +% overwrites these commands. + +\def\pgf@lt@moveto#1#2{% + \pgf@protocolsizes{#1}{#2}% + \pgfsyssoftpath@moveto{\the#1}{\the#2}% +} +\def\pgf@lt@lineto#1#2{% + \pgf@protocolsizes{#1}{#2}% + \pgfsyssoftpath@lineto{\the#1}{\the#2}% +} +\def\pgf@lt@curveto#1#2#3#4#5#6{% + \pgf@protocolsizes{#1}{#2}% + \pgf@protocolsizes{#3}{#4}% + \pgf@protocolsizes{#5}{#6}% + \pgfsyssoftpath@curveto{\the#1}{\the#2}{\the#3}{\the#4}{\the#5}{\the#6}% +} + +\let\pgf@lt@closepath\pgfsyssoftpath@closepath + +\let\pgf@nlt@moveto\pgf@lt@moveto +\let\pgf@nlt@lineto\pgf@lt@lineto +\let\pgf@nlt@curveto\pgf@lt@curveto +\let\pgf@nlt@closepath\pgf@lt@closepath + +\let\pgf@nlt@list\pgfutil@empty % If non-empty, the nlt module is active + + % Move current point to #1. % % #1 = new current point @@ -87,8 +119,7 @@ \def\pgfpathmoveto#1{% \pgfpointtransformed{#1}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% - \pgfsyssoftpath@moveto{\the\pgf@x}{\the\pgf@y}% + \pgf@nlt@moveto{\pgf@x}{\pgf@y}% \global\pgf@path@lastx=\pgf@x% \global\pgf@path@lasty=\pgf@y% } @@ -147,9 +178,8 @@ \def\pgfpathlineto#1{% \pgfpointtransformed{#1}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@roundcornerifneeded% - \pgfsyssoftpath@lineto{\the\pgf@x}{\the\pgf@y}% + \pgf@nlt@lineto{\pgf@x}{\pgf@y}% \global\pgf@path@lastx=\pgf@x% \global\pgf@path@lasty=\pgf@y% } @@ -173,7 +203,7 @@ \def\pgfpathclose{% \pgf@roundcornerifneeded% - \pgfsyssoftpath@closepath% + \pgf@nlt@closepath% } @@ -192,17 +222,14 @@ \def\pgfpathcurveto#1#2#3{% \pgfpointtransformed{#3}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@xb=\pgf@x% \pgf@yb=\pgf@y% \pgfpointtransformed{#2}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% \pgfpointtransformed{#1}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@roundcornerifneeded% - \pgfsyssoftpath@curveto{\the\pgf@x}{\the\pgf@y}{\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xb}{\the\pgf@yb}% + \pgf@nlt@curveto{\pgf@x}{\pgf@y}{\pgf@xa}{\pgf@ya}{\pgf@xb}{\pgf@yb}% \global\pgf@path@lastx=\pgf@xb% \global\pgf@path@lasty=\pgf@yb% } @@ -223,7 +250,6 @@ \def\pgfpathquadraticcurveto#1#2{% \pgfpointtransformed{#2}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@xb=\pgf@x% \pgf@yb=\pgf@y% \pgfpointtransformed{#1}% @@ -234,13 +260,11 @@ \pgf@ya=.33333333\pgf@yb% \advance\pgf@xa by\pgf@xc% \advance\pgf@ya by\pgf@yc% - \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% % compute first control point \advance\pgf@xc by.3333333\pgf@path@lastx% \advance\pgf@yc by.3333333\pgf@path@lasty% - \pgf@protocolsizes{\pgf@xc}{\pgf@yc}% \pgf@roundcornerifneeded% - \pgfsyssoftpath@curveto{\the\pgf@xc}{\the\pgf@yc}{\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xb}{\the\pgf@yb}% + \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@xa}{\pgf@ya}{\pgf@xb}{\pgf@yb}% \global\pgf@path@lastx=\pgf@xb% \global\pgf@path@lasty=\pgf@yb% } @@ -374,12 +398,9 @@ \pgf@yc=\pgf@yb\relax% \advance \pgf@xc by \pgf@x\relax% \advance \pgf@yc by \pgf@y\relax% - \pgfsyssoftpath@curveto{\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xc}{\the\pgf@yc}{\the\pgf@xb}{\the\pgf@yb}% + \pgf@nlt@curveto{\pgf@xa}{\pgf@ya}{\pgf@xc}{\pgf@yc}{\pgf@xb}{\pgf@yb}% \global\pgf@path@lastx=\pgf@xb% \global\pgf@path@lasty=\pgf@yb% - \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% - \pgf@protocolsizes{\pgf@xb}{\pgf@yb}% - \pgf@protocolsizes{\pgf@xc}{\pgf@yc}% }% } @@ -819,7 +840,7 @@ \pgfpatharcofellipse@{% \pgfpoint {\pgfpath@center@x + #5*cos(\pgfpath@angle@i)} - {\pgfpath@center@y + #6*sin(\pgfpath@angle@i)} + {\pgfpath@center@y + #6*sin(\pgfpath@angle@i)}% }% % \advance\c@pgf@countd by1 @@ -900,8 +921,7 @@ {% \advance\pgf@xa by\pgf@xc% \advance\pgf@ya by\pgf@yc% - \pgfsyssoftpath@moveto{\the\pgf@xa}{\the\pgf@ya}% - \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% + \pgf@nlt@moveto{\pgf@xa}{\pgf@ya}% }% \pgf@x=0.55228475\pgf@xb% first arc \pgf@y=0.55228475\pgf@yb% @@ -909,8 +929,7 @@ \advance\pgf@y by\pgf@ya% \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% - \edef\pgf@temp{{\the\pgf@x}{\the\pgf@y}}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% + \edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}% \pgf@x=0.55228475\pgf@xa% \pgf@y=0.55228475\pgf@ya% \advance\pgf@x by\pgf@xb% @@ -919,10 +938,9 @@ \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% \advance\pgf@xb by\pgf@xc% - \advance\pgf@yb by\pgf@yc% - \expandafter\pgfsyssoftpath@curveto\pgf@temp{\the\pgf@x}{\the\pgf@y}{\the\pgf@xb}{\the\pgf@yb}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% - \pgf@protocolsizes{\pgf@xb}{\pgf@yb}% + \advance\pgf@yb by\pgf@yc% + \pgf@temp% + \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xb}{\pgf@yb}% }% \pgf@xa=-\pgf@xa% flip first axis \pgf@ya=-\pgf@ya% @@ -932,8 +950,7 @@ \advance\pgf@y by\pgf@yb% \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% - \edef\pgf@temp{{\the\pgf@x}{\the\pgf@y}}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% + \edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}% \pgf@x=0.55228475\pgf@xb% \pgf@y=0.55228475\pgf@yb% \advance\pgf@x by\pgf@xa% @@ -942,10 +959,9 @@ \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% \advance\pgf@xa by\pgf@xc% - \advance\pgf@ya by\pgf@yc% - \expandafter\pgfsyssoftpath@curveto\pgf@temp{\the\pgf@x}{\the\pgf@y}{\the\pgf@xa}{\the\pgf@ya}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% - \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% + \advance\pgf@ya by\pgf@yc% + \pgf@temp% + \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xa}{\pgf@ya}% }% \pgf@xb=-\pgf@xb% flip second axis \pgf@yb=-\pgf@yb% @@ -955,8 +971,7 @@ \advance\pgf@y by\pgf@ya% \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% - \edef\pgf@temp{{\the\pgf@x}{\the\pgf@y}}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% + \edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}% \pgf@x=0.55228475\pgf@xa% \pgf@y=0.55228475\pgf@ya% \advance\pgf@x by\pgf@xb% @@ -966,9 +981,8 @@ \advance\pgf@y by\pgf@yc% \advance\pgf@xb by\pgf@xc% \advance\pgf@yb by\pgf@yc% - \expandafter\pgfsyssoftpath@curveto\pgf@temp{\the\pgf@x}{\the\pgf@y}{\the\pgf@xb}{\the\pgf@yb}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% - \pgf@protocolsizes{\pgf@xb}{\pgf@yb}% + \pgf@temp% + \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xb}{\pgf@yb}% }% \pgf@xa=-\pgf@xa% flip first axis once more \pgf@ya=-\pgf@ya% @@ -978,8 +992,7 @@ \advance\pgf@y by\pgf@yb% \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% - \edef\pgf@temp{{\the\pgf@x}{\the\pgf@y}}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% + \edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}% \pgf@x=0.55228475\pgf@xb% \pgf@y=0.55228475\pgf@yb% \advance\pgf@x by\pgf@xa% @@ -989,12 +1002,11 @@ \advance\pgf@y by\pgf@yc% \advance\pgf@xa by\pgf@xc% \advance\pgf@ya by\pgf@yc% - \expandafter\pgfsyssoftpath@curveto\pgf@temp{\the\pgf@x}{\the\pgf@y}{\the\pgf@xa}{\the\pgf@ya}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% - \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% + \pgf@temp% + \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xa}{\pgf@ya}% }% - \pgfsyssoftpath@closepath% - \pgfsyssoftpath@moveto{\the\pgf@xc}{\the\pgf@yc}% + \pgf@nlt@closepath% + \pgf@nlt@moveto{\pgf@xc}{\pgf@yc}% } @@ -1029,7 +1041,9 @@ \ifpgf@pt@identity% \ifpgf@arccorners% \else% - \let\pgfrect@next=\pgf@normalrect% + \ifx\pgf@nlt@list\pgfutil@empty% + \let\pgfrect@next=\pgf@normalrect% + \fi% \fi% \fi% \pgfrect@next% @@ -1087,8 +1101,8 @@ % Append a grid to the current path. % -% #1 = lower left point of grid -% #2 = upper right point of grid +% #1 = first corner point of grid +% #2 = second corner point of grid % % Options: % @@ -1119,97 +1133,86 @@ \pgf@xb=\pgf@x% \pgf@yb=\pgf@y% \pgf@process{#2}% - \pgf@xa=\pgf@x\relax% - \pgf@ya=\pgf@y\relax% - {% - % compute bounding box - % first corner - \pgf@x=\pgf@xb% - \pgf@y=\pgf@yb% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% - % second corner + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + % Swap coordinates if one of them is smaller than the other: + \ifdim\pgf@xa>\pgf@xb% \pgf@x=\pgf@xb% - \pgf@y=\pgf@ya% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% - % third corner - \pgf@x=\pgf@xa% + \pgf@xb=\pgf@xa% + \pgf@xa=\pgf@x% + \fi% + \ifdim\pgf@ya>\pgf@yb% \pgf@y=\pgf@yb% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% - % fourth corner - \pgf@x=\pgf@xa% - \pgf@y=\pgf@ya% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% - }% - \c@pgf@counta=\pgf@y\relax% + \pgf@yb=\pgf@ya% + \pgf@ya=\pgf@y% + \fi% + \c@pgf@counta=\pgf@ya\relax% \c@pgf@countb=\pgf@yc\relax% \divide\c@pgf@counta by\c@pgf@countb\relax% - \pgf@y=\c@pgf@counta\pgf@yc\relax% - \ifdim\pgf@y<\pgf@ya% - \advance\pgf@y by\pgf@yc% + \pgfutil@tempdima=\c@pgf@counta\pgf@yc\relax% + \ifdim\pgfutil@tempdima<\pgf@ya% + \advance\pgfutil@tempdima by\pgf@yc% \fi% - \loop% horizontal lines + \pgfutil@tempdimb\pgf@x + \pgfutil@loop% horizontal lines {% - \pgf@xa=\pgf@x% - \pgf@ya=\pgf@y% + \pgf@xa=\pgfutil@tempdimb% + \pgf@ya=\pgfutil@tempdima% \pgf@pos@transform{\pgf@xa}{\pgf@ya} - \pgfsyssoftpath@moveto{\the\pgf@xa}{\the\pgf@ya}% + \pgf@nlt@moveto{\pgf@xa}{\pgf@ya}% \pgf@xa=\pgf@xb% - \pgf@ya=\pgf@y% + \pgf@ya=\pgfutil@tempdima% \pgf@pos@transform{\pgf@xa}{\pgf@ya} - \pgfsyssoftpath@lineto{\the\pgf@xa}{\the\pgf@ya}% + \pgf@nlt@lineto{\pgf@xa}{\pgf@ya}% }% - \advance\pgf@y by\pgf@yc% - \ifdim\pgf@y<\pgf@yb% - \repeat% - \advance\pgf@y by-0.01pt\relax% - \ifdim\pgf@y<\pgf@yb% + \advance\pgfutil@tempdima by\pgf@yc% + \ifdim\pgfutil@tempdima<\pgf@yb% + \pgfutil@repeat% + \advance\pgfutil@tempdima by-0.01pt\relax% + \ifdim\pgfutil@tempdima<\pgf@yb% {% - \pgf@xa=\pgf@x% - \pgf@ya=\pgf@y% + \pgf@xa=\pgfutil@tempdimb% + \pgf@ya=\pgfutil@tempdima% \pgf@pos@transform{\pgf@xa}{\pgf@ya} - \pgfsyssoftpath@moveto{\the\pgf@xa}{\the\pgf@ya}% + \pgf@nlt@moveto{\pgf@xa}{\pgf@ya}% \pgf@xa=\pgf@xb% - \pgf@ya=\pgf@y% + \pgf@ya=\pgfutil@tempdima% \pgf@pos@transform{\pgf@xa}{\pgf@ya} - \pgfsyssoftpath@lineto{\the\pgf@xa}{\the\pgf@ya}% + \pgf@nlt@lineto{\pgf@xa}{\pgf@ya}% }% \fi% - \c@pgf@counta=\pgf@x\relax% + \c@pgf@counta=\pgfutil@tempdimb\relax% \c@pgf@countb=\pgf@xc\relax% \divide\c@pgf@counta by\c@pgf@countb\relax% - \pgf@x=\c@pgf@counta\pgf@xc\relax% - \ifdim\pgf@x<\pgf@xa% - \advance\pgf@x by\pgf@xc% + \pgfutil@tempdimb=\c@pgf@counta\pgf@xc\relax% + \ifdim\pgfutil@tempdimb<\pgf@xa% + \advance\pgfutil@tempdimb by\pgf@xc% \fi% - \loop% vertical lines + \pgfutil@loop% vertical lines {% - \pgf@xc=\pgf@x% + \pgf@xc=\pgfutil@tempdimb% \pgf@yc=\pgf@ya% \pgf@pos@transform{\pgf@xc}{\pgf@yc} - \pgfsyssoftpath@moveto{\the\pgf@xc}{\the\pgf@yc}% - \pgf@xc=\pgf@x% + \pgf@nlt@moveto{\pgf@xc}{\pgf@yc}% + \pgf@xc=\pgfutil@tempdimb% \pgf@yc=\pgf@yb% \pgf@pos@transform{\pgf@xc}{\pgf@yc} - \pgfsyssoftpath@lineto{\the\pgf@xc}{\the\pgf@yc}% + \pgf@nlt@lineto{\pgf@xc}{\pgf@yc}% }% - \advance\pgf@x by\pgf@xc% - \ifdim\pgf@x<\pgf@xb% - \repeat% - \advance\pgf@x by-0.01pt\relax% - \ifdim\pgf@x<\pgf@xb% + \advance\pgfutil@tempdimb by\pgf@xc% + \ifdim\pgfutil@tempdimb<\pgf@xb% + \pgfutil@repeat% + \advance\pgfutil@tempdimb by-0.01pt\relax% + \ifdim\pgfutil@tempdimb<\pgf@xb% {% - \pgf@xc=\pgf@x% + \pgf@xc=\pgfutil@tempdimb% \pgf@yc=\pgf@ya% \pgf@pos@transform{\pgf@xc}{\pgf@yc} - \pgfsyssoftpath@moveto{\the\pgf@xc}{\the\pgf@yc}% - \pgf@xc=\pgf@x% + \pgf@nlt@moveto{\pgf@xc}{\pgf@yc}% + \pgf@xc=\pgfutil@tempdimb% \pgf@yc=\pgf@yb% \pgf@pos@transform{\pgf@xc}{\pgf@yc} - \pgfsyssoftpath@lineto{\the\pgf@xc}{\the\pgf@yc}% + \pgf@nlt@lineto{\pgf@xc}{\pgf@yc}% }% \fi% } diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathprocessing.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathprocessing.code.tex index 9bcfc739f56..b9c47231afa 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathprocessing.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathprocessing.code.tex @@ -7,9 +7,107 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepathprocessing.code.tex,v 1.8 2008/10/09 16:46:56 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepathprocessing.code.tex,v 1.9 2013/09/09 10:05:41 tantau Exp $ +% Split a path at the last subpath of a path +% +% #1 = a macro that stores a path +% +% Description: +% +% This command will split the path into two parts: +% +% \pgfprocessresultpathprefix +% The part of the path before the last subpath. +% +% \pgfprocessresultpathsuffix +% The last subpath on the path. +% +% #1 will always be equal to the contents of the two above macros +% concatenated. Normally, your objective will be to modify the +% \pgfprocessresultpathsuffix and then concatenate the result. + +\def\pgfprocesssplitpath#1{% + \let\pgfprocessresultpathprefix\pgfutil@empty% + \let\pgfprocessresultpathsuffix\pgfutil@empty% + \let\pgf@next\pgf@process@split% + \expandafter\pgf@process@split#1\pgfsyssoftpath@movetotoken{}{}\pgf@stop% +} + +\def\pgf@process@split#1\pgfsyssoftpath@movetotoken#2#3#4{% + \ifx#4\pgf@stop% ok, end reached! + \expandafter\def\expandafter\pgfprocessresultpathsuffix\expandafter{\pgfprocessresultpathsuffix#1}% + \let\pgf@next\pgfutil@gobble% + \else% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgfprocessresultpathprefix% + \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultpathprefix\pgfprocessresultpathsuffix#1}% + \def\pgfprocessresultpathsuffix{\pgfsyssoftpath@movetotoken{#2}{#3}}% + \fi% + \pgf@next#4% +} + + + +% Split a subpath at the end +% +% #1 = a macro that stores an open subpath that contains at least two +% path commands (so, not just a moveto); +% +% Description: +% +% Splits the supath into two parts: +% +% \pgfprocessresultsubpathsuffix +% This macro contains the last two "relevant" path commands: The end +% of the path command that led to the last path command and this +% last path command. In essence, this macro contains everything you +% "need to modify" if you wish to modify the end of the path. +% +% \pgfprocessresultsubpathprefix +% Everything before the previous macro on the subpath. + +\def\pgfprocesssplitsubpath#1{% + % First, we need to find the end: + \let\pgf@tempa\pgfutil@emtpy% + \let\pgf@tempb\pgfutil@emtpy% + \let\pgf@tempc\pgfutil@emtpy% + \let\pgf@tempd\pgfutil@emtpy% + \let\pgfprocessresultsubpathprefix\pgfutil@empty% + \let\pgfprocessresultsubpathsuffix\pgfutil@empty% + \let\pgf@next\pgf@split@subpath% + \expandafter\pgf@split@subpath#1\pgf@stop% +} + +\newif\ifpgf@split@move + +\def\pgf@split@subpath#1#2#3#4{% + \ifx#4\pgf@stop% + \expandafter\def\expandafter\pgfprocessresultsubpathsuffix\expandafter{\pgfprocessresultsubpathsuffix#1{#2}{#3}}% + \let\pgf@next\pgfutil@gobble% + \else% + \pgf@split@movetrue% + \ifx#1\pgfsyssoftpath@curvetosupportatoken% + \pgf@split@movefalse% + \else + \ifx#1\pgfsyssoftpath@curvetosupportbtoken% + \pgf@split@movefalse% + \fi% + \fi% + \ifpgf@split@move% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgfprocessresultsubpathprefix% + \expandafter\expandafter\expandafter{% + \expandafter\pgfprocessresultsubpathprefix\pgfprocessresultsubpathsuffix}% + \def\pgfprocessresultsubpathsuffix{#1{#2}{#3}}% + \else% + \expandafter\def\expandafter\pgfprocessresultsubpathsuffix\expandafter{\pgfprocessresultsubpathsuffix#1{#2}{#3}}% + \fi% + \fi% + \pgf@next#4% +} + diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathusage.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathusage.code.tex index b803cce9caf..e60f66cce2f 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathusage.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathusage.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepathusage.code.tex,v 1.12 2008/04/22 17:03:26 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepathusage.code.tex,v 1.23 2013/12/13 15:11:58 tantau Exp $ % Stroke/fill/clip/etc. the current path. Depending on the options, @@ -16,9 +16,9 @@ % of them are performed (in a sensible order). % % #1 = action(s) to be applied to the current path. Valid actions are: -% stroke - strokes the path. If no options are given, this is the -% default. -% draw - same as stroke. +% stroke - strokes the path. +% draw - strokes the path and adds arrow tips. +% tips - adds arrow tips. % fill - fills the path. % clip - clip the path. % discard - Discards the path. Same effect as having an empty @@ -33,27 +33,73 @@ % \pgfusepath{stroke} \pgfkeys{ - /pgf/stroke/.code=\def\pgf@up@stroke{stroke}, - /pgf/draw/.code=\def\pgf@up@stroke{stroke}, - /pgf/fill/.code=\def\pgf@up@fill{fill}, - /pgf/clip/.code=\def\pgf@up@clip{clip}, + /pgf/stroke/.code=\let\pgf@up@stroke\pgf@up@stroke@text\pgf@up@path@neededtrue, + /pgf/draw/.code=\let\pgf@up@stroke\pgf@up@stroke@text\pgf@up@path@neededtrue, + /pgf/fill/.code=\let\pgf@up@fill\pgf@up@fill@text\pgf@up@path@neededtrue, + /pgf/clip/.code=\let\pgf@up@clip\pgf@up@clip@text\pgf@up@path@neededtrue, /pgf/discard/.code=, - /pgf/use as bounding box/.code=\def\pgf@up@bb{\pgf@relevantforpicturesizefalse} + /pgf/use as bounding box/.code=\let\pgf@up@bb\pgf@do@up@bb, + /pgf/arrow keys/flex/.code=\pgferror{You need to say \string\usetikzlibrary{bending} for flexing and bending arrows}, + /pgf/arrow keys/flex'/.code=\pgferror{You need to say \string\usetikzlibrary{bending} for flexing and bending arrows}, + /pgf/arrow keys/bend/.code=\pgferror{You need to say \string\usetikzlibrary{bending} for flexing and bending arrows}, + /pgf/arrow keys/quick/.code=\pgfarrowsaddtooptions{\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@quick}, } +\pgfkeys{ + /pgf/.cd, + tips/.is choice, + tips/.default=true, + tips/proper/.code=\let\pgf@tips@mode\pgf@tips@mode@onproper, + tips/on proper draw/.code=\let\pgf@tips@mode\pgf@tips@mode@onproperdraw, + tips/true/.code=\let\pgf@tips@mode\pgf@tips@mode@true, + tips/on draw/.code=\let\pgf@tips@mode\pgf@tips@mode@ondraw, + tips/never/.code=\let\pgf@tips@mode\pgf@tips@mode@false, + tips/false/.code=\let\pgf@tips@mode\pgf@tips@mode@false, +} +\def\pgf@tips@mode@onproper{4} +\def\pgf@tips@mode@onproperdraw{3} +\def\pgf@tips@mode@true{2} +\def\pgf@tips@mode@ondraw{1} +\def\pgf@tips@mode@false{0} +\let\pgf@tips@mode\pgf@tips@mode@ondraw + + +% The following can only be set to "true" using the options in the +% module "bending" +\newif\ifpgf@precise@shortening +\def\pgf@arrow@mode@is@quick{0} +\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@quick + +\newif\ifpgf@up@path@needed +\newif\ifpgf@up@draw@arrows +\def\pgf@up@stroke@text{stroke} +\def\pgf@up@fill@text{fill} +\def\pgf@up@clip@text{clip} +\def\pgf@do@up@bb{\pgf@relevantforpicturesizefalse} + \def\pgfusepath#1{% + \pgf@up@path@neededfalse% + \pgf@up@draw@arrowsfalse% \let\pgf@up@stroke\pgfutil@empty% \let\pgf@up@fill\pgfutil@empty% \let\pgf@up@clip\pgfutil@empty% - \let\pgf@up@discard\pgfutil@empty% \let\pgf@up@bb\pgfutil@empty% \pgfset{#1}% \expandafter\def\expandafter\pgf@up@action\expandafter{\csname pgfsys@\pgf@up@fill\pgf@up@stroke\endcsname}% + \ifnum\pgf@tips@mode=2\relax% + \pgf@up@path@neededtrue% + \fi% + \ifnum\pgf@tips@mode=4\relax% + \pgf@up@path@neededtrue% + \fi% + \ifpgf@up@path@needed% + \else% + \pgfsyssoftpath@setcurrentpath\pgfutil@empty% + \fi% \ifx\pgf@up@stroke\pgfutil@empty% \ifx\pgf@up@fill\pgfutil@empty% + \let\pgf@up@action=\pgfutil@empty% \ifx\pgf@up@clip\pgfutil@empty% - \let\pgf@up@action=\pgfutil@empty% - \pgfsyssoftpath@setcurrentpath\pgfutil@empty% \else% % only clipping \let\pgf@up@action=\pgfsys@discardpath% @@ -86,29 +132,38 @@ % \ifx\pgf@up@clip\pgfutil@empty% \ifx\pgf@up@stroke\pgfutil@empty% - \pgfsyssoftpath@invokecurrentpath% - \pgfsyssoftpath@getcurrentpath\pgf@last@used@path% - \pgf@up@action% - \else% - \pgf@check@for@arrows% - \ifpgf@drawarrows% - \pgf@shorten@path@as@needed% - \pgfsyssoftpath@invokecurrentpath% - \pgfsyssoftpath@getcurrentpath\pgf@last@used@path% - \pgf@up@action% - \pgf@stroke@inner@line@if@needed% - \pgfsyssoftpath@setcurrentpath\pgfutil@empty% - \pgf@add@arrows@as@needed% - \else% + \ifx\pgf@up@action\pgfutil@empty% + \ifnum\pgf@tips@mode=2\relax% + \pgf@up@draw@arrows@only% + \fi% + \ifnum\pgf@tips@mode=4\relax% + \pgf@up@draw@arrows@only% + \fi% + \else% \pgfsyssoftpath@invokecurrentpath% - \pgfsyssoftpath@getcurrentpath\pgf@last@used@path% \pgf@up@action% - \pgf@stroke@inner@line@if@needed% + \fi% + \else% + \pgfgetpath\pgf@arrowpath% + \pgf@path@setup@tempswa% + \pgfprocesscheckclosed{\pgf@arrowpath}{\pgfutil@tempswafalse}% + \pgf@path@check@proper% + \ifpgfutil@tempswa% + \pgf@prepare@end@of@path% + \begingroup% + \pgf@prepare@start@of@path% + \fi% + \pgfsyssoftpath@invokecurrentpath% + \pgf@up@action% + \pgf@stroke@inner@line@if@needed% + \ifpgfutil@tempswa% + \pgf@add@arrow@at@start% + \endgroup% + \pgf@add@arrow@at@end% \fi% \fi% \else% \pgfsyssoftpath@invokecurrentpath% - \pgfsyssoftpath@getcurrentpath\pgf@last@used@path% \pgfsys@clipnext% \pgf@up@action% \pgf@relevantforpicturesizefalse% @@ -118,9 +173,70 @@ \pgf@resetpathsizes% \ignorespaces% } +\def\pgf@path@setup@tempswa{% + \ifnum\pgf@tips@mode>0\relax + \pgfutil@tempswatrue% + \else + \pgfutil@tempswafalse% + \fi% +} +\def\pgf@up@draw@arrows@only{% + \pgfgetpath\pgf@arrowpath% + \pgfutil@tempswatrue% + \pgfprocesscheckclosed{\pgf@arrowpath}{\pgfutil@tempswafalse}% + \pgf@path@check@proper% + \ifpgfutil@tempswa% + \pgf@prepare@end@of@path% + \begingroup% + \pgf@prepare@start@of@path% + \pgf@add@arrow@at@start% + \endgroup% + \pgf@add@arrow@at@end% + \fi% +} + +\def\pgf@path@check@proper{% + \ifpgfutil@tempswa% + \ifnum\pgf@tips@mode>2\relax% + \pgf@path@check@proper@% + \fi% + \fi% +} + + +\def\pgf@path@check@proper@{% + {% + \pgf@x0pt\pgf@y\pgf@x% + \pgfutil@tempswatrue% + \let\pgfsyssoftpath@movetotoken\pgf@path@proper@init% + \let\pgfsyssoftpath@linetotoken\pgf@path@proper@test%% + \let\pgfsyssoftpath@curvetosupportatoken\pgf@path@proper@test% + \let\pgfsyssoftpath@curvetosupportbtoken=\pgf@path@proper@test% + \let\pgfsyssoftpath@curvetotoken\pgf@path@proper@test% + \let\pgfsyssoftpath@rectcornertoken\pgf@path@proper@test% + \let\pgfsyssoftpath@rectsizetoken\pgf@path@proper@zero@test% + \let\pgfsyssoftpath@closepathtoken\pgf@path@proper@test% + % Execute the path: + \pgf@arrowpath% + \expandafter + }% + \ifpgfutil@tempswa\pgfutil@tempswafalse\else\pgfutil@tempswatrue\fi% +} + +\def\pgf@path@proper@init#1#2{\pgfutil@tempswatrue\pgf@x#1\pgf@y#2}% +\def\pgf@path@proper@test#1#2{% + \ifdim\pgf@x=#1\relax\else\pgfutil@tempswafalse\fi% + \ifdim\pgf@y=#2\relax\else\pgfutil@tempswafalse\fi} +\def\pgf@path@proper@zero@test#1#2{% + \ifdim\pgf@x=0pt\relax\else\pgfutil@tempswafalse\fi% + \ifdim\pgf@y=0pt\relax\else\pgfutil@tempswafalse\fi} + + + \def\pgf@stroke@inner@line@if@needed{% \ifdim\pgfinnerlinewidth>0pt\relax% + \expandafter\let\expandafter\pgf@temp@save\csname\string\color@pgfstrokecolor\endcsname% \pgfsys@beginscope% {% \pgfsys@setlinewidth{\pgfinnerlinewidth}% @@ -129,9 +245,17 @@ \pgfsys@stroke% }% \pgfsys@endscope% + \expandafter\global\expandafter\let\csname\string\color@pgfstrokecolor\endcsname\pgf@temp@save% \fi% } +\let\pgf@prepare@start@of@path\relax% +\let\pgf@add@arrow@at@end\relax% +\let\pgf@add@arrow@at@start\relax% + + + + % Shorten start/end of paths by a certain amount. % % #1 = amount by which paths should be shortened. @@ -149,94 +273,374 @@ \def\pgfsetshortenstart#1{\pgfmathsetlength\pgf@shorten@start@additional{#1}} \def\pgfsetshortenend#1{\pgfmathsetlength\pgf@shorten@end@additional{#1}} -\newif\ifpgf@drawarrows - -\def\pgf@check@for@arrows{% - \pgf@drawarrowsfalse% - \ifx\pgf@startarrow\pgfutil@empty\else\pgf@drawarrowstrue\fi% - \ifx\pgf@endarrow\pgfutil@empty\else\pgf@drawarrowstrue\fi% - \ifdim\pgf@shorten@end@additional=0pt\relax\else\pgf@drawarrowstrue\fi% - \ifdim\pgf@shorten@start@additional=0pt\relax\else\pgf@drawarrowstrue\fi% - \ifpgf@drawarrows% - \pgfsyssoftpath@getcurrentpath\pgf@arrowpath% - \ifx\pgf@arrowpath\pgfutil@empty% - \pgf@drawarrowsfalse% - \else% - \pgfprocesscheckclosed{\pgf@arrowpath}{\pgf@drawarrowsfalse}% +\newdimen\pgf@shorten@end@additional +\newdimen\pgf@shorten@start@additional + + + +% +% +% Handling the end of a path +% +% +% The "handling" consists of first testing whether we need to do +% anything at all, namely because either an arrow tip should be drawn +% at the end or because the path should be shortened at the end. If +% so, we shorten the path if needed and, later on, add the arrow tip. +% + +\newif\ifpgf@worry + + +% Prepare the end of the path: Test whether anything must be done +% (step 0) and, if so, split the path (step 1), extract the interesting points from +% the path (step 2), prepare further computations (step 3), shorten +% the path (step 4) if necessary, and add the arrow tip (step 4 in +% macro \pgf@add@arrow@at@end, which is called later). + +\def\pgf@prepare@end@of@path{% + \let\pgfprocessresultpathsuffix\relax% flag that nothing has happened... + \let\pgfprocessresultsubpathsuffix\relax% + \pgfsyssoftpath@getcurrentpath\pgf@arrowpath% + % + % Step 0 start: + % + % Do we need to worry about the end? + % + \ifx\pgf@arrowpath\pgfutil@empty\else% + \pgf@worryfalse% + \ifx\pgf@end@tip@sequence\pgfutil@empty\else\pgf@worrytrue\fi% Yes, worry if we have to draw an arrow + \pgf@precise@shorteningfalse% + \pgf@arrow@compute@shortening\pgf@end@tip@sequence% + \advance\pgf@xa by\pgf@shorten@end@additional% + \advance\pgf@xb by\pgf@shorten@end@additional% + \ifdim\pgf@xa=0pt\relax\else\pgf@worrytrue\fi% Also, worry if shortening is requested + \edef\pgf@path@shortening@distance{\the\pgf@xa}% + \edef\pgf@arrow@tip@total@length{\the\pgf@xb}% + % + % Step 0 done. + % + \ifpgf@worry% + % Ok, need to "worry" about the end, either because we need to + % shorten it or to draw an arrow head. + % + % Step 1: Split + % + \pgfprocesssplitpath{\pgf@arrowpath}% + \pgfprocesssplitsubpath{\pgfprocessresultpathsuffix}% + % + % Step 2: extract + % + \expandafter\pgf@parse@end\pgfprocessresultsubpathsuffix\pgf@stop\pgf@stop\pgf@stop% + % + % Step 3: prep + % + \pgf@prep@end% + % + % Step 4: shorten + % + \ifdim\pgf@path@shortening@distance=0pt\else\pgf@do@shorten@end\fi% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgf@arrowpath% + \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultpathprefix\pgfprocessresultpathsuffix}% + \pgfsyssoftpath@setcurrentpath\pgf@arrowpath% \fi% \fi% } -\newdimen\pgf@shorten@end@additional -\newdimen\pgf@shorten@start@additional +\def\pgf@parse@end#1#2#3#4#5#6{% + \ifx#4\pgf@stop% Only a moveto! -> do nothing! + \def\pgfpointlastonpath{\pgfqpoint{#2}{#3}}% + \let\pgf@next\relax% + \let\pgf@do@shorten@end\relax% + \let\pgf@do@draw@end\pgf@do@draw@straightend% + \let\pgf@prep@end\pgf@prep@movetoend% + \else\ifx#4\pgfsyssoftpath@curvetosupportatoken% A curve -> this will get complicated... + \def\pgfsubpathfourthlasttoken{#1}% + \def\pgfpointfourthlastonpath{\pgfqpoint{#2}{#3}}% + \def\pgfpointthirdlastonpath{\pgfqpoint{#5}{#6}}% + \ifpgf@precise@shortening% + \let\pgf@do@shorten@end\pgf@do@shorten@curvedend% + \let\pgf@do@draw@end\pgf@do@draw@curvedend% + \let\pgf@prep@end\pgf@prep@curveend% + \else% + \def\pgfsubpathstart{\noexpand#1{#2}{#3}\noexpand#4{#5}{#6}}% + \let\pgf@do@shorten@end\pgf@do@shorten@straightend% + \let\pgf@do@draw@end\pgf@do@draw@straightend% + \let\pgf@prep@end\pgf@prep@straightend% + \fi% + \let\pgf@next\pgf@parse@end@curve@cont% + \else% A straight line -> great! + \def\pgfsubpathstart{\noexpand#1{#2}{#3}\noexpand#4}% + \def\pgfpointsecondlastonpath{\pgfqpoint{#2}{#3}}% + \def\pgfpointlastonpath{\pgfqpoint{#5}{#6}}% + \let\pgfpointfourthlastonpath\relax% + \let\pgfpointthirdlastonpath\relax% + \let\pgf@next\pgf@parse@end@gobble@three% + \let\pgf@do@shorten@end\pgf@do@shorten@straightend% + \let\pgf@do@draw@end\pgf@do@draw@straightend% + \let\pgf@prep@end\pgf@prep@straightend% + \fi\fi% + \pgf@next% Needed for reading rest of path... +} -\let\pgf@shorten@end=\pgfutil@empty -\let\pgf@shorten@start=\pgfutil@empty +\def\pgf@parse@end@gobble@three#1#2#3{}% +\def\pgf@parse@end@curve@cont#1#2#3#4#5#6#7#8#9{% + \def\pgfpointsecondlastonpath{\pgfqpoint{#2}{#3}}% + \def\pgfpointlastonpath{\pgfqpoint{#5}{#6}}% + \ifpgf@precise@shortening% + \else% + \expandafter\def\expandafter\pgfsubpathstart\expandafter{\pgfsubpathstart\noexpand#1{#2}{#3}\noexpand#4}% + \fi% +} -\def\pgf@shorten@path@as@needed{% - \pgfprocesspathextractpoints{\pgf@arrowpath}% - \let\pgf@arrow@next=\pgf@shorten@now% - \ifx\pgf@shorten@start\pgfutil@empty% - \ifx\pgf@shorten@end\pgfutil@empty% - \ifdim\pgf@shorten@end@additional=0pt\relax% - \ifdim\pgf@shorten@start@additional=0pt\relax% - \let\pgf@arrow@next=\relax% - \fi% +% +% Preps +% +\def\pgf@prep@movetoend{% + \pgf@process{\pgfpointlastonpath}% + \pgf@xb\pgf@x + \pgf@yb\pgf@y + \pgf@xc\pgf@x + \pgf@yc\pgf@y +} +\def\pgf@prep@straightend{% + \let\pgf@ref\pgfpointsecondlastonpath + \ifx\pgfpointlastonpath\pgfpointsecondlastonpath% degenerate! + \ifx\pgfpointthirdlastonpath\relax% cannot help it: really a zero-length path + \else% + \ifx\pgfpointlastonpath\pgfpointthirdlastonpath% double degenerate! + \let\pgf@ref\pgfpointfourthlastonpath% Use third point for reference. + \else + \let\pgf@ref\pgfpointthirdlastonpath% Use third point for reference. \fi% \fi% \fi% - \pgf@arrow@next% + \pgfpointlineatdistance{\pgf@path@shortening@distance}{\pgfpointlastonpath}{\pgf@ref}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% } -\def\pgf@shorten@now{% - {% - \pgf@x=0pt% - \pgf@shorten@start% - \advance\pgf@x by\pgf@shorten@start@additional% - \pgf@xc=\pgf@x% - \pgfpointlineatdistance{\pgf@xc}{\pgfpointfirstonpath}{\pgfpointsecondonpath}% - \global\pgf@xb=\pgf@x% - \global\pgf@yb=\pgf@y% - \pgf@process{\pgfpointsecondonpath}% - \global\advance\pgf@x by\pgf@xa% - \global\advance\pgf@y by\pgf@ya% - }% - \edef\pgfpointfirstonpath{\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}% - \edef\pgfpointsecondonpath{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + +% +% Line shortening for straight lines: +% +\def\pgf@do@shorten@straightend{% + \edef\pgfprocessresultsubpathsuffix{\pgfsubpathstart{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgfprocessresultpathsuffix% + \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultsubpathprefix\pgfprocessresultsubpathsuffix}% +} + + +% +% Draw an end arrow by calling an appropriate subfunction, if necessary +% + +\def\pgf@add@arrow@at@end{% + \ifx\pgf@arrowpath\pgfutil@empty\else% + \ifx\pgf@end@tip@sequence\pgfutil@empty\else% + \pgf@do@draw@end% + \fi% + \fi% +} + +% +% Draw an end arrow at the end of a straight line +% +\def\pgf@do@draw@straightend{% {% - \pgf@x=0pt% - \pgf@shorten@end% - \advance\pgf@x by\pgf@shorten@end@additional% - \pgf@xc=\pgf@x% - \pgfpointlineatdistance{\pgf@xc}{\pgfpointlastonpath}{\pgfpointsecondlastonpath}% - \global\pgf@xb=\pgf@x% - \global\pgf@yb=\pgf@y% - \pgf@process{\pgfpointsecondlastonpath}% - \global\advance\pgf@x by\pgf@xa% - \global\advance\pgf@y by\pgf@ya% + \pgftransformreset% + \pgftransformarrow{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{\pgf@xb}{\pgf@yb}}% + \pgf@arrow@draw@arrow\pgf@end@tip@sequence\pgf@arrow@tip@total@length% }% - \edef\pgfpointlastonpath{\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}% - \edef\pgfpointsecondlastonpath{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - \pgfprocesspathreplacestartandend{\pgf@arrowpath}{\pgfpointfirstonpath}{\pgfpointlastonpath}% - \pgfsyssoftpath@setcurrentpath\pgf@arrowpath% } -\def\pgf@add@arrows@as@needed{% - \ifx\pgf@startarrow\pgfutil@empty% - \else% - \pgflowlevelobj% - {\pgftransformarrow{\pgfpointsecondonpath}{\pgfpointfirstonpath}} - {\pgf@startarrow}% + + +% +% +% Handling the start of a path +% +% +% The "handling" is similar to the case for the start of the path. We +% may be able to skip the splitting if that was done already for the +% end. Otherwise, things are basically the same. +% + +% Prepare the start of the path: Test whether anything must be done +% (step 0) and, if so, split the path (step 1) if necesssary, extract +% the interesting points from the path (step 2), prepare computations +% (step 3) needed for both shortening and tip adding, shorten the path +% (step 4), and add the arrow tip (step 5 in macro +% \pgf@add@arrow@at@start, which is called later). + +\def\pgf@prepare@start@of@path{% + % + % Step 0 start: + % + % Do we need to worry about the start? + % + \ifx\pgf@arrowpath\pgfutil@empty\else% + \pgf@worryfalse% + \ifx\pgf@start@tip@sequence\pgfutil@empty\else\pgf@worrytrue\fi% Yes, worry if we have to draw an arrow + \pgf@precise@shorteningfalse% + \pgf@arrow@compute@shortening\pgf@start@tip@sequence% + \advance\pgf@xa by\pgf@shorten@start@additional% + \advance\pgf@xb by\pgf@shorten@start@additional% + \ifdim\pgf@xa=0pt\relax\else\pgf@worrytrue\fi% Also, worry if shortening is requested + \edef\pgf@path@shortening@distance{\the\pgf@xa}% + \edef\pgf@arrow@tip@total@length{\the\pgf@xb}% + % + % Step 0 done. + % + \ifpgf@worry% + % Ok, need to "worry" about the start, either because we need to + % shorten it or to draw an arrow head. + % + % Step 1: Split + % + \ifx\pgfprocessresultpathsuffix\relax% + % Ok, still need to compute the split: + \pgfprocesssplitpath{\pgf@arrowpath}% + \fi% + % + % Step 2: extract + % + \expandafter\pgf@parse@start\pgfprocessresultpathsuffix\pgf@stop\pgf@stop\pgf@stop% + % + % Step 3: prep + % + \pgf@prep@start% + % + % Step 4: shorten + % + \ifdim\pgf@path@shortening@distance=0pt\else\pgf@do@shorten@start\fi% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgf@arrowpath% + \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultpathprefix\pgfprocessresultpathsuffix}% + \pgfsyssoftpath@setcurrentpath\pgf@arrowpath% + \fi% \fi% - \ifx\pgf@endarrow\pgfutil@empty% - \else% - \pgflowlevelobj% - {\pgftransformarrow{\pgfpointsecondlastonpath}{\pgfpointlastonpath}} - {\pgf@endarrow}% - \fi% } -\let\pgf@startarrow=\pgfutil@empty -\let\pgf@endarrow=\pgfutil@empty +\def\pgf@parse@start#1#2#3#4#5#6{% + \def\pgfpointfirstonpath{\pgfqpoint{#2}{#3}}% + \def\pgfpointsecondonpath{\pgfqpoint{#5}{#6}}% + \let\pgfpointthirdonpath\relax% + \let\pgfpointfourthonpath\relax% + \def\pgfsubpathfirsttoken{\noexpand#1}% + \def\pgfsubpathsecondtoken{\noexpand#4}% + \ifx#4\pgf@stop% Only a moveto! -> do nothing! + \let\pgf@next\relax% + \let\pgf@do@shorten@start\relax% + \let\pgf@prep@start\pgf@prep@movetostart% + \let\pgf@do@draw@start\pgf@do@draw@straightstart% + \else\ifx#4\pgfsyssoftpath@curvetosupportatoken% A curve -> this will get complicated... + \ifpgf@precise@shortening% + \let\pgf@next\pgf@parse@start@curve@cont% + \let\pgf@do@shorten@start\pgf@do@shorten@curvedstart% + \let\pgf@do@draw@start\pgf@do@draw@curvedstart% + \let\pgf@prep@start\pgf@prep@curvedstart% + \else% can treat the end like a straight line... + \let\pgf@next\pgf@parse@start@curve@cont@straight% + \let\pgf@do@shorten@start\pgf@do@shorten@straightstart% + \let\pgf@do@draw@start\pgf@do@draw@straightstart% + \let\pgf@prep@start\pgf@prep@straightstart% + \fi% + \else% A straight line -> great! + \let\pgf@next\pgf@parse@start@till@stop% + \let\pgf@do@shorten@start\pgf@do@shorten@straightstart% + \let\pgf@do@draw@start\pgf@do@draw@straightstart% + \let\pgf@prep@start\pgf@prep@straightstart% + \fi\fi% + \pgf@next% Needed for reading rest of path... +} + +\def\pgf@parse@start@till@stop#1\pgf@stop\pgf@stop\pgf@stop{\def\pgfsubpathend{#1}}% + +\def\pgf@parse@start@curve@cont#1#2#3#4#5#6#7\pgf@stop\pgf@stop\pgf@stop{% + \def\pgfpointthirdonpath{\pgfqpoint{#2}{#3}}% + \def\pgfpointfourthonpath{\pgfqpoint{#5}{#6}}% + \def\pgfsubpathend{#7}% +} + +\def\pgf@parse@start@curve@cont@straight#1#2#3#4#5#6#7\pgf@stop\pgf@stop\pgf@stop{% + \def\pgfpointthirdonpath{\pgfqpoint{#2}{#3}}% + \def\pgfpointfourthonpath{\pgfqpoint{#5}{#6}}% + \def\pgfsubpathend{#1{#2}{#3}#4{#5}{#6}#7}% +} + +% +% Preps +% +\def\pgf@prep@movetostart{% + \pgf@process{\pgfpointfirstonpath}% + \pgf@xb\pgf@x + \pgf@yb\pgf@y + \pgf@xc\pgf@x + \pgf@yc\pgf@y +} +\def\pgf@prep@straightstart{% + \let\pgf@ref\pgfpointsecondonpath + \ifx\pgfpointfirstonpath\pgfpointsecondonpath% degenerate! + \ifx\pgfpointthirdonpath\relax% cannot help it: really a zero-length path + \else% + \ifx\pgfpointfirstonpath\pgfpointthirdonpath% double degenerate! + \let\pgf@ref\pgfpointfourthonpath% Use third point for reference. + \else + \let\pgf@ref\pgfpointthirdonpath% Use third point for reference. + \fi% + \fi% + \fi% + \pgfpointlineatdistance{\pgf@path@shortening@distance}{\pgfpointfirstonpath}{\pgf@ref}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% +} + +% +% Line shortening for straight lines: +% +\def\pgf@do@shorten@straightstart{% + \edef\pgfprocessresultpathsuffix{\pgfsubpathfirsttoken{\the\pgf@xa}{\the\pgf@ya}\pgfsubpathsecondtoken{\the\pgf@xc}{\the\pgf@yc}}% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgfprocessresultpathsuffix% + \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultpathsuffix\pgfsubpathend}% +} + + +% +% Draw a start arrow by calling an appropriate subfunction, if necessary +% + +\def\pgf@add@arrow@at@start{% + \ifx\pgf@arrowpath\pgfutil@empty\else% + \ifx\pgf@start@tip@sequence\pgfutil@empty\else% + \pgf@do@draw@start% + \fi% + \fi% +} + +% +% Draw an start arrow at the start of a straight line +% +\def\pgf@do@draw@straightstart{% + {% + \pgftransformreset% + \pgftransformarrow{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{\pgf@xb}{\pgf@yb}}% + \pgf@arrow@draw@arrow\pgf@start@tip@sequence\pgf@arrow@tip@total@length% + }% +} + + + +\let\pgf@shorten@end=\pgfutil@empty +\let\pgf@shorten@start=\pgfutil@empty + + +\endinput% + + + + -\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepatterns.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepatterns.code.tex index b308c5aef8f..54b5afcf6ae 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepatterns.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepatterns.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepatterns.code.tex,v 1.3 2009/07/02 11:43:15 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepatterns.code.tex,v 1.5 2013/11/07 15:45:46 tantau Exp $ % Creates a new uncolored pattern % @@ -53,8 +53,8 @@ % } % \def\pgfdeclarepatternformonly{% - \def\pgf@pattern@type{formonly}% - \pgfutil@ifnextchar[{\pgf@declarepattern@checkarg}{\pgf@declarepattern@checkarg[]}% + \def\pgf@pattern@type{formonly}% + \pgfutil@ifnextchar[{\pgf@declarepattern@checkarg}{\pgf@declarepattern@checkarg[]}% } @@ -92,8 +92,8 @@ % } % \def\pgfdeclarepatterninherentlycolored{% - \def\pgf@pattern@type{inherentlycolored}% - \pgfutil@ifnextchar[{\pgf@declarepattern@checkarg}{\pgf@declarepattern@checkarg[]}% + \def\pgf@pattern@type{inherentlycolored}% + \pgfutil@ifnextchar[{\pgf@declarepattern@checkarg}{\pgf@declarepattern@checkarg[]}% } @@ -101,26 +101,26 @@ \def\pgf@declarepattern@checkarg[#1]{% - \def\pgf@pattern@tempvars{#1}% - \ifx\pgf@pattern@tempvars\pgfutil@empty% - \expandafter\let\expandafter\pgf@next\csname pgf@declarepattern\pgf@pattern@type\endcsname% - \else% - \expandafter\let\expandafter\pgf@next\csname pgf@declarepattern\pgf@pattern@type @mutable\endcsname% - \fi% - \pgf@next} + \def\pgf@pattern@tempvars{#1}% + \ifx\pgf@pattern@tempvars\pgfutil@empty% + \expandafter\let\expandafter\pgf@next\csname pgf@declarepattern\pgf@pattern@type\endcsname% + \else% + \expandafter\let\expandafter\pgf@next\csname pgf@declarepattern\pgf@pattern@type @mutable\endcsname% + \fi% + \pgf@next} \long\def\pgf@declarepatternformonly#1#2#3#4#5{\pgf@declarepattern{#1}{#2}{#3}{#4}{#5}{0}} - + \long\def\pgf@declarepatterninherentlycolored#1#2#3#4#5{\pgf@declarepattern{#1}{#2}{#3}{#4}{#5}{1}} - + \long\def\pgf@declarepatternformonly@mutable#1#2#3#4#5{% - \def\pgf@marshal{\pgf@declarepatternmutable{#1}}% - \expandafter\pgf@marshal\expandafter{\pgf@pattern@tempvars}{#2}{#3}{#4}{#5}{2}% + \def\pgf@marshal{\pgf@declarepatternmutable{#1}}% + \expandafter\pgf@marshal\expandafter{\pgf@pattern@tempvars}{#2}{#3}{#4}{#5}{2}% } \long\def\pgf@declarepatterninherentlycolored@mutable#1#2#3#4#5#6{% - \def\pgf@marshal{\pgf@declarepatternmutable{#1}}% - \expandafter\pgf@marshal\expandafter{\pgf@pattern@tempvars}{#2}{#3}{#4}{#5}{3}% + \def\pgf@marshal{\pgf@declarepatternmutable{#1}}% + \expandafter\pgf@marshal\expandafter{\pgf@pattern@tempvars}{#2}{#3}{#4}{#5}{3}% } \def\pgf@declarepattern#1#2#3#4#5#6{% @@ -134,6 +134,7 @@ \pgfsysprotocol@setcurrentprotocol\pgfutil@empty% \pgfsysprotocol@bufferedtrue% \pgfsys@beginscope% + \pgfsetarrows{-}% #5% \pgfsys@endscope% \pgfsysprotocol@getcurrentprotocol\pgf@pattern@code% @@ -162,22 +163,22 @@ \expandafter\global\expandafter\let\csname pgf@pattern@instantiate@#1\endcsname=\pgf@marshal% } {% - \PackageError{pgfcorepatterns}{Pattern `#1' already defined}{}% + \pgferror{Pattern `#1' already defined}% }% } \def\pgf@pattern@number{0}% \def\pgf@declarepatternmutable#1#2#3#4#5#6#7{% - \pgfutil@ifundefined{pgf@pattern@name@#1}{% - \expandafter\gdef\csname pgf@pattern@name@#1\endcsname{#1}% - \expandafter\gdef\csname pgf@pattern@variables@#1\endcsname{#2}% - \expandafter\gdef\csname pgf@pattern@lowerleft@#1\endcsname{#3}% - \expandafter\gdef\csname pgf@pattern@upperright@#1\endcsname{#4}% - \expandafter\gdef\csname pgf@pattern@tilesize@#1\endcsname{#5}% - \expandafter\long\expandafter\gdef\csname pgf@pattern@code@#1\endcsname{#6}% - \expandafter\gdef\csname pgf@pattern@type@#1\endcsname{7}% - }{\PackageError{pgfcorepatterns}{The pattern `#1' is already defined}{}}% + \pgfutil@ifundefined{pgf@pattern@name@#1}{% + \expandafter\gdef\csname pgf@pattern@name@#1\endcsname{#1}% + \expandafter\gdef\csname pgf@pattern@variables@#1\endcsname{#2}% + \expandafter\gdef\csname pgf@pattern@lowerleft@#1\endcsname{#3}% + \expandafter\gdef\csname pgf@pattern@upperright@#1\endcsname{#4}% + \expandafter\gdef\csname pgf@pattern@tilesize@#1\endcsname{#5}% + \expandafter\long\expandafter\gdef\csname pgf@pattern@code@#1\endcsname{#6}% + \expandafter\gdef\csname pgf@pattern@type@#1\endcsname{7}% + }{\pgferror{The pattern `#1' is already defined}}% } \def\pgf@ifpatternisinherentlycolored#1#2#3{% @@ -210,49 +211,49 @@ % \pgfsetfillpattern{stars}{red} % \def\pgfsetfillpattern#1#2{% - \pgfutil@ifundefined{pgf@pattern@name@#1}% - {% - \PackageError{pgfcorepatterns}{Undefined pattern `#1'}{}% - }% - {% - \pgf@ifpatternismutable{#1}% - {% - % So, a mutable pattern. Check to see if the pattern - % has been used with the current variable values... - \let\pgf@pattern@tempvars\pgfutil@empty% - \expandafter\expandafter\expandafter\pgf@pattern@check@vars% - \csname pgf@pattern@variables@#1\endcsname,\pgf@stop,% - \edef\pgf@pattern@nametemp{pgf@pattern@#1@\pgf@pattern@tempvars}% - \expandafter\pgfutil@ifundefined\expandafter{\pgf@pattern@nametemp}% - {% - % ...Nope. So declare a new instance of the mutable pattern. - \pgf@ifpatternisinherentlycolored{#1}% - {\let\pgf@set@fillpattern@declare\pgfdeclarepatterninherentlycolored}% - {\let\pgf@set@fillpattern@declare\pgfdeclarepatternformonly}% - \pgf@set@fillpattern@declare% - {\pgf@pattern@nametemp}% - {\csname pgf@pattern@lowerleft@#1\endcsname}% - {\csname pgf@pattern@upperright@#1\endcsname}% - {\csname pgf@pattern@tilesize@#1\endcsname}% - {\csname pgf@pattern@code@#1\endcsname}% - }% - {% - % ...Yep. So do nothing. - }% - \expandafter\pgf@set@fillpattern\expandafter{\pgf@pattern@nametemp}{#2}% - \expandafter\gdef\csname\pgf@pattern@nametemp\endcsname{#1}% - }% - {% - % A non-mutable pattern. - \pgf@set@fillpattern{#1}{#2}% - }% - }% + \pgfutil@ifundefined{pgf@pattern@name@#1}% + {% + \pgferror{Undefined pattern `#1'}% + }% + {% + \pgf@ifpatternismutable{#1}% + {% + % So, a mutable pattern. Check to see if the pattern + % has been used with the current variable values... + \let\pgf@pattern@tempvars\pgfutil@empty% + \expandafter\expandafter\expandafter\pgf@pattern@check@vars% + \csname pgf@pattern@variables@#1\endcsname,\pgf@stop,% + \edef\pgf@pattern@nametemp{pgf@pattern@#1@\pgf@pattern@tempvars}% + \expandafter\pgfutil@ifundefined\expandafter{\pgf@pattern@nametemp}% + {% + % ...Nope. So declare a new instance of the mutable pattern. + \pgf@ifpatternisinherentlycolored{#1}% + {\let\pgf@set@fillpattern@declare\pgfdeclarepatterninherentlycolored}% + {\let\pgf@set@fillpattern@declare\pgfdeclarepatternformonly}% + \pgf@set@fillpattern@declare% + {\pgf@pattern@nametemp}% + {\csname pgf@pattern@lowerleft@#1\endcsname}% + {\csname pgf@pattern@upperright@#1\endcsname}% + {\csname pgf@pattern@tilesize@#1\endcsname}% + {\csname pgf@pattern@code@#1\endcsname}% + }% + {% + % ...Yep. So do nothing. + }% + \expandafter\pgf@set@fillpattern\expandafter{\pgf@pattern@nametemp}{#2}% + \expandafter\gdef\csname\pgf@pattern@nametemp\endcsname{#1}% + }% + {% + % A non-mutable pattern. + \pgf@set@fillpattern{#1}{#2}% + }% + }% } \def\pgf@set@fillpattern#1#2{% \pgfutil@ifundefined{pgf@pattern@name@#1}{% - \PackageError{pgfcorepatterns}{Undefined pattern `#1'}{}} + \pgferror{Undefined pattern `#1'}} {% \csname pgf@pattern@instantiate@#1\endcsname% \expandafter\global\expandafter\let\csname pgf@pattern@instantiate@#1\endcsname=\relax% @@ -273,24 +274,24 @@ } \def\pgf@pattern@check@vars#1,{% - \ifx#1\pgf@stop% - \let\pgf@next\relax% - \else% - \afterassignment\pgfmath@gobbletilpgfmath@% - \expandafter\let\expandafter\pgf@pattern@char#1#1\pgfmath@% - \ifx\pgf@pattern@char/% - \edef\pgf@pattern@tempvar{(\pgfkeysvalueof{#1})}% - \else% - \expandafter\ifcat\pgf@pattern@char\relax% - \edef\pgf@pattern@tempvar{(\the#1)}% - \else% - \edef\pgf@pattern@tempvar{(#1)}% - \fi% - \fi% - \edef\pgf@pattern@tempvars{\pgf@pattern@tempvars\pgf@pattern@tempvar}% - \let\pgf@next\pgf@pattern@check@vars% - \fi% - \pgf@next% + \ifx#1\pgf@stop% + \let\pgf@next\relax% + \else% + \afterassignment\pgfmath@gobbletilpgfmath@% + \expandafter\let\expandafter\pgf@pattern@char#1#1\pgfmath@% + \ifx\pgf@pattern@char/% + \edef\pgf@pattern@tempvar{(\pgfkeysvalueof{#1})}% + \else% + \expandafter\ifcat\pgf@pattern@char\relax% + \edef\pgf@pattern@tempvar{(\the#1)}% + \else% + \edef\pgf@pattern@tempvar{(#1)}% + \fi% + \fi% + \edef\pgf@pattern@tempvars{\pgf@pattern@tempvars\pgf@pattern@tempvar}% + \let\pgf@next\pgf@pattern@check@vars% + \fi% + \pgf@next% } \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex index 79cb3a06f77..b546d5df40f 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepoints.code.tex,v 1.20 2010/04/09 08:53:45 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepoints.code.tex,v 1.27 2013/10/07 15:51:46 tantau Exp $ \newdimen\pgf@picminx \newdimen\pgf@picmaxx @@ -99,10 +99,6 @@ % point yourself. In the below example, this command is used for a low level % coordinate system shift. % -% In addition to applying the transformation matrix to the given -% point, this function also applies the pre- and post-morphing -% macros. -% % Example: % % \begin{pgflowleveltransformshiftscope}{\pgfpointtransformed{\pgfpointorigin}} @@ -112,9 +108,7 @@ \def\pgfpointtransformed#1{% \pgf@process{% #1% - \pgfmorph@prelist% \pgf@pos@transform{\pgf@x}{\pgf@y}% - \pgfmorph@postlist% }% } @@ -201,7 +195,7 @@ % \pgfpointintersectionoflines{\pgfpointxy{0}{1}}{\pgfpointxy{1}{0}}{\pgfpointxy{2}{2}}{\pgfpointxy{3}{4}} \def\pgfpointintersectionoflines#1#2#3#4{% - { + {% % % Compute orthogonal vector to #1--#2 % @@ -439,6 +433,9 @@ % % x = x-component of #1*start + (1-#1)*end % y = y-component of #1*start + (1-#1)*end +% xa/ya = #1*start + (1-#1)*end +% xb/yb = start point +% xc/yc = end point % % Example: % @@ -447,14 +444,19 @@ \def\pgfpointlineattime#1#2#3{% \pgf@process{#3}% - \pgf@xa=\pgf@x% - \pgf@ya=\pgf@y% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgf@xc\pgf@x% + \pgf@yc\pgf@y% \pgf@process{#2}% - \advance\pgf@xa by-\pgf@x\relax% - \advance\pgf@ya by-\pgf@y\relax% - \advance\pgf@x by #1\pgf@xa\relax% - \advance\pgf@y by #1\pgf@ya\relax% - \ignorespaces} + \pgf@xb\pgf@x% + \pgf@yb\pgf@y% + \pgfmathsetmacro\pgf@temp{#1}% + \advance\pgf@xa by-\pgf@x% + \advance\pgf@ya by-\pgf@y% + \advance\pgf@x by\pgf@temp\pgf@xa% + \advance\pgf@y by\pgf@temp\pgf@ya% +} % Move point #2 #1 many units in the direction of #3. @@ -462,27 +464,35 @@ % #1 = a distance % #2 = start point % #3 = end point +% +% Description: +% +% Computes % -% x = x-component of start + #1*(normalise(end-start)) -% y = y-component of start + #1*(normalise(end-start)) -% xa = #1*(normalise(end-start)) -% ya = #1*(normalise(end-start)) +% x/y = start + #1*(normalise(end-start)) % -% Example: +% and additionally % +% xa/ya = #1*(normalise(end-start)) +% xb/yb = start +% xc/yc = end +% +% Example: % % \pgfpathmoveto{\pgfpointlineatdistance{2pt}{\pgfpointxy{0}{1}}{\pgfpointxy{2}{3}}} % \pgfpathlineto{\pgfpointlineatdistance{3pt}{\pgfpointxy{2}{3}}{\pgfpointxy{0}{1}}} \def\pgfpointlineatdistance#1#2#3{% + \pgfmathsetlength\pgf@xa{#1}% \pgf@process{#2}% - \pgf@xb=\pgf@x\relax% xb/yb = start point - \pgf@yb=\pgf@y\relax% + \pgf@xb\pgf@x% xb/yb = start point + \pgf@yb\pgf@y% \pgf@process{#3}% + \pgf@xc\pgf@x% + \pgf@yc\pgf@y% \advance\pgf@x by-\pgf@xb\relax% \advance\pgf@y by-\pgf@yb\relax% \pgf@process{\pgfpointnormalised{}}% x/y = normalised vector - \pgfmathsetlength\pgf@xa{#1}% \pgf@ya=\pgf@xa\relax% \pgf@xa=\pgf@sys@tonumber{\pgf@x}\pgf@xa% \pgf@ya=\pgf@sys@tonumber{\pgf@y}\pgf@ya% @@ -490,7 +500,7 @@ \pgf@y=\pgf@yb\relax% \advance\pgf@x by\pgf@xa\relax% \advance\pgf@y by\pgf@ya\relax% - \ignorespaces} +} % Returns point on a curve from #2 to #5 with controls #3 and #4 at time #1. @@ -506,7 +516,9 @@ % % Additionally, (\pgf@xa,\pgf@ya) and (\pgf@xb,\pgf@yb) will be on a % tangent to the point on the curve (this can be useful for computing -% a label rotation). +% a label rotation). (\pgf@xc,\pgf@yc) will be equal to the end +% point. \pgf@time@s will equal the value of #1 and \pgf@time@t will +% equal 1-#1. % % Example: % @@ -552,6 +564,58 @@ +% Returns point on an arc at a certain "time" +% +% #1 = a time +% #2 = center of a ellipse +% #3 = 0-degree exis of the ellipse +% #4 = 90-degree exis of the ellipse +% #5 = start angle of an arc on the ellipse +% #6 = end angle of an arc on the ellipse +% +% Result: +% +% \pgf@x = x-component of place on the arc at time t +% \pgf@y = y-component of place on the arc at time t +% +% Additionally, (\pgf@xa,\pgf@ya) will be a tangent to the +% point on the arc (this can be useful for computing a label rotation). +% +% Example: +% +% \pgfpointarcaxesattime{0.25}{\pgfpoint{1cm}{1cm}}{\pgfpoint{1cm}{0cm}}{\pgfpoint{0cm}{1cm}}{1cm}{30}{40} + +\def\pgfpointarcaxesattime#1#2#3#4#5#6{% + \pgfmathsetmacro\pgf@angle@start{#5}% + \pgfmathsetmacro\pgf@angle@end{#6}% + \pgfmathparse{#1}% + \pgf@x=\pgfmathresult pt% + \pgf@x=-\pgf@x% + \advance\pgf@x by 1pt% + \pgfmathsetmacro\pgf@angle@mid{\pgf@angle@end*\pgfmathresult+\pgf@angle@start*\pgf@sys@tonumber{\pgf@x}}% + \pgfmathcos@{\pgf@angle@mid}% + \let\pgf@angle@cos\pgfmathresult% + \pgfmathsin@{\pgf@angle@mid}% + \let\pgf@angle@sin\pgfmathresult% + \pgf@process{#3}% + \edef\pgf@angle@zero@axis{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}} + \pgf@process{#4}% + \edef\pgf@angle@ninety@axis{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}} + % Compute tangent + \pgf@process{\pgfpointadd{\pgfpointscale{\pgf@angle@sin}{\pgf@angle@zero@axis}}% + {\pgfpointscale{-\pgf@angle@cos}{\pgf@angle@ninety@axis}}}% + \ifdim\pgf@angle@start pt>\pgf@angle@end pt% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \else% + \pgf@xa=-\pgf@x% + \pgf@ya=-\pgf@y% + \fi% + % Compute position + \pgf@process{\pgfpointadd{#2}{% + \pgfpointadd{\pgfpointscale{\pgf@angle@cos}{\pgf@angle@zero@axis}}% + {\pgfpointscale{\pgf@angle@sin}{\pgf@angle@ninety@axis}}}}% +} @@ -1202,4 +1266,13 @@ \pgf@def{cosfrac}{97}{0.717792} \pgf@def{cosfrac}{98}{0.714213} \pgf@def{cosfrac}{99}{0.710651} \pgf@def{cosfrac}{100}{0.707107} + + + +% Forward declarations for nonlinear stuff (have no effect till module +% nonlineartransformations is loaded) + +\let\pgfpointtransformednonlinear\pgfpointtransformed + + \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorescopes.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorescopes.code.tex index 558f715788c..406d52e3a22 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorescopes.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorescopes.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorescopes.code.tex,v 1.34 2010/09/08 15:07:18 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorescopes.code.tex,v 1.44 2013/10/09 18:30:27 tantau Exp $ % Globals @@ -50,10 +50,14 @@ \pgfsys@beginscope% \pgf@resetpathsizes% \edef\pgfscope@linewidth{\the\pgflinewidth}% + \expandafter\let\expandafter\pgfscope@stroke@color\csname\string\color@pgfstrokecolor\endcsname% + \expandafter\let\expandafter\pgfscope@fill@color\csname\string\color@pgffillcolor\endcsname% \begingroup} \def\endpgfscope{% \endgroup% \global\pgflinewidth=\pgfscope@linewidth% + \expandafter\global\expandafter\let\csname\string\color@pgfstrokecolor\endcsname\pgfscope@stroke@color% + \expandafter\global\expandafter\let\csname\string\color@pgffillcolor\endcsname\pgfscope@fill@color% \pgfsys@endscope} @@ -116,6 +120,8 @@ \expandafter\pgf@text@setkeys\expandafter{\pgf@text@options}% \csname pgf@halign\pgf@text@hshift\endcsname% \csname pgf@valign\pgf@text@vshift\endcsname% + % + \pgfapproximatenonlineartransformation% % Protocol sizes: \pgf@process{\pgfpointtransformed{\pgfqpoint{0pt}{\dp\pgf@hbox}}}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% @@ -190,8 +196,6 @@ % \pgfusepath{stroke} % \end{pgfpicture} -\newif\ifpgfpicture - \def\pgfresetboundingbox{% \global\pgf@picmaxx=-16000pt\relax% \global\pgf@picminx=16000pt\relax% @@ -257,23 +261,26 @@ \pgf@relevantforpicturesizefalse% \pgf@process{\pgf@baseline}% \xdef\pgf@shift@baseline{\the\pgf@y}% - % + % \pgf@process{\pgf@trimleft}% \global\advance\pgf@x by-\pgf@picminx - % prepare \hskip\pgf@trimleft@final. + % prepare \hskip\pgf@trimleft@final. % note that \pgf@trimleft@final is also queried % by the pgf image externalization. \xdef\pgf@trimleft@final{-\the\pgf@x}% - % + % \pgf@process{\pgf@trimright}% \global\advance\pgf@x by-\pgf@picmaxx - % prepare \hskip\pgf@trimright@final. + % prepare \hskip\pgf@trimright@final. % note that \pgf@trimright@final is also queried % by the pgf image externalization. \xdef\pgf@trimright@final{\the\pgf@x}% + % + \pgf@remember@layerlist@globally \endgroup% \hss% \egroup% + \pgf@restore@layerlist@from@global \pgf@insertlayers% \endgroup% \pgfsys@discardpath% @@ -287,6 +294,12 @@ \endgroup% } +\def\pgf@remember@layerlist@globally{% + \global\let\pgf@layerlist@=\pgf@layerlist +}% +\def\pgf@restore@layerlist@from@global{% + \let\pgf@layerlist=\pgf@layerlist@ +}% \def\pgf@insertlayers{% \box\pgf@layerbox@main% } @@ -356,20 +369,20 @@ % \pgfsetbaseline{default}% resets to default value \def\pgfsetbaseline#1{% - \def\pgf@temp{#1}% - \ifx\pgf@temp\pgf@default@text - \pgfsetbaseline{\pgf@picminy}% - \else - \pgfsetbaselinepointlater{\pgfpoint{0pt}{#1}}% - \fi + \def\pgf@temp{#1}% + \ifx\pgf@temp\pgf@default@text + \pgfsetbaseline{\pgf@picminy}% + \else + \pgfsetbaselinepointlater{\pgfpoint{0pt}{#1}}% + \fi } \pgfsetbaseline{\pgf@picminy} % controls how the image externalization implements trim: \newif\ifpgf@trim@lowlevel \pgfkeys{ - /pgf/trim lowlevel/.is if=pgf@trim@lowlevel, - /pgf/trim lowlevel/.default=true, + /pgf/trim lowlevel/.is if=pgf@trim@lowlevel, + /pgf/trim lowlevel/.default=true, } % Same as the y-baseline for horizontal alignment. @@ -385,12 +398,12 @@ % or % \pgfsettrimleft{default} \def\pgfsettrimleft#1{% - \def\pgf@temp{#1}% - \ifx\pgf@temp\pgf@default@text - \pgfsettrimleft{\pgf@picminx} - \else - \pgfsettrimleftpointlater{\pgfpoint{#1}{0pt}}% - \fi + \def\pgf@temp{#1}% + \ifx\pgf@temp\pgf@default@text + \pgfsettrimleft{\pgf@picminx} + \else + \pgfsettrimleftpointlater{\pgfpoint{#1}{0pt}}% + \fi } \pgfsettrimleft{\pgf@picminx} @@ -404,12 +417,12 @@ % or % \pgfsettrimright{default} \def\pgfsettrimright#1{% - \def\pgf@temp{#1}% - \ifx\pgf@temp\pgf@default@text - \pgfsettrimright{\pgf@picmaxx}% - \else - \pgfsettrimrightpointlater{\pgfpoint{#1}{0pt}}% - \fi + \def\pgf@temp{#1}% + \ifx\pgf@temp\pgf@default@text + \pgfsettrimright{\pgf@picmaxx}% + \else + \pgfsettrimrightpointlater{\pgfpoint{#1}{0pt}}% + \fi } \pgfsettrimright{\pgf@picmaxx} @@ -445,6 +458,7 @@ \pgfsyssoftpath@setcurrentpath\pgfutil@empty% \edef\pgfscope@linewidth{\the\pgflinewidth}% \let\pgf@interrupt@lastmoveto=\pgfsyssoftpath@lastmoveto% + \let\pgf@interrupt@nlt@infos=\pgf@nlt@infos% \begingroup% } \def\endpgfinterruptpath @@ -453,9 +467,10 @@ \global\pgflinewidth=\pgfscope@linewidth% \pgfsyssoftpath@setcurrentpath\pgf@interrupt@path% \pgf@setpathsizes\pgf@interrupt@pathsizes% - \global\pgf@path@lastx=\pgf@interrupt@savex% - \global\pgf@path@lasty=\pgf@interrupt@savey% - \global\let\pgfsyssoftpath@lastmoveto=\pgf@interrupt@lastmoveto% + \global\pgf@path@lastx\pgf@interrupt@savex% + \global\pgf@path@lasty\pgf@interrupt@savey% + \global\let\pgfsyssoftpath@lastmoveto\pgf@interrupt@lastmoveto% + \global\let\pgf@nlt@infos=\pgf@interrupt@nlt@infos% \endgroup% } @@ -570,5 +585,4 @@ \let\pgf@savelayers=\relax \let\pgf@restorelayers=\relax - \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreshade.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreshade.code.tex index d4b0e8bee74..86bd57c32fe 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreshade.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreshade.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoreshade.code.tex,v 1.13 2008/11/23 16:07:47 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoreshade.code.tex,v 1.15 2013/07/15 14:24:02 tantau Exp $ % % Parsing functions @@ -133,8 +133,8 @@ \pgfutil@ifnextchar g{\pgf@grabgray}% {% \pgfutil@ifnextchar c{\pgf@grabcolor}% - {\PackageError{pgfshade}{Illformed shading - specification}{}\pgf@converttorgb}% + {\pgferror{Illformed shading + specification}\pgf@converttorgb}% }% }% }% @@ -424,7 +424,7 @@ \edef\pgf@shadingname{@pgfshading#1}% \pgf@tryextensions{\pgf@shadingname}{\pgfalternateextension}% \expandafter\pgfutil@ifundefined\expandafter{\pgf@shadingname}% - {\PackageError{pgfshade}{Undefined shading "#1"}{}}% + {\pgferror{Undefined shading "#1"}}% {% {% \pgfutil@globalcolorsfalse% @@ -531,22 +531,25 @@ \def\pgfshadepath#1#2{% \ifdim\pgf@pathminx=16000pt% - \PackageWarning{pgfshade}{No path specified that can be filled}% + \pgfwarning{No path specified that can be filled}% \else% \begingroup% + % Calculate center: + \pgf@xb=.5\pgf@pathmaxx% + \advance\pgf@xb by.5\pgf@pathminx% + \pgf@yb=.5\pgf@pathmaxy% + \advance\pgf@yb by.5\pgf@pathminy% + % Calculate scaling: + \pgf@xc=\pgf@pathmaxx% + \advance\pgf@xc by-\pgf@pathminx% + \pgf@yc=\pgf@pathmaxy% + \advance\pgf@yc by-\pgf@pathminy% + \pgf@xc=.01992528\pgf@xc% + \pgf@yc=.01992528\pgf@yc% + \ifdim\pgf@xc<0.0001pt\relax\ifdim\pgf@xc>-0.0001pt\relax\pgf@no@shadetrue\fi\fi% + \ifdim\pgf@yc<0.0001pt\relax\ifdim\pgf@yc>-0.0001pt\relax\pgf@no@shadetrue\fi\fi% + \ifpgf@no@shade\else% \pgfsys@beginscope% - % Calculate center: - \pgf@xb=.5\pgf@pathmaxx% - \advance\pgf@xb by.5\pgf@pathminx% - \pgf@yb=.5\pgf@pathmaxy% - \advance\pgf@yb by.5\pgf@pathminy% - % Calculate scaling: - \pgf@xc=\pgf@pathmaxx% - \advance\pgf@xc by-\pgf@pathminx% - \pgf@yc=\pgf@pathmaxy% - \advance\pgf@yc by-\pgf@pathminy% - \pgf@xc=.01992528\pgf@xc% - \pgf@yc=.01992528\pgf@yc% \pgfsyssoftpath@invokecurrentpath% \pgfsys@clipnext% \pgfsys@discardpath% @@ -570,10 +573,12 @@ \fi% \pgfuseshading{#1}% \pgfsys@endscope% + \fi% \endgroup% \fi% } +\newif\ifpgf@no@shade % Additionally transform shade paths % diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransformations.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransformations.code.tex index 442531ffa6f..83f89b1fa2d 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransformations.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransformations.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoretransformations.code.tex,v 1.11 2009/06/10 09:22:57 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoretransformations.code.tex,v 1.17 2013/10/10 08:53:09 tantau Exp $ % Position transformations @@ -57,15 +57,15 @@ % % \pgfsettransformentries\aa\ab\ba\bb\shiftx\shifty \def\pgfgettransformentries#1#2#3#4#5#6{% - \edef#1{\pgf@pt@aa}% - \edef#2{\pgf@pt@ab}% - \edef#3{\pgf@pt@ba}% - \edef#4{\pgf@pt@bb}% - \edef#5{\the\pgf@pt@x}% - \edef#6{\the\pgf@pt@y}% + \edef#1{\pgf@pt@aa}% + \edef#2{\pgf@pt@ab}% + \edef#3{\pgf@pt@ba}% + \edef#4{\pgf@pt@bb}% + \edef#5{\the\pgf@pt@x}% + \edef#6{\the\pgf@pt@y}% }% \def\pgfsettransformentries#1#2#3#4#5#6{% - \pgfsettransform{{#1}{#2}{#3}{#4}{#5}{#6}}% + \pgfsettransform{{#1}{#2}{#3}{#4}{#5}{#6}}% }% % Restore the current transformation matrix from a macro. @@ -273,41 +273,6 @@ } -% Add a pre-morph -% -% #1 = morphing code -% -% Description: -% -% This function adds code to the pre-morphing list. When a -% coordinate is transformed, the current pre-morphing code is -% called first. Then the transformation matrix is applied. Finally, all -% post-morphing code is called. The morphing list is local to the -% current TeX group. -% -% The job of the #1 macro is to modify the values of \pgf@x and -% \pgf@y. It should not have any other sideeffects. -% -% Example: -% -% \pgfmorphaddmorph{\advance\pgf@x by 1cm\relax} - -\def\pgfmorphaddpre#1{\expandafter\def\expandafter\pgfmorph@prelist\expandafter{\pgfmorph@prelist#1}} -\let\pgfmorph@prelist=\pgfutil@empty - - -% Add a post-morph -% -% #1 = morphing macro -% -% Description: -% -% The only difference to the pre-morphs is that post morphs are -% executed after the transformation matrix has been applied. - -\def\pgfmorphaddpost#1{\expandafter\def\expandafter\pgfmorph@postlist\expandafter{\pgfmorph@postlist#1}} -\let\pgfmorph@postlist=\pgfutil@empty - % Transformation into a given triangle. The three corners of the % triangle are called "origin", "x" and "y" are given. After this @@ -385,9 +350,9 @@ % % \pgftansformshift{\pgfpoint{1cm}{1cm}} -\def\pgftransformshift#1{\pgftransformcm{1.0}{0}{0}{1.0}{#1}} -\def\pgftransformxshift#1{\pgftransformcm{1.0}{0}{0}{1.0}{\pgfpoint{#1}{0pt}}} -\def\pgftransformyshift#1{\pgftransformcm{1.0}{0}{0}{1.0}{\pgfpoint{0pt}{#1}}} +\def\pgftransformshift#1{\pgftransformcm{1}{0}{0}{1}{#1}} +\def\pgftransformxshift#1{\pgftransformcm{1}{0}{0}{1}{\pgfpoint{#1}{+0pt}}} +\def\pgftransformyshift#1{\pgftransformcm{1}{0}{0}{1}{\pgfpoint{+0pt}{#1}}} @@ -487,25 +452,71 @@ % } % \def\pgftransformlineattime#1#2#3{% - \pgftransformshift{\pgfpointlineattime{#1}{#2}{#3}}% + \pgf@process{#2}% + \pgf@xb=\pgf@x% xb/yb = start point + \pgf@yb=\pgf@y% + \pgf@process{#3}% + \pgf@xc=\pgf@x% xc/yc = end point + \pgf@yc=\pgf@y% + \pgftransformshift{\pgfpointlineattime{#1}{\pgfqpoint{\pgf@xb}{\pgf@yb}}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}% + \ifpgfresetnontranslationattime% + \pgftransformresetnontranslations% + \fi% + \ifpgfslopedattime% + \advance\pgf@xc by-\pgf@xb% + \advance\pgf@yc by-\pgf@yb% + \ifpgfallowupsidedownattime% + \else% + \ifdim\pgf@xc<0pt% + \pgf@xc=-\pgf@xc% + \pgf@yc=-\pgf@yc% + \fi% + \fi% + \pgf@x=\pgf@xc% + \pgf@y=\pgf@yc% + \pgfpointnormalised{}% x/y = normalised vector + \pgf@ya=-\pgf@y% + \pgftransformcm% + {\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}% + {\pgf@sys@tonumber{\pgf@ya}}{\pgf@sys@tonumber{\pgf@x}}{\pgfpointorigin}% + \fi% +} + + +% Transform to the coordinate system of a point on an arc +% +% #1 = a time fraction of line where to put the label, where 0 means start, +% 1 means end, and for example 0.5 means the middle. +% #2 = center of an ellipse +% #3 = 0-degree axis of the ellipse +% #4 = 90-degree axis of the ellipse +% #4 = start angle of the arc on this ellipse +% #5 = end angle of the arc on this ellipse +% +% Example: +% +% { +% \pgftransformlineattime{.5}{\pgfpoint{1cm}{1cm}}{\pgfpoint{1cm}{0cm}}{\pgfpoint{0cm}{1cm}}{30}{40} +% \pgftext{Hi!} +% } + +\def\pgftransformarcaxesattime#1#2#3#4#5#6{% + \pgfpointarcaxesattime{#1}{#2}{#3}{#4}{#5}{#6}% + \pgftransformshift{\pgfqpoint{\pgf@x}{\pgf@y}}% \ifpgfresetnontranslationattime% \pgftransformresetnontranslations% \fi% \ifpgfslopedattime% - \pgf@process{#2}% - \pgf@xa=\pgf@x% xb/yb = start point - \pgf@ya=\pgf@y% - \pgf@process{#3}% - \advance\pgf@x by-\pgf@xa% - \advance\pgf@y by-\pgf@ya% + \pgf@x=\pgf@xa% + \pgf@y=\pgf@ya% + \pgf@process{\pgfpointnormalised{}}% \ifpgfallowupsidedownattime% \else% - \ifdim\pgf@x<0pt% + \ifdim\pgf@x<0pt% \pgf@x=-\pgf@x% \pgf@y=-\pgf@y% \fi% \fi% - \pgfpointnormalised{}% x/y = normalised vector \pgf@ya=-\pgf@y% \pgftransformcm% {\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}% @@ -579,8 +590,8 @@ % \pgftransformarrow{\pgfpointorigin}{\pgfpoint{1cm}{0cm}} \def\pgftransformarrow#1#2{% - \pgftransformshift{#2}% \pgf@process{#2}% + \pgftransformshift{}% \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% \pgf@process{#1}% @@ -658,5 +669,13 @@ +% Forward declarations for nonlinear stuff (have no effect till module +% nonlineartransformations is loaded) + +\let\pgfapproximatenonlineartranslation\relax +\let\pgfapproximatenonlineartransformation\relax +\def\pgftransformnonlinear#1{\pgferror{You need to say + \string\usepgfmodule{nonlineartransformation} to use nonlinear transformations}} + \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransparency.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransparency.code.tex index 3048e6077fe..47484997af7 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransparency.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransparency.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoretransparency.code.tex,v 1.2 2008/01/17 20:09:16 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoretransparency.code.tex,v 1.5 2013/09/30 18:30:15 tantau Exp $ % Sets the opacity of stroking operations. @@ -39,6 +39,37 @@ +% Sets the current blend mode. See Section 7.2.4 of the PDF +% Specification 1.7 for an introduction to blend modes in general. +% +% #1 = One of the following modes, see also section 7.2.4 of the +% PDF Specification 1.7. (The PGF names, which are all lowercase with +% spaces as usual, must be mapped to the PDF or SVG by the drivers.) +% +% normal +% multiply +% screen +% overlay +% darken +% lighten +% color dodge +% color burn +% hard light +% soft light +% difference +% exclusion +% saturation +% color +% hue +% luminosity +% +% Example: +% +% \pgfsetblendmode{multiply} + +\def\pgfsetblendmode#1{\pgfsys@blend@mode{#1}} + + % Declares a new fading based on the contents of a box. % % #1 = name of the fading @@ -156,8 +187,10 @@ % Calculate scaling: \pgf@xc=\pgf@pathmaxx% \advance\pgf@xc by-\pgf@pathminx% + \ifdim\pgf@xc<0.1pt\pgf@xc=0.1pt\fi% \pgf@yc=\pgf@pathmaxy% \advance\pgf@yc by-\pgf@pathminy% + \ifdim\pgf@yc<0.1pt\pgf@yc=0.1pt\fi% \pgf@xc=.02\pgf@xc% \pgf@yc=.02\pgf@yc% % Compute new transformation matrix: @@ -171,6 +204,49 @@ +% Use a previously declared fading scaled for the current path. +% +% #1 - an fading +% #2 - extra transformations +% +% Description: +% +% This command works like \pgfsetfadingforcurrentpath, only it takes +% the current line width into account: Before the path is considered, +% it is enlarged by half the line width in all directions. + +\def\pgfsetfadingforcurrentpathstroked#1#2{% + \ifdim\pgf@pathminx=16000pt% + % Path was empty -> use natural size + \pgfsetfading{#1}{#2}% + \else% + \pgfsetfading{#1}{% + % Calculate center: + \pgf@xb=.5\pgf@pathmaxx% + \advance\pgf@xb by.5\pgf@pathminx% + \pgf@yb=.5\pgf@pathmaxy% + \advance\pgf@yb by.5\pgf@pathminy% + % Calculate scaling: + \pgf@xc=\pgf@pathmaxx% + \advance\pgf@xc by-\pgf@pathminx% + \advance\pgf@xc by\pgflinewidth% + \ifdim\pgf@xc<0.1pt\pgf@xc=0.1pt\fi% + \pgf@yc=\pgf@pathmaxy% + \advance\pgf@yc by-\pgf@pathminy% + \advance\pgf@yc by\pgflinewidth% + \ifdim\pgf@yc<0.1pt\pgf@yc=0.1pt\fi% + \pgf@xc=.02\pgf@xc% + \pgf@yc=.02\pgf@yc% + % Compute new transformation matrix: + \pgftransformcm{1}{0}{0}{1}{\pgfqpoint{\pgf@xb}{\pgf@yb}}% + \pgftransformcm{\pgf@sys@tonumber{\pgf@xc}}{0}{0}{\pgf@sys@tonumber{\pgf@yc}}{\pgfpointorigin}% + #2% + }% + \fi% +} + + + % Group things in a a transparency group % % Description: @@ -186,9 +262,22 @@ % \def\pgftransparencygroup{% + \pgfutil@ifnextchar[{\pgftransparencygroup@}{\pgftransparencygroup@[]}% +} +\def\pgftransparencygroup@[#1]{% \begingroup% + \pgfkeys{/pgf/transparency group options/.cd,% + isolated=false, + knockout=false, + #1}% \setbox\pgfutil@tempboxa=\hbox\bgroup% } +\pgfkeys{ + /pgf/transparency group options/.cd, + isolated/.is if=pgfsys@transparency@group@isolated, + knockout/.is if=pgfsys@transparency@group@knockout +} + \def\endpgftransparencygroup{% \egroup% % Now compute the correct position. This is a bit tricky... diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgpgf.cfg b/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgpgf.cfg deleted file mode 100644 index f1e0f36ce16..00000000000 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgpgf.cfg +++ /dev/null @@ -1,2 +0,0 @@ -\SYSTEM {http://www.tcs.uni-luebeck.de/dtds/svgpgf.dtd} {svgpgf.xmt} -\NAME{svgpgf} {svgpgf.xmt} diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgpgf.xmt b/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgpgf.xmt deleted file mode 100644 index 7a3e688e6ee..00000000000 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgpgf.xmt +++ /dev/null @@ -1,48 +0,0 @@ -\DeclareNamespace{svg}{http://www.w3.org/2000/svg} - -\XMLelement{svg:svg}{ -} -{\begin{pgfpicture} - \pgfsetyvec{\pgfpoint{0cm}{-1cm}}} -{\end{pgfpicture}} - -\XMLelement{svg:rect}{ - \XMLattribute{width}{\svgwidth}{0} - \XMLattribute{height}{\svgheight}{0} - \XMLattribute{x}{\svgx}{0} - \XMLattribute{y}{\svgy}{0} - \XMLattribute{fill}{\svgfill}{x000} -} -{ - \expandafter\svgparsefill\svgfill - \pgfsetfillcolor{mycol} - \pgfpathrectangle{\pgfpointxy{\svgx}{\svgy}}{\pgfpointxy{\svgwidth}{\svgheight}} - \pgfusepath{fill}} -{} - -\gdef\svgparsefill#1#2#3#4{% - \pgfmathparse{\csname tonum#2\endcsname/16} - \let\myred=\pgfmathresult - \pgfmathparse{\csname tonum#3\endcsname/16} - \let\mygreen=\pgfmathresult - \pgfmathparse{\csname tonum#4\endcsname/16} - \let\myblue=\pgfmathresult - \definecolor{mycol}{rgb}{\myred,\mygreen,\myblue} -} - -\expandafter\gdef\csname tonum0\endcsname{0} -\expandafter\gdef\csname tonum1\endcsname{1} -\expandafter\gdef\csname tonum2\endcsname{2} -\expandafter\gdef\csname tonum3\endcsname{3} -\expandafter\gdef\csname tonum4\endcsname{4} -\expandafter\gdef\csname tonum5\endcsname{5} -\expandafter\gdef\csname tonum6\endcsname{6} -\expandafter\gdef\csname tonum7\endcsname{7} -\expandafter\gdef\csname tonum8\endcsname{8} -\expandafter\gdef\csname tonum9\endcsname{9} -\expandafter\gdef\csname tonuma\endcsname{10} -\expandafter\gdef\csname tonumb\endcsname{11} -\expandafter\gdef\csname tonumc\endcsname{12} -\expandafter\gdef\csname tonumd\endcsname{13} -\expandafter\gdef\csname tonume\endcsname{14} -\expandafter\gdef\csname tonumf\endcsname{15} diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.cfg b/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.cfg deleted file mode 100644 index f658cf84240..00000000000 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.cfg +++ /dev/null @@ -1,3 +0,0 @@ -%\PUBLIC {-//W3C//DTD SVG 1.1//EN} {svgpgf.xmt} -%\NAME{svg} {svgpgf.xmt} - diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.tex deleted file mode 100644 index 4e919ca1371..00000000000 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.tex +++ /dev/null @@ -1,15 +0,0 @@ -\documentclass{article} - -\usepackage{pgfsvg} - -\begin{document} - -Huhu... - -\xmlinclude{svgtest.xml} -foo... -\xmlinclude{rect01.xml} - -%\xmlinclude{svgtest.xml} - -\end{document}
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.xml b/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.xml deleted file mode 100644 index 109ee812629..00000000000 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" - "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> - -<svg xmlns="http://www.w3.org/2000/svg" - width="200" - height="200" - viewBox="0 0.5 5 5" preserveAspectRatio="none"> - <rect id="black_stripe" - fill="#000" - width="5" - height="1"/> - <rect id="gray_i" - fill="#484" - width="6" - height="1" y="2"/> - <rect id="gray_ii" - fill="#888" - width="3" - height="1" y="3"/> - <rect id="gray_iii" - fill="#ccc" - width="2" - height="1" y="4"/> - <rect id="white" - fill="#fff" - width="5" - height="1" y="5"/> -</svg> diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.code.tex index 693da7c5907..e8aeabd2468 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.code.tex @@ -77,8 +77,8 @@ } } \newcount\tikz@lib@circ@count -\def\tikz@zero@text{0} -\def\tikz@one@text{1} +\def\tikz@zero@text{0.0} +\def\tikz@one@text{1.0} \def\tikz@lib@circ@compute@direction#1{% \tikz@scan@one@point\tikz@lib@circ@save@start(\tikztostart)% @@ -176,6 +176,7 @@ [annotation arrow,->] [label distance=#2,##1] #3 + \tikz@after@path% \egroup% } }, @@ -189,6 +190,7 @@ [annotation arrow,->] [label distance=#2,##1] #3 + \tikz@after@path% \egroup% } } @@ -251,13 +253,15 @@ \def\tikz@lib@circ@lab[#1]#2\pgf@stop#3#4{\tikzset{label={[every info/.try,every #4/.try,#1]$\mathrm{#2#3}$}}} \def\tikz@lib@circ@lab@sloped[#1]#2\pgf@stop#3#4{\tikzset{label={[every info/.try,every #4/.try,transform shape,#1]$\mathrm{#2#3}$}}} -\def\tikz@lib@circ@labp[#1]#2\pgf@stop#3#4{\tikzset{label={[every info/.try,every #4/.try,#1]below:$\mathrm{#2#3}$}}} -\def\tikz@lib@circ@lab@slopedp[#1]#2\pgf@stop#3#4{\tikzset{label={[every info/.try,every #4/.try,transform shape,#1]below:$\mathrm{#2#3}$}}} +\def\tikz@lib@circ@labp[#1]#2\pgf@stop#3#4{\tikzset{label={[label position=below,every info/.try,every #4/.try,#1]$\mathrm{#2#3}$}}} +\def\tikz@lib@circ@lab@slopedp[#1]#2\pgf@stop#3#4{\tikzset{label={[label +position=below,every info/.try,every #4/.try,transform shape,#1]$\mathrm{#2#3}$}}} \def\tikz@lib@circ@lab@plain[#1]#2\pgf@stop{\tikzset{label={[every info/.try,#1]#2}}} \def\tikz@lib@circ@lab@sloped@plain[#1]#2\pgf@stop{\tikzset{label={[every info/.try,transform shape,#1]#2}}} -\def\tikz@lib@circ@labp@plain[#1]#2\pgf@stop{\tikzset{label={[every info/.try,#1]below:#2}}} -\def\tikz@lib@circ@lab@slopedp@plain[#1]#2\pgf@stop{\tikzset{label={[every info/.try,transform shape,#1]below:#2}}} +\def\tikz@lib@circ@labp@plain[#1]#2\pgf@stop{\tikzset{label={[label position=below,every info/.try,#1]#2}}} +\def\tikz@lib@circ@lab@slopedp@plain[#1]#2\pgf@stop{\tikzset{label={[label +position=below,every info/.try,transform shape,#1]#2}}} diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.code.tex index 91641309ab5..d8337acefcd 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.code.tex @@ -127,29 +127,15 @@ (.2\tikzcircuitssizeunit,.65\tikzcircuitssizeunit) edge[line to] ++(-45:1.25\tikzcircuitssizeunit) (-.2\tikzcircuitssizeunit,.25\tikzcircuitssizeunit) edge[line to] ++(-45:1.25\tikzcircuitssizeunit) }, - adjustable/.style={ - append after command={% - \bgroup - [current point is local=true] - [every adjustable/.try] - [annotation arrow,->] - let \p1=(\tikzlastnode.north), \p2=(\tikzlastnode.south) in - [label distance=1.5\tikzcircuitssizeunit-.5*abs(\y2-\y1),#1] - (-1.5\tikzcircuitssizeunit,-1.5\tikzcircuitssizeunit) edge[line to] (1.5\tikzcircuitssizeunit,1.5\tikzcircuitssizeunit) - \egroup% - } + circuit declare annotation={adjustable}{1.5\tikzcircuitssizeunit} + { + [shift=(\tikzlastnode.center)] + (-1.5\tikzcircuitssizeunit,-1.5\tikzcircuitssizeunit) edge[line to] (1.5\tikzcircuitssizeunit,1.5\tikzcircuitssizeunit) }, - adjustable'/.style={ - append after command={% - \bgroup - [current point is local=true,yscale=-1] - [every adjustable/.try] - [annotation arrow,->] - let \p1=(\tikzlastnode.north), \p2=(\tikzlastnode.south) in - [label distance=1.5\tikzcircuitssizeunit-.5*abs(\y2-\y1),#1] - (-1.5\tikzcircuitssizeunit,-1.5\tikzcircuitssizeunit) edge[line to] (1.5\tikzcircuitssizeunit,1.5\tikzcircuitssizeunit) - \egroup% - } + circuit declare annotation={adjustable'}{1.5\tikzcircuitssizeunit} + { + [shift=(\tikzlastnode.center)] + (-1.5\tikzcircuitssizeunit,1.5\tikzcircuitssizeunit) edge[line to] (1.5\tikzcircuitssizeunit,-1.5\tikzcircuitssizeunit) } } diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.code.tex index c717e95cf7b..e181c3b97ab 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.code.tex,v 1.31 2010/09/15 22:27:36 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.code.tex,v 1.44 2013/07/19 13:16:48 tantau Exp $ \usepgfmodule{datavisualization} \usetikzlibrary{backgrounds} @@ -60,14 +60,29 @@ % /tikz/every data is executed for each data, which can be useful to % generally set, say, a certain data format. % -% "info" blocks. % -% Syntax: info [options] {code} +% "data set" blocks. +% +% Syntax: data set [options] {name} = { ... } +% Syntax: data set [options] {name} += { ... } +% Syntax: data set [options] {name} +% +% The first syntax allows you to define a data set. The data block +% inside {...} will be stored inside the data set +% "name". Subsequently, the data set can be referenced by using the +% third syntax. The second syntax allows you to extend the +% definition of an already defined data set. +% +% +% "info" and "info'" blocks. +% +% Syntax: info [options] {code} +% Syntax: info' [options] {code} +% +% A block starting with "info" or "info'" may contain any code. It +% will be executed after the visualization (info) or before the +% visualization (info'). % -% A block starting with "info" may contain any code. It -% will be executed after the visualization. In order to execute code -% at some other time (like, say, before the visualization), use -% options like "before visualization". % % Options blocks. % @@ -103,7 +118,7 @@ % var x: interval [0:3]; % func y = \value x*\value x; % } -% [before visualization={ +% [at begin visualization={ % \fill [black!10] (visualization cs:x=0,y=0) -- (visualization cs:x=3,y=9); % }] % info[red] @@ -121,6 +136,7 @@ \def\tikz@lib@datavisualization{ \begingroup% + \let\tikz@path@do@at@end=\relax% % Ok, first, start a new data visualization \pgfoonew \tikz@main@dv=new data visualization()% % Next, create a scope for the dv @@ -141,6 +157,7 @@ \tikz@main@dv.before visualization(% )% \tikz@main@dv.after visualization(% + \tikz@lib@dv@alias@dv@bb \pgfkeysvalueof{/tikz/data visualization/grid actions} \pgfkeysvalueof{/tikz/data visualization/subminor grid actions} \pgfkeysvalueof{/tikz/data visualization/minor grid actions} @@ -167,7 +184,7 @@ \pgfutil@ifnextchar i\tikz@lib@dv@handle@info{% \pgfutil@ifnextchar [\tikz@lib@dv@handle@options{% \pgfutil@ifnextchar \egroup\tikz@lib@dv@handle@endscope{% - \PackageError{tikz}{Semicolon expected}{}% + \tikzerror{Semicolon expected}% \endgroup% }% }% @@ -177,11 +194,12 @@ }% }% } -\def\tikz@lib@dv@parse@end{% +\def\tikz@lib@dv@parse@end;{% % Go! \tikz@main@dv.survey()% \tikz@main@dv.visualize()% \endgroup% + \tikz@path@do@at@end% } \def\tikz@lib@dv@handle@par\par{\tikz@lib@dv@parse@loop} @@ -196,27 +214,74 @@ } \def\tikz@lib@dv@beg@opt[#1]{% \pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}% - \pgfkeysvalueof{/pgf/data visualization/obj}.add data({{\begingroup\pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}}})% + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{\begingroup\pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}}})}% \pgfutil@ifnextchar\bgroup{ \afterassignment\tikz@lib@dv@parse@loop% \let\tikz@dummy=%get rid of \bgroup }{% - \PackageError{pgf}{Opening brace expected}{}% + \tikzerror{Opening brace expected}% + \tikz@lib@dv@parse@loop% }% } \def\tikz@lib@dv@handle@endscope{% - \pgfkeysvalueof{/pgf/data visualization/obj}.add data(\endgroup)% + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data(\endgroup)}% \endgroup% \afterassignment\tikz@lib@dv@parse@loop% \let\tikz@dummy=%get rid of \egroup } -\def\tikz@lib@dv@handle@data data{\pgfdata} +\def\tikz@lib@dv@handle@data data{% + \pgfutil@ifnextchar g{\tikz@lib@dv@handle@data@group}{% + \pgfutil@ifnextchar p{\tikz@lib@dv@handle@data@point}{% + \pgfdata}}} + +\def\tikz@lib@dv@handle@data@group group{\pgfutil@ifnextchar[{\tikz@lib@dv@handle@data@group@opt}{\tikz@lib@dv@handle@data@group@opt[]}}%} + +\def\tikz@lib@dv@handle@data@group@opt[#1]#2{% + \pgfutil@ifnextchar={\tikz@lib@dv@handle@data@group@def{#1}{#2}}{% + \pgfutil@ifnextchar+{\tikz@lib@dv@handle@data@group@extend{#1}{#2}}{% + \tikz@lib@dv@handle@data@group@use{#1}{#2}}}} + +\def\tikz@lib@dv@handle@data@group@def#1#2={% + \pgfkeys{/pgf/data/new group=#2}% + \tikz@lib@dv@handle@data@group@extend{#1}{#2}+=% +} + +\def\tikz@lib@dv@handle@data@group@extend#1#2+={% + \pgfutil@ifnextchar\bgroup{ + \begingroup% + \pgfkeys{/pgf/data/store in group=#2}% + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{\begingroup\pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}}})}% + \afterassignment\tikz@lib@dv@parse@loop% + \let\tikz@dummy=%get rid of \bgroup + }{% + \tikzerror{Opening brace expected}% + \tikz@lib@dv@parse@loop% + }% +} + +\def\tikz@lib@dv@handle@data@group@use#1#2{% + \pgfdata[#1,use group=#2]% +} + +\def\tikz@lib@dv@handle@data@point point{\pgfutil@ifnextchar[{\tikz@lib@dv@handle@data@point@opt}{\tikz@lib@dv@handle@data@point@opt[]}}%] +\def\tikz@lib@dv@handle@data@point@opt[#1]{% + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{\bgroup\pgfkeys{/data point/.cd,#1}\pgfdatapoint\egroup}})}% + \tikz@lib@dv@parse@loop% +} -\def\tikz@lib@dv@handle@info info{ +\def\tikz@lib@dv@handle@info info{% + \pgfutil@ifnextchar'{\tikz@lib@dv@handle@info@prime}{\tikz@lib@dv@handle@info@noprime}} +\def\tikz@lib@dv@handle@info@noprime{% \pgfutil@ifnextchar[{\tikz@lib@dv@handle@info@block@opt}{\tikz@lib@dv@handle@info@block@opt[]}}%} \def\tikz@lib@dv@handle@info@block@opt[#1]#2{% - \tikz@main@dv.after visualization({{\scope[#1]#2\endscope}})% + \tikz@main@dv.after visualization({\scope[#1]#2\endscope})% + \tikz@lib@dv@parse@loop +} +\def\tikz@lib@dv@handle@info@prime'{% + \pgfutil@ifnextchar[{\tikz@lib@dv@handle@info@block@opt@prime}{\tikz@lib@dv@handle@info@block@opt@prime[]}}%} +\def\tikz@lib@dv@handle@info@block@opt@prime[#1]#2{% + \tikz@main@dv.before visualization({\scope[#1]#2\endscope})% \tikz@lib@dv@parse@loop } @@ -229,17 +294,31 @@ % \tikzdatavisualizationset{ - before survey/.code=\tikz@main@dv.before survey({{#1}}), - after survey/.code=\tikz@main@dv.after survey({{#1}}), - before visualization/.code=\tikz@main@dv.before visualization({{#1}}), - after visualization/.code=\tikz@main@dv.after visualization({{#1}}), - at start survey/.code=\tikz@main@dv.at start survey({{#1}}), - at end survey/.code=\tikz@main@dv.at end survey({{#1}}), - at start visualization/.code=\tikz@main@dv.at start visualization({{#1}}), - at end visualization/.code=\tikz@main@dv.at end visualization({{#1}}), + before survey/.code=\tikz@main@dv.before survey({#1}), + after survey/.code=\tikz@main@dv.after survey({#1}), + before visualization/.code=\tikz@main@dv.before visualization({#1}), + after visualization/.code=\tikz@main@dv.after visualization({#1}), + at start survey/.code=\tikz@main@dv.at start survey({#1}), + at end survey/.code=\tikz@main@dv.at end survey({#1}), + at start visualization/.code=\tikz@main@dv.at start visualization({#1}), + at end visualization/.code=\tikz@main@dv.at end visualization({#1}), } +\def\tikz@lib@dv@alias@dv@bb{ + \pgfnodealias{data bounding box}{data visualization bounding box}% + \pgfkeys{/pgf/freeze local bounding box=data bounding box}% +} + +% +% The data point key +% +\tikzdatavisualizationset{ + data point/.code={ + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{\bgroup\pgfkeys{/data point/.cd,#1}\pgfdatapoint\egroup}})}% + } +} + % % Object setup @@ -409,7 +488,7 @@ % \tikzdatavisualizationset{% - new axis/.style={ + new axis base/.style={ new object={ class=scaling mapper, store=/tikz/data visualization/#1/scaling mapper, @@ -462,8 +541,6 @@ node styling/.style={% /utils/exec={\pgfkeysgetvalue{/tikz/data visualization/@node styling}\tikz@temp\expandafter\tikzset\expandafter{\tikz@temp}}}, node style/.style={/tikz/data visualization/@node styling/.append={,#1}}, - grid styling/.style=, - grid style/.style={grid styling/.append style={#1}}, % General extends (both axes, grid and ticks) low/.initial=0, high/.initial=0, @@ -483,20 +560,31 @@ @setup at setters, % Tick keys direction axis/.initial=, - value/.initial=, - pos/.initial=, + % Tick text modifiers + tick text low even padding/.initial=0pt, + tick text high even padding/.initial=0pt, + tick text low odd padding/.initial=0pt, + tick text high odd padding/.initial=0pt, + tick text odd padding/.style={tick text low odd padding={-#1},tick text high odd padding={#1}}, + tick text even padding/.style={tick text low even padding={-#1},tick text high even padding={#1}}, + tick text padding/.style={tick text odd padding={#1},tick text even padding={#1}}, + stack/.style={tick text even padding={#1}}, + stack'/.style={tick text odd padding={#1}}, + stack/.default=1em, + stack'/.default=1em, tick text at low/.is if=tikz@dv@min@tick@node, tick text at high/.is if=tikz@dv@max@tick@node, no tick text/.style={tick text at low=false,tick text at high=false}, + % every major ticks/.style={style={line cap=round},tick length=2pt}, - every minor ticks/.style={style={help lines,thin,line cap=round},tick length=1.4pt}, - every subminor ticks/.style={style={help lines,line cap=round},tick length=0.8pt}, + every minor ticks/.style={style={solid, help lines,thin,line cap=round},tick length=1.4pt}, + every subminor ticks/.style={style={solid, help lines,line cap=round},tick length=0.8pt}, clean ticks/.style={node style={fill=white}}, % Default grid styles - grid style={high=max,low=min}, - every major grid/.style={style={help lines,thin,black!25}}, - every minor grid/.style={style={help lines,black!25}}, - every subminor grid/.style={style={help lines,black!10}}, + every grid/.style={high=max,low=min}, + every major grid/.style={style={solid, help lines,thin,black!25}}, + every minor grid/.style={style={solid, help lines,black!25}}, + every subminor grid/.style={style={solid, help lines,black!10}}, at default ticks/.code={% \expandafter\pgfkeysalso\expandafter{\tikz@lib@dv@ticks@default@at}}, at ticks/.code={% @@ -549,21 +637,21 @@ rounded corners=1.5pt } }, - every visualizer label/.style={ + every data set label/.style={ every ticks, node style={ - font=\pgfutil@font@small + font=\pgfutil@font@small, } }, @color of visualizer labels/.style={text=black}, - every visualizer legend label/.style={ + every label in legend/.style={ node style={ - fill=none + fill=none, } }, every axis label/.style={ node style={% - font=\pgfutil@font@small + font=\pgfutil@font@small, } } } @@ -580,7 +668,15 @@ padding min/.style={\tikz@dv@axis/padding min={#1}}, padding max/.style={\tikz@dv@axis/padding max={#1}}, padding/.style={padding min={-#1},padding max={#1}}, - label/.style={\tikz@dv@axis/label={#1}}, + label/.code={% + \def\pgf@temp{#1}% + \ifx\pgf@temp\tikz@lib@dv@auto@attribute% + \tikzdatavisualizationset{\tikz@dv@axis/label/.expanded=$\noexpand\mathit{\pgfkeysvalueof{\tikz@dv@axis/attribute}}$}% + \else + \tikzdatavisualizationset{\tikz@dv@axis/label={#1}}% + \fi + }, + label/.default=\tikz@lib@dv@auto@attribute, % % Strategies % @@ -590,17 +686,9 @@ % Attribute setter % goto/.code={\tikz@dv@goto{\tikz@dv@axis}{#1}}, - % - % Modification of the range - % - include values/.style={% - /tikz/data visualization/before survey/.expanded={% - \noexpand\pgfkeysgetvalue{\tikz@dv@axis/scaling mapper}\noexpand\tikz@dv@axis@mapper% - \noexpand\foreach \noexpand\tikz@lib@dv@temp in {#1} {% - \noexpand\tikz@dv@axis@mapper.include in value(\noexpand\tikz@lib@dv@temp)% - }% - }% - }, + goto pos/.code={\tikz@dv@goto@pos{\tikz@dv@axis}{#1}}, + anchor at min/.code={\tikz@lib@dv@special@at{\tikz@dv@axis}{\tikz@dv@min@anchor}}, + anchor at max/.code={\tikz@lib@dv@special@at{\tikz@dv@axis}{\tikz@dv@max@anchor}}, % % Visualization setters % @@ -609,6 +697,7 @@ % Ticks settings % ticks/.style={\tikz@dv@axis/ticks at/.append={,#1}}, + ticks/.default=some, visualize ticks/.code=\expandafter\tikz@lib@dv@tv\expandafter{\tikz@dv@axis}{#1}, % % Grid settings @@ -617,11 +706,52 @@ grid/.default=at default ticks, visualize grid/.code=\expandafter\tikz@lib@dv@gv\expandafter{\tikz@dv@axis}{#1}, % + ticks and grid/.style={\tikz@dv@axis/ticks at/.append={,#1},\tikz@dv@axis/grid at/.append={,#1}}, + % % Visualizing axis labels % visualize label/.code=\expandafter\tikz@lib@dv@lv\expandafter{\tikz@dv@axis}{#1}, } +\def\tikz@lib@dv@auto@attribute{\tikz@lib@dv@auto@attribute} + + +% Range options +\tikzdatavisualizationset{ + axis options/.cd, + % + % Including a value in the range + % + include value/.style={% + /tikz/data visualization/before survey/.expanded={% + \noexpand\pgfkeysgetvalue{\tikz@dv@axis/scaling mapper}\noexpand\tikz@dv@axis@mapper% + \noexpand\foreach \noexpand\tikz@lib@dv@temp in {#1} {% + \noexpand\tikz@dv@axis@mapper.include in value(\noexpand\tikz@lib@dv@temp)% + }% + }% + }, + % + % Directly setting the min or max + % + min value/.style={ + /tikz/data visualization/at end survey/.expanded={% + \noexpand\pgfkeysgetvalue{\tikz@dv@axis/scaling mapper}\noexpand\tikz@dv@axis@mapper% + \noexpand\tikz@lib@dv@set\noexpand\tikz@dv@axis@mapper{#1}{min}% + } + }, + max value/.style={ + /tikz/data visualization/at end survey/.expanded={% + \noexpand\pgfkeysgetvalue{\tikz@dv@axis/scaling mapper}\noexpand\tikz@dv@axis@mapper% + \noexpand\tikz@lib@dv@set\noexpand\tikz@dv@axis@mapper{#1}{max}% + } + }, +} + +\def\tikz@lib@dv@set#1#2#3{% + \pgfdvmathenter{\pgf@dv@value}{#2}% + #1.get in range interval()% + \pgfdvinrangeinterval.let #3(\pgf@dv@value)% +} % Layer options \tikzdatavisualizationset{ @@ -664,15 +794,15 @@ } \def\tikz@dv@goto#1#2{% - \edef\pgf@temp{#2}% - \ifx\pgf@temp\tikz@lib@dv@padded@min@text% + \edef\pgf@@temp{#2}% + \ifx\pgf@@temp\tikz@lib@dv@padded@min@text% \pgfkeysvalueof{#1/scaling mapper}.set in to(min)% \pgfkeysvalueof{#1/scaling mapper}.get out()% \pgfkeysgetvalue{#1/padding min}\pgf@temp% \pgfmathparse{\pgf@temp}% \pgfkeyslet{/data point/\pgfdvout/offset}\pgfmathresult% \else% - \ifx\pgf@temp\tikz@lib@dv@padded@max@text% + \ifx\pgf@@temp\tikz@lib@dv@padded@max@text% \pgfkeysvalueof{#1/scaling mapper}.set in to(max)% \pgfkeysvalueof{#1/scaling mapper}.get out()% \pgfkeysgetvalue{#1/padding max}\pgf@temp% @@ -682,10 +812,21 @@ \pgfkeysvalueof{#1/scaling mapper}.set in to(#2)% \fi% \fi% -} +} + +\def\tikz@dv@goto@pos#1#2{% + \pgfkeyssetvalue{/data point/\pgfkeysvalueof{#1/attribute}/out pos}{#2}% +} \def\tikz@lib@dv@padded@min@text{padded min} \def\tikz@lib@dv@padded@max@text{padded max} + +\def\tikz@lib@dv@special@at#1#2{% + % Ok, calculate direction vector: + \tikzpointandanchordirection{\pgfkeysvalueof{#1/scaling mapper}.set in to(min)}{\pgfkeysvalueof{#1/scaling mapper}.set in to(max)} + \tikzset{anchor/.expanded=#2} +} + % Ticks visualization % @@ -743,19 +884,22 @@ {% \let\tikz@dv@at@list\pgfutil@empty% \let\tikz@dv@style@at@list\pgfutil@empty% + \pgfkeysgetvalue{#2/scaling mapper}\tikz@lib@dv@mapper + \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@settings}% \scope[/tikz/data visualization/.cd,every ticks/.try,every #1 ticks/.try,#3]% % Setup options - \pgfkeysgetvalue{#2/scaling mapper}\tikz@lib@dv@mapper - \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@settings}% \pgfkeysgetvalue{/tikz/data visualization/common}\tikz@temp \expandafter\tikzdatavisualizationset\expandafter{\tikz@temp} \pgfkeysgetvalue{/tikz/data visualization/#1}\tikz@temp \expandafter\tikzdatavisualizationset\expandafter{\tikz@temp} \pgfkeysgetvalue{/tikz/data visualization/\pgfkeysvalueof{/tikz/data visualization/direction axis}/scaling mapper}\pgf@dv@tick@dir@mapper % Ok, now it's time to draw the ticks! - \foreach \tikz@dv@tick@pos in \tikz@dv@at@list + \foreach \tikz@dv@tick@pos[count=\tikz@dv@tick@count] in \tikz@dv@at@list { \ifx\tikz@dv@tick@pos\pgfutil@empty + \c@pgf@counta=\tikz@dv@tick@count\relax% + \advance\c@pgf@counta by-1\relax% + \edef\tikz@dv@tick@count{\the\c@pgf@counta}% \else \expandafter\tikz@lib@dv@parse\tikz@dv@tick@pos\pgf@stop% \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@tick@opt}% @@ -768,15 +912,40 @@ \xdef\pgf@dv@tick@dir{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}} % Now, show something: \tikz@lib@handle@at@style% - \scope[/tikz/data visualization/styling] - \pgf@process{\pgfpointadd{\pgf@dv@tick@origin}{\pgfpointscale{\pgfkeysvalueof{/tikz/data visualization/high}}{\pgf@dv@tick@dir}}} - \xdef\tikz@dv@max@tick{\the\pgf@x,\the\pgf@y} - \pgf@process{\pgfpointadd{\pgf@dv@tick@origin}{\pgfpointscale{\pgfkeysvalueof{/tikz/data visualization/low}}{\pgf@dv@tick@dir}}} - \xdef\tikz@dv@min@tick{\the\pgf@x,\the\pgf@y} - \scope[data visualization/ticks layer] \draw (\tikz@dv@min@tick) -- (\tikz@dv@max@tick); \endscope - \iftikz@dv@min@tick@node \scope[data visualization/ticks node layer] \path (\tikz@dv@min@tick) \tikz@dv@handle@tick{\tikz@dv@min@anchor}; \endscope \fi - \iftikz@dv@max@tick@node \scope[data visualization/ticks node layer] \path (\tikz@dv@max@tick) \tikz@dv@handle@tick{\tikz@dv@max@anchor}; \endscope\fi + \pgfkeysgetvalue{/tikz/data visualization/high}\tikz@dv@max@val% + \pgfkeysgetvalue{/tikz/data visualization/low}\tikz@dv@min@val% + \iftikz@dv@max@tick@node\pgfmathsetmacro\tikz@dv@max@val{% + \tikz@dv@max@val+(\pgfkeysvalueof{% + /tikz/data visualization/tick text high + \ifodd\tikz@dv@tick@count odd \else even \fi padding}% + )}% + \fi% + \iftikz@dv@min@tick@node\pgfmathsetmacro\tikz@dv@min@val{% + \tikz@dv@min@val+(\pgfkeysvalueof{% + /tikz/data visualization/tick text low + \ifodd\tikz@dv@tick@count odd \else even \fi padding}% + )}% + \fi% + \pgf@process{\pgfpointadd{\pgf@dv@tick@origin}{\pgfpointscale{\tikz@dv@max@val}{\pgf@dv@tick@dir}}} + \xdef\tikz@dv@max@tick{\the\pgf@x,\the\pgf@y} + \pgf@process{\pgfpointadd{\pgf@dv@tick@origin}{\pgfpointscale{\tikz@dv@min@val}{\pgf@dv@tick@dir}}} + \xdef\tikz@dv@min@tick{\the\pgf@x,\the\pgf@y} + \scope[data visualization/ticks layer] + \tikzdatavisualizationset{every \ifodd\tikz@dv@tick@count odd \else even \fi tick/.try} + \draw [/tikz/data visualization/styling] (\tikz@dv@min@tick) -- (\tikz@dv@max@tick); \endscope + \iftikz@dv@min@tick@node + \scope[data visualization/ticks node layer] + \tikzdatavisualizationset{every \ifodd\tikz@dv@tick@count odd \else even \fi tick/.try} + \path [/tikz/data visualization/styling] (\tikz@dv@min@tick) \tikz@dv@handle@tick{\tikz@dv@min@anchor}; + \endscope + \fi + \iftikz@dv@max@tick@node + \scope[data visualization/ticks node layer] + \tikzdatavisualizationset{every \ifodd\tikz@dv@tick@count odd \else even \fi tick/.try} + \path [/tikz/data visualization/styling] (\tikz@dv@max@tick) \tikz@dv@handle@tick{\tikz@dv@max@anchor}; + \endscope + \fi \fi } \endscope @@ -808,7 +977,7 @@ \pgfdvmathenter{\tikz@lib@dv@typesetnum}{\tikz@dv@tick@pos}% \pgfdvmathexitbyscientificformat{\tikz@lib@dv@typesetnum}{\tikz@lib@dv@typesetnum}% hmm... not sure about this... \pgfkeysvalueof{/tikz/data visualization/tick prefix}% - \pgfkeysvalueof{/tikz/data visualization/tick typesetter}{\tikz@lib@dv@typesetnum}% + \pgfkeys{/tikz/data visualization/tick typesetter=\tikz@lib@dv@typesetnum}% \pgfkeysvalueof{/tikz/data visualization/tick suffix}% } @@ -860,7 +1029,7 @@ % Help function \def\tikzpointandanchordirection#1#2{% % This function works like pgfpointdvdirection, but also computes - % appriate "min" and "max" anchors. + % appropriate "min" and "max" anchors. \pgf@process{\pgfpointdvdirection{#1}{#2}} { \pgf@ya=\pgf@y @@ -907,10 +1076,10 @@ {% \let\tikz@dv@at@list\pgfutil@empty \let\tikz@dv@style@at@list\pgfutil@empty - \scope[data visualization/grid layer,/tikz/data visualization/.cd,every #1 grid/.try,grid styling,grid styling/.style=,#3] + \pgfkeysgetvalue{#2/scaling mapper}\tikz@lib@dv@mapper + \let\tikz@lib@dv@ticks@default@at\pgfutil@empty% + \scope[data visualization/grid layer,/tikz/data visualization/.cd,every grid,every #1 grid/.try,#3] % Setup options - \pgfkeysgetvalue{#2/scaling mapper}\tikz@lib@dv@mapper - \let\tikz@lib@dv@ticks@default@at\pgfutil@empty% \pgfkeysgetvalue{#2/ticks at}\tikz@lib@dv@ticks@at% \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@settings}% \pgfkeysgetvalue{/tikz/data visualization/common}\tikz@temp @@ -925,7 +1094,6 @@ \else \expandafter\tikz@lib@dv@parse\tikz@dv@grid@pos\pgf@stop% \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@tick@opt}% - \tikzdatavisualizationset{grid styling}% \tikz@lib@dv@mapper.set in to(\tikz@dv@tick@pos)% \draw[/tikz/data visualization/styling] \pgfextra{ @@ -966,46 +1134,17 @@ \ifx\tikz@dv@lib@label\pgfutil@empty% % Great, nothing to do \else - \scope[/tikz/data visualization/.cd,every axis label/.try,#2] - \pgfkeysgetvalue{/tikz/data visualization/value}\tikz@lib@dv@at% - \pgfkeysgetvalue{/tikz/data visualization/pos}\tikz@lib@dv@pos% - \pgfkeysgetvalue{#1/scaling mapper}\tikz@dv@mapper - \ifx\tikz@lib@dv@pos\pgfutil@empty% - \ifx\tikz@lib@dv@at\pgfutil@empty% - % Well, hopefully the node options setup things correctly... - \else% - % Special treatment of "min" and "max" - \ifx\tikz@lib@dv@at\pgf@min@text% - \tikz@lib@dv@special@at{\tikz@dv@min@anchor} - \else \ifx\tikz@lib@dv@at\tikz@lib@dv@padded@min@text% - \tikz@lib@dv@special@at{\tikz@dv@min@anchor} - \else \ifx\tikz@lib@dv@at\pgf@max@text% - \tikz@lib@dv@special@at{\tikz@dv@max@anchor} - \else \ifx\tikz@lib@dv@at\tikz@lib@dv@padded@max@text% - \tikz@lib@dv@special@at{\tikz@dv@max@anchor} - \fi\fi\fi\fi% - \tikz@dv@goto{#1}{\tikz@lib@dv@at}% - \pgftransformshift{\pgfpointdvlocaldatapoint}% - \fi% - \else% - \tikz@dv@mapper.set in to(min)% - \pgftransformshift{\pgfpointscale{1-\tikz@lib@dv@pos}{\pgfpointdvlocaldatapoint}} - \tikz@dv@mapper.set in to(max)% - \pgftransformshift{\pgfpointscale{\tikz@lib@dv@pos}{\pgfpointdvlocaldatapoint}} - \fi + \scope[anchor=center,/tikz/data visualization/.cd,every axis label/.try,#2] \expandafter\tikz@lib@dv@parse@node\tikz@dv@lib@label\pgf@stop \endscope \fi } -\def\tikz@lib@dv@special@at#1{% - % Ok, calculate direction vector: - \tikzpointandanchordirection{\tikz@dv@mapper.set in to(min)}{\tikz@dv@mapper.set in to(max)} - \tikzset{anchor=#1} -} \def\tikz@lib@dv@parse@node{\pgfutil@ifnextchar[\tikz@lib@dv@parse@node@opt{\tikz@lib@dv@parse@node@opt[]}}%} \def\tikz@lib@dv@parse@node@opt[#1]#2\pgf@stop{ - \node [/tikz/data visualization/node styling,#1] {#2}; + \tikzdatavisualizationset{#1} + \pgftransformshift{\pgfpointdvlocaldatapoint}% + \node [/tikz/data visualization/node styling] {#2}; } @@ -1020,10 +1159,10 @@ minor steps between steps/.initial=, minor steps between steps/.default=9, phase/.initial=0, - tick typesetter/.initial=\pgfmathprintnumber, + tick typesetter/.code=\pgfmathprintnumber{#1}, tick prefix/.initial=, tick suffix/.initial=, - tick unit/.style={tick suffix={#1}},% this is an alias + tick unit/.style={tick suffix={$\,\rm#1$}},% this is an alias } \def\tikz@lib@dv@compute@at@linear{% @@ -1111,6 +1250,7 @@ standard about strategy/.style={about strategy={1.5/1.0,2.3/2.0,4/2.5,7/5,11/10}}, standard about strategy, euro about strategy/.style={about strategy={1.5/1.0,3/2.0,7/5,11/10}}, + decimal about strategy/.style={about strategy={3/1.0,11/10}}, half about strategy/.style={about strategy={2/1.0,7/5,11/10}}, quarter about strategy/.style={about strategy={1.8/1.0,4/2.5,7/5,11/10}}, int about strategy/.style={about strategy={1.5/1.0,2.5/2.0,3.5/3.0,4.5/4.0,7/5,11/10}}, @@ -1269,7 +1409,7 @@ \tikzdatavisualizationset{% new Cartesian axis/.style={ - new axis={#1}, + new axis base={#1}, new object={ class=linear transformer, store=/tikz/data visualization/#1/linear transformer, @@ -1277,7 +1417,7 @@ arg2 from key=/tikz/data visualization/#1/unit vector, }, #1/scaling/default/.initial=0 at 0 and 1 at 1cm, - #1/unit vector/.initial=, + #1/unit vector/.initial=\pgfqpoint{1pt}{0pt}, } } @@ -1285,8 +1425,6 @@ /tikz/data visualization/axis options/.cd, unit vector/.code=\tikz@scan@one@point\tikz@lib@dv@uv#1, length/.style={\tikz@dv@axis/scaling=min at 0 and max at #1}, - positive length/.style={\tikz@dv@axis/scaling=0 at 0 and max at #1}, - negative length/.style={\tikz@dv@axis/scaling=min at -#1 and 0 at 0}, unit length/.code={\tikz@dv@parse@unit@length{#1}}, power unit length/.style={\tikz@dv@axis/scaling=1 at 0 and 10 at #1} } @@ -1313,34 +1451,62 @@ % \tikzdatavisualizationset{ - new visualizer/.style 2 args={ - /pgf/data/#1/.style={/data point/visualizer=#1}, + new visualizer/.style n args={3}{ #1/.code={ \def\tikz@visualizer{#1}% \pgfkeys{/tikz/data visualization/visualizer options/.cd,##1} + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data(\pgfkeys{/data point/set=#1})}% }, /utils/exec={ \advance\tikzdvvisualizercounter by 1\relax - \edef\tikz@temp{/data point/visualizer/#1/.initial=\the\tikzdvvisualizercounter} + \edef\tikz@temp{/data point/set/#1/.initial=\the\tikzdvvisualizercounter} \expandafter\tikzset\expandafter{\tikz@temp} }, /data point/#1/execute at begin/.initial={ - \pgfkeyssetvalue{/data point/visualizer}{#1} + \pgfkeyssetvalue{/data point/set}{#1} \scope[ - /tikz/data visualization/every visualizer/.try, #2, - /utils/exec=\pgf@signalstyle.emit(), + /tikz/data visualization/every visualizer/.try, + /tikz/data visualization/visualizers/#1/signal, /tikz/data visualization/visualizers/#1/styling/.try] }, /data point/#1/execute at end/.initial={ \path; % invokes every path implicitly \endscope }, + /tikz/data visualization/visualizers/#1/signal/.code=\pgf@signalstyle.emit(), /tikz/data visualization/visualizers/#1/styling/.style=, + /tikz/data visualization/visualizers/#1/label in legend options/.style={#3}, }, - visualizer style sheet/.style={/data point/visualizer/.style sheet={#1}} + style sheet/.style={/data point/set/.style sheet={#1}}, + /pgf/data/set/.style={/data point/set=#1}, +} + +\tikzdatavisualizationset{ + new sub visualizer/.style n args={4}{ + #4/#1/.code={ + \def\tikz@visualizer{#4/#1}% + \pgfkeys{/tikz/data visualization/visualizer options/.cd,##1} + }, + /data point/#4/#1/execute at begin/.initial={ + \pgfkeyssetvalue{/data point/set}{#4} + \scope[ + #2, + /tikz/data visualization/every visualizer/.try, + /tikz/data visualization/visualizers/#4/signal, + /tikz/data visualization/visualizers/#4/styling/.try, + /tikz/data visualization/visualizers/#4/#1/styling/.try] + }, + /data point/#4/#1/execute at end/.initial={ + \path; % invokes every path implicitly + \endscope + }, + /tikz/data visualization/visualizers/#4/#1/styling/.style=, + /tikz/data visualization/visualizers/#4/#1/label in legend options/.style={#3}, + } } + \def\tikz@do@visualizer#1#2{% \tikzdatavisualizationset{ #2=#1 @@ -1351,16 +1517,19 @@ \newif\iftikz@dv@visualizer@label@inline -\tikzset{ - @set plot handler/.code={\let\tikz@plot@handler=#1}, - no lines/.style={@set plot handler=\pgfplothandlerdiscard,/utils/exec=\tikzdatavisualizationset{default label in legend mark}}, - smooth line/.style={@set plot handler=\pgfplothandlercurveto,/utils/exec=\tikzdatavisualizationset{default label in legend path}}, - smooth cycle/.style={@set plot handler=\pgfplothandlerclosedcurve,/utils/exec=\tikzdatavisualizationset{default label in legend closed path}}, - straight line/.style={@set plot handler=\pgfplothandlerlineto,/utils/exec=\tikzdatavisualizationset{default label in legend path}}, - straight cycle/.style={@set plot handler=\pgfplothandlerpolygon,/utils/exec=\tikzdatavisualizationset{default label in legend closed path}}, - polygon/.style={straight cycle=cycle},% alias - gapped line/.style={@set plot handler=\pgfplothandlergaplineto,/utils/exec=\tikzdatavisualizationset{default label in legend path}}, - gapped cycle/.style={@set plot handler=\pgfplothandlergapcycle,/utils/exec=\tikzdatavisualizationset{gapped circular label in legend line}} +\tikzdatavisualizationset{visualizer options/.cd, + @set/.style 2 args={ + /tikz/data visualization/visualizers/\tikz@visualizer/styling/.append style={/utils/exec={\let\tikz@dv@plot@handler=#1}}, + /tikz/data visualization/visualizers/\tikz@visualizer/label in legend options/.append style={#2} + }, + no lines/.style={@set={\pgfplothandlerdiscard}{default label in legend mark}}, + smooth line/.style={@set={\pgfplothandlercurveto}{default label in legend path}}, + smooth cycle/.style={@set={\pgfplothandlerclosedcurve}{default label in legend closed path}}, + straight line/.style={@set={\pgfplothandlerlineto}{default label in legend path}}, + straight cycle/.style={@set={\pgfplothandlerpolygon}{default label in legend closed path}}, + polygon/.style={straight cycle},% alias + gap line/.style={@set={\pgfplothandlergaplineto}{default label in legend path}}, + gap cycle/.style={@set={\pgfplothandlergapcycle}{gap circular label in legend line}} } @@ -1378,16 +1547,17 @@ \begingroup \def\tikz@visualizer{#1}% \pgfkeys{/tikz/data visualization/visualizer label options/.cd, - /tikz/data visualization/every label visualizer/.try, #2} \pgfkeysgetvalue{/tikz/data visualization/visualizer label options/text}\tikz@dv@temp@lab \def\tikz@tempa{ - \scope[/tikz/data visualization/visualizer label options/.cd, - /tikz/data visualization/every label visualizer/.try, + \scope[ + /utils/exec=\def\tikz@visualizer{#1},% + /tikz/data visualization/visualizer label options/.cd, #2] + \tikzdatavisualizationset{every data set label/.try} \path [ - /data point/visualizer=#1,/utils/exec=\pgf@signalstyle.emit(), - /tikz/data visualization/.cd,every visualizer label] + /data point/set=#1,/utils/exec=\pgf@signalstyle.emit(), + /tikz/data visualization/.cd,every label in data/.try] (label visualizer coordinate') -- (label visualizer coordinate) node [ @@ -1405,7 +1575,7 @@ \endgroup }, arg1/.expand once=\tikz@dv@label@attribute, - arg2/.expand once=\tikz@dv@label@threshold, + arg2=\tikz@dv@label@threshold, arg3/.expand once=\tikz@dv@label@code, arg4=\pgfdvvisualizerfilter{#1} }, @@ -1418,40 +1588,45 @@ \def\tikz@create@label@count#1{ \tikzdatavisualizationset{ new object={ - when=after survey, + when=before survey, store=/tikz/data visualization/visualizers/#1/count/obj, class=count, - arg1=visualizers/#1/count, - after creation={ - \tikzdvobj.set filter({% - \pgfkeysgetvalue{/data point/visualizer}\pgf@tempa% - \def\pgf@tempb{#1}% - \ifx\pgf@tempa\pgf@tempb% - \else - \pgfdvfilterpassedfalse% - \fi - }) - } + arg1=set/#1/count, + after creation={\tikzdvobj.set filter(\pgfdvvisualizerfilter{#1})} } } } \pgfkeys{ /tikz/data visualization/visualizer label options/.cd, - at/.code args={#1>=#2}{% + when/.code args={#1 is#2}{% \def\tikz@dv@label@attribute{#1}% \def\tikz@dv@label@threshold{#2}% }, index/.code={% - \edef\tikz@dv@label@attribute{visualizers/\tikz@visualizer/count}% + \edef\tikz@dv@label@attribute{set/\tikz@visualizer/count}% \def\tikz@dv@label@threshold{#1}% }, + pos/.code={% + \edef\tikz@dv@label@attribute{set/\tikz@visualizer/count}% + \pgfkeysvalueof{/tikz/data visualization/visualizers/\tikz@visualizer/count/obj}.get max(\tikz@lib@max) + \edef\tikz@dv@label@threshold{(#1*\tikz@lib@max)}% + }, + auto/.code={% + \edef\tikz@dv@label@attribute{set/\tikz@visualizer/count}% + \pgfkeysvalueof{/tikz/data visualization/visualizers/\tikz@visualizer/count/obj}.get max(\tikz@lib@max) + \edef\tikz@dv@label@threshold{({(\pgfkeysvalueof{/data point/set/\tikz@visualizer}-0.5)/\the\tikzdvvisualizercounter*\tikz@lib@max})} + }, text/.initial=, - text'/.style={text={#1},node style=swap}, + text'/.style={text={#1},node style=swap,/utils/exec=\def\tikz@lib@dv@pin@sign{-}}, node style/.style={/tikz/data visualization/node style={#1}}, text colored/.style=/tikz/data visualization/text colored, + pin angle/.store in=\tikz@lib@dv@pin@dir, + pin length/.style={node style={pin distance={#1}}}, } +\let\tikz@lib@dv@pin@sign\pgfutil@empty + \let\tikz@dv@label@attribute\pgfutil@empty \let\tikz@dv@label@threshold\pgfutil@empty \let\tikz@dv@label@code\pgfutil@empty @@ -1486,7 +1661,7 @@ \let\pgfdvendrow=\pgfmatrixendrow% \def\pgf@marshal{ \matrix[at/.expand once=\pgf@dv@at,matrix anchor/.expand - once=\pgf@dv@anchor,/tikz/data visualization/#1/styling] + once=\pgf@dv@anchor,/tikz/data visualization/#1/matrix node styling] } \expandafter\pgf@marshal\expandafter{\pgf@dv@temp}; } @@ -1500,7 +1675,7 @@ #1/@strategy/.initial=down then right, #1/anchor/.initial=west, #1/at/.initial=(data visualization bounding box.east), - #1/styling/.style={row sep=0pt,column sep=.8em}, + #1/matrix node styling/.style={row sep=0pt,column sep=.8em}, % % % @@ -1511,7 +1686,11 @@ }, #1={every new legend} }}}, - legend/.style={new legend=legend,legend={#1}} + new legend/.default=main legend, + legend/.style={ + new legend, + main legend={#1} + } } \def\tikz@do@legend@options#1#2{ @@ -1545,38 +1724,187 @@ % anchor/.style={\tikz@dv@legend/anchor={#1}}, at/.style={\tikz@dv@legend/at={#1}}, - right/.style={ + % Outer placements + right/.style={east outside}, + left/.style={west outside}, + above/.style={north outside}, + below/.style={south outside}, + east outside/.style={ columns=1, at={([xshift=.8em]data visualization bounding box.east)}, anchor=west, }, - left/.style={ + north east outside/.style={ + columns=1, + at={([xshift=.8em]data visualization bounding box.north east|- + data bounding box.north)}, + anchor=north west, + }, + south east outside/.style={ + columns=1, + at={([xshift=.8em]data visualization bounding box.south east |- + data bounding box.south)}, + anchor=south west, + }, + west outside/.style={ columns=1, + label style=text left, at={([xshift=-.8em]data visualization bounding box.west)}, anchor=east, }, - below/.style={ + north west outside/.style={ + columns=1, + label style=text left, + at={([xshift=-.8em]data visualization bounding box.north west |- + data bounding box.north)}, + anchor=north east, + }, + south west outside/.style={ + columns=1, + label style=text left, + at={([xshift=-.8em]data visualization bounding box.south west |- + data bounding box.south)}, + anchor=south east, + }, + south outside/.style={ rows=1, at={([yshift=-.5em]data visualization bounding box.south)}, anchor=north, }, - above/.style={ + north outside/.style={ rows=1, at={([yshift=.5em]data visualization bounding box.north)}, anchor=south, }, - every new legend/.style={right,label style=text right}, + every new legend/.style={east outside,label style=text right}, + % + % Inner placements + % + % First, styling + every legend inside/.style={ + opaque=white, + label style={node style={font=\pgfutil@font@footnotesize}} + }, + opaque/.style={ + matrix node style={ + inner sep=.333ex, + outer sep=.5ex, + rounded corners=3pt, + execute at begin cell={\tikzset{sharp corners}}, % get rid of + % rounded corners in cells of the + % legend matrix + fill=#1 + }, + }, + opaque/.default=white, + transparent/.style={matrix node style={fill=none}}, + % Second, the placements + north east inside/.style={ + columns=1, + at={([xshift=-.3em]data bounding box.north east)}, + anchor=north east, + every legend inside + }, + south west inside/.style={ + columns=1, + at={([xshift=.3em]data bounding box.south west)}, + anchor=south west, + every legend inside + }, + north west inside/.style={ + columns=1, + at={([xshift=.3em]data bounding box.north west)}, + anchor=north west, + every legend inside + }, + south east inside/.style={ + columns=1, + at={([xshift=-.3em]data bounding box.south east)}, + anchor=south east, + every legend inside + }, + west inside/.style={ + columns=1, + at={([xshift=.3em]data bounding box.west)}, + anchor=west, + every legend inside + }, + east inside/.style={ + columns=1, + at={([xshift=.3em]data bounding box.east)}, + anchor=east, + every legend inside + }, + north inside/.style={ + rows=1, + at={(data bounding box.north)}, + anchor=north, + every legend inside + }, + south inside/.style={ + rows=1, + at={(data bounding box.south)}, + anchor=south, + every legend inside + }, + % Additional inner placements + at values/.style={ + at={(visualization cs:#1)}, + anchor=center, + every legend inside + }, + right of/.style={ + at={(visualization cs:#1)}, + anchor=west, + every legend inside + }, + left of/.style={ + at={(visualization cs:#1)}, + anchor=east, + every legend inside + }, + above of/.style={ + at={(visualization cs:#1)}, + anchor=south, + every legend inside + }, + below of/.style={ + at={(visualization cs:#1)}, + anchor=north, + every legend inside + }, + above right of/.style={ + at={(visualization cs:#1)}, + anchor=south west, + every legend inside + }, + above left of/.style={ + at={(visualization cs:#1)}, + anchor=south east, + every legend inside + }, + below right of/.style={ + at={(visualization cs:#1)}, + anchor=north west, + every legend inside + }, + below left of/.style={ + at={(visualization cs:#1)}, + anchor=north east, + every legend inside + }, + % + % % % Label text styling % label style/.style={ - style={/tikz/data visualization/legend entry options/every label - in legend/.append style={#1}} + matrix node style={/tikz/data visualization/every label in legend/.append style={#1}} }, % % Styling % - style/.style={\tikz@dv@legend/styling/.append style={#1}}, + matrix node style/.style={\tikz@dv@legend/matrix node styling/.append style={#1}}, } @@ -1593,30 +1921,30 @@ } \def\tikz@dv@add@legend@entry#1#2{ - \tikz@main@dv.at start survey({{ + \tikz@main@dv.at start survey({ \pgfkeysgetvalue{/tikz/data visualization/#1/obj}\pgf@temp \pgf@temp.add entry(\tikz@dv@render@legend@entry{legend=#1,#2}) - }}) + }) } \def\tikz@dv@render@legend@entry#1{ - \pgfkeys{/tikz/data visualization/.cd, - every visualizer label, - every visualizer legend label - } - \pgfkeys{/tikz/data visualization/legend entry options/.cd,#1} + \pgfkeys{/tikz/data visualization/.cd,every data set label} + \pgfkeys{/tikz/data visualization/legend entry options/.cd, + /tikz/data visualization/every label in legend,#1}% \pgfkeysgetvalue{/tikz/data visualization/legend entry options/text}\tikz@dv@temp@lab \pgfkeysgetvalue{/tikz/data visualization/@node styling}\tikz@dv@temp@style \pgfkeysgetvalue{/tikz/data visualization/legend entry options/setup}\tikz@dv@temp@setup - \pgfkeysgetvalue{/tikz/data visualization/legend entry options/value visualizer}\tikz@dv@temp@visual - \pgfkeysgetvalue{/tikz/data visualization/legend entry options/value visualizer styling}\tikz@dv@temp@visual@styling + \pgfkeysgetvalue{/tikz/data visualization/legend entry options/visualizer in legend styling}\tikz@dv@temp@visual@styling \scope[/utils/exec=\expandafter\pgfkeysalso\expandafter{\tikz@dv@temp@setup}, /utils/exec=\pgf@signalstyle.emit()] \node[/tikz/data visualization/node styling, /utils/exec=\expandafter\pgfkeysalso\expandafter{\tikz@dv@temp@style}] {\tikz@dv@pre@height\tikz@dv@temp@lab\tikz@dv@post@height}; \scope[/utils/exec=\expandafter\pgfkeysalso\expandafter{\tikz@dv@temp@visual@styling}] - \tikz@dv@temp@visual + \iftikz@lib@dv@text@only + \else + \pgfkeysvalueof{/tikz/data visualization/legend entry options/visualizer in legend} + \fi \endscope \endscope } @@ -1633,66 +1961,84 @@ % text/.initial=, node style/.style={/tikz/data visualization/node style={#1}}, - legend/.initial=legend, + legend/.initial=main legend, setup/.initial=, - value visualizer/.initial=, - value visualizer styling/.initial=, - value visualizer style/.style={value visualizer styling/.append={,#1}}, - value visualizer macro/.initial=, + visualizer in legend/.initial=, + visualizer in legend styling/.initial=, + visualizer in legend style/.style={visualizer in legend styling/.append={,#1}}, % % Legend visualizers for plots % text right/.style={ node style={anchor=mid west,inner ysep=1pt,inner xsep=0pt,reset cm,xshift=.333em}, - value visualizer style={reset cm}, - value visualizer macro=\tikz@dv@legend@entry@as@example + visualizer in legend style={reset cm}, }, text left/.style={ node style={anchor=mid east,inner ysep=1pt,inner xsep=0pt,reset cm,xshift=-.333em,align=right}, - value visualizer style={reset cm,xscale=-1}, - value visualizer macro=\tikz@dv@legend@entry@as@example + visualizer in legend style={reset cm,xscale=-1}, }, text only/.style={ node style={anchor=mid west,inner ysep=1pt,inner xsep=0pt,reset cm,text=visualizer color}, - value visualizer style={}, - value visualizer macro=\relax, + /utils/exec=\tikz@lib@dv@text@onlytrue }, text colored/.style=/tikz/data visualization/text colored, } - +\let\tikz@lib@dv@pin@dir\pgfutil@empty +\newif\iftikz@lib@dv@text@only \pgfkeys{ /tikz/data visualization/visualizer options/.cd, label in legend/.code={\expandafter\tikz@dv@new@label@in@legend@for@visualizer\expandafter{\tikz@visualizer}{#1}}, - label in data/.code=\tikzdatavisualizationset{new label visualizer/.expand once=\expandafter{\tikz@visualizer}{#1}}, - style/.style={/tikz/data visualization/visualizers/\tikz@visualizer/styling/.append style={#1}}, + label in data/.code=\tikzdatavisualizationset{new label visualizer/.expand once=\expandafter{\tikz@visualizer}{auto,#1}}, + pin in data/.style={label in data={% + node style={% + /utils/exec={ + \ifx\tikz@lib@dv@pin@dir\pgfutil@empty + \pgf@process{\pgfpointnormalised{% + \pgfpointdiff% + {\pgfpointanchor{label visualizer coordinate}{center}}% + {\pgfpointanchor{label visualizer coordinate'}{center}}}}% + \pgf@x=-\pgf@x\relax% + \edef\tikz@lib@dv@temp@rot{\noexpand\pgfqpoint{\the\pgf@y}{\the\pgf@x}}% + \tikz@addtransform{\pgftransformshift{\pgfpointscale{\tikz@lib@dv@pin@sign\tikz@pin@distance}{\tikz@lib@dv@temp@rot}}} + \else% + \tikz@addtransform{\pgftransformshift{\pgfpointpolar{\tikz@lib@dv@pin@dir}{\tikz@lib@dv@pin@sign\tikz@pin@distance}}} + \fi% + }, + append after command={ + \bgroup + [current point is local=true] + (\tikzlastnode) edge [solid, every pin edge] (label visualizer coordinate) + \egroup% + }}, + ,#1}}, + style/.style={/tikz/data visualization/visualizers/\tikz@visualizer/styling/.append style={,#1}}, + label in legend options/.style={/tikz/data visualization/visualizers/\tikz@visualizer/label in legend options/.append style={,#1}}, + ignore style sheets/.style={/tikz/data visualization/visualizers/\tikz@visualizer/signal/.code=,/utils/exec=\advance\tikzdvvisualizercounter by -1\relax}, } \def\tikz@dv@new@label@in@legend@for@visualizer#1#2{ \tikzdatavisualizationset{ new legend entry={ - every legend entry/.try, - every label in legend/.try, - /tikz/data visualization/every label/.try, + visualizer in legend style={/tikz/data visualization/visualizers/#1/styling/.try}, + /tikz/data visualization/every label in legend/.try, + /tikz/.cd, + every label/.try, + /tikz/data visualization/legend entry options/.cd, + setup={/data point/set=#1}, + /tikz/data visualization/visualizers/#1/label in legend options/.try, #2, - setup={/data point/visualizer=#1}, - /utils/exec=\pgfkeysgetvalue{/tikz/data visualization/legend entry options/value visualizer macro}\tikz@dv@visualizer@macro, - value visualizer={ - \scope[/tikz/data visualization/visualizers/#1/styling/.try] - \def\tikz@visualizer{#1} - \tikz@dv@visualizer@macro - \endscope - } } } } \def\tikz@dv@legend@entry@as@example{ + \pgfkeysgetvalue{/data point/set}{\tikz@visualizer} \pgfkeysvalueof{/data point/\tikz@visualizer/execute at begin} - \tikz@plot@handler + \tikz@dv@plot@handler \pgfplotstreamstart - \pgfkeysgetvalue{/tikz/data visualization/label in legend line coordinates}{\tikz@dv@temp} + \pgfkeysgetvalue{/tikz/data visualization/legend entry options/label in legend line coordinates}{\tikz@dv@temp} \foreach \coordinate in \tikz@dv@temp { \pgfplotstreampoint{\expandafter\tikz@scan@one@point\expandafter\pgfutil@firstofone\coordinate} } \pgfplotstreamend @@ -1700,7 +2046,7 @@ \pgfkeysvalueof{/data point/\tikz@visualizer/execute at begin} \tikz@dv@plot@mark@maker \pgfplotstreamstart - \pgfkeysgetvalue{/tikz/data visualization/label in legend mark coordinates}{\tikz@dv@temp} + \pgfkeysgetvalue{/tikz/data visualization/legend entry options/label in legend mark coordinates}{\tikz@dv@temp} \foreach \coordinate in \tikz@dv@temp { \pgfplotstreampoint{\expandafter\tikz@scan@one@point\expandafter\pgfutil@firstofone\coordinate} } \pgfplotstreamend @@ -1709,7 +2055,9 @@ \tikzdatavisualizationset{ + legend entry options/.cd, label in legend line coordinates/.initial=, + label in legend rectangle coordinates/.initial={(-1ex,-.5ex),(-1ex,0.968ex),(0ex,0.968ex),(0ex,-.5ex)}, label in legend mark coordinates/.initial=, label in legend one mark/.style={ label in legend line coordinates={}, @@ -1720,7 +2068,7 @@ label in legend mark coordinates={(-3ex,-.3ex),(-1.5ex,.3ex),(0,0)}, }, straight label in legend line/.style={ - label in legend line coordinates={(-2em,0),(0,0)}, + label in legend line coordinates={(-2em,0),(-1.5em,0),(-.5em,0),(0,0)}, label in legend mark coordinates={(-1.5em,0),(-.5em,0)}, }, zig zag label in legend line/.style={ @@ -1730,20 +2078,16 @@ circular label in legend line/.style={ label in legend line coordinates={% ([xshift=-1em]0:.9em and .35ex),% - ([xshift=-1em]30:.9em and .35ex),% - ([xshift=-1em]60:.9em and .35ex),% + ([xshift=-1em]45:.9em and .35ex),% ([xshift=-1em]90:.9em and .35ex),% - ([xshift=-1em]120:.9em and .35ex),% - ([xshift=-1em]150:.9em and .35ex),% + ([xshift=-1em]135:.9em and .35ex),% ([xshift=-1em]180:.9em and .35ex),% - ([xshift=-1em]210:.9em and .35ex),% - ([xshift=-1em]240:.9em and .35ex), + ([xshift=-1em]225:.9em and .35ex),% ([xshift=-1em]270:.9em and .35ex),% - ([xshift=-1em]300:.9em and .35ex),% - ([xshift=-1em]330:.9em and .35ex)}, + ([xshift=-1em]315:.9em and .35ex)},% label in legend mark coordinates={([xshift=-1em]120:.9em and .35ex),([xshift=-1em]-60:.9em and .35ex)}, }, - gapped circular label in legend line/.style={ + gap circular label in legend line/.style={ label in legend line coordinates={% ([xshift=-1em,yshift=.2ex]90:1.4ex and 0.9ex),% ([xshift=-1em,yshift=.2ex]162:1.4ex and 0.9ex),% @@ -1779,30 +2123,40 @@ store=/tikz/data visualization/visualizers/#1, class=plot handler visualizer, arg1=#1, - arg2={\tikz@plot@handler,\tikz@dv@plot@mark@maker} + arg2={\tikz@dv@plot@handler,\tikz@dv@plot@mark@maker} }, new visualizer={#1}{% every path/.style={draw}, style={every mark/.append style={color=visualizer color}}, - straight line, + mark size=2pt, semithick, color=visualizer color, mark=none, /tikz/data visualization/every visualize as line/.try, - }, - /data point/visualizer=#1 + }{visualizer in legend=\tikz@dv@legend@entry@as@example}, + #1={straight line} }, visualize as line/.default=line, visualize as smooth line/.style={ visualize as line={#1}, - #1={style=smooth line} + #1={smooth line} }, visualize as smooth line/.default=line, visualize as scatter/.style={ - visualize as line={#1}, - #1={style=no lines, - /tikz/data visualization/every visualize as scatter/.try}, - visualizer style sheet=cross marks + new object={ + when=after survey, + store=/tikz/data visualization/visualizers/#1, + class=plot handler visualizer, + arg1=#1, + arg2={\tikz@dv@plot@mark@maker} + }, + new visualizer={#1}{% + mark=x, + mark size=2pt, + style={every mark/.append style={color=visualizer color}}, + /tikz/data visualization/every visualize as scatter/.try, + }{visualizer in legend=\tikz@dv@legend@entry@as@example}, + #1={no lines} }, visualize as scatter/.default=scatter } @@ -1812,32 +2166,62 @@ \let\tikz@transform=\pgfutil@empty% \tikzset{solid,shift only,every mark}% \tikz@options% - \pgfplothandlermark{\tikz@transform\pgfuseplotmark{\tikz@plot@mark}} + \ifx\tikz@plot@mark\pgfutil@empty% + \pgfplothandlerdiscard + \else + \pgfplothandlermark{\tikz@transform\pgfuseplotmark{\tikz@plot@mark}} + \fi } +% +% Rectangle visualizers +% + -% The following needs to be fixed... \tikzdatavisualizationset{ - new rectangles visualizer/.style={ + visualize as rectangles/.style={ new object={ + when=before survey, store=/tikz/data visualization/visualizers/#1, class=rectangle visualizer, - arg1 from key=/tikz/data visualization/#1/attribute 1, - arg2 from key=/tikz/data visualization/#1/attribute 2, - arg3=#1/use path + arg1=#1 }, - #1/attribute 1/.initial=x, - #1/attribute 2/.initial=y, - /data point/#1/use path/.initial=\pgfusepath{stroke}, - /data point/#1/style/.code=\pgfkeysalso{/data point/#1/use path={\path[every rectangles/.try,##1];}} + /data point/#1/attribute 1/.initial=x, + /data point/#1/attribute 2/.initial=y, + new visualizer={#1}{% + every path/.style={draw}, + semithick, + color=visualizer color, + /tikz/data visualization/every visualize as rectangles/.try, + }{visualizer in legend=\tikz@dv@legend@entry@as@rectangle}, + #1={} }, - rectangle visualizer/.default=rectangles + visualize as rectangles/.default=rectangles, + % + % + % + visualizer options/.cd, + attribute 1/.style={/data point/\tikz@visualizer/attribute 1=#1}, + attribute 2/.style={/data point/\tikz@visualizer/attribute 2=#1}, } +\def\tikz@dv@legend@entry@as@rectangle{ + \pgfkeysgetvalue{/data point/set}{\tikz@visualizer} + \pgfkeysvalueof{/data point/\tikz@visualizer/execute at begin} + \pgfplothandlerpolygon + \pgfplotstreamstart + \pgfkeysgetvalue{/tikz/data visualization/legend entry options/label in legend rectangle coordinates}{\tikz@dv@temp} + \foreach \coordinate in \tikz@dv@temp + { \pgfplotstreampoint{\expandafter\tikz@scan@one@point\expandafter\pgfutil@firstofone\coordinate} } + \pgfplotstreamend + \pgfkeysvalueof{/data point/\tikz@visualizer/execute at end} +} + + % @@ -1946,7 +2330,7 @@ \pgfdvdeclarestylesheet{strong colors} { - default style/.style={black}, + default style/.style={visualizer color=black}, 1/.style={visualizer color=black}, 2/.style={visualizer color=red!80!black}, 3/.style={visualizer color=blue!80!black}, @@ -1958,13 +2342,30 @@ \pgfdvdeclarestylesheet{cross marks} { - default style/.style={mark=x,every mark/.append style=thin,mark size=1.8pt}, - 1/.style={mark=x,every mark/.append style=thin,mark size=1.8pt}, - 2/.style={mark=+,every mark/.append style=thin,mark size=1.8pt}, - 3/.style={mark=Mercedes star,every mark/.append style=thin,mark size=1.8pt}, - 4/.style={mark=Mercedes star flipped,every mark/.append style=thin,mark size=1.8pt}, - 5/.style={mark=star,every mark/.append style=thin,mark size=1.8pt}, - 6/.style={mark=10-pointed star,every mark/.append style={line width=.3pt,mark size=1.6pt}} + default style/.style={mark=x,every mark/.append style=thin,mark size=2pt}, + 1/.style={mark=x,every mark/.append style=thin,mark size=2pt}, + 2/.style={mark=+,every mark/.append style=thin,mark size=2pt}, + 3/.style={mark=Mercedes star,every mark/.append style=thin,mark size=2pt}, + 4/.style={mark=Mercedes star flipped,every mark/.append style=thin,mark size=2pt}, + 5/.style={mark=star,every mark/.append style=thin,mark size=2pt}, + 6/.style={mark=10-pointed star,every mark/.append style={line width=.3pt,mark size=1.8pt}} +} + + +\pgfdvdeclarestylesheet{* mark} +{ + default style/.style={mark=*,every mark/.append style=thin,mark size=1.4pt}, +} + +\pgfdvdeclarestylesheet{dot mark} +{ + default style/.style={mark=*,every mark/.append style=thin,mark size=0.6pt}, +} + + +\pgfdvdeclarestylesheet{o mark} +{ + default style/.style={mark=o,every mark/.append style=thin,mark size=1.4pt}, } @@ -1994,9 +2395,10 @@ } } -\tikzdvdeclarestylesheetcolorseries{varying hue}{hsb}{.4,0.9,0.8}{.213,0,0} +\tikzdvdeclarestylesheetcolorseries{vary hue}{hsb}{.4,0.9,0.8}{.213,0,0} \tikzdvdeclarestylesheetcolorseries{shades of blue}{hsb}{.65,1.4,1}{0,-.4,-.0} \tikzdvdeclarestylesheetcolorseries{shades of red}{hsb}{0,1.4,1}{0,-.4,-.0} +\tikzdvdeclarestylesheetcolorseries{gray scale}{hsb}{0,0,-.34}{0,0,.34} @@ -2020,7 +2422,7 @@ new Cartesian axis=y axis, y axis={attribute=y,unit vector={(0cm,1pt)}} }, - xy axes/.style={x axis={#1},y axis={#1}}, + Xy axes/.style={x axis={#1},y axis={#1}}, uv Cartesian/.style={ new Cartesian axis=u axis, u axis={attribute=u,unit vector={(1pt,0cm)}}, @@ -2047,6 +2449,24 @@ +% +% Create a new axis system +% + +\tikzdatavisualizationset{ + new axis system/.style n args={4}{ + #1/.style={ + #2, + #1/.cd, + #3, + /tikz/data visualization/every #1/.try, + ##1, + /tikz/data visualization/.cd, + #4, + } + } +} + % The school book axes % @@ -2062,56 +2482,67 @@ % instance. \tikzdatavisualizationset{ - school book axes/.style={ + new axis system={school book axes}{% xy Cartesian, x axis={ - include values=0, + include value=0, + scaling=0 at 0 and \pgfkeysvalueof{/tikz/data visualization/school book axes/unit} at 1cm, visualize axis={y axis={goto=0},style=->,padded}, visualize ticks={common={y axis={goto=0},direction axis=y axis}, major={tick text at low, options at=0 as [{style={draw=none},no tick text}] }}, visualize grid={common={direction axis=y axis,padded}}, - ticks={step=1}, - padding=0.75em, - visualize label={visualize x axis label} + ticks={step=\pgfkeysvalueof{/tikz/data visualization/school book axes/unit}}, + padding=0.75em }, y axis={ - include values=0, + include value=0, + scaling=0 at 0 and \pgfkeysvalueof{/tikz/data visualization/school book axes/unit} at 1cm, visualize axis={x axis={goto=0},style=->,padded}, visualize ticks={ common={x axis={goto=0},direction axis=x axis}, major={tick text at low,options at=0 as [{high=0,low=0,style={draw=none},node style={anchor=north east}}]} }, visualize grid={common={direction axis=x axis,padded}}, - ticks={step=1}, - padding=0.75em, - visualize label={visualize y axis label} - }, - school book axes standard labels, - every school book axes/.try - } -} - - -% Possible axis positionings: - -\tikzdatavisualizationset{ - % + ticks={step=\pgfkeysvalueof{/tikz/data visualization/school book axes/unit}}, + padding=0.75em + } + }{% + standard labels + }{% + @make labels + }, + school book axes/.cd, + % Possible axis positionings: + % % Place labels at the ends of the axes - school book axes standard labels/.style={ - visualize x axis label/.style={ - value=padded max, - y axis={goto=0} - }, - visualize y axis label/.style={ - value=padded max, - x axis={goto=0} + % + standard labels/.style={ + /tikz/data visualization/@make labels/.style={ + x axis={ + visualize label={ + x axis={goto=padded max, anchor at max}, + y axis={goto=0} + } + }, + y axis={ + visualize label={ + y axis={goto=padded max, anchor at max}, + x axis={goto=0} + } + } } - } + }, + % + % Basic unit + % + unit/.initial=1, } + + % The scientific axes % % The scientific axes is a 2d plot that has a predetermined width and @@ -2119,154 +2550,163 @@ % this given rectangle. \tikzdatavisualizationset{ - scientific axes/width/.initial=5cm, - scientific axes/height/.initial=0.618*\pgfkeysvalueof{/tikz/data visualization/scientific axes/width},% golden ratio... - scientific axes/.style={ + new axis system={scientific axes}{% xy Cartesian, every axis/.append style={style={draw=black!50}}, every ticks/.append style={style={draw=black!50}}, x axis={ length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/width}, - ticks={some}, - visualize ticks={common={y axis={goto=padded min},direction axis=y axis,high=0pt},major={tick text at low}}, - visualize ticks={common={y axis={goto=padded max},direction axis=y axis,low=0pt}}, - visualize axis={y axis={goto=padded min},padded}, - visualize axis={y axis={goto=padded max},padded}, - visualize grid={common={direction axis=y axis,padded}}, - visualize label=visualize x axis label + ticks }, y axis={ length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height}, - ticks={some}, - visualize ticks={common={x axis={goto=padded min},direction axis=x axis,high=0pt},major={tick text at low}}, - visualize ticks={common={x axis={goto=padded max},direction axis=x axis,low=0pt}}, - visualize axis={x axis={goto=padded min},padded}, - visualize axis={x axis={goto=padded max},padded}, - visualize grid={common={direction axis=x axis,padded}}, - visualize label=visualize y axis label - }, - scientific axes standard labels, - every scientific axes/.try + ticks + } + }{% + standard labels, + outer ticks, + }{% + @make axes, + @make labels }, - scientific inner axes/.style={ - xy Cartesian, - every axis/.append style={style={draw=black!50}}, - every ticks/.append style={style={draw=black!50}}, - x axis={ - length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/width}, - ticks={some}, - visualize ticks={common={y axis={goto=padded min},direction axis=y axis,low=0pt},major={tick text at low}}, - visualize ticks={common={y axis={goto=padded max},direction axis=y axis,high=0pt}}, - visualize axis={y axis={goto=padded min},padded}, - visualize axis={y axis={goto=padded max},padded}, - visualize grid={common={direction axis=y axis,padded}}, - visualize label=visualize x axis label - }, - y axis={ - length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height}, - ticks={some}, - visualize ticks={common={x axis={goto=padded min},direction axis=x axis,low=0pt},major={tick text at low}}, - visualize ticks={common={x axis={goto=padded max},direction axis=x axis,high=0pt}}, - visualize axis={x axis={goto=padded min},padded}, - visualize axis={x axis={goto=padded max},padded}, - visualize grid={common={direction axis=x axis,padded}}, - visualize label=visualize y axis label - }, - scientific axes standard labels, - every scientific axes/.try + scientific axes/.cd, + width/.initial=5cm, + height/.initial=0.618*\pgfkeysvalueof{/tikz/data visualization/scientific axes/width},% golden ratio... + outer ticks/.style={ + /tikz/data visualization/@make axes/.style={ + x axis={ + visualize ticks={common={y axis={goto=padded min},direction axis=y axis,high=0pt},major={tick text at low}}, + visualize ticks={common={y axis={goto=padded max},direction axis=y axis,low=0pt}}, + visualize axis={y axis={goto=padded min},padded}, + visualize axis={y axis={goto=padded max},padded}, + visualize grid={common={direction axis=y axis,padded}}, + }, + y axis={ + visualize ticks={common={x axis={goto=padded min},direction axis=x axis,high=0pt},major={tick text at low}}, + visualize ticks={common={x axis={goto=padded max},direction axis=x axis,low=0pt}}, + visualize axis={x axis={goto=padded min},padded}, + visualize axis={x axis={goto=padded max},padded}, + visualize grid={common={direction axis=x axis,padded}}, + } + } }, - scientific clean axes/.style={ - xy Cartesian, - x axis={ - length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/width}, - ticks={some}, - visualize ticks={common={y axis={goto=padded min},direction axis=y axis,high=0pt},major={tick text at low}}, - visualize axis={y axis={goto=padded min}}, - visualize grid={common={direction axis=y axis}}, - visualize label=visualize x axis label, - grid={major={also at=min,also at=max}}, - }, - y axis={ - length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height}, - ticks={some}, - visualize ticks={common={x axis={goto=padded min},direction axis=x axis,high=0pt},major={tick text at low}}, - visualize axis={x axis={goto=padded min}}, - visualize grid={common={direction axis=x axis}}, - visualize label=visualize y axis label, - grid={major={also at=min,also at=max}}, - }, - all axes={padding=.5em}, - scientific axes standard labels, - every scientific axes/.try + inner ticks/.style={ + /tikz/data visualization/@make axes/.style={ + x axis={ + visualize ticks={common={y axis={goto=padded min},direction axis=y axis,low=0pt},major={tick text at low}}, + visualize ticks={common={y axis={goto=padded max},direction axis=y axis,high=0pt}}, + visualize axis={y axis={goto=padded min},padded}, + visualize axis={y axis={goto=padded max},padded}, + visualize grid={common={direction axis=y axis,padded}}, + }, + y axis={ + visualize ticks={common={x axis={goto=padded min},direction axis=x axis,low=0pt},major={tick text at low}}, + visualize ticks={common={x axis={goto=padded max},direction axis=x axis,high=0pt}}, + visualize axis={x axis={goto=padded min},padded}, + visualize axis={x axis={goto=padded max},padded}, + visualize grid={common={direction axis=x axis,padded}}, + } + } }, -} - - - -% Possible axis positionings: - -\tikzdatavisualizationset{ + clean/.style={ + /tikz/data visualization/@make axes/.style={ + x axis={ + visualize ticks={common={y axis={goto=padded min},direction axis=y axis,high=0pt},major={tick text at low}}, + visualize axis={y axis={goto=padded min}}, + visualize axis={y axis={goto=min}, style={black!25, line cap=rect}}, + visualize axis={y axis={goto=max}, style={black!25, line cap=rect}}, + visualize grid={common={direction axis=y axis}}, + padding=.5em, + }, + y axis={ + visualize ticks={common={x axis={goto=padded min},direction axis=x axis,high=0pt},major={tick text at low}}, + visualize axis={x axis={goto=padded min}}, + visualize axis={x axis={goto=min}, style={black!25, line cap=rect}}, + visualize axis={x axis={goto=max}, style={black!25, line cap=rect}}, + visualize grid={common={direction axis=x axis}}, + padding=.5em + }, + } + }, + % Possible axis positionings: % % Place axes labels below and left, where left label is rotated % - scientific axes standard labels/.style={ - visualize x axis label/.style={ - % Horizontal position is middle of axis: - pos=0.5, - y axis={goto=padded min}, - % Vertical position comes from bounding box: - node style={ - at={(0,0 |- data visualization bounding box.south)}, - below + standard labels/.style={ + /tikz/data visualization/@make labels/.style={ + x axis={ + visualize label={ + x axis={goto pos=.5}, + % Vertical position comes from bounding box: + node style={ + at={(0,0 |- data visualization bounding box.south)}, + below + } + } + }, + y axis={ + visualize label={ + y axis={goto pos=.5}, + % Horizontal position comes from bounding box: + node style={ + at={(0,0 -| data visualization bounding box.west)}, + rotate=90, + above} + } } - }, - visualize y axis label/.style={% - % Vertical position is middle of axis: - pos=0.5, - x axis={goto=padded min}, - % Horizontal position comes from bounding box: - node style={ - at={(0,0 -| data visualization bounding box.west)}, - rotate=90, - above} } }, % % Place axes labels below and left, no rotation % - scientific axes upright labels/.style={ - scientific axes standard labels, - visualize y axis label/.style={% - % Vertical position is middle of axis: - pos=0.5, - x axis={goto=padded min}, - % Horizontal position comes from bounding box: - node style={ - at={(0,0 -| data visualization bounding box.west)}, - left + upright labels/.style={ + /tikz/data visualization/@make labels/.style={ + x axis={ + visualize label={ + x axis={goto pos=.5}, + % Vertical position comes from bounding box: + node style={ + at={(0,0 |- data visualization bounding box.south)}, + below + } + } + }, + y axis={ + visualize label={ + y axis={goto pos=.5}, + % Horizontal position comes from bounding box: + node style={ + at={(0,0 -| data visualization bounding box.west)}, + left + } + } } } }, % % Place axes at the ends of the axes % - scientific axes end labels/.style={ - visualize x axis label/.style={ - value=max, - y axis={goto=padded min}, - % Vertical position comes from bounding box: - node style={ - at={(0,0 -| data visualization bounding box.east)}, - right - } - }, - visualize y axis label/.style={ - value=max, - x axis={goto=padded min}, - % Horizontal position comes from bounding box: - node style={ - at={(0,0 |- data visualization bounding box.north)}, - above + end labels/.style={ + /tikz/data visualization/@make labels/.style={ + x axis={ + visualize label={ + y axis={goto=padded min}, + % Vertical position comes from bounding box: + node style={ + at={(0,0 -| data visualization bounding box.east)}, + right + } + } + }, + y axis={ + visualize label={ + x axis={goto=padded min}, + % Horizontal position comes from bounding box: + node style={ + at={(0,0 |- data visualization bounding box.north)}, + above + } + } } } } diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.polar.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.polar.code.tex index 8b4d99f49dd..1615f0d1bfc 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.polar.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.polar.code.tex @@ -7,21 +7,21 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.polar.code.tex,v 1.3 2008/11/24 18:31:22 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.polar.code.tex,v 1.8 2011/05/06 11:15:33 tantau Exp $ \usetikzlibrary{datavisualization} \usepgflibrary{datavisualization.polar} \tikzdatavisualizationset{% - new polar/.style={ - new axis=angle axis, - angle axis={attribute=angle}, - new axis=radius axis, - radius axis={attribute=radius}, - radius axis/scaling/default=0 at 0 and 1 at 1cm, + new polar axes/.style 2 args={ + new axis base=#1, + #1={attribute=angle}, + new axis base=#2, + #2={attribute=radius}, + #2/scaling/default=0 at 0 and 1 at 1cm, new object={ - store=/tikz/data visualization/polar transformer, + store=/tikz/data visualization/#1/polar transformer, class=polar transformer, arg1/.expanded=\pgfkeysvalueof{/tikz/data visualization/angle axis/attribute}/scaled, arg2/.expanded=\pgfkeysvalueof{/tikz/data visualization/radius axis/attribute}/scaled, @@ -30,28 +30,530 @@ }, /tikz/data visualization/#1/unit vector 0 degrees/.initial=\pgfqpoint{1pt}{0pt}, /tikz/data visualization/#1/unit vector 90 degrees/.initial=\pgfqpoint{0pt}{1pt}, - /tikz/data visualization/#1/unit vectors/.code 2 args={ - \def\tikz@dv@polar{/tikz/data visualization/#1} - \tikz@scan@one@point\tikz@lib@dv@polar@a##1 - \tikz@scan@one@point\tikz@lib@dv@polar@b##2 - } }, - new polar/.default=polar + new polar axes/.default={angle axis}{radius axis} } \def\tikz@lib@dv@polar@a#1{ - \pgfkeyssetvalue{\tikz@dv@polar/unit vector 0 degrees}{#1} + \pgfkeyssetvalue{\tikz@dv@axis/unit vector 0 degrees}{#1} } \def\tikz@lib@dv@polar@b#1{ - \pgfkeyssetvalue{\tikz@dv@polar/unit vector 90 degrees}{#1} + \pgfkeyssetvalue{\tikz@dv@axis/unit vector 90 degrees}{#1} +} + + + +% +% Scientific polar axes +% + +\tikzset{ + /tikz/data visualization/axis options/.cd, + unit vectors/.code 2 args={ + \tikz@scan@one@point\tikz@lib@dv@polar@a#1 + \tikz@scan@one@point\tikz@lib@dv@polar@b#2 + }, + degrees/.style={\tikz@dv@axis/scaling=0 at 0 and 1 at 1}, + radians/.style={\tikz@dv@axis/scaling=0 at 0 and 0.03141592653589793 at 1.8}, +} + + + +\tikzdatavisualizationset{ + new axis system={scientific polar axes}{% + new polar axes, + angle axis={attribute=angle}, + radius axis={attribute=radius}, + every axis/.append style={style={draw=black!50}}, + every ticks/.append style={style={draw=black!50}}, + }{% + 0 to 360,% + outer ticks, + }{% + @make axes, + scientific polar axes/@setup axes, + /utils/exec={ + \edef\pgf@marshal{\noexpand\tikzdatavisualizationset{\pgfkeysvalueof{/tikz/data visualization/@which visualize radius axis}/.list={\pgfkeysvalueof{/tikz/data visualization/\pgfkeysvalueof{/tikz/data visualization/@which radius axes at}}}}} + \pgf@marshal + }, + @make labels + }, + @which radius axes at/.initial=@inner radius axes at, + @which visualize radius axis/.initial=@visualize radius axis, + @inner radius axes at/.initial=, + @clean radius axes at/.initial=, + @visualize radius axis/.style 2 args={ + radius axis={ + visualize axis={angle axis={goto=#1},high=padded max,low=0}, + visualize ticks={ + common={angle axis={goto=#1}, direction axis=angle axis}, + major={tick text at #2, + options at=0 as [{style={draw=none},no tick text}] + } + } + } + }, + @visualize clean radius axis/.style n args={5}{ + radius axis={ + visualize axis={angle + axis={goto=#1},high=max,low=0,style={black!25,line cap=rect}}, + visualize axis={angle + axis={goto=#1},high=max,low=0,style={line cap=rect,#4}}, + visualize ticks={ + style={#4}, + common={angle axis={goto=#1}, direction axis=angle axis, #3=0}, + major={tick text at #2,#5} + } + } + }, + @visualize zero/.style={@inner visualize zero={#1}}, + @clean visualize zero/.style={}, + @inner visualize zero/.style={ + radius axis={ + visualize ticks={ + common={angle axis={goto=0}, direction axis=angle axis}, + major={tick text at low,low=0,high=0,at=0 as + [{style={draw=none},node style={anchor=#1}}] + } + } + } + }, + @degrees/.style={ + angle axis={degrees, ticks={step=15, tick suffix=$^\circ$, major={ + options at=360 as [{style={draw=none},no tick text}], + options at=-180 as [{style={draw=none},no tick text}]}}} + }, + @rad/.style={ + angle axis={radians, ticks={ + step=(pi/12), + node style={ + /pgf/number format/frac, + /pgf/number format/frac shift={1} + }, + tick typesetter/.code={% + \pgfmathsetmacro{\tikz@lib@dv@pol}{round(####1*3.819718634205488)/12}% + \pgfmathapproxequalto{\tikz@lib@dv@pol}{0}% + \ifdim\pgfmathresult pt=1.0pt% + $0$% + \else% + \pgfmathapproxequalto{\tikz@lib@dv@pol}{1}% + \ifdim\pgfmathresult pt=1.0pt% + $\pi$% + \else + \pgfmathapproxequalto{\tikz@lib@dv@pol}{-1}% + \ifdim\pgfmathresult pt=1.0pt% + $-\pi$% + \else% + \pgfmathprintnumber{\tikz@lib@dv@pol}$\pi$% + \fi% + \fi% + \fi% + }, + major={ + options at=6.2831985e0 as [{style={draw=none},no tick text}], + options at=6.2831192e0 as [{style={draw=none},no tick text}], + options at=6.2830794e0 as [{style={draw=none},no tick text}], + options at=6.2828787e0 as [{style={draw=none},no tick text}], + options at=6.2831598e0 as [{style={draw=none},no tick text}], + options at=-3.1415991e0 as [{style={draw=none},no tick text}], + options at=-3.1415802e0 as [{style={draw=none},no tick text}], + options at=-3.1415602e0 as [{style={draw=none},no tick text}], + options at=-3.14153961e0 as [{style={draw=none},no tick text}], + options at=-3.1414406e0 as [{style={draw=none},no tick text}], + } + } + } + }, + @make labels/.style={}, +} + +\tikzdatavisualizationset{ + scientific polar axes/.cd, + % + % + % + outer ticks/.style={ + /tikz/data visualization/@make axes/.style={ + radius axis={ + min value=0, + length=\pgfkeysvalueof{/tikz/data visualization/scientific polar axes/radius}, + padding=0em, + ticks={few}, + visualize grid={common={direction axis=angle axis,low=min,high=max}}, + }, + angle axis={ + visualize axis={radius axis={goto=padded max},low=min,high=max}, + visualize ticks={common={radius axis={goto=padded max},direction + axis=radius axis},common={low=0},major={tick text at high}}, + visualize grid={common={direction axis=radius axis},low=0,high=padded max}, + } + }, + /tikz/data visualization/@which radius axes at=@inner radius axes at, + /tikz/data visualization/@which visualize radius axis=@visualize radius axis, + /tikz/data visualization/@visualize zero/.style={@inner visualize zero={##1}}, + }, + inner ticks/.style={ + /tikz/data visualization/@make axes/.style={ + radius axis={ + min value=0, + length=\pgfkeysvalueof{/tikz/data visualization/scientific polar axes/radius}, + padding=0em, + ticks={few}, + visualize grid={common={direction axis=angle axis,low=min,high=max}}, + }, + angle axis={ + visualize axis={radius axis={goto=padded max},low=min,high=max}, + visualize ticks={common={radius axis={goto=padded max},direction + axis=radius axis},common={high=0},major={tick text at high}}, + visualize grid={common={direction axis=radius axis},low=0,high=padded max}, + } + }, + /tikz/data visualization/@which radius axes at=@inner radius axes at, + /tikz/data visualization/@which visualize radius axis=@visualize radius axis, + /tikz/data visualization/@visualize zero/.style={@inner visualize zero={##1}}, + }, + clean/.style={ + /tikz/data visualization/@make axes/.style={ + radius axis={ + min value=0, + length=\pgfkeysvalueof{/tikz/data visualization/scientific polar axes/radius}, + padding=.5em, + ticks={few}, + visualize grid={common={direction axis=angle axis,low=min,high=max}}, + }, + angle axis={ + padding=.5em, + visualize axis={radius axis={goto=max}, style={black!25, line cap=rect},low=min,high=max}, + visualize axis={radius axis={goto=padded max}, style={line cap=rect}, low=min,high=max}, + visualize ticks={common={radius axis={goto=padded max}, direction axis=radius axis},common={low=0},major={tick text at high}}, + visualize grid={common={direction axis=radius axis},low=0,high=max}, + } + }, + /tikz/data visualization/@which radius axes at=@clean radius axes at, + /tikz/data visualization/@which visualize radius axis=@visualize clean radius axis, + /tikz/data visualization/@visualize zero/.style={@clean visualize zero={##1}}, + }, + radius/.initial=3.25cm, + % + % First quadrant + % + 0 to pi half/.style={ + @setup axes/.style={ + angle axis={min value=0, max value=1.570796326794897}, + @rad, + @visualize zero=north east, + @inner radius axes at={{0}{low},{1.570796326794897}{high}}, + @clean radius axes at={% + {0}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {1.570796326794897}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{} + } + } + }, + 0 to 90/.style={ + @setup axes/.style={ + angle axis={min value=0, max value=90}, + @degrees, + @visualize zero=north east, + @inner radius axes at={{0}{low},{90}{high}}, + @clean radius axes at={% + {0}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {90}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{} + } + } + }, + quadrant/.style={ + @setup axes/.style={ + angle axis={scaling=min at 0 and max at 90, ticks}, + @visualize zero=north east, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{} + } + } + }, + quadrant clockwise/.style={ + @setup axes/.style={ + angle axis={scaling=min at 90 and max at 0, ticks}, + @visualize zero=north east, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {max}{high}{low}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {min}{low}{high}{xshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{} + } + } + }, + % + % Fourth quadrant + % + -pi half to 0/.style={ + @setup axes/.style={ + angle axis={min value=-1.570796326794897, max value=0}, + @rad, + @visualize zero=south east, + @inner radius axes at={{-1.570796326794897}{low},{0}{high}}, + @clean radius axes at={% + {-1.570796326794897}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {0}{high}{low}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{} + } + } + }, + -90 to 0/.style={ + @setup axes/.style={ + angle axis={min value=-90, max value=0}, + @degrees, + @visualize zero=south east, + @inner radius axes at={{-90}{low},{0}{high}}, + @clean radius axes at={% + {-90}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {0}{high}{low}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{} + } + } + }, + fourth quadrant/.style={ + @setup axes/.style={ + angle axis={scaling=min at -90 and max at 0, ticks}, + @visualize zero=south east, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{} + } + } + }, + fourth quadrant clockwise/.style={ + @setup axes/.style={ + angle axis={scaling=min at 0 and max at -90, ticks}, + @visualize zero=south east, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {max}{high}{low}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {min}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{} + } + } + }, + % + % Upper half + % + 0 to pi/.style={ + @setup axes/.style={ + angle axis={min value=0, max value=3.141592653589793}, + @rad, + @visualize zero=north, + @inner radius axes at={{0}{low},{1.570796326794897}{high},{3.141592653589793}{high}}, + @clean radius axes at={% + {0}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {3.141592653589793}{high}{low}{yshift=-\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + 0 to 180/.style={ + @setup axes/.style={ + angle axis={min value=0, max value=180}, + @degrees, + @visualize zero=north, + @inner radius axes at={{0}{low},{90}{high},{180}{high}}, + @clean radius axes at={% + {0}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {180}{high}{low}{yshift=-\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + upper half/.style={ + @setup axes/.style={ + angle axis={scaling=min at 0 and max at 180, ticks}, + @visualize zero=north, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{yshift=-\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + upper half clockwise/.style={ + @setup axes/.style={ + angle axis={scaling=min at 180 and max at 0, ticks}, + @visualize zero=north, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{yshift=-\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + % + % Lower half + % + lower half/.style={ + @setup axes/.style={ + angle axis={scaling=min at -180 and max at 0, ticks}, + @visualize zero=south, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{yshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{yshift=\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + lower half clockwise/.style={ + @setup axes/.style={ + angle axis={scaling=min at 0 and max at -180, ticks}, + @visualize zero=south, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{yshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{yshift=\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + % + % Right half + % + -pi half to pi half/.style={ + @setup axes/.style={ + @rad, + angle axis={min value=-1.570796326794897, max value=1.570796326794897}, + @visualize zero=east, + @inner radius axes at={{0}{low},{1.570796326794897}{low},{-1.570796326794897}{high}}, + @clean radius axes at={% + {-1.570796326794897}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {1.570796326794897}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + -90 to 90/.style={ + @setup axes/.style={ + angle axis={min value=-90, max value=90}, + @degrees, + @visualize zero=east, + @inner radius axes at={{-90}{low},{0}{low},{90}{high}}, + @clean radius axes at={% + {-90}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {90}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + right half/.style={ + @setup axes/.style={ + angle axis={scaling=min at -90 and max at 90, ticks}, + @visualize zero=east, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + right half clockwise/.style={ + @setup axes/.style={ + angle axis={scaling=min at 90 and max at -90, ticks}, + @visualize zero=east, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + % + % Left half + % + left half/.style={ + @setup axes/.style={ + angle axis={scaling=min at 90 and max at 270, ticks}, + @visualize zero=west, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{xshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{xshift=\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + left half clockwise/.style={ + @setup axes/.style={ + angle axis={scaling=min at 270 and max at 90, ticks}, + @visualize zero=west, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{xshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{xshift=\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + % + % Full circle + % + 0 to 2pi/.style={ + @setup axes/.style={ + angle axis={min value=0, max value=6.283185307179586}, + @rad, + @visualize zero=north east, + @inner radius axes at={{0}{low},{1.570796326794897}{high},{3.141592653589793}{high},{4.71238898038469}{low}}, + @clean radius axes at={{0}{low}{high}{}{}} + } + }, + -pi to pi/.style={ + @setup axes/.style={ + angle axis={min value=-3.141592653589793, max value=3.141592653589793}, + @rad, + @visualize zero=north east, + @inner radius axes at={{0}{low},{1.570796326794897}{high},{3.141592653589793}{high},{-1.57079632679489}{low}}, + @clean radius axes at={{0}{low}{high}{}{}} + } + }, + 0 to 360/.style={ + @setup axes/.style={ + angle axis={min value=0, max value=360}, + @degrees, + @visualize zero=north east, + @inner radius axes at={{0}{low},{90}{high},{180}{high},{270}{low}}, + @clean radius axes at={{0}{low}{high}{}{}} + } + }, + -180 to 180/.style={ + @setup axes/.style={ + angle axis={min value=-180, max value=180}, + @degrees, + @visualize zero=north east, + @inner radius axes at={{0}{low},{90}{high},{180}{high},{-90}{low}}, + @clean radius axes at={{0}{low}{high}{}{}} + } + }, } + + +% +% Pie-charts -- still under construction... +% + \tikzset{ /tikz/data visualization/axis options/.cd, - deg/.style={\tikz@dv@axis/scaling=0 at 0 and 360 at 360}, - rad/.style={\tikz@dv@axis/scaling=0 at 0 and pi at 180}, - grad/.style={\tikz@dv@axis/scaling=0 at 0 and 400 at 360}, - percent/.style={\tikz@dv@axis/scaling=0 at 0 and 100 at 360}, + percent/.style={\tikz@dv@axis/scaling=0 at 0 and 1 at 3.6}, full circle/.style={\tikz@dv@axis/scaling=min at 0 and max at 360}, half circle/.style={\tikz@dv@axis/scaling=min at 0 and max at 180}, quarter circle/.style={\tikz@dv@axis/scaling=min at 0 and max at 90} @@ -59,4 +561,5 @@ + \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.basic.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.basic.code.tex deleted file mode 100644 index 7464369161c..00000000000 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.basic.code.tex +++ /dev/null @@ -1,29 +0,0 @@ -% Copyright 2010 by Till Tantau -% -% This file may be distributed and/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 details. - -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.basic.code.tex,v 1.1 2010/10/23 16:35:41 tantau Exp $ - - - -% -% This is jsut a place-holder -% - -\tikzset{graphs/n/.initial=1} - -\tikzdefgraph{K} -{ - \pgfkeysgetvalue{/tikz/graphs/n}\tikz@lib@graph@temp@n -} -{ - [connect as=clique] - \foreach \tikz@lib@graph@temp@i in {1,...,\tikz@lib@graph@temp@n} - { \tikz@lib@graph@temp@i [at=(\tikz@lib@graph@temp@i*360/\tikz@lib@graph@temp@n:2cm)] } -} - diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.code.tex index 32fd3a374a7..c82c98c7db7 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.code.tex @@ -1,4 +1,5 @@ % Copyright 2010 by Till Tantau +% Copyright 2011 by Jannis Pohlmann % % This file may be distributed and/or modified % @@ -7,19 +8,63 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.code.tex,v 1.1 2010/10/23 16:35:41 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.code.tex,v 1.43 2013/10/10 09:08:58 tantau Exp $ % % Interface keys % -\tikzset{ - graphs/new edge directed/.code n args={3}{\path (#1) edge[->,#3] (#2);}, - graphs/new edge undirected/.code n args={3}{\path (#1) edge[-,#3] (#2);}, - graphs/new edge bidirected/.code n args={3}{\path (#1) edge[<->,#3] (#2);}, - graphs/new edge back directed/.style n args={3}{new edge directed={#2}{#1}{#3}}, - graphs/default edge kind/.initial=undirected +\def\tikzgraphsset{\pgfqkeys{/tikz/graphs}} + +\tikzgraphsset{ + new ->/.code n args={4}{% + \path [->,every new ->/.try] + (#1\tikzgraphleftanchor) + edge[#3] #4 + (#2\tikzgraphrightanchor);}, + new --/.code n args={4}{ + \path [-,every new --/.try] + (#1\tikzgraphleftanchor) + edge[#3] #4 + (#2\tikzgraphrightanchor);}, + new <->/.code n args={4}{ + \path [<->,every new <->/.try] + (#1\tikzgraphleftanchor) + edge[#3] #4 + (#2\tikzgraphrightanchor);}, + new -!-/.code n args={4}{}, + new <-/.code n args={4}{% + \path [<-,every new <-/.try] + (#1\tikzgraphleftanchor) + edge[#3] #4 + (#2\tikzgraphrightanchor); + } +} + + +\def\tikz@lib@graph@store@anchor#1#2{% + \def\tikz@temp{#1} + \ifx\tikz@temp\pgfutil@empty% + \let#2\tikz@temp% + \else% + \def\tikz@temp{.#1} + \let#2\tikz@temp% + \fi% +} + +\tikzgraphsset{ + default edge kind/.initial=--, + --/.style={default edge kind=--}, + ->/.style={default edge kind=->}, + <-/.style={default edge kind=<-}, + <->/.style={default edge kind=<->}, + -!-/.style={default edge kind=-!-}, + default edge operator/.initial=matching and star, + left anchor/.code=\tikz@lib@graph@store@anchor{#1}{\tikzgraphleftanchor}, + right anchor/.code=\tikz@lib@graph@store@anchor{#1}{\tikzgraphrightanchor}, + left anchor=, + right anchor= } @@ -28,8 +73,8 @@ % it were declared there % -\tikzset{ - graphs/use existing nodes/.code=\tikz@lib@graph@alltrue +\tikzgraphsset{ + use existing nodes/.is if=tikz@lib@graph@all } \tikzset{ @@ -37,6 +82,7 @@ \expandafter\global\expandafter\let\csname tikz@lg@node@set #1\endcsname\pgfutil@empty% }, set/.code={ + \tikz@fig@mustbenamed% \expandafter\def\expandafter\tikz@alias\expandafter{\tikz@alias% \expandafter\def\expandafter\pgf@temp\expandafter{\csname tikz@lg@node@set #1\endcsname}% \expandafter\expandafter\expandafter\pgfutil@g@addto@macro\expandafter\pgf@temp\expandafter{\expandafter\tikz@lg@do\expandafter{\tikz@fig@name}}% @@ -48,16 +94,96 @@ % +% Simple versus multi graphs +% +\tikzgraphsset{ + simple/.code={ + \iftikz@lib@graph@simple% + % is already simple, ignore + \else + \tikz@lib@graph@simpletrue% + \pgfkeysalso{operator=\tikz@lib@graph@simple@done}% + \fi% + }, + multi/.code={ + \tikz@lib@graph@simplefalse% + } +} + +\newif\iftikz@lib@graph@simple + +\def\tikz@lib@graph@set@simple@edge#1#2#3#4#5{% + % #1 = kind (<-, ->, ...) + % #2 = from + % #3 = to + % #4 = options + % #5 = edge nodes + % + % Ok, first, test, whether edge exists: + \ifcsname tikz@lg@e@#3@#2\endcsname% + \expandafter\global\expandafter\let\csname tikz@lg@e@#3@#2\endcsname\relax% reset + \fi% + \expandafter\gdef\csname tikz@lg@e@#2@#3\endcsname{\tikz@lib@graph@make@simple@edge{#1}{#2}{#3}{#4}{#5}}% +} + +\def\tikz@lib@graph@make@simple@edge#1#2#3#4#5{% + \pgfqkeys{/tikz/graphs}{new #1={#2}{#3}{#4}{#5}}% +} + + +\def\tikz@lib@graph@simple@done{% + \tikz@lib@graph@pack@node@list% + {% + \let\tikz@lg@do\tikz@lib@graph@simple@node% + \tikz@lib@graph@node@list + }% +} + +\def\tikz@lib@graph@simple@node#1{% + {% + \def\tikz@lib@graph@simple@from@node{#1}% + \let\tikz@lg@do\tikz@lib@graph@simple@other@node% + \tikz@lib@graph@node@list% + }% +} + +\def\tikz@lib@graph@simple@other@node#1{% + \ifcsname tikz@lg@e@\tikz@lib@graph@simple@from@node @#1\endcsname% + \csname tikz@lg@e@\tikz@lib@graph@simple@from@node @#1\endcsname% + \expandafter\global\expandafter\let\csname tikz@lg@e@\tikz@lib@graph@simple@from@node @#1\endcsname\relax% + \fi% +} + + +% % Basic options % -\tikzset{ - graphs/@nodes styling/.style=, - graphs/nodes/.style={/tikz/graphs/@nodes styling/.append style={,#1}}, - graphs/@edges styling/.initial=, - graphs/edges/.style={/tikz/graphs/@edges styling/.append={,#1}}, - graphs/join/.initial=match, - graphs/connect as/.initial=, +\tikzgraphsset{ + @nodes styling/.style=, + nodes/.style={/tikz/graphs/@nodes styling/.append style={,#1}}, + @edges styling/.initial=, + edges/.style={/tikz/graphs/@edges styling/.append={,#1}}, + edge/.style={edges={#1}}, + @edges node/.initial=, + edge node/.style={/tikz/graphs/@edges node/.append={#1}}, + edge label/.style={/tikz/graphs/@edges node/.append={node[auto]{#1}}}, + edge label'/.style={/tikz/graphs/@edges node/.append={node[auto,swap]{#1}}}, + @operators/.initial=, + operator/.style={/tikz/graphs/@operators/.append={#1}}, + @extra group options/.style=, +} + + +\def\tikzgraphinvokeoperator#1{% + {% + \pgfkeyslet{/tikz/graphs/@operators}\pgfutil@empty% + \pgfkeys{/tikz/graphs/.cd,#1}% + \pgfkeysgetvalue{/tikz/graphs/@operators}\tikz@lib@graph@temp% + \global\let\tikz@lib@graph@temp\tikz@lib@graph@temp% + }% + \tikz@lib@graph@temp% + \global\let\tikz@lib@graph@temp\relax% } @@ -69,25 +195,159 @@ \pgfutil@ifnextchar[{\tikz@lib@graph@parser@}{\tikz@lib@graph@parser@[]}%] } -\long\def\tikz@lib@graph@parser@[#1]#2{% - \scope[graphs/.cd,every graph/.try,#1]% - \let\tikz@lib@graph@options\pgfutil@empty% - \let\tikz@lib@graph@node@list\pgfutil@empty% - \tikz@lib@graph@parse@group{#2}% - \let\tikz@lg@do=\tikz@lib@graph@cleanup% - \tikz@lib@graph@node@list% - \endscope% +\def\tikz@lib@graph@parser@[#1]{% + \setbox\tikz@whichbox=\hbox\bgroup% + \unhbox\tikz@whichbox% + \hbox\bgroup + \bgroup% + \pgfinterruptpath% + \scope[graphs/.cd,@graph drawing setup/.try,@operators=,every graph/.try,#1]% + \begingroup% + \iftikz@graph@quick% + \expandafter\tikz@lib@graphs@parse@quick@graph% + \else% + \expandafter\tikz@lib@graphs@normal@main% + \fi% +} + +\long\def\tikz@lib@graphs@normal@main#1{% + \pgfkeysgetvalue{/tikz/graphs/@operators}\tikz@lib@graph@outer@operators% + \let\tikz@lib@graph@options\pgfutil@empty% + \let\tikz@lib@graph@node@list\pgfutil@empty% + \pgfkeyssetvalue{/tikz/graphs/placement/depth}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/width}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/level}{0}% + \tikz@lib@graph@start@hint@group% + \tikz@lib@graph@parse@group{#1}% + \tikz@lib@graph@end@hint@group + \tikz@lib@graph@outer@operators% + \let\tikz@lg@do=\tikz@lib@graph@cleanup% + \tikz@lib@graph@node@list% + \tikz@lib@graph@main@done% +} + +\def\tikz@lib@graph@main@done{% + \endgroup% + \endscope% + \endpgfinterruptpath% + \egroup + \egroup% + \egroup% \tikz@lib@graph@parser@done% } -\long\def\tikz@lib@graph@parse@group#1{% + +\def\tikz@lib@graph@start@hint@group{% + \pgfkeyssetvalue{/tikz/graphs/placement/local depth}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/local width}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/chain count}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/element count}{0}% +} + +\def\tikz@lib@graph@end@hint@group{% + % Get local depth and width outside + \xdef\tikz@lib@graph@group@depth{\pgfkeysvalueof{/tikz/graphs/placement/local depth}} + \xdef\tikz@lib@graph@group@width{\pgfkeysvalueof{/tikz/graphs/placement/local width}} +} + +\def\tikz@lib@graph@hint@aftergroup{% + \pgfkeysgetvalue{/tikz/graphs/placement/width}\tikz@temp@h% + \pgfkeysgetvalue{/tikz/graphs/placement/local width}\tikz@temp@lh% + \pgfkeysgetvalue{/tikz/graphs/placement/local depth}\tikz@temp@lw% + \pgfmathsetmacro\tikz@temp@h{\tikz@lib@graph@group@width+\tikz@temp@h} + \pgfmathsetmacro\tikz@temp@lh{\tikz@lib@graph@group@width+\tikz@temp@lh} + \pgfmathsetmacro\tikz@temp@lw{max(\tikz@lib@graph@group@depth,\tikz@temp@lw)} + \pgfkeyslet{/tikz/graphs/placement/width}\tikz@temp@h% + \pgfkeyslet{/tikz/graphs/placement/local width}\tikz@temp@lh% + \pgfkeyslet{/tikz/graphs/placement/local depth}\tikz@temp@lw% + % + \pgfkeysgetvalue{/tikz/graphs/placement/element count}\tikz@temp% + \c@pgf@counta=\tikz@temp\relax% + \advance\c@pgf@counta by1\relax% + \edef\tikz@temp{\the\c@pgf@counta}% + \pgfkeyslet{/tikz/graphs/placement/element count}\tikz@temp% +} + +\def\tikz@lib@graph@placement@update{% + \pgfkeys{/tikz/graphs/placement/logical node depth/.expand once=\tikz@lib@graph@name} + \let\tikz@lib@graph@node@depth\pgfmathresult + \pgfkeys{/tikz/graphs/placement/logical node width/.expand once=\tikz@lib@graph@name} + \let\tikz@lib@graph@node@width\pgfmathresult + % This is a single node, so update the lengths accordingly + \pgfkeysgetvalue{/tikz/graphs/placement/width}\tikz@temp@h% + \pgfkeysgetvalue{/tikz/graphs/placement/local width}\tikz@temp@lh% + \pgfkeysgetvalue{/tikz/graphs/placement/local depth}\tikz@temp@lw% + \pgfmathsetmacro\tikz@temp@h{\tikz@lib@graph@node@width+\tikz@temp@h} + \pgfmathsetmacro\tikz@temp@lh{\tikz@lib@graph@node@width+\tikz@temp@lh} + \pgfmathsetmacro\tikz@temp@lw{max(\tikz@lib@graph@node@depth,\tikz@temp@lw)} + \pgfkeyslet{/tikz/graphs/placement/width}\tikz@temp@h% + \pgfkeyslet{/tikz/graphs/placement/local width}\tikz@temp@lh% + \pgfkeyslet{/tikz/graphs/placement/local depth}\tikz@temp@lw% + % + \pgfkeysgetvalue{/tikz/graphs/placement/element count}\tikz@temp% + \c@pgf@counta=\tikz@temp\relax% + \advance\c@pgf@counta by1\relax% + \edef\tikz@temp{\the\c@pgf@counta}% + \pgfkeyslet{/tikz/graphs/placement/element count}\tikz@temp% +} + +\def\tikz@lib@graph@placement@after@chain@update{% + \pgfkeysgetvalue{/tikz/graphs/placement/depth}\tikz@temp@w% + \pgfkeysgetvalue{/tikz/graphs/placement/local width}\tikz@temp@lh% + \pgfkeysgetvalue{/tikz/graphs/placement/local depth}\tikz@temp@lw% + \pgfmathsetmacro\tikz@temp@w{\tikz@lib@graph@chain@depth+\tikz@temp@w}% + \pgfmathsetmacro\tikz@temp@lw{\tikz@lib@graph@chain@depth+\tikz@temp@lw}% + \pgfmathsetmacro\tikz@temp@lh{max(\tikz@lib@graph@chain@width,\tikz@temp@lh)}% + \pgfkeyslet{/tikz/graphs/placement/depth}\tikz@temp@w% + \pgfkeyslet{/tikz/graphs/placement/local width}\tikz@temp@lh% + \pgfkeyslet{/tikz/graphs/placement/local depth}\tikz@temp@lw% + % + \pgfkeysgetvalue{/tikz/graphs/placement/chain count}\tikz@temp% + \c@pgf@counta=\tikz@temp\relax% + \advance\c@pgf@counta by1\relax% + \edef\tikz@temp{\the\c@pgf@counta}% + \pgfkeyslet{/tikz/graphs/placement/chain count}\tikz@temp% +} + + +% +% Parse a group +% + +\long\def\tikz@lib@graph@parse@group#1{ + \let\tikz@lib@graph@group@qa\pgfutil@empty% + \let\tikz@lib@graph@group@q\pgfutil@empty% \let\tikz@lib@graph@group@c\pgfutil@empty% \let\tikz@lib@graph@group@cont\pgfutil@empty% \let\tikz@lib@graph@group@conta\pgfutil@empty% - \tikz@lib@graph@par#1\par\pgf@stop@eogroup% + \tikz@lib@graph@group@check#1\par\pgf@stop@eogroup% +} + + + +% +% Start of a group +% +\def\tikz@lib@graph@group@check{% + \pgfutil@ifnextchar[\tikz@lib@graph@group@opt{\tikz@lib@graph@group@opt[]}%] +} + +\def\tikz@lib@graph@group@opt[#1]{% + \let\tikz@lib@graph@parse@extras\pgfutil@empty% + \tikzgraphsset{ + @operators=, + every group/.try, + @extra group options, + @extra group options/.style=,% + #1}% + \expandafter\tikz@lib@graph@par\tikz@lib@graph@parse@extras% +} + +\tikzgraphsset{ + parse/.code={\expandafter\def\expandafter\tikz@lib@graph@parse@extras\expandafter{\tikz@lib@graph@parse@extras#1}}, } @@ -96,19 +356,95 @@ % Remove \par % -\long\def\tikz@lib@graph@par#1\par{% +\def\tikz@lib@graph@par{% + \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@par@@}{\tikz@lib@graph@par@}% +} +\long\def\tikz@lib@graph@par@#1\par{% \pgfutil@ifnextchar\pgf@stop@eogroup{% - \expandafter\tikz@lib@graph@encloser\tikz@lib@graph@group@c#1[}{% + \expandafter\tikz@lib@graph@quotes\tikz@lib@graph@group@c#1"}{% \expandafter\def\expandafter\tikz@lib@graph@group@c\expandafter{\tikz@lib@graph@group@c#1}% \tikz@lib@graph@par% }% } +\long\def\tikz@lib@graph@par@@#1{% + \expandafter\def\expandafter\tikz@lib@graph@group@c\expandafter{\tikz@lib@graph@group@c{#1}}% + \tikz@lib@graph@par +} + + + +% +% Replace ..."..."... by ..."{...}"... +% +\def\tikz@lib@graph@quotes{% + \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@quotes@@}{\tikz@lib@graph@quotes@}% +}% +\def\tikz@lib@graph@quotes@#1"{% + \pgfutil@ifnextchar\pgf@stop@eogroup{% + \tikz@lib@graph@passon{#1}% + }{% + \expandafter\def\expandafter\tikz@lib@graph@group@q\expandafter{\tikz@lib@graph@group@q#1"}% + \tikz@lib@graph@quotes@cont% + }% +} + +\def\tikz@lib@graph@quotes@cont#1"#2"{% + \pgfutil@ifnextchar\pgf@stop@eogroup{% + \tikz@lib@graph@passon{{#1}"#2}}{% + \expandafter\def\expandafter\tikz@lib@graph@group@q\expandafter{\tikz@lib@graph@group@q{#1}"#2"}% + \tikz@lib@graph@quotes@cont}% +} + +\def\tikz@lib@graph@quotes@@#1{% + \expandafter\def\expandafter\tikz@lib@graph@group@q\expandafter{\tikz@lib@graph@group@q{#1}}% + \tikz@lib@graph@quotes% +} + + + +% +% Replace ..."..."... by ..."{...}"... (active version) +% +{ + \catcode`\"=13\relax + + \gdef\tikz@lib@graph@passon#1{\expandafter\tikz@lib@graph@quotesactive\tikz@lib@graph@group@q#1"}% + + \gdef\tikz@lib@graph@quotesactive{% + \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@quotesactive@@}{\tikz@lib@graph@quotesactive@}% + }% + \gdef\tikz@lib@graph@quotesactive@#1"{% + \pgfutil@ifnextchar\pgf@stop@eogroup{% + \expandafter\tikz@lib@graph@encloser\tikz@lib@graph@group@qa#1[% + }{% + \expandafter\def\expandafter\tikz@lib@graph@group@qa\expandafter{\tikz@lib@graph@group@qa#1"}% + \tikz@lib@graph@quotesactive@cont% + }% + } + + \gdef\tikz@lib@graph@quotesactive@cont#1"#2"{% + \pgfutil@ifnextchar\pgf@stop@eogroup{% + \expandafter\tikz@lib@graph@encloser\tikz@lib@graph@group@qa{#1}"#2[}{% + \expandafter\def\expandafter\tikz@lib@graph@group@qa\expandafter{\tikz@lib@graph@group@qa{#1}"#2"}% + \tikz@lib@graph@quotesactive@cont}% + } + + \gdef\tikz@lib@graph@quotesactive@@#1{% + \expandafter\def\expandafter\tikz@lib@graph@group@qa\expandafter{\tikz@lib@graph@group@qa{#1}}% + \tikz@lib@graph@quotesactive% + } +} + + % % Replace ...[...]... by ...[{...}]... % -\def\tikz@lib@graph@encloser#1[{% +\def\tikz@lib@graph@encloser{% + \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@encloser@@}{\tikz@lib@graph@encloser@}% +}% +\def\tikz@lib@graph@encloser@#1[{% \pgfutil@ifnextchar\pgf@stop@eogroup{% \expandafter\tikz@lib@graph@semi\tikz@lib@graph@group@cont#1;% }{% @@ -124,31 +460,31 @@ \tikz@lib@graph@encloser@cont}% } +\def\tikz@lib@graph@encloser@@#1{% + \expandafter\def\expandafter\tikz@lib@graph@group@cont\expandafter{\tikz@lib@graph@group@cont{#1}}% + \tikz@lib@graph@encloser% +} + + + % % Replace ; by , % -\def\tikz@lib@graph@semi#1;{% +\def\tikz@lib@graph@semi{% + \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@semi@@}{\tikz@lib@graph@semi@}% +} +\def\tikz@lib@graph@semi@#1;{% \pgfutil@ifnextchar\pgf@stop@eogroup{% - \expandafter\tikz@lib@graph@start@group\tikz@lib@graph@group@conta#1,}{% + \expandafter\tikz@lib@graph@main@parser\tikz@lib@graph@group@conta#1,}{% \expandafter\def\expandafter\tikz@lib@graph@group@conta\expandafter{\tikz@lib@graph@group@conta#1,}% \tikz@lib@graph@semi% }% } - - - -% -% Start of a group -% -\def\tikz@lib@graph@start@group{% - \pgfutil@ifnextchar[\tikz@lib@graph@start@group@opt{\tikz@lib@graph@start@group@opt[]}%] -} - -\def\tikz@lib@graph@start@group@opt[#1]{% - \pgfkeys{/tikz/graphs/.cd,connect as=,every group/.try,#1}% - \tikz@lib@graph@main@parser% +\def\tikz@lib@graph@semi@@#1{% + \expandafter\def\expandafter\tikz@lib@graph@group@conta\expandafter{\tikz@lib@graph@group@conta{#1}}% + \tikz@lib@graph@semi% } @@ -156,13 +492,26 @@ % Main parse % -\def\tikz@lib@graph@main@parser#1,{% +\def\tikz@lib@graph@main@parser{% \begingroup% + \pgfkeyssetvalue{/tikz/graphs/placement/local depth}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/local width}{0}% \let\tikz@lib@graph@stored@actions\pgfutil@empty% \let\tikz@lib@graph@node@list\pgfutil@empty% reset - \tikz@lib@graph@parse@one#1-\pgf@stop@eodashes% + \tikz@lib@graph@main@parser@start% +} +\def\tikz@lib@graph@main@parser@start{% + \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@protect@group}{\tikz@lib@graph@main@parser@cont}% } +\def\tikz@lib@graph@protect@group#1{% skip space + \pgfutil@ifnextchar\relax{\tikz@lib@graph@main@parser@cont{{#1}}}{\tikz@lib@graph@main@parser@cont{{#1}}}% +} + +\def\tikz@lib@graph@main@parser@cont{\tikz@lib@graph@check@quotes\tikz@lib@graph@main@parser@cont@normal} +\def\tikz@lib@graph@main@parser@cont@normal#1,{% + \tikz@lib@graph@parse@one#1-\pgf@stop@eodashes% +} \def\tikz@lib@graph@parse@one{% \pgfutil@ifnextchar\bgroup\tikz@lib@graph@scope\tikz@lib@graph@node% @@ -170,10 +519,134 @@ +% Special quoted nodes + +\def\tikz@lib@graph@check@quotes#1{% + \let\tikz@lib@graph@cont@quote#1% + \pgfutil@ifnextchar"{\begingroup\pgfkeys@temptoks{}\pgfutil@empty\tikz@lib@graph@quote@parser}{\tikz@lib@graph@check@quotes@active}% +} +{ + \catcode`\"=13\relax + \gdef\tikz@lib@graph@check@quotes@active{% + \pgfutil@ifnextchar"{\begingroup\pgfkeys@temptoks{}\pgfutil@empty\tikz@lib@graph@quote@parser@active}{\tikz@lib@graph@cont@quote}% + } + \gdef\tikz@lib@graph@quote@parser@active"#1"{% + \pgfkeys@temptoks\expandafter{\the\pgfkeys@temptoks #1}% + \pgfutil@ifnextchar"{\pgfkeys@temptoks\expandafter{\the\pgfkeys@temptoks "}\tikz@lib@graph@quote@parser@active}{\tikz@lib@graph@quote@parser@done}% + } +} + +\def\tikz@lib@graph@quote@parser"#1"{% + \pgfkeys@temptoks\expandafter{\the\pgfkeys@temptoks #1}% + \pgfutil@ifnextchar"{\pgfkeys@temptoks\expandafter{\the\pgfkeys@temptoks "}\tikz@lib@graph@quote@parser}{\tikz@lib@graph@quote@parser@done}% +} + +\def\tikz@lib@graph@quote@parser@done{% + {\expandafter\scantokens\expandafter{% + \expandafter\expandafter\expandafter\tikzlibgraphactivations\expandafter\expandafter\expandafter\tikzlibgraphdoedef\expandafter{\the\pgfkeys@temptoks}% + }}% + {\expandafter\scantokens\expandafter{\expandafter\tikzlibgraphactivationsbrace\expandafter\xdef\expandafter\tikzlibgraphreplaced\expandafter<\tikzlibgraphreplaced>\catcode`\}=2\relax}}% + \edef\tikzlibgraphreplaced{\expandafter\detokenize\expandafter{\tikzlibgraphreplaced}} + \pgfutil@ifnextchar/\tikz@lib@graph@quotes@slash\tikz@lib@graph@quotes@no@slash% +} +\def\tikz@lib@graph@quotes@no@slash{% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% + \tikz@smuggle\expandafter\expandafter\expandafter{\expandafter\tikzlibgraphreplaced\expandafter/\expandafter{\the\pgfkeys@temptoks}}% + \expandafter\endgroup\expandafter\tikz@lib@graph@cont@quote\tikz@smuggle% +} +\def\tikz@lib@graph@quotes@slash/{% + \pgfutil@ifnextchar/% Ah, double slash... + {\tikz@lib@graph@quotes@no@slash/}{\expandafter\endgroup\expandafter\tikz@lib@graph@cont@quote\tikzlibgraphreplaced/}% +} +\def\tikzlibgraphdoedef{\xdef\tikzlibgraphreplaced} + +\def\tikz@lib@prepare@active#1#2#3{% + {% + \catcode`#1=13\relax% + \scantokens{\gdef\tikzlibgraphactivator{\def#2{@#3@}}}% + } + \pgfutil@g@addto@macro\tikzlibgraphactivations{\catcode`#1=13\relax} + \expandafter\pgfutil@g@addto@macro\expandafter\tikzlibgraphactivations\expandafter{\tikzlibgraphactivator} +} + +\let\tikzlibgraphactivations\pgfutil@empty + +% +% Remove \outer from \+ for plain TeX +% + +\outer\def\tikz@lib@outer@test{\tabalign} +\ifx\+\tikz@lib@outer@test + \def\+{\tabalign} +\fi + +\tikz@lib@prepare@active{\$}{$}{DOLLAR SIGN}% $ +\tikz@lib@prepare@active{\&}{&}{AMPERSAND}% +\tikz@lib@prepare@active{\^}{^}{CIRCUMFLEX ACCENT}% +\tikz@lib@prepare@active{\~}{~}{TILDE}% +\tikz@lib@prepare@active{\_}{_}{LOW LINE}% +\tikz@lib@prepare@active{\|}{|}{VERTICAL LINE}% +\tikz@lib@prepare@active{\[}{[}{LEFT SQUARE BRACKET}% +\tikz@lib@prepare@active{\]}{]}{RIGHT SQUARE BRACKET}% +\tikz@lib@prepare@active{\(}{(}{LEFT PARENTHESIS}% +\tikz@lib@prepare@active{\)}{)}{RIGHT PARENTHESIS}% +\tikz@lib@prepare@active{\/}{/}{SOLIDUS}% +\tikz@lib@prepare@active{\.}{.}{FULL STOP}% +\tikz@lib@prepare@active{\-}{-}{HYPHEN MINUS}% +\tikz@lib@prepare@active{\,}{,}{COMMA}% +\tikz@lib@prepare@active{\+}{+}{PLUS SIGN}% +\tikz@lib@prepare@active{\*}{*}{ASTERISK}% +\tikz@lib@prepare@active{\'}{'}{APOSTROPHE}% +\tikz@lib@prepare@active{\!}{!}{EXCLAMATION MARK}% +\tikz@lib@prepare@active{\"}{"}{QUOTATION MARK}% +\tikz@lib@prepare@active{\:}{:}{COLON}% +\tikz@lib@prepare@active{\;}{;}{SEMINCOLON}% +\tikz@lib@prepare@active{\<}{<}{LESS THAN SIGN}% +\tikz@lib@prepare@active{\=}{=}{EQUALS SIGN}% +\tikz@lib@prepare@active{\>}{>}{GREATER THAN SIGN}% +\tikz@lib@prepare@active{\?}{?}{QUESTION MARK}% +%\tikz@lib@prepare@active{\@}{@}{COMMERCIAL AT}% +\tikz@lib@prepare@active{\`}{`}{GRAVE ACCENT}% +{\catcode`\%=11\catcode`\#=11 +\tikz@lib@prepare@active{\%}{%}{PERCENT SIGN} +\tikz@lib@prepare@active{\#}{#}{NUMBER SIGN} +} + +\pgfutil@g@addto@macro\tikzlibgraphactivations{\catcode`\\=13\relax} +{ + \catcode`\|=0\relax + \catcode`\\=13\relax + |pgfutil@g@addto@macro|tikzlibgraphactivations{|def\{@REVERSE SOLIDUS@}} +} +{ + \gdef\tikzlibgraphscommercialat{@COMMERCIAL AT@} + \let\g=\pgfutil@g@addto@macro + \catcode`\@=13\relax + \g\tikzlibgraphactivations{\catcode`\@=13\relax\let@=\tikzlibgraphscommercialat} +} + +\def\tikzlibgraphactivationsbrace{% + \catcode`\{=13\relax% + \catcode`\}=13\relax% + \catcode`\<=1\relax% + \catcode`\>=2\relax% +} +{ + \catcode`\{=13\relax% + \catcode`\}=13\relax% + \catcode`\<=1\relax% + \catcode`\>=2\relax% + \pgfutil@g@addto@macro\tikzlibgraphactivationsbrace<\def{<@LEFT CURLY BRACE@>> %} + \pgfutil@g@addto@macro\tikzlibgraphactivationsbrace<\def}<@RIGHT CURLY BRACE@>> %{ +> % A normal node -\def\tikz@lib@graph@node#1-{% +% First, check for special quote syntax: + +\def\tikz@lib@graph@node{\tikz@lib@graph@check@quotes\tikz@lib@graph@node@normal} + +\def\tikz@lib@graph@node@normal#1-{% % Detect trailing < \tikz@lib@graph@@node#1<\pgf@stop% } @@ -186,7 +659,7 @@ % Syntax: node name [options] % % Grab node name - \tikz@lib@graph@grab@name#1[\pgf@stop% + \tikz@lib@graph@grab@name#1\pgf@stop% \tikz@lib@graph@stored@actions% \pgfutil@ifnextchar\pgf@stop@eodashes{% \tikz@lib@graph@graph@done% @@ -194,7 +667,7 @@ % % Now, get arrow kind % - \def\pgf@test{#2}% + \def\pgf@test{#2}% \ifx\pgf@test\pgfutil@empty% \expandafter\tikz@lib@graph@no@back@arrow% \else% @@ -206,30 +679,37 @@ \def\tikz@lib@graph@no@back@arrow{% \pgfutil@ifnextchar>\tikz@lib@graph@forward@arrow{% \pgfutil@ifnextchar-\tikz@lib@graph@undirected@arrow{% - \PackageError{graphs library}{One of the arrow types <-, --, ->, or <-> expected}{}% - \tikz@lib@graph@undirected@arrow% + \pgfutil@ifnextchar!\tikz@lib@graph@no@arrow{% + \tikzerror{One of the arrow types <-, --, ->, -!- or <-> expected}% + \tikz@lib@graph@undirected@arrow% + }% }% }% } \def\tikz@lib@graph@undirected@arrow-{% - \def\tikz@lib@graph@arrow@type{undirected}% + \def\tikz@lib@graph@arrow@type{--}% \tikz@lib@graph@after@arrow% } \def\tikz@lib@graph@forward@arrow>{% - \def\tikz@lib@graph@arrow@type{directed}% + \def\tikz@lib@graph@arrow@type{->}% \tikz@lib@graph@after@arrow% } \def\tikz@lib@graph@bi@arrow>{% - \def\tikz@lib@graph@arrow@type{bidirected}% + \def\tikz@lib@graph@arrow@type{<->}% + \tikz@lib@graph@after@arrow% +} + +\def\tikz@lib@graph@no@arrow!-{% + \def\tikz@lib@graph@arrow@type{-!-}% \tikz@lib@graph@after@arrow% } \def\tikz@lib@graph@back@arrow{% \pgfutil@ifnextchar>{\tikz@lib@graph@bi@arrow}{% - \def\tikz@lib@graph@arrow@type{back directed}% + \def\tikz@lib@graph@arrow@type{<-}% \tikz@lib@graph@after@arrow% }% } @@ -241,46 +721,62 @@ \def\tikz@lib@graph@after@arrow@opt[#1]{% % % Ok, first recolor - % - \pgfkeys{/tikz/graph node/recolor in by=in''} - \pgfkeys{/tikz/graph node/recolor out by=out'} + % + \tikzgraphinvokeoperator{recolor source by=source''} + \tikzgraphinvokeoperator{recolor target by=target'} % Save action for next node \expandafter\def\expandafter\tikz@lib@graph@stored@actions\expandafter{% \expandafter\tikz@lib@graph@joiner\expandafter{\tikz@lib@graph@arrow@type}{#1}}% + % + \tikzgdeventgroupcallback{descendants}% \tikz@lib@graph@parse@one% } \def\tikz@lib@graph@joiner#1#2{% - \pgfkeys{/tikz/graph node/recolor in by=in'} - \pgfkeys{/tikz/graph node/recolor in'' by=in} + \tikzgraphinvokeoperator{recolor source by=source'} + \tikzgraphinvokeoperator{recolor source'' by=source} {% + \tikz@enable@edge@quotes% \pgfkeyssetvalue{/tikz/graphs/default edge kind}{#1}% - \pgfkeys{/tikz/graphs/.cd,#2}% - \pgfkeysgetvalue{/tikz/graphs/join}\pgf@temp% - \expandafter\tikz@lg@do@connector\expandafter{\pgf@temp}% + \pgfkeys{/tikz/graphs/.cd,@operators=,% + /tikz/graphs/.unknown/.code=\tikz@lib@graph@unknown@edge@option{##1},#2}% + \pgfkeysgetvalue{/tikz/graphs/@operators}\pgf@temp% + \ifx\pgf@temp\pgfutil@empty% + \edef\pgf@temp{\noexpand\pgfkeys{/tikz/graphs/.cd,\pgfkeysvalueof{/tikz/graphs/default edge operator}}}% + \pgf@temp% + \pgfkeysgetvalue{/tikz/graphs/@operators}\pgf@temp% + \fi% + \pgf@temp% }% - \pgfkeys{/tikz/graph node/!in',/tikz/graph node/!out'} + \tikzgraphinvokeoperator{not source',not target'} +} + +\def\tikz@lib@graph@unknown@edge@option#1{% + \def\tikz@temp{/tikz/graphs/@edges styling/.append=} + \expandafter\expandafter\expandafter\pgfkeys% + \expandafter\expandafter\expandafter{\expandafter\tikz@temp\expandafter{\expandafter,\pgfkeyscurrentname={#1}}} } \def\tikz@lib@graph@graph@done\pgf@stop@eodashes{% + % Get local depth and width outside + \xdef\tikz@lib@graph@chain@depth{\pgfkeysvalueof{/tikz/graphs/placement/local depth}} + \xdef\tikz@lib@graph@chain@width{\pgfkeysvalueof{/tikz/graphs/placement/local width}} % Get node list outside... \expandafter% \endgroup% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\tikz@lib@graph@node@list% \expandafter\expandafter\expandafter{\expandafter\tikz@lib@graph@node@list\tikz@lib@graph@node@list}% + % Compute new local depth and width of group... + \tikz@lib@graph@placement@after@chain@update + % \pgfutil@ifnextchar\pgf@stop@eogroup% \tikz@lib@graph@graph@group@done% \tikz@lib@graph@main@parser% } \def\tikz@lib@graph@graph@group@done\pgf@stop@eogroup{% - \pgfkeysgetvalue{/tikz/graphs/connect as}\tikz@lib@graph@group@connector - \expandafter\tikz@lg@do@connector\expandafter{\tikz@lib@graph@group@connector} -} - -\def\tikz@lg@do@connector#1{% - \tikzset{/tikz/connectors/.cd,#1} + \pgfkeysvalueof{/tikz/graphs/@operators}% } @@ -289,18 +785,42 @@ % Handle node % \def\tikz@lib@graph@grab@name{% - \pgfutil@ifnextchar\foreach\tikz@lib@graph@do@foreach\tikz@lib@graph@grab@name@@% + \pgfutil@ifnextchar\foreach\tikz@lib@graph@do@foreach\tikz@lib@graph@parse@node@text% } -\def\tikz@lib@graph@do@foreach\foreach#1in#2#3[\pgf@stop{% +\def\tikz@lib@graph@do@foreach\foreach#1in{% + \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@do@foreach@normal{#1}}{\def\tikz@temp{#1}\tikz@lib@graph@do@foreach@macro}% +} +\def\tikz@lib@graph@do@foreach@macro#1{% + \expandafter\expandafter\expandafter\tikz@lib@graph@do@foreach@normal\expandafter\tikz@temp\expandafter{#1}% +} + +\def\tikz@lib@graph@do@foreach@normal#1#2#3\pgf@stop{% % Ok, we do a parse on a foreach loop. - % We have to make sure that we \begingroup \let\tikz@lib@graph@node@list@saved\pgfutil@empty% + \xdef\tikz@lib@graph@saved@placement{% + {\pgfkeysvalueof{/tikz/graphs/placement/local depth}}% + {\pgfkeysvalueof{/tikz/graphs/placement/local width}}% + {\pgfkeysvalueof{/tikz/graphs/placement/chain count}}% + {\pgfkeysvalueof{/tikz/graphs/placement/element count}}% + {\pgfkeysvalueof{/tikz/graphs/placement/width}}% + {\pgfkeysvalueof{/tikz/graphs/placement/depth}}% + }% \foreach #1 in {#2}% {% \let\tikz@lib@graph@node@list\tikz@lib@graph@node@list@saved% + \expandafter\tikz@lib@graph@setup@placement\tikz@lib@graph@saved@placement% \tikz@lib@graph@parse@group{#3}% + \xdef\tikz@lib@graph@saved@placement{% + {\pgfkeysvalueof{/tikz/graphs/placement/local depth}}% + {\pgfkeysvalueof{/tikz/graphs/placement/local width}}% + {\pgfkeysvalueof{/tikz/graphs/placement/chain count}}% + {\pgfkeysvalueof{/tikz/graphs/placement/element count}}% + {\pgfkeysvalueof{/tikz/graphs/placement/width}}% + {\pgfkeysvalueof{/tikz/graphs/placement/depth}}% + }% + % TODO: Need to also save hints! \global\let\tikz@lib@graph@node@list@saved\tikz@lib@graph@node@list% }% \expandafter% @@ -308,37 +828,179 @@ \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\tikz@lib@graph@node@list% \expandafter\expandafter\expandafter{\expandafter\tikz@lib@graph@node@list\tikz@lib@graph@node@list@saved}% + \expandafter\tikz@lib@graph@setup@placement\tikz@lib@graph@saved@placement% } +\def\tikz@lib@graph@setup@placement#1#2#3#4#5#6{% + \pgfkeyssetvalue{/tikz/graphs/placement/local depth}{#1}% + \pgfkeyssetvalue{/tikz/graphs/placement/local width}{#2}% + \pgfkeyssetvalue{/tikz/graphs/placement/chain count}{#3}% + \pgfkeyssetvalue{/tikz/graphs/placement/element count}{#4}% + \pgfkeyssetvalue{/tikz/graphs/placement/width}{#5}% + \pgfkeyssetvalue{/tikz/graphs/placement/depth}{#6}% +} + +\def\tikz@lib@graph@parse@node@text#1\pgf@stop{% + % + % Ok, first test whether #1 contains "//" + % + \pgfutil@in@{//}{#1 } + \ifpgfutil@in@% + % Ok, a layout node: + \tikz@lib@parse@layout@node#1\pgf@stop% + \else% + \tikz@lib@graph@fake@nodefalse + \let\tikz@lib@graph@node@parsed\tikz@lib@graph@node@opt@normal% + \def\tikz@lib@graph@empty@node@parsed{\tikzgdeventcallback{node}{}}% + \tikz@lib@parse@normal@node#1[\pgf@stop% + \fi% +} + + +% +% Parse the normal part of a node (name and, possibly, text after slash) +% -\def\tikz@lib@graph@grab@name@@#1[{% - \tikz@lib@graph@read#1\pgf@stop% - \let\tikz@lib@graph@as\tikz@lib@graph@as@default% +\def\tikz@lib@parse@normal@node#1[{ + % + % Test whether #1 contains "/" or "__" + % + \pgfutil@in@{/}{#1}% + \ifpgfutil@in@% + \tikz@lib@parse@node@with@slash#1\pgf@stop% + \else + \pgfutil@in@{__}{#1}% + \ifpgfutil@in@% + \tikz@lib@parse@node@with@doubleunder#1\pgf@stop% + \else + \pgfkeys@spdef\tikz@lib@graph@name@only{#1}% + \let\tikz@lib@graph@node@text\tikz@lib@graph@name@only% + \edef\tikz@lib@graph@name{\tikz@lib@graph@path\tikz@lib@graph@name@only}% + \fi% + \fi% + \tikz@lib@graph@handle@node@cont% +} + +\def\tikz@lib@parse@node@with@slash#1/{ + \pgfkeys@spdef\tikz@lib@graph@name@only{#1}% + \ifx\tikz@lib@graph@name@only\pgfutil@empty% + \global\advance\tikz@fig@count by1\relax + \edef\tikz@lib@graph@name@only{tikz@f@\the\tikz@fig@count}% + \fi% + \edef\tikz@lib@graph@name{\tikz@lib@graph@path\tikz@lib@graph@name@only}% + \pgfutil@ifnextchar"\tikz@lg@slash@quote{\pgfutil@ifnextchar\tikz@active@quotes@token\tikz@lg@slash@quote@active\tikz@lg@slash@cont} +} +\def\tikz@lg@slash@quote"#1"#2\pgf@stop{% + \iftikz@handle@active@nodes% + \def\tikz@lib@graph@node@text{\scantokens{#1}}% + \else + \def\tikz@lib@graph@node@text{#1}% + \fi% +} +{\catcode`\"=13\relax + \gdef\tikz@lg@slash@quote@active"#1"#2\pgf@stop{% + \iftikz@handle@active@nodes% + \def\tikz@lib@graph@node@text{\scantokens{#1}}% + \else + \def\tikz@lib@graph@node@text{#1}% + \fi% + } +} +\def\tikz@lg@slash@cont#1\pgf@stop{% + \iftikz@handle@active@nodes% + \def\tikz@lib@graph@node@text{\scantokens{#1}}% + \else + \def\tikz@lib@graph@node@text{#1}% + \fi% +} + +\def\tikz@lib@parse@node@with@doubleunder#1__{\tikz@lib@parse@node@with@slash{#1}/} + +\def\tikz@lg@find@fresh@name{% + \edef\tikz@lib@graph@name@only{\tikz@lib@graph@name@only'}% + \edef\tikz@lib@graph@name{\tikz@lib@graph@path\tikz@lib@graph@name@only}% + \tikz@lg@if@local@node{\tikz@lib@graph@name}{\tikz@lg@find@fresh@name}{}% +} + + +% +% We have now parsed everything up to the opening "[". We continue +% + +\def\tikz@lib@graph@handle@node@cont{% + \iftikz@lib@graph@fresh@node% + \tikz@lg@if@local@node{\tikz@lib@graph@name}{\tikz@lg@find@fresh@name}{}% + \fi% + \let\tikzgraphnodeas\tikzgraphnodeas@default% \pgfutil@ifnextchar\pgf@stop{% - \ifx\tikz@lib@graph@name\pgfutil@empty% + \ifx\tikz@lib@graph@name@only\pgfutil@empty% + \expandafter\tikz@lib@graph@node@empty@done% \else - \expandafter\tikz@lib@graph@noskip% + \expandafter\tikz@lib@graph@node@opt\expandafter[\expandafter]\expandafter[% \fi% }{\tikz@lib@graph@node@opt[}% } -\def\tikz@lib@graph@noskip{\tikz@lib@graph@node@opt[][}%] -\def\tikz@lib@graph@as@default{% - \let\tikzgraphnodename\tikz@lib@graph@name% +\def\tikzgraphnodeas@default{% \tikz@lib@graph@typesetter% } -\def\tikz@lib@graph@read#1\pgf@stop{% - \pgfkeys@spdef\tikz@lib@graph@name{#1}% - \edef\tikz@lib@graph@name{\tikz@lib@graph@path\tikz@lib@graph@name}% +\let\tikz@lib@graph@empty@node@parsed\relax% + +\def\tikz@lib@graph@node@opt[#1]#2[\pgf@stop{% + \tikz@lib@graph@node@parsed{#1}% } +\def\tikz@lib@graph@node@empty@done\pgf@stop{\tikz@lib@graph@empty@node@parsed} -\def\tikz@lib@graph@node@opt[#1]#2[\pgf@stop{% - \ifx\tikz@lib@graph@name\tikz@lib@graph@usetext +% +% Parse a layout node +% + +\def\tikz@lib@parse@layout@node#1//{% + \pgf@lib@graph@empty@layout@nodefalse% + \let\tikz@lib@graph@node@parsed\tikz@lib@layout@node@parsed% + \let\tikz@lib@graph@empty@node@parsed\tikz@lib@graph@empty@layout@node@parsed + \tikz@lib@parse@normal@node#1[\pgf@stop% +} + +\newif\ifpgf@lib@graph@empty@layout@node + +\def\tikz@lib@layout@node@parsed{% + \tikz@lib@layout@parse@rest% +} + +\def\tikz@lib@graph@empty@layout@node@parsed{% + \pgf@lib@graph@empty@layout@nodetrue + \tikz@lib@layout@parse@rest{}% +} + +\def\tikz@lib@layout@parse@rest#1{% + \def\tikz@lib@layout@node@options{#1}% + \pgfutil@ifnextchar[{\tikz@lib@layout@node@opt}{\tikz@lib@layout@node@opt[]}%} +} + +\def\tikz@lib@layout@node@parsed#1{% + \def\tikz@lib@layout@node@options{#1}% + \pgfutil@ifnextchar[{\tikz@lib@layout@node@opt}{\tikz@lib@layout@node@opt[]}%} +} + +\def\tikz@lib@layout@node@opt[#1]{% + \def\tikz@lib@layout@options{#1}% + \pgfutil@ifnextchar\bgroup{\tikz@lib@layout@start}{\tikzerror{Opening brace at beginning of sublayout expected}}% +} + + +% +% Typeset a normal node +% + +\def\tikz@lib@graph@node@opt@normal#1{% + \expandafter\tikz@lib@graph@test@use@list\tikz@lib@graph@name@only\pgf@stop + \iftikz@lib@graph@use@list% % Ok, make a list of the nodes stored in #1: \let\tikz@lg@temp\pgfutil@empty% - \foreach \tikz@lg@node@name in {#1} {\expandafter\tikz@lib@graph@handle@use\expandafter{\tikz@lg@node@name}} + \foreach \tikz@lg@node@name in \tikz@lib@graph@use@list {\expandafter\tikz@lib@graph@handle@use\expandafter{\tikz@lg@node@name}} % Ok, now add the nodes to the node list \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\tikz@lib@graph@node@list% @@ -348,26 +1010,70 @@ \let\tikz@lg@do\tikz@lib@graph@do@use% \tikz@lg@temp% \else% - \expandafter\ifx\csname tikz@lib@graph@def@\tikz@lib@graph@name\endcsname\relax% + \edef\tikz@lib@graph@name{\tikz@lib@graph@path\tikz@lib@graph@name@only}% + \expandafter\ifx\csname tikz@lib@graph@def@\tikz@lib@graph@name@only\endcsname\relax% + \pgfkeysgetvalue{/tikz/graphs/placement/level}\tikz@temp% + \c@pgf@counta=\tikz@temp\relax% + \advance\c@pgf@counta by1\relax% + \edef\tikz@temp{\the\c@pgf@counta}% + \pgfkeyslet{/tikz/graphs/placement/level}\tikz@temp% + \tikzgraphsset{ + level/.try=\pgfkeysvalueof{/tikz/graphs/placement/level}, + level \pgfkeysvalueof{/tikz/graphs/placement/level}/.try + } {% \edef\tikz@lib@graph@node@list{\noexpand\tikz@lg@do{\tikz@lib@graph@name}}% + \global\tikz@lib@graph@node@createdfalse% + \pgfkeyslet{/tikz/graphs/@operators}\pgfutil@empty% + \tikz@lib@activate@source@target@edge@syntax% \tikz@lg@if@local@node{\tikz@lib@graph@name}% - {\tikzset{/tikz/graph node/.cd,in,out,#1}}% + {\tikz@lg@local@node@handle{#1}}% {% - \tikz@lg@init@color{\tikz@lib@graph@name}{\tikz@lgc@all@true\tikz@lgc@in@true\tikz@lgc@out@true}% + \tikz@lg@init@color{\tikz@lib@graph@name}{\tikz@lgc@all@true\tikz@lgc@source@true\tikz@lgc@target@true}% \iftikz@lib@graph@all% - \tikzset{/tikz/graph node/.cd,#1}% + \tikzgraphsset{#1}\pgfkeysvalueof{/tikz/graphs/@operators}% \else% - \node [name=\tikz@lib@graph@name,/tikz/graph - node/.cd,/tikz/graphs/@nodes styling,#1] - {\tikz@lib@graph@as};% + \pgfkeys{/tikz/graphs/placement/place}% + \let\tikzgraphnodetext\tikz@lib@graph@node@text% + \let\tikzgraphnodename\tikz@lib@graph@name@only% + \let\tikzgraphnodepath\tikz@lib@graph@path% + \let\tikzgraphnodefullname\tikz@lib@graph@name% + \iftikz@lib@graph@fake@node% + {% run options in protected mode... + \pgfkeys{ + /tikz/graphs/.cd,% + .unknown/.code=, + /tikz/graphs/@nodes styling,% + #1}% + \pgfkeysgetvalue{/tikz/graphs/@operators}\tikz@lib@graph@op@save% + \global\let\tikz@lib@graph@op@save\tikz@lib@graph@op@save% + }% + \else% + \node [% + name=\tikz@lib@graph@name,% + execute at end node={% + \pgfkeysgetvalue{/tikz/graphs/@operators}\tikz@lib@graph@op@save% + \global\let\tikz@lib@graph@op@save\tikz@lib@graph@op@save% + },% + graphs/redirect unknown to tikz, + /tikz/graphs/.cd,% + /tikz/graphs/@nodes styling,% + #1]% + {% + \tikzgraphnodeas% + };% + \fi% + \tikz@lib@graph@op@save\global\let\tikz@lib@graph@op@save\relax%% + \global\tikz@lib@graph@node@createdtrue% \fi }% }% + \iftikz@lib@graph@node@created\tikz@lib@graph@placement@update\fi% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\tikz@lib@graph@node@list% \expandafter\expandafter\expandafter{% \expandafter\tikz@lib@graph@node@list\expandafter\tikz@lg@do\expandafter{\tikz@lib@graph@name}}% + \iftikz@lib@graph@trie\tikzgraphsset{name=\tikz@lib@graph@name@only}\fi% \else % The name of the node is a graph name \tikz@lib@graph@handle@graph{#1}% @@ -375,6 +1081,185 @@ \fi% } +\newif\iftikz@lib@graph@fake@node + +\newif\iftikz@lib@graph@use@list +\def\tikz@lib@graph@test@use@list{% + \pgfutil@ifnextchar({\tikz@lib@graph@use@list@grap}{\tikz@lib@graph@test@use@list@done}%) +} + +\def\tikz@lib@graph@test@use@list@done#1\pgf@stop{\tikz@lib@graph@use@listfalse} +\def\tikz@lib@graph@use@list@grap(#1)\pgf@stop{\def\tikz@lib@graph@use@list{#1}\tikz@lib@graph@use@listtrue} + + +% +% Typeset a layout node +% + +\def\tikz@lib@layout@start#1#2\pgf@stop{% + \tikz@lib@ensure@gd@loaded% + % Parameters are: + % + % Node name is \tikz@lib@graph@name@only + % Node text is \tikz@lib@graph@node@text + % Node options are \tikz@lib@layout@node@options + % Layout options are \tikz@lib@layout@options + % Layout is #1 + % Rest is #2 (should be empty or just whitespace) + \tikz@lib@graph@fake@nodefalse% + \ifpgf@lib@graph@empty@layout@node% + \else% + \ifx\tikz@lib@graph@name\pgfutil@empty% + \tikzerror{Internal error: Node has no name, but it should!}% + \else + \tikz@lib@graph@fake@nodetrue% + \expandafter\tikz@lib@graph@node@opt@normal\expandafter{\tikz@lib@layout@node@options}% + \fi% + \fi% + \edef\tikz@lib@graph@name{\tikz@lib@graph@path\tikz@lib@graph@name@only}% + % + % Prepare tikz node options + % + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\tikz@lib@layout@node@options\expandafter\expandafter\expandafter{\expandafter\tikz@lib@layout@startup@node@options\tikz@lib@layout@node@options,}% + \begingroup + % Create a subgraph node, if name is given. + \iftikz@lib@graph@fake@node% + \expandafter\expandafter\expandafter% + \expandafter\expandafter\expandafter\expandafter\tikz@lib@make@subgraph@node% + \expandafter\expandafter\expandafter% + \expandafter\expandafter\expandafter\expandafter{% + \expandafter\expandafter\expandafter\tikz@lib@graph@name% + \expandafter\expandafter\expandafter}% + \expandafter\expandafter\expandafter{% + \expandafter\tikz@lib@graph@node@text\expandafter}\expandafter{\tikz@lib@layout@node@options} + \fi% + % + % Here comes the scope: + % + \expandafter\expandafter\expandafter\scope\expandafter\expandafter\expandafter[\expandafter\tikz@lib@layout@node@options@prefix\tikz@lib@layout@options] + \tikzgdeventgroupcallback{array}% + \let\tikz@lib@graph@node@list\pgfutil@empty% + \tikz@lib@graph@start@hint@group% + \tikz@lib@graph@parse@group{#1}% + \tikz@lib@graph@end@hint@group% + \def\tikz@lg@old@col{\tikz@lgc@source@true}% + \let\tikz@lg@new@col\pgfutil@empty% + \let\tikz@lg@do\tikz@lg@change@color% + \tikz@lib@graph@node@list% + \def\tikz@lg@old@col{\tikz@lgc@target@true}% + \tikz@lib@graph@node@list% + \expandafter% + \endscope\expandafter% + \endgroup% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\tikz@lib@graph@node@list% + \expandafter\expandafter\expandafter{\expandafter\tikz@lib@graph@node@list\tikz@lib@graph@node@list}% + \tikz@lib@graph@hint@aftergroup% +} +\def\tikz@lib@make@subgraph@node#1#2#3{% + \pgfgdsubgraphnode{#1}{#3}{\pgfgdsubgraphnodecontents{#2}}% +} +\def\tikz@lib@layout@startup@node@options{% + /utils/exec=\tikzlibignorecomparisonsINTERNAL, + /tikz/graphs/.cd,% + redirect unknown to tikz,% + anchor=base,% + /tikz/every subgraph node/.try,% +} +\def\tikzlibignorecomparisonsINTERNAL{% + \pgfkeys{/handlers/first char syntax=true} + \pgfkeyssetvalue{/handlers/first char syntax/the character >}{\pgfutil@gobble}% + \pgfkeyssetvalue{/handlers/first char syntax/the character <}{\pgfutil@gobble}% +} +\def\tikz@lib@layout@node@options@prefix{graphs/.cd,} + +\ifx\tikz@lib@ensure@gd@loaded\pgfutil@undefined% +\def\tikz@lib@ensure@gd@loaded{\tikzerror{You must say \string\usetikzlibrary{graphdrawing} to use the (sub)layout syntax}} +\fi + +\def\tikz@lg@local@node@handle#1{% + % + % Handle late options and operators + \tikzgraphsset{source,target,.unknown/.code=,#1}% + \tikzgdlatenodeoptionacallback{\tikz@lib@graph@name}% + \node also[graphs/redirect unknown to tikz,/tikz/graphs/.cd,#1](\tikz@lib@graph@name);% + \pgfkeysvalueof{/tikz/graphs/@operators}% +} + +\tikzgraphsset{redirect unknown to tikz/.style={ + /tikz/graphs/.unknown/.code={% + \let\tikz@key\pgfkeyscurrentname% + \pgfkeys{tikz/.cd,\tikz@key={##1},/tikz/graphs/.cd}% + }} +} + +\def\tikz@lib@activate@source@target@edge@syntax{% + \pgfkeys{/handlers/first char syntax=true} + \pgfkeyssetvalue{/handlers/first char syntax/the character >}{\tikz@lg@parse@more}% + \pgfkeyssetvalue{/handlers/first char syntax/the character <}{\tikz@lg@parse@less}% +} + +\def\tikz@lg@parse@less#1{\tikz@lg@parse@less@#1\pgf@stop} +\def\tikz@lg@parse@less@<{\pgfutil@ifnextchar"{\tikz@lg@parse@quote{source}}{\tikz@lg@parse@noquote{source}}} +\def\tikz@lg@parse@more#1{\tikz@lg@parse@more@#1\pgf@stop} +\def\tikz@lg@parse@more@>{\pgfutil@ifnextchar"{\tikz@lg@parse@quote{target}}{\tikz@lg@parse@noquote{target}}} + +\def\tikz@lg@parse@noquote#1#2\pgf@stop{{\tikzgraphsset{#1 edge style={#2}}}} +\def\tikz@lg@parse@quote#1#2\pgf@stop{% + {\tikzgraphsset{/tikz/node quotes mean={#1 edge node={node [every edge quotes,##2]{##1}}},/utils/exec=\tikz@enable@node@quotes,#2}}% +} + +\tikzgraphsset{ + clear >/.style=target edge clear, + clear </.style=source edge clear +} + + +% Positioning + +\def\tikz@lib@graph@x{0} +\def\tikz@lib@graph@y{0} + +\tikzgraphsset{ + x/.code=\def\tikz@lib@graph@x{#1}\tikz@lib@graphs@check@at, + y/.code=\def\tikz@lib@graph@y{#1}\tikz@lib@graphs@check@at +} +\def\tikz@lib@graphs@check@at{% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\tikz@temp% + \expandafter\expandafter\expandafter{% + \expandafter\expandafter\expandafter(% + \expandafter\expandafter\expandafter{\expandafter\tikz@lib@graph@x\expandafter}% + \expandafter,\expandafter{\tikz@lib@graph@y})}% + \pgfqkeys{/tikz}{at/.expand once=\tikz@temp}% +} + + +\newif\iftikz@lib@graph@trie +\tikzgraphsset{ + trie/.is if=tikz@lib@graph@trie, + put node text on incoming + edges/.style={nodes={/utils/exec=\tikz@lg@make@edge@node{target}{#1}}}, + put node text on outgoing + edges/.style={nodes={/utils/exec=\tikz@lg@make@edge@node{source}{#1}}}, + edge quotes/.style={/tikz/every edge quotes/.style={#1}}, + edge quotes center/.style={edge quotes={anchor=center}}, + edge quotes mid/.style={edge quotes={anchor=mid}} +} + +\def\tikz@lg@make@edge@node#1#2{% + \def\pgf@marshal{node[#2]}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@marshal\expandafter\expandafter\expandafter{\expandafter\pgf@marshal\expandafter{\tikzgraphnodetext}}% + \pgfkeysalso{#1 edge node/.expand once=\pgf@marshal,as=}% +} + +\newif\iftikz@lib@graph@fresh@node +\tikzgraphsset{fresh nodes/.is if=tikz@lib@graph@fresh@node} + + +\newif\iftikz@lib@graph@node@created + \def\tikz@lib@graph@handle@use#1{% % Is #1 the name of a node set? \expandafter\let\expandafter\pgf@temp\csname tikz@lg@node@set #1\endcsname @@ -386,20 +1271,14 @@ } \def\tikz@lib@graph@do@use#1{% - \tikz@lg@init@color{#1}{\tikz@lgc@all@true\tikz@lgc@in@true\tikz@lgc@out@true}% + \tikz@lg@init@color{#1}{\tikz@lgc@all@true\tikz@lgc@source@true\tikz@lgc@target@true}% } -\def\tikz@lib@graph@usetext{use} - -\def\tikz@lib@graph@typeset@def#1 as #2\pgf@stop{ - \def\tikz@lib@graph@typesetter#1\pgf@stop{#2} -} - -\tikzset{ - graphs/typeset/.store in=\tikz@lib@graph@typesetter, - graphs/math nodes/.style={/tikz/graphs/typeset=$\tikzgraphnodename$}, - graphs/empty nodes/.style={/tikz/graphs/typeset=}, - graphs/typeset=\tikzgraphnodename +\tikzgraphsset{ + typeset/.store in=\tikz@lib@graph@typesetter, + math nodes/.style={/tikz/graphs/typeset=$\tikzgraphnodetext$}, + empty nodes/.style={/tikz/graphs/typeset=}, + typeset=\tikzgraphnodetext } @@ -407,19 +1286,22 @@ % Handle scope % \def\tikz@lib@graph@scope#1{ - \begingroup + \begingroup% + \tikzgdeventgroupcallback{array}% \let\tikz@lib@graph@node@list\pgfutil@empty% - \tikz@lib@graph@parse@group{#1}% + \tikz@lib@graph@start@hint@group% + \tikz@lib@graph@parse@group{#1}% + \tikz@lib@graph@end@hint@group% \expandafter% \endgroup% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\tikz@lib@graph@node@list% \expandafter\expandafter\expandafter{\expandafter\tikz@lib@graph@node@list\tikz@lib@graph@node@list}% + \tikz@lib@graph@hint@aftergroup% \tikz@lib@graph@stored@actions% \pgfutil@ifnextchar-{\tikz@lib@graph@scope@minus}{% \pgfutil@ifnextchar<{\tikz@lib@graph@scope@less}{% - \PackageError{graphs library}{One of the arrow types <-, --, ->, - or <-> expected}{}% + \tikzerror{One of the arrow types <-, --, ->, -!-, or <-> expected}% }% }% } @@ -427,9 +1309,11 @@ \def\tikz@lib@graph@scope@minus-{ \pgfutil@ifnextchar>\tikz@lib@graph@forward@arrow{% \pgfutil@ifnextchar-\tikz@lib@graph@undirected@arrow{% - \pgfutil@ifnextchar\pgf@stop@eodashes\tikz@lib@graph@graph@done{% - \PackageError{graphs library}{One of the arrow types <-, --, ->, or <-> expected}{}% - \tikz@lib@graph@undirected@arrow% + \pgfutil@ifnextchar!\tikz@lib@graph@no@arrow{% + \pgfutil@ifnextchar\pgf@stop@eodashes\tikz@lib@graph@graph@done{% + \tikzerror{One of the arrow types <-, --, ->, -!-, or <-> expected}% + \tikz@lib@graph@undirected@arrow% + }% }% }% }% @@ -444,31 +1328,36 @@ % Predefining graphs % -\def\tikzdefgraph#1#2#3{% - \expandafter\def\csname tikz@lib@graph@def@#1\endcsname{\tikz@lib@graph@do@graph{#2}{#3}}% +\tikzgraphsset{ + declare/.code 2 args={\expandafter\def\csname tikz@lib@graph@def@#1\endcsname{\tikz@lib@graph@do@graph{#2}}}% } \def\tikz@lib@graph@handle@graph#1{% \begingroup% \let\tikz@lib@graph@node@list\pgfutil@empty% - \tikzset{graphs/.cd,#1}% - \csname tikz@lib@graph@def@\tikz@lib@graph@name\endcsname% + \tikzgraphsset{@extra group options/.style={#1}}% + \tikz@lib@graph@start@hint@group% + \csname tikz@lib@graph@def@\tikz@lib@graph@name@only\endcsname% + \tikz@lib@graph@end@hint@group% \expandafter% \endgroup% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\tikz@lib@graph@node@list% \expandafter\expandafter\expandafter{\expandafter\tikz@lib@graph@node@list\tikz@lib@graph@node@list}% + \tikz@lib@graph@hint@aftergroup% } -\def\tikz@lib@graph@do@graph#1#2{% - #1% - \tikz@lib@graph@parse@group{#2}% +\def\tikz@lib@graph@do@graph#1{% + \tikz@lib@graph@parse@group{#1}% } \let\tikz@lib@graph@path\pgfutil@empty -\tikzset{graphs/name/.code={% - \edef\tikz@lib@graph@path{#1\space\tikz@lib@graph@path}% +\tikzgraphsset{ + name separator/.store in=\tikz@lib@graph@name@separator, + name separator=\space, + name/.code={% + \edef\tikz@lib@graph@path{\tikz@lib@graph@path#1\tikz@lib@graph@name@separator}% }% } @@ -476,44 +1365,36 @@ % % Colors % - -\tikzset{ - graph node/.unknown/.code={% - \let\tikz@key\pgfkeyscurrentname% - \pgfkeys{/tikz/\tikz@key={#1}}% - }, - graph node/as/.code=\def\tikz@lib@graph@as{#1}% -} - - -\tikzset{% - new graph color/.style={% - /utils/exec=\expandafter\newif\csname iftikz@lgc@#1@\endcsname, - graph node/#1/.code={% +\def\tikz@lg@newif{\csname newif\endcsname} +\tikzgraphsset{ + as/.code=\def\tikzgraphnodeas{#1},% + color class/.style={% + /utils/exec=\expandafter\tikz@lg@newif\csname iftikz@lgc@#1@\endcsname, + #1/.style={operator={% \edef\tikz@lg@col{\expandafter\noexpand\csname tikz@lgc@#1@true\endcsname}% \let\tikz@lg@do\tikz@lg@colorize% \tikz@lib@graph@node@list% - }, - graph node/!#1/.code={% + }}, + not #1/.style={operator={% \edef\tikz@lg@old@col{\expandafter\noexpand\csname tikz@lgc@#1@true\endcsname}% - \def\tikz@lg@new@col{}% + \let\tikz@lg@new@col\pgfutil@empty% \let\tikz@lg@do\tikz@lg@change@color% \tikz@lib@graph@node@list% - }, - graph node/recolor #1 by/.code={% + }}, + recolor #1 by/.style={operator={% \edef\tikz@lg@old@col{\expandafter\noexpand\csname tikz@lgc@#1@true\endcsname}% \edef\tikz@lg@new@col{\expandafter\noexpand\csname tikz@lgc@##1@true\endcsname}% \let\tikz@lg@do\tikz@lg@change@color% \tikz@lib@graph@node@list% - }, - graph node/not #1/.style=!#1, + }}, + !#1/.style=not #1, }, - new graph color=in, - new graph color=in', - new graph color=in'', - new graph color=out, - new graph color=out', - new graph color=all + color class=source, + color class=source', + color class=source'', + color class=target, + color class=target', + color class=all } \def\tikz@lg@init@color#1#2{% @@ -522,6 +1403,8 @@ \def\tikz@lib@graph@cleanup#1{% \expandafter\global\expandafter\let\csname tikz@lgc@#1\endcsname\relax% + \ifcsname tikz@lgca@@#1\endcsname\expandafter\global\expandafter\let\csname tikz@lgca@@#1\endcsname\relax\fi% + \ifcsname tikz@lgcb@@#1\endcsname\expandafter\global\expandafter\let\csname tikz@lgcb@@#1\endcsname\relax\fi% } \def\tikz@lg@colorize#1{% @@ -583,7 +1466,54 @@ \def\tikz@lib@reset@temp{\let\pgf@temp\iffalse} +% +% Handle connection annotations +% +\def\tikz@lib@annotate@#1#2#3#4{% + \expandafter\ifx\csname tikz@lgc#1@@#2\endcsname\relax% + \expandafter\gdef\csname tikz@lgc#1@@#2\endcsname{{#3}{#4}}% + \else% + \expandafter\expandafter\expandafter\tikz@lib@annotate@read\csname tikz@lgc#1@@#2\endcsname{#3}{#4}% + \expandafter\global\expandafter\let\csname tikz@lgc#1@@#2\endcsname\pgf@temp% + \fi% +} +\def\tikz@lib@annotate@read#1#2#3#4{\def\pgf@temp{{#1,#3}{#2#4}}} + +\tikzgraphsset{ + source edge style/.code=\tikz@lib@annotate@{a}{\tikz@lib@graph@name}{#1}{}, + source edge node/.code=\tikz@lib@annotate@{a}{\tikz@lib@graph@name}{}{#1}, + source edge clear/.code={ + \expandafter\global\expandafter\let\csname tikz@lgca@@\tikz@lib@graph@name\endcsname\relax% + }, + target edge style/.code=\tikz@lib@annotate@{b}{\tikz@lib@graph@name}{#1}{}, + target edge node/.code=\tikz@lib@annotate@{b}{\tikz@lib@graph@name}{}{#1}, + target edge clear/.code={% + \expandafter\global\expandafter\let\csname tikz@lgcb@@\tikz@lib@graph@name\endcsname\relax% + } +}% + + + +% Packing a node list: Replace the node list by a new node list where +% each node is mentioned at most once. + +\def\tikz@lib@graph@pack@node@list{% + {% + \let\tikz@lg@packed\pgfutil@empty% + \let\tikz@lg@do\tikz@lg@packer% + \tikz@lib@graph@node@list% + \expandafter + }\expandafter% + \def\expandafter\tikz@lib@graph@node@list\expandafter{\tikz@lg@packed}% +} +\def\tikz@lg@packer#1{% + \expandafter\ifx\csname tikz@lg@p@#1\endcsname\pgf@stop% + \else% + \expandafter\let\csname tikz@lg@p@#1\endcsname\pgf@stop% + \expandafter\def\expandafter\tikz@lg@packed\expandafter{\tikz@lg@packed\tikz@lg@do{#1}} + \fi +} % % Color functions @@ -600,7 +1530,8 @@ % macro should take a single parameter, which will be set % to the node's name. -\def\tikzlibgraphforeachcolorednode#1#2{% +\def\tikzgraphforeachcolorednode#1#2{% + \tikz@lib@graph@pack@node@list% \expandafter\def\expandafter\iftikz@lib@graph@color@picker\expandafter{\csname iftikz@lgc@#1@\endcsname}% \let\tikz@lib@graph@action#2% \let\tikz@lg@do\tikz@lg@pick% @@ -619,6 +1550,7 @@ } + % Prepare a color % % #1 is the color name @@ -639,18 +1571,19 @@ % The bottom line of all this is that after a preparation you can % easily iterate over nodes having a certain color. If you wish to % iterate over a single color, it will be quicker and easier to call -% \tikzlibgraphforeachcolorednode, but if you need to iterate over two +% \tikzgraphforeachcolorednode, but if you need to iterate over two % colors simultaneously, it will be better to first prepare the color. -\def\tikzlibgraphpreparecolor#1#2#3{% +\def\tikzgraphpreparecolor#1#2#3{% \let\tikz@lib@graph@count#2% + \tikz@lib@graph@count0\relax \def\tikz@lib@graph@prefix{#3}% - \tikzlibgraphforeachcolorednode{#1}\tikz@lib@graph@prepare% + \tikzgraphforeachcolorednode{#1}\tikz@lib@graph@prepare% } \def\tikz@lib@graph@prepare#1{% \advance\tikz@lib@graph@count by1\relax% - \expandafter\def\csname \tikz@lib@graph@prefix\the\tikz@lib@graph@count\endcsname{#1}% + \expandafter\def\csname\tikz@lib@graph@prefix\the\tikz@lib@graph@count\endcsname{#1}% } @@ -660,18 +1593,24 @@ % The bipartite connector % -\tikzset{ - connectors/bipartite/.code 2 args={ +\tikzgraphsset{ + complete bipartite/.style 2 args={operator={ \def\tikz@lg@shoreb{#2}% - \tikzlibgraphforeachcolorednode{#1}\tikz@lib@graph@bipartite@outer + \tikzgraphforeachcolorednode{#1}\tikz@lib@graph@bipartite@outer + }}, + complete bipartite/.default={target'}{source'}, + induced complete bipartite/.style 2 args={ + induced independent set={#1}, + induced independent set={#2}, + complete bipartite={#1}{#2} }, - connectors/bipartite/.default={out'}{in'} + induced complete bipartite/.default={target'}{source'}, } \def\tikz@lib@graph@bipartite@outer#1{% \def\tikz@lib@graph@from{#1}% {% - \tikzlibgraphforeachcolorednode{\tikz@lg@shoreb}\tikz@lib@graph@bipartite@inner% + \tikzgraphforeachcolorednode{\tikz@lg@shoreb}\tikz@lib@graph@bipartite@inner% }% } @@ -682,25 +1621,51 @@ \fi% } -\def\tikz@lib@graph@default@new@edge{% +\def\tikz@lib@graph@default@new@edge#1#2{% \pgfkeysgetvalue{/tikz/graphs/@edges styling}\pgf@temp - \expandafter\tikz@lib@graph@default@new@edge@\expandafter{\pgf@temp}% + \pgfkeysgetvalue{/tikz/graphs/@edges node}\pgf@temp@b + \let\tikz@lib@add@temp\pgfutil@empty% + \tikz@lib@graph@add@edge@annotations{a}{#1} + \tikz@lib@graph@add@edge@annotations{b}{#2} + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgf@temp% + \expandafter\expandafter\expandafter{\expandafter\pgf@temp\tikz@lib@add@temp}% + \expandafter\expandafter\expandafter\tikz@lib@graph@default@new@edge@% + \expandafter\expandafter\expandafter{\expandafter\pgf@temp\expandafter}\expandafter{\pgf@temp@b}{#1}{#2}% +} +\def\tikz@lib@graph@default@new@edge@#1#2#3#4{% + \iftikz@lib@graph@simple% + \edef\tikz@temp{{\pgfkeysvalueof{/tikz/graphs/default edge kind}}{#3}{#4}} + \expandafter\tikz@lib@graph@set@simple@edge\tikz@temp{#1}{#2}% + \else% + \pgfkeys{/tikz/graphs/.cd,new \pgfkeysvalueof{/tikz/graphs/default edge kind}={#3}{#4}{#1}{#2}}% + \fi% } -\def\tikz@lib@graph@default@new@edge@#1#2#3{% - \pgfkeys{/tikz/graphs/.cd,new edge \pgfkeysvalueof{/tikz/graphs/default edge kind}={#2}{#3}{#1}}% +\def\tikz@lib@graph@add@edge@annotations#1#2{% + \ifcsname tikz@lgc#1@@#2\endcsname% + \expandafter\let\expandafter\tikz@lg@temp@\csname tikz@lgc#1@@#2\endcsname% + \ifx\tikz@lg@temp@\relax\else + \expandafter\tikz@lib@graph@add@edge@annotations@\tikz@lg@temp@% + \let\tikz@lib@add@temp\tikz@lib@final@edge@style + \fi% + \fi% } +\def\tikz@lib@graph@add@edge@annotations@#1#2{ + \expandafter\def\expandafter\pgf@temp\expandafter{\pgf@temp,#1}% + \expandafter\def\expandafter\pgf@temp@b\expandafter{\pgf@temp@b#2}% +} +\def\tikz@lib@final@edge@style{,after source and target edge/.try} - % % The clique connector % -\tikzset{ - connectors/clique/.code={ - \tikzlibgraphpreparecolor{#1}\c@pgf@counta{tikz@lg}% - \tikz@lg@clique@loop% - }, - connectors/clique/.default=all +\tikzgraphsset{ + clique/.style={operator={ + \tikzgraphpreparecolor{#1}\c@pgf@counta{tikz@lg}% + \tikz@lg@clique@loop% + }}, + clique/.default=all } \def\tikz@lg@clique@loop{% @@ -716,22 +1681,58 @@ \def\tikz@lg@clique@loop@inner{% \advance\c@pgf@countb by-1\relax% \ifnum\c@pgf@countb>0\relax% - \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@counta\endcsname}{\csname tikz@lg\the\c@pgf@countb\endcsname}% + \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{\csname tikz@lg\the\c@pgf@counta\endcsname}% \expandafter\tikz@lg@clique@loop@inner% \fi% } % +% The independent set connector +% + +\tikzgraphsset{ + induced independent set/.style={operator={ + \pgfkeysgetvalue{/tikz/graphs/default edge kind}\tikz@lg@default% + \pgfkeyssetvalue{/tikz/graphs/default edge kind}{-!-}% + \tikzgraphpreparecolor{#1}\c@pgf@counta{tikz@lg}% + \tikz@lg@indep@loop% + \pgfkeyslet{/tikz/graphs/default edge kind}\tikz@lg@default% + }}, + induced independent set/.default=all +} + +\def\tikz@lg@indep@loop{% + \ifnum\c@pgf@counta=0\relax% + \else + \c@pgf@countb=\c@pgf@counta\relax% + \tikz@lg@indep@loop@inner% + \advance\c@pgf@counta by-1\relax% + \expandafter\tikz@lg@indep@loop% + \fi% +} + +\def\tikz@lg@indep@loop@inner{% + \advance\c@pgf@countb by-1\relax% + \ifnum\c@pgf@countb>0\relax% + \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@counta\endcsname}{\csname tikz@lg\the\c@pgf@countb\endcsname}% + \expandafter\tikz@lg@indep@loop@inner% + \fi% +} + + +% % The path connector % -\tikzset{ - connectors/path/.code={% - \let\tikz@lg@prev\relax% - \tikzlibgraphforeachcolorednode{#1}\tikz@lib@graph@path@do% - }, - connectors/path/.default=all +\tikzgraphsset{ + path/.style={operator={% + \let\tikz@lg@prev\relax% + \tikzgraphforeachcolorednode{#1}\tikz@lib@graph@path@do% + }}, + path/.default=all, + induced path/.style={induced independent set={#1},path={#1}}, + induced path/.default=all, } \def\tikz@lib@graph@path@do#1{% @@ -747,17 +1748,19 @@ % The cycle connector % -\tikzset{ - connectors/cycle/.code={% +\tikzgraphsset{ + cycle/.style={operator={% \let\tikz@lg@prev\relax% \let\tikz@lg@first\relax% - \tikzlibgraphforeachcolorednode{#1}\tikz@lib@graph@cycle@do% + \tikzgraphforeachcolorednode{#1}\tikz@lib@graph@cycle@do% \ifx\tikz@lg@first\relax% \else% \tikz@lib@graph@default@new@edge{\tikz@lg@prev}{\tikz@lg@first}% \fi% - }, - connectors/cycle/.default=all + }}, + cycle/.default=all, + induced cycle/.style={induced independent set={#1},cycle={#1}}, + induced cycle/.default=all, } \def\tikz@lib@graph@cycle@do#1{% @@ -774,68 +1777,98 @@ % -% The match connector +% The matching and star connector % -\tikzset{ - connectors/match/.code 2 args={ +\tikzgraphsset{ + matching and star/.style 2 args={operator=% {% - \tikzlibgraphpreparecolor{#1}\c@pgf@counta{tikz@lg} + \tikzgraphpreparecolor{#1}\c@pgf@counta{tikz@lg} \c@pgf@countb=0\relax% \let\tikz@lg@prev\relax - \tikzlibgraphforeachcolorednode{#2}\tikz@lib@graph@match@do% - \tikz@lib@graph@match@rest% + \tikzgraphforeachcolorednode{#2}\tikz@lib@graph@flow@do% + \tikz@lib@graph@flow@rest% }% }, - connectors/match/.default={out'}{in'} + matching and star/.default={target'}{source'} } -\def\tikz@lib@graph@match@do#1{% +\def\tikz@lib@graph@flow@do#1{% \advance\c@pgf@countb by1\relax% \ifnum\c@pgf@countb>\c@pgf@counta\relax% \c@pgf@countb=\c@pgf@counta\relax% \fi% - \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{#1}% + \ifnum\c@pgf@countb>0\relax% + \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{#1}% + \fi% \def\tikz@lg@prev{#1}% } -\def\tikz@lib@graph@match@rest{% +\def\tikz@lib@graph@flow@rest{% \ifnum\c@pgf@countb<\c@pgf@counta\relax% - \advance\c@pgf@countb by1\relax% - \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{\tikz@lg@prev}% - \expandafter\tikz@lib@graph@match@rest% + \ifnum\c@pgf@countb>0\relax% + \advance\c@pgf@countb by1\relax% + \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{\tikz@lg@prev}% + \expandafter\tikz@lib@graph@flow@rest% + \fi% + \fi% +} + + + +% +% The matching connector +% + +\tikzgraphsset{ + matching/.style 2 args={operator= + {% + \tikzgraphpreparecolor{#1}\c@pgf@counta{tikz@lg} + \c@pgf@countb=0\relax% + \tikzgraphforeachcolorednode{#2}\tikz@lib@graph@matching@do% + }% + }, + matching/.default={target'}{source'} +} + +\def\tikz@lib@graph@matching@do#1{% + \advance\c@pgf@countb by1\relax% + \ifnum\c@pgf@countb>\c@pgf@counta\relax% + \else% + \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{#1}% \fi% } + + % % The butterfly connector % -\tikzset{ - connectors/butterfly/.code={ +\tikzgraphsset{ + butterfly/.style={operator= {}{% - \pgfkeys{/tikz/connectors/butterfly/.cd,#1}% - \ifnum\pgfkeysvalueof{/tikz/connectors/butterfly/level}=0\relax% - \pgfkeysalso{/tikz/connectors/match={\pgfkeysvalueof{/tikz/connectors/butterfly/from}}{\pgfkeysvalueof{/tikz/connectors/butterfly/to}}}% + \pgfkeys{/tikz/graphs/butterfly/.cd,#1}% + \ifnum\pgfkeysvalueof{/tikz/graphs/butterfly/level}=0\relax% + \tikzgraphinvokeoperator{matching and star={\pgfkeysvalueof{/tikz/graphs/butterfly/from}}{\pgfkeysvalueof{/tikz/graphs/butterfly/to}}}% \else% {% - \tikzlibgraphpreparecolor{\pgfkeysvalueof{/tikz/connectors/butterfly/from}}\c@pgf@counta{tikz@lg} + \tikzgraphpreparecolor{\pgfkeysvalueof{/tikz/graphs/butterfly/from}}\c@pgf@counta{tikz@lg} \c@pgf@countb=0\relax% - \tikzlibgraphforeachcolorednode{\pgfkeysvalueof{/tikz/connectors/butterfly/to}}\tikz@lib@graph@butterfly@do% + \tikzgraphforeachcolorednode{\pgfkeysvalueof{/tikz/graphs/butterfly/to}}\tikz@lib@graph@butterfly@do% }% - \iftikz@butterfly@prime\else\pgfkeysalso{/tikz/connectors/match={\pgfkeysvalueof{/tikz/connectors/butterfly/from}}{\pgfkeysvalueof{/tikz/connectors/butterfly/to}}}\fi% + \iftikz@butterfly@prime\else\tikzgraphinvokeoperator{matching and star={\pgfkeysvalueof{/tikz/graphs/butterfly/from}}{\pgfkeysvalueof{/tikz/graphs/butterfly/to}}}\fi% \fi% }% }, - connectors/butterfly/.default=, - connectors/butterfly/level/.initial=1, - connectors/butterfly/from/.initial=out', - connectors/butterfly/to/.initial=in', - connectors/butterfly'/.code={% - {}{\tikz@butterfly@primetrue\pgfkeysalso{butterfly={#1}}}}, - connectors/butterfly'/.default=, + butterfly/.default=, + butterfly/level/.initial=1, + butterfly/from/.initial=target', + butterfly/to/.initial=source', + butterfly'/.style={operator={}{\tikz@butterfly@primetrue\pgfkeysalso{butterfly={#1}}}}, + butterfly'/.default=, } \newif\iftikz@butterfly@prime @@ -843,7 +1876,7 @@ \def\tikz@lib@graph@butterfly@do#1{% \advance\c@pgf@countb by1\relax% % Compute other side... - \c@pgf@countc=\pgfkeysvalueof{/tikz/connectors/butterfly/level}\relax% + \c@pgf@countc=\pgfkeysvalueof{/tikz/graphs/butterfly/level}\relax% {% % Computer countb mod (2level) \count0=\c@pgf@countc\relax% @@ -875,3 +1908,733 @@ + +% +% The no edges connector +% +\tikzgraphsset{no edges/.style={operator=\relax}} + + + + +% +% The grid connector +% +\tikzgraphsset{ + grid/.style={operator={ + \tikzgraphpreparecolor{#1}\c@pgf@counta{tikz@lg}% + \c@pgf@countb=0\relax% + \tikzgraphpreparewrapafter% + \tikz@lg@grid@loop% + }% + }, + grid/.default=all +} + +\def\tikzgraphpreparewrapafter{% + \pgfkeysgetvalue{/tikz/graphs/wrap after}\tikz@temp% + \ifnum\tikz@temp=0\relax% + \pgfmathparse{sqrt(\tikzgraphVnum)}% + \pgfmathint{\pgfmathresult}% + \edef\tikzgraphwrapafter{\pgfmathresult}% + \else% + \edef\tikzgraphwrapafter{\tikz@temp} + \fi% +} + +\def\tikz@lg@grid@loop{% + \ifnum\c@pgf@counta=0\relax% + \else% + \advance\c@pgf@countb by 1\relax% + \pgfmathmod{\c@pgf@countb-1}{\tikzgraphwrapafter}% + \pgfmathint{\pgfmathresult}% + \ifnum\pgfmathresult>0% + \pgfmathsubtract{\c@pgf@countb}{1}% + \pgfmathint{\pgfmathresult}% + \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{\csname tikz@lg\pgfmathresult\endcsname}% + \fi% + \pgfmathparse{\c@pgf@countb <= \tikzgraphwrapafter}% + \ifnum\pgfmathresult=0% + \pgfmathsubtract{\c@pgf@countb}{\tikzgraphwrapafter}% + \pgfmathint{\pgfmathresult}% + \tikz@lib@graph@default@new@edge{\csname tikz@lg\pgfmathresult\endcsname}{\csname tikz@lg\the\c@pgf@countb\endcsname}% + \fi% + \advance\c@pgf@counta by-1\relax% + \expandafter\tikz@lg@grid@loop% + \fi% +} + + + + +% Positioning +% +% It is not the job of the graph library to compute good positions for +% nodes in a graph. However, some basic support is provided for simple +% cases. +% +% The idea is at follows: Graphs are specified hierarchically. For +% instance, consider the following graph specification: +% +% graph { a, b, c -> d -> {e -> f -> g, h} -> i, j -> k } +% +% Here, we have the *group* {e->f->g,h} inside the larger graph +% specification. Each group consists of sequence of *chains* like +% e->f->g or j->k. +% +% In order to facilitate the automatic positioning of nodes, the graph +% library will provide you with information about the position of +% nodes inside their groups and chains. +% +% As a chain is being parsed, a counter stored in +% /tikz/graphs/placement/element count is available that is advanced for +% each element in the chain. +% +% Additionally, a counter stored in placement/width is +% available. This "logical" width is defined recursively as follows: The +% width of a single node is computed by calling the key +% placement/logical node width, which should return a real or logical +% width of the node passed as a parameter in the macor \pgfmathresult. The +% width of a chain is the sum of the widths of its elements. The +% width of a group is the maximum of the widths of its elements. +% +% +% Symmetrically, as a group is being constructed, a counter stored in +% placement/chain count is available that is advanced for each chain +% in the group. The number placement/depth is the defined +% recursively as follows: For a single node, the depth is +% computed by the key placement/logical node depth. The depth +% of a group is the sum of the depths of its elements. The depth of a +% chain is the maximum of the depth of its elements. +% +% +% The above keys get updated automatically. You should setup the key +% placement/compute position such that it uses the above keys to +% compute a good position for a new node based on the above +% keys. Typically, this key should execute node={shift=(...)} to setup +% the necessary shift for a new node. +% +% The key placement/compute position should not be called +% directly. Instead, the key placement/place should be used. This key +% has two effects: First, it calls placement/compute position. Second, +% it resets the length and normal counters. It will setup a completely +% new counting of lengths and counters inside the current scope. +% +% The placmenet/place key is executed automatically whenever a new +% node is automatically created. Furthermore, placement strategies +% will call this key. + +\tikzgraphsset{ + placement/.cd, + compute position/.code=\tikz@lib@graph@linear@pos, + place/.code={% + \pgfkeys{/tikz/graphs/placement/compute position}% + \aftergroup\tikz@lib@graph@reset@locals% + \pgfkeyssetvalue{/tikz/graphs/placement/element count}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/chain count}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/depth}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/width}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/local depth}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/local width}{0}% + }, + element count/.initial=0, + chain count/.initial=0, + depth/.initial=0, + width/.initial=0, + level/.initial=0, + logical node depth/.code=\def\pgfmathresult{1}, + logical node width/.code=\def\pgfmathresult{1}, +} + +\def\tikz@lib@graph@reset@locals{% + \gdef\tikz@lib@graph@group@depth{0}% + \gdef\tikz@lib@graph@group@width{0}% +} + + +% Arrange nodes evenly +% +% This strategy works as follows: You specify a "chain shift vector" +% and a "group shift vector". Then each new element on a chain is +% shifted by the chain shift vector relative to the previous element +% on the chain. Similarly for each new element of a group. + +\tikzgraphsset{ + Cartesian placement/.style={ + placement/place, + placement/compute position/.code=\tikz@lib@graph@linear@pos% + }, + chain shift/.initial={(1,0)}, + group shift/.initial={(0,-1)}, + grow right/.style={ + placement/place, + chain shift={(#1,0)}, + @auto anchor horizontal=center, + placement/logical node width/.code=\def\pgfmathresult{1} + }, + grow right/.default=1, + grow left/.style={ + placement/place, + chain shift={(-#1,0)}, + @auto anchor horizontal=center, + placement/logical node width/.code=\def\pgfmathresult{1} + }, + grow left/.default=1, + grow up/.style={ + placement/place, + chain shift={(0,#1)}, + @auto anchor horizontal=center, + placement/logical node width/.code=\def\pgfmathresult{1} + }, + grow up/.default=1, + grow down/.style={ + placement/place, + chain shift={(0,-#1)}, + @auto anchor vertical=center, + placement/logical node width/.code=\def\pgfmathresult{1} + }, + grow down/.default=1, + branch right/.style={ + placement/place, + group shift={(#1,0)}, + @auto anchor horizontal=center, + placement/logical node depth/.code=\def\pgfmathresult{1} + }, + branch right/.default=1, + branch left/.style={ + placement/place, + group shift={(-#1,0)}, + @auto anchor horizontal=center, + placement/logical node depth/.code=\def\pgfmathresult{1} + }, + branch left/.default=1, + branch up/.style={ + placement/place, + group shift={(0,#1)}, + @auto anchor vertical=center, + placement/logical node depth/.code=\def\pgfmathresult{1} + }, + branch up/.default=1, + branch down/.style={ + placement/place, + group shift={(0,-#1)}, + @auto anchor vertical=center, + placement/logical node depth/.code=\def\pgfmathresult{1} + }, + branch down/.default=1, + % + % Sep shifts + % + grow right sep/.style={ + Cartesian placement, + chain shift={(1pt,0)}, + @auto anchor horizontal=west, + placement/logical node width/.code=\tikz@lib@graph@width@sep{##1}{#1} + }, + grow right sep/.default=1em, + grow left sep/.style={ + Cartesian placement, + chain shift={(-1pt,0)}, + @auto anchor horizontal=east, + placement/logical node width/.code=\tikz@lib@graph@width@sep{##1}{#1} + }, + grow left sep/.default=1em, + grow up sep/.style={ + Cartesian placement, + chain shift={(0,1pt)}, + @auto anchor vertical=south, + placement/logical node width/.code=\tikz@lib@graph@depth@sep{##1}{#1} + }, + grow up sep/.default=1em, + grow down sep/.style={ + Cartesian placement, + chain shift={(0,-1pt)}, + @auto anchor vertical=north, + placement/logical node width/.code=\tikz@lib@graph@depth@sep{##1}{#1} + }, + grow down sep/.default=1em, + grow right sep/.style={ + Cartesian placement, + chain shift={(1pt,0)}, + @auto anchor horizontal=west, + placement/logical node width/.code=\tikz@lib@graph@width@sep{##1}{#1} + }, + % + branch right sep/.style={ + Cartesian placement, + group shift={(1pt,0)}, + @auto anchor horizontal=west, + placement/logical node depth/.code=\tikz@lib@graph@width@sep{##1}{#1} + }, + branch right sep/.default=1em, + branch left sep/.style={ + Cartesian placement, + group shift={(-1pt,0)}, + @auto anchor horizontal=east, + placement/logical node depth/.code=\tikz@lib@graph@width@sep{##1}{#1} + }, + branch left sep/.default=1em, + branch up sep/.style={ + Cartesian placement, + group shift={(0,1pt)}, + @auto anchor vertical=south, + placement/logical node depth/.code=\tikz@lib@graph@depth@sep{##1}{#1} + }, + branch up sep/.default=1em, + branch down sep/.style={ + Cartesian placement, + group shift={(0,-1pt)}, + @auto anchor vertical=north, + placement/logical node depth/.code=\tikz@lib@graph@depth@sep{##1}{#1} + }, + branch down sep/.default=1em, + % + @auto anchor horizontal/.style={ + nodes={anchor=\csname tikz@lib@graph@auto@\tikz@lib@graph@auto@h @\tikz@lib@graph@auto@v\endcsname}, + /utils/exec=\def\tikz@lib@graph@auto@h{#1} + }, + @auto anchor vertical/.style={ + nodes={anchor=\csname tikz@lib@graph@auto@\tikz@lib@graph@auto@h @\tikz@lib@graph@auto@v\endcsname}, + /utils/exec=\def\tikz@lib@graph@auto@v{#1} + }, + % + % + no placement/.style={ + placement/place, + placement/compute position/.code=% + } +} + +\def\tikz@lib@graph@auto@h{center} +\def\tikz@lib@graph@auto@v{center} + +\def\tikz@lib@graph@auto@center@center{center} +\def\tikz@lib@graph@auto@west@center{west} +\def\tikz@lib@graph@auto@east@center{east} +\def\tikz@lib@graph@auto@center@north{north} +\def\tikz@lib@graph@auto@west@north{north west} +\def\tikz@lib@graph@auto@east@north{north east} +\def\tikz@lib@graph@auto@center@south{south} +\def\tikz@lib@graph@auto@west@south{south west} +\def\tikz@lib@graph@auto@east@south{south east} + +\def\tikz@lib@graph@linear@pos{% + \pgfkeysgetvalue{/tikz/graphs/chain shift}\tikz@temp + \expandafter\tikz@scan@one@point\expandafter\pgf@process\tikz@temp + \pgf@process{\pgfpointscale{\pgfkeysvalueof{/tikz/graphs/placement/width}}{}}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgfkeysgetvalue{/tikz/graphs/group shift}\tikz@temp + \expandafter\tikz@scan@one@point\expandafter\pgf@process\tikz@temp + \pgf@process{\pgfpointscale{\pgfkeysvalueof{/tikz/graphs/placement/depth}}{}}% + \advance\pgf@xa by\pgf@x% + \advance\pgf@ya by\pgf@y% + \edef\tikz@lib@graph@shift{(\the\pgf@xa,\the\pgf@ya)} + \pgfkeys{/tikz/graphs/nodes/.expanded={shift={\tikz@lib@graph@shift}}} +} + + +\def\tikz@lib@graph@width@sep#1#2{% + \pgf@process{\pgfpointdiff{\pgfpointanchor{#1}{west}}{\pgfpointanchor{#1}{east}}}% + \pgfmathparse{#2+\the\pgf@x}% +} + +\def\tikz@lib@graph@depth@sep#1#2{% + \pgf@process{\pgfpointdiff{\pgfpointanchor{#1}{south}}{\pgfpointanchor{#1}{north}}}% + \pgfmathparse{#2+\the\pgf@y}% +} + + +% Circular arrangements +% +% This strategy works a bit like the arrange evenly strategy, but in +% polar coordinates. Both for the chains and the groups you specify a +% polar shift, which must be in the form "(delta degree:delta +% distance)". For each element in a chain, the delta degree is added +% to the chain degree, likewise for each element the delta distance is +% added. Similarly for groups. +% +% There is an initial degree and radius, stored in the key "phase" and +% "radius". + +\tikzgraphsset{, + circular placement/.style={ + placement/place, + placement/compute position/.code=\tikz@lib@graph@circular@pos,% + placement/logical node depth/.code=\def\pgfmathresult{1}, + placement/logical node width/.code=\def\pgfmathresult{1}, + }, + clockwise/.style={ + circular placement, + group polar shift={(-360/#1:0)} + }, + clockwise/.default=\tikzgraphVnum, + counterclockwise/.style={ + circular placement, + group polar shift={(360/#1:0)} + }, + counterclockwise/.default=\tikzgraphVnum, + chain polar shift/.initial={(0:1cm)}, + group polar shift/.initial={(60:0)}, + radius/.initial=1cm, + phase/.initial=90, +} + +\def\tikz@lib@graph@circular@pos{% + \pgfkeysgetvalue{/tikz/graphs/chain polar shift}\tikz@temp + \expandafter\tikz@lib@graph@decompose@polar\tikz@temp% + \pgf@process{\pgfpointscale{\pgfkeysvalueof{/tikz/graphs/placement/width}}{}}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgfkeysgetvalue{/tikz/graphs/group polar shift}\tikz@temp + \expandafter\tikz@lib@graph@decompose@polar\tikz@temp% + \pgf@process{\pgfpointscale{\pgfkeysvalueof{/tikz/graphs/placement/depth}}{}}% + \advance\pgf@xa by\pgf@x% + \advance\pgf@ya by\pgf@y% + \pgfmathparse{\pgfkeysvalueof{/tikz/graphs/radius}}% + \advance\pgf@ya by\pgfmathresult pt% + \pgfmathsetmacro\tikz@temp{\the\pgf@xa+\pgfkeysvalueof{/tikz/graphs/phase}}% + \edef\tikz@lib@graph@shift{(\tikz@temp:\the\pgf@ya)} + \pgfkeys{/tikz/graphs/nodes/.expanded={shift={\tikz@lib@graph@shift}}} +} + + +\def\tikz@lib@graph@decompose@polar(#1:#2){% + \pgfmathsetlength\pgf@x{#1}% + \pgfmathsetlength\pgf@y{#2}% +} + + +% Grid arrangements +% +\tikzgraphsset{ + grid placement/.style={ + placement/place, + placement/compute position/.code=\tikz@lib@graph@grid@pos,% + }, +} + + +\def\tikz@lib@graph@grid@pos{% + % + % Make sure to set \tikzgraphwrapafter before we compute + % the positions of nodes in the grid + % + \tikzgraphpreparewrapafter% + % + % find out the coordinate in the grid + % + \pgfkeysgetvalue{/tikz/graphs/placement/depth}\tikz@temp@depth% + \pgfkeysgetvalue{/tikz/graphs/placement/width}\tikz@temp@width% + \pgfmathsetmacro{\tikz@temp}{max(\tikz@temp@depth, \tikz@temp@width)}% + \pgfmathsetmacro{\tikz@temp@col}{mod(\tikz@temp,\tikzgraphwrapafter)}% + \pgfmathsetmacro{\tikz@temp@row}{div(\tikz@temp,\tikzgraphwrapafter)}% + % + % multiply row by the group shift and col by the chain shift + % + \pgfkeysgetvalue{/tikz/graphs/group shift}\tikz@temp% + \expandafter\tikz@scan@one@point\expandafter\tikz@lib@graph@grid@pos@a\tikz@temp% + \pgfkeysgetvalue{/tikz/graphs/chain shift}\tikz@temp% + \expandafter\tikz@scan@one@point\expandafter\tikz@lib@graph@grid@pos@b\tikz@temp% + % + % apply the shift + % + \edef\tikz@lib@graph@shift{(\the\pgf@xa,\the\pgf@ya)} + \pgfkeys{/tikz/graphs/nodes/.expanded={shift={\tikz@lib@graph@shift}}} +} + +\def\tikz@lib@graph@grid@pos@a#1{\pgf@process{\pgfpointscale{\tikz@temp@row}{#1}}\pgf@xa=\pgf@x\relax\pgf@ya=\pgf@y\relax} +\def\tikz@lib@graph@grid@pos@b#1{\pgf@process{\pgfpointscale{\tikz@temp@col}{#1}}% + \advance\pgf@xa by\pgf@x\relax + \advance\pgf@ya by\pgf@y\relax} + +\tikzgraphsset{ + % Grids: + wrap after/.initial=0, + % Node sets: + V/.code={% + \def\tikzgraphV{#1} + \c@pgf@counta=0\foreach \tikz@dummy in {#1} {\global\advance\c@pgf@counta by1\relax} + \edef\tikzgraphVnum{\the\c@pgf@counta} + }, + V={1}, + n/.style={V={1,...,#1},name shore V/.style={name=V}}, + W/.code={% + \def\tikzgraphW{#1} + \c@pgf@counta=0\foreach \tikz@dummy in {#1} {\global\advance\c@pgf@counta by1\relax} + \edef\tikzgraphWnum{\the\c@pgf@counta} + }, + W={1}, + m/.style={W={1,...,#1},name shore W/.style={name=W}}, + % Shores: + name shore V/.style=, + name shore W/.style=, +} + + + +% +% Quick graphs +% +% Parsing the graph syntax can take a lot of time for large +% graphs. This is mainly due to the transformation of commas and +% semicolons and all the internal bookkeeping. +% +% For large graphs, the quick graph syntax offers a greatly reduced +% syntax that will be processed much more quickly. This syntax is +% compatible with the normal graph syntax in the sense that all +% specifications written in the reduced syntax are also legal in the +% normal syntax, but not the other way round. +% +% The following rules apply: +% +% 1) A quick graph consists of a sequence of either nodes, edges sequences, or +% groups. These are separated by commas or semicolons. +% +% 2) Every node is of the form +% +% "node name"/"node text"[options] +% +% Here, the quotation marks are mandatory. The part '/"node text"' may +% be missing, in which case the node name is used as the node +% text. The options may also be missing. The node name may not contain +% any "funny" characters (unlike in the normal graph command). +% +% 3) Every edge is of the form +% +% <node spec> <connector> <node spec> <connector> <node spec> ... <connector> <node spec>; +% +% Here, the <node spec> are node specifications as described above, +% the <connector> is one of the four connectors "->", "<-", "--", and +% "<->", followed by optional options in square +% brackets. The semicolon may be replaced by a comma. +% +% 4) Every group is of the form +% +% { [options] lines }; +% +% The options are compulsory, the lines must be a sequence of nodes, +% edges, and groups as described above. The semicolon can, again, be +% replaced by a comma. +% +% +% Things that are allowed in the normal syntax, but not in the quick +% syntax, include: +% +% - Connecting a node and a group as in a->{b,c}. +% - Node names without quotation marks. +% - Using subgraphs (graph macros). +% - Using graph sets. +% - Using graph color classes. +% - Using anonymous nodes. +% - Using the "fresh nodes" option. +% - Using sublayouts. +% - Using the -!- edge connector. +% - Using the "simple" option. +% - Using edge annotations. +% +% Example: +% +% \graph [quick] { +% "a"/"$a$"[red] -> "b"[blue] -> "c"; +% "b" -> "d"; +% "c" ->[thick] "e"; +% { [same layer] "c", "d" }; +% }; +% +% + +\tikzgraphsset{quick/.is if=tikz@graph@quick} +\newif\iftikz@graph@quick + +\def\tikz@lib@graphs@parse@quick@graph{ + % Ok, we are before the initial brace. We open a group and start + % setting up some bookkeeping + \begingroup% + \global\tikz@qnode@count0\relax% + \let\tikzgraphnodepath\pgfutil@empty% + \tikz@q@outertrue% + \afterassignment\tikz@lib@graphs@quick@main\let\pgf@temp=% +} + +\newcount\tikz@qnode@count +\newif\iftikz@q@outer + +\def\tikz@lib@graphs@quick@main{% + \afterassignment\tikz@lib@graphs@quick@handle\let\pgf@let@token=% +} +\def\tikz@lib@graphs@quick@handle{% + \ifx\pgf@let@token"% + \expandafter\tikz@lib@graphs@quick@first@node% + \else% + \expandafter\tikz@lib@graphs@quick@other% + \fi% +} +\def\tikz@lib@graphs@quick@other{% + \let\tikz@next\tikz@lib@graphs@quick@error% + \ifx\pgf@let@token\egroup% + \let\tikz@next\tikz@lib@graphs@quick@end@group% + \else% + \ifx\pgf@let@token\bgroup% + \let\tikz@next\tikz@lib@graphs@quick@start@group% + \else% + \ifx\pgf@let@token\par% + \let\tikz@next\tikz@lib@graphs@quick@main% + \fi% + \fi + \fi% + \tikz@next% +} + +\def\tikz@lib@graphs@quick@error#1{\tikzerror{Unexpected token '\string#1' in quick graph syntax}\tikz@lib@graphs@quick@main} +\def\tikz@lib@graphs@quick@start@group{% + \pgfutil@ifnextchar[\tikz@lib@graphs@quick@start@group@{\tikzerror{Group + in quick graph syntax must start with options.}} +} + +\def\tikz@lib@graphs@quick@start@group@[#1]{% + \begingroup% + \tikz@q@outerfalse% + \tikzgraphsset{#1}% + \tikz@lib@graphs@quick@main% +} +\def\tikz@lib@graphs@quick@end@group{% + \iftikz@q@outer% + \endgroup% + % Ok, cleanup! + \pgfutil@loop% + \ifnum\tikz@qnode@count>0\relax% + \expandafter\global\expandafter\let\csname tikz@gr@q@@\csname tikz@gr@qn@@\the\tikz@qnode@count\endcsname\endcsname\relax% + \expandafter\global\expandafter\let\csname tikz@gr@qn@@\the\tikz@qnode@count\endcsname\relax% + \global\advance\tikz@qnode@count by-1\relax% + \pgfutil@repeat% + \expandafter\tikz@lib@graph@main@done% + \else% + \endgroup% + \expandafter\tikz@lib@graphs@end@group@% + \fi% +} +\def\tikz@lib@graphs@end@group@{% + \pgfutil@ifnextchar;{\expandafter\tikz@lib@graphs@quick@main\pgfutil@gobble}{% + \pgfutil@ifnextchar,{\expandafter\tikz@lib@graphs@quick@main\pgfutil@gobble}{% + \tikzerror{Graph groups in quick syntax must be followed by a semicolon or a comma.}% + }% + }% +} + + +\def\tikz@lib@graphs@quick@first@node{% + \let\tikz@quick@prev@node\relax% + \tikz@lib@graphs@quick@node% +} + +\def\tikz@lib@graphs@quick@node#1"{% + \def\tikzgraphnodename{#1}% + \pgfutil@ifnextchar/\tikz@lib@graphs@quick@text\tikz@lib@graphs@quick@notext% +} +\def\tikz@lib@graphs@quick@text/"#1"{% + \def\tikzgraphnodetext{#1}% + \tikz@lib@graphs@quick@opt% +} +\def\tikz@lib@graphs@quick@notext{% + \let\tikzgraphnodetext\tikzgraphnodename% + \tikz@lib@graphs@quick@opt% +} +\def\tikz@lib@graphs@quick@opt{% + \pgfutil@ifnextchar[\tikz@lib@graphs@quick@withopt{\tikz@lib@graphs@quick@withopt[]}%] +} +\def\tikz@lib@graphs@quick@withopt[#1]{% + % Test, whether node already exists + \expandafter\ifx\csname tikz@gr@q@@\tikzgraphnodename\endcsname\relax% + % New node + \global\advance\tikz@qnode@count by1\relax% + \expandafter\global\expandafter\let\csname tikz@gr@q@@\tikzgraphnodename\endcsname\pgfutil@empty% not relax + \expandafter\global\expandafter\let\csname tikz@gr@qn@@\the\tikz@qnode@count\endcsname\tikzgraphnodename% back pointer + \let\tikzgraphnodefullname\tikzgraphnodename% + \let\tikzgraphnodeas\tikzgraphnodeas@default% + \node [% + name=\tikzgraphnodename,% + graphs/redirect unknown to tikz, + /tikz/graphs/.cd,% + /tikz/graphs/@nodes styling,% + #1]% + {% + \tikzgraphnodeas% + };% + \else% + % + % Handle late options and operators + \tikzgdlatenodeoptionacallback{\tikzgraphnodename}% + \node also[graphs/redirect unknown to tikz,/tikz/graphs/.cd,#1](\tikzgraphnodename);% + \fi% + % Connect, if necessary + \tikz@lig@graph@quikc@make@edge@if@necessary% + \tikz@lib@graphs@quick@scan@after@node% +} + +\def\tikz@lig@graph@quikc@make@edge@if@necessary{% + \ifx\tikz@quick@prev@node\relax% + \else% + \tikz@lib@graphs@quick@make@edge% + \fi% +} + +\def\tikz@lib@graphs@quick@scan@after@node{% + \pgfutil@ifnextchar,\tikz@lib@graphs@quick@comma{% + \pgfutil@ifnextchar;\tikz@lib@graphs@quick@semi{% + \pgfutil@ifnextchar\egroup{\tikz@lib@graphs@quick@semi;}{% + \pgfutil@ifnextchar\par{\expandafter\tikz@lib@graphs@quick@scan@after@node\tikz@lib@graphs@quick@gobble@par}% + \tikz@lib@graphs@quick@connector}}}% +} +\long\def\tikz@lib@graphs@quick@gobble@par#1{}% + +\def\tikz@lib@graphs@quick@comma,{\tikz@lib@graphs@quick@main} +\def\tikz@lib@graphs@quick@semi;{\tikz@lib@graphs@quick@main} +\def\tikz@lib@graphs@quick@connector#1#2{% + \def\tikz@lib@graphs@quick@edge@kind{#1#2}% + \pgfutil@ifnextchar>\tikz@lib@graphs@back@edge{% + \pgfutil@ifnextchar[\tikz@lib@graphs@quick@connector@handle@opt{\tikz@lib@graphs@quick@connector@handle@opt[]}%] + }% +} +\def\tikz@lib@graphs@back@edge#1{% + \expandafter\def\expandafter\tikz@lib@graphs@quick@edge@kind\expandafter{\tikz@lib@graphs@quick@edge@kind#1}% + \pgfutil@ifnextchar[\tikz@lib@graphs@quick@connector@handle@opt{\tikz@lib@graphs@quick@connector@handle@opt[]}%] +} +\def\tikz@lib@graphs@quick@connector@handle@opt[#1]{% + \def\tikz@lib@graphs@quick@edge@options{#1}% + \let\tikz@quick@prev@node\tikzgraphnodename% + \tikz@lib@graphs@quick@scan@after@connector% +} +\def\tikz@lib@graphs@quick@scan@after@connector{% + \pgfutil@ifnextchar\par{\expandafter\tikz@lib@graphs@quick@scan@after@connector\tikz@lib@graphs@quick@gobble@par}{% + \pgfutil@ifnextchar"{\expandafter\tikz@lib@graphs@quick@node\pgfutil@gobble}{% + \tikzerror{Quotation marks expected after edge connector}% + }% + }% +} + +\def\tikz@lib@graphs@quick@make@edge{% + { + \expandafter\tikz@lib@graphs@quick@make@edge@styling\expandafter{\tikz@lib@graphs@quick@edge@options}% + \expandafter\expandafter\expandafter\tikz@lib@graphs@quick@make@edge@for% + \expandafter\expandafter\expandafter{\expandafter\tikz@quick@prev@node\expandafter}\expandafter{\tikzgraphnodename}% + } +} + +\def\tikz@lib@graphs@quick@make@edge@styling#1{% + \tikz@enable@edge@quotes% + \tikzgraphsset{.unknown/.code=\tikz@lib@graph@unknown@edge@option{##1},#1}% +} + +\def\tikz@lib@graphs@quick@make@edge@for#1#2{% + \pgfkeysgetvalue{/tikz/graphs/@edges styling}\pgf@tempa + \pgfkeysgetvalue{/tikz/graphs/@edges node}\pgf@temp@b + \expandafter\expandafter\expandafter\tikz@lib@graphs@quick@make@edge@for@with% + \expandafter\expandafter\expandafter{\expandafter\pgf@tempa\expandafter}\expandafter{\pgf@temp@b}{#1}{#2}% +} + +\def\tikz@lib@graphs@quick@make@edge@for@with#1#2#3#4{% + \tikzgraphsset{new \tikz@lib@graphs@quick@edge@kind={#3}{#4}{#1}{#2}}% +} + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.standard.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.standard.code.tex new file mode 100644 index 00000000000..a56702bcf96 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.standard.code.tex @@ -0,0 +1,112 @@ +% Copyright 2010 by Till Tantau +% Copyright 2011 by Jannis Pohlmann +% +% This file may be distributed and/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 details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.standard.code.tex,v 1.9 2012/02/27 20:00:11 tantau Exp $ + + +% +% Basic graphs +% + + +\tikzgraphsset{ + % + % An independent set $V$ of nodes. + % + declare={subgraph I_n}% + { + \foreach \tikz@lib@graph@node@num in \tikzgraphV + { \tikz@lib@graph@node@num } + }, + % + % An two-shore independent set $V$ with shores V and W. + % + declare={subgraph I_nm}% + { + subgraph I_n [name shore V] -- [no edges] + subgraph I_n [name shore W, V/.expand once=\tikzgraphW] + }, + % + % The complete clique on $V$. + % + declare={subgraph K_n}% + { + [clique] + subgraph I_n + }, + % + % A complete bipartite graph with shores V and W. + % + declare={subgraph K_nm}% + { + [color class=shore V, + color class=shore W, + complete bipartite={shore V}{shore W}] + subgraph I_n [name shore V, shore V] -- [no edges] + subgraph I_n [name shore W, V/.expand once=\tikzgraphW, shore W] + }, + % + % A cycle with n nodes. + % + declare={subgraph C_n}% + { + [cycle] + subgraph I_n + }, + % + % A path with n nodes. + % + declare={subgraph P_n}% + { + [path] + subgraph I_n + }, + % + % A grid with n nodes. + % + declare={subgraph Grid_n}% + { + [grid] + subgraph I_n + }, + % + % A random graph according to the G_{n,p} model: For each pair of + % vertices there is an edge between them with probability p. + % + p/.initial=0.5, + declare={subgraph G_np}% + { + [/utils/exec={ + \pgfmathsetmacro\tikz@lib@lg@p{\pgfkeysvalueof{/tikz/graphs/p}} + \let\tikz@lib@gnp@edges\pgfutil@empty% + \foreach \tikz@lib@graph@node@a [count=\tikz@lib@g@count@a] in \tikzgraphV + \foreach \tikz@lib@graph@node@b [count=\tikz@lib@g@count@b] in \tikzgraphV + { + \ifnum\tikz@lib@g@count@a<\tikz@lib@g@count@b\relax + \pgfmathparse{rnd} + \ifdim\pgfmathresult pt<\tikz@lib@lg@p pt% + \ifx\tikz@lib@gnp@edges\pgfutil@empty + \xdef\tikz@lib@gnp@edges{\tikz@lib@graph@node@a--\tikz@lib@graph@node@b}% + \else + \xdef\tikz@lib@gnp@edges{\tikz@lib@gnp@edges,\tikz@lib@graph@node@a--\tikz@lib@graph@node@b}% + \fi + \fi + \fi + } + }] + \foreach \tikz@lg@temp in \tikz@lib@gnp@edges { + [parse/.expand once=\tikz@lg@temp] + } + }, +} + + + + diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzexternalshared.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzexternalshared.code.tex index 8c22215eda4..fc01637466b 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzexternalshared.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzexternalshared.code.tex @@ -26,8 +26,8 @@ \toksdef\t@tikzexternal@tmpa=0 \toksdef\t@tikzexternal@tmpb=1 -\newwrite\tikzexternal@outfile \newif\iftikzexternal@nestedflag +\newif\iftikzexternal@verboseuptodate \newif\iftikzexternal@verboseio \newif\iftikzexternal@genfigurelist \newif\iftikzexternal@onlynamed @@ -112,6 +112,9 @@ \pgfqkeys{/tikz/external}{ figure list/.is if=tikzexternal@genfigurelist, aux in dpth/.style={/pgf/images/aux in dpth=#1},% + disable dependency files/.code={% + \let\tikzexternalfiledependsonfile@ACTIVE=\tikzexternalfiledependsonfile + }, % 'mode' applies only if \jobname==real job name. mode/.is choice, mode/only graphics/.code = {% @@ -148,9 +151,11 @@ verbose IO/.default=true, verbose IO=true, verbose optimize/.is if=tikzexternal@verbose@optimize, + verbose up to date/.is if=tikzexternal@verboseuptodate, verbose/.style={ verbose IO=#1, verbose optimize=#1, + verbose up to date=#1, }, shell escape/.initial=-shell-escape, read main aux/.is if=pgfexternalreadmainaux, @@ -249,6 +254,12 @@ \expandafter\gdef\csname c@tikzext@no@#1\endcsname{0}% },% prefix/.code={\tikzsetexternalprefix{#1}}, + up to date check/.is choice, + up to date check/simple/.code={\def\tikzexternal@uptodate@mode{0}}, + % md5 relies on \pdfmdfivesum of pdftex. It uses 'diff' as fallback if we do not have that command. + up to date check/md5/.code={\def\tikzexternal@uptodate@mode{1}}, + up to date check/diff/.code={\def\tikzexternal@uptodate@mode{2}}, + up to date check=md5, } \def\tikzsetfigurename#1{\pgfkeyssetvalue{/tikz/external/figure name}{#1}}% @@ -325,6 +336,14 @@ } \def\tikzexternalize@hasbeencalled{0}% +\def\tikzifexternalizehasbeencalled#1#2{% + \if1\tikzexternalize@hasbeencalled + #1% + \else + #2% + \fi +}% + % If mode=`convert with system call', the boolean \ifpgfexternalreadmainaux % will be set depending on the current lock file. % @@ -710,6 +729,7 @@ \def\tikzexternalgetnextfilename#1{% \begingroup \let\tikzexternal@getnextfilename@advancecount\relax% NOP + \let\tikzexternal@getnextfilename@resetglobals=\relax% NOP \def\tikzexternal@protocol@to@file##1{}% NOP \tikzexternal@getnextfilename#1% \pgfmath@smuggleone#1% @@ -774,11 +794,15 @@ \fi \fi % + \tikzexternal@getnextfilename@resetglobals% + % + \tikzexternal@protocol@to@file#1% +}% + +\def\tikzexternal@getnextfilename@resetglobals{% % Reset global flags: \global\let\tikzexternal@nextfile=\pgfutil@empty \global\tikzexternalexportnexttrue - % - \tikzexternal@protocol@to@file#1% }% % #1: the image file name which should be protocolled. (can be a @@ -792,6 +816,11 @@ \else \pgfutil@ifundefined{tikzexternal@listmode@openedfile}{% \message{Opening '\tikzexternal@realjob.figlist' for writing.}% + \begingroup + \globaldefs=1 + % this gets round '\outer\newwrite' in plain TeX: + \csname newwrite\endcsname\tikzexternal@outfile + \endgroup \immediate\openout\tikzexternal@outfile=\tikzexternal@realjob.figlist\relax \gdef\tikzexternal@listmode@openedfile{1}% \if\tikzexternal@opmode5% mode='list and make' @@ -812,6 +841,9 @@ \def\tikzexternal@list@and@make@gentarget#1{% \tikzexternal@assemble@systemcall{#1}{\pgf@tempa}% + \def\tikzexternal@tempb{\pgfutilstrreplace{^^J}{^^J\tikzexternal@TABchar}}% + \expandafter\tikzexternal@tempb\expandafter{\pgf@tempa}% + \let\pgf@tempa=\pgfretval \iftikzexternal@verboseio \immediate\write16{Writing '#1' to '\tikzexternal@realjob.makefile'.}% \fi @@ -856,6 +888,7 @@ \def\tikzexternalmakefiledefaultdeprule{% \immediate\write\tikzexternal@outmakefile{\tikzexternal@PERCENTchar.\tikzexternaldepext:}% + \immediate\write\tikzexternal@outmakefile{\tikzexternal@TABchar mkdir -p $(dir $@)}% \immediate\write\tikzexternal@outmakefile{\tikzexternal@TABchar touch $@ \tikzexternal@HASHchar\space will be filled later.}% }% @@ -868,14 +901,16 @@ % Will write something to the make file. If the makefile is not yet % opened, #1 will be written as soon as it *is* opened. \def\tikzexternalwritetomakefile#1{% - \pgfutil@ifundefined{tikzexternal@outmakefile}{% - \expandafter\gdef\expandafter\tikzexternal@outmakefile@pendingcommands\expandafter{% - \tikzexternal@outmakefile@pendingcommands + \if\tikzexternal@opmode5% mode='list and make' + \pgfutil@ifundefined{tikzexternal@outmakefile}{% + \expandafter\gdef\expandafter\tikzexternal@outmakefile@pendingcommands\expandafter{% + \tikzexternal@outmakefile@pendingcommands + \immediate\write\tikzexternal@outmakefile{#1}% + }% + }{% \immediate\write\tikzexternal@outmakefile{#1}% }% - }{% - \immediate\write\tikzexternal@outmakefile{#1}% - }% + \fi }% \def\tikzexternal@dep@file@name{} @@ -896,33 +931,67 @@ % could be auto-generated: empty file name means "picture % won't be externalized". Skip it. \else - \edef\tikzpicturedependsonfile@name{#1.\tikzexternaldepext}% - \ifx\tikzexternal@dep@file@name\tikzpicturedependsonfile@name - % file is open and ready. - \else - % create new output file. - \pgfutil@ifundefined{tikzexternal@dep@file}{% - \begingroup - % this makes \tikzexternal@dep@file global: - \globaldefs=1 - % this gets round '\outer\newwrite' in plain TeX: - \csname newwrite\endcsname\tikzexternal@dep@file - \endgroup - }{}% - \ifx\tikzexternal@dep@file@name\pgfutil@empty - \else - % it is already open. Close it. - \immediate\closeout\tikzexternal@dep@file - \fi - \global\let\tikzexternal@dep@file@name=\tikzpicturedependsonfile@name - \immediate\openout\tikzexternal@dep@file=\tikzexternal@dep@file@name\relax - \fi - \immediate\write\tikzexternal@dep@file{#1\tikzexternalimgextension: #2}% + % if we encounter any dependencies while we externalize a + % picture, we have to write these things into the image's .dep + % file. + \tikzifexternalizingcurrent + {\tikzexternalfiledependsonfile@append@to@dep@file{#1}{#2}}% + {\tikzexternalfiledependsonfile@append@to@makefile{#1}{#2}}% \fi \endgroup }% \def\tikzexternalfiledependsonfile#1#2{}% NO-OP until \tikzexternalize has been called. +% sub-routine of \tikzexternalfiledependsonfile which appends stuff to +% the pictures .dep file. +% +% The file #1.dep is generated during the externalization of #1. If +% you change and/or overwrite it in any other context, its information +% might get lost (because #1 won't be regenerated). +% +% Consequently, this here has to be called if and only if #1 is about +% to be externalized. +\def\tikzexternalfiledependsonfile@append@to@dep@file#1#2{% + % write every dependency which is defined *INSIDE* of the current + % picture into the .dep file of the current picture: + \tikzexternalgetcurrentfilename\tikzpicturedependsonfile@name + \edef\tikzpicturedependsonfile@name{\tikzpicturedependsonfile@name.\tikzexternaldepext}% + %\edef\tikzpicturedependsonfile@name{#1.\tikzexternaldepext}% + \ifx\tikzexternal@dep@file@name\tikzpicturedependsonfile@name + % file is open and ready. + \else + % create new output file. + \pgfutil@ifundefined{tikzexternal@dep@file}{% + \begingroup + % this makes \tikzexternal@dep@file global: + \globaldefs=1 + % this gets round '\outer\newwrite' in plain TeX: + \csname newwrite\endcsname\tikzexternal@dep@file + \endgroup + }{}% + \ifx\tikzexternal@dep@file@name\pgfutil@empty + \else + % it is already open. Close it. + \immediate\closeout\tikzexternal@dep@file + \fi + \global\let\tikzexternal@dep@file@name=\tikzpicturedependsonfile@name + \immediate\openout\tikzexternal@dep@file=\tikzexternal@dep@file@name\relax + \fi + \immediate\write\tikzexternal@dep@file{#1\tikzexternalimgextension: #2}% +} + +% sub-routine of \tikzexternalfiledependsonfile which appends stuff to +% the makefile of the current \jobname . +% +% This is used for dependencies which are recomputed by every run of +% tex; we must not write them into #1.dep (for reasons explained in +% the documentation of +% \tikzexternalfiledependsonfile@append@to@dep@file) +\def\tikzexternalfiledependsonfile@append@to@makefile#1#2{% + \edef\tikzexternal@temp{#1\tikzexternalimgextension: #2}% + \expandafter\tikzexternalwritetomakefile\expandafter{\tikzexternal@temp}% +} + % Adds a dependency for the NEXT picture which is about to be % externalized. If we are currently inside of a picture, the % dependency is added for this current picture. @@ -1064,7 +1133,7 @@ }% \long\def\tikzexternal@optimize@away@latex@env@close#1{% \iftikzexternal@verbose@optimize - \immediate\write16{The complete contents of \string\begin{tikzexternal@optimize@away@latex@env@} up to the next \end{tikzexternal@optimize@away@latex@env@} has been optimized away because it does not contribute to exported PDF. Use '/tikz/external/optimize=false' to disable this.}% + \immediate\write16{The complete contents of \string\begin{tikzexternal@optimize@away@latex@env@} up to the next \end{tikzexternal@optimize@away@latex@env@} has been optimized away because it does not contribute to the exported PDF. Use '/tikz/external/optimize=false' to disable this.}% \fi \endgroup % we still need to invoke \end{<name>} in latex because \begin{<name>} @@ -1104,6 +1173,7 @@ \immediate\write16{A tikzpicture has been optimized away. Use '/tikz/external/optimize=false' to disable this.}% \fi \tikzexternal@closeenvironments + \pgfkeysvalueof{/tikz/external/optimize away text/.@cmd}tikzpicture\pgfeov% } % Processes tikzpicture normally; without any externalization. @@ -1142,17 +1212,32 @@ \def\tikzexternal@forcegraphics{% \tikzexternal@TEXDIALECT@collectpicture\tikzexternal@forcegraphics@@ } -\long\def\tikzexternal@forcegraphics@@#1{% +\long\def\tikzexternal@forcegraphics@@#1{\tikzexternal@forcegraphics@@@}% +\def\tikzexternal@forcegraphics@@@{% + \if5\tikzexternal@opmode + \let\tikz@refundefinedtrue@@=\G@refundefinedtrue + \gdef\G@refundefinedtrue{% + \tikz@refundefinedtrue@@ + \tikzexternal@forceremake@undefined@reference@handler + }% + \fi \expandafter\pgfincludeexternalgraphics\expandafter{\tikzexternal@curfilename}% + \global\let\G@refundefinedtrue=\tikz@refundefinedtrue@@ \tikzexternal@closeenvironments } +\def\tikzexternal@forceremake@undefined@reference@handler{% + \immediate\write16{===== 'mode=list and make': encountered undefined reference in current picture. Adding dependency to FORCEREMAKE. Rerun make to update the picture.' ========^^J}% + \tikzpicturedependsonfile{FORCEREMAKE}% +}% + % Simply replaces the complete picture by some placeholder text. % It is used by 'mode=list only' to reduce runtime. \def\tikzexternal@listmodepicture{% \tikzexternal@TEXDIALECT@collectpicture\tikzexternal@listmodepicture@@ } -\long\def\tikzexternal@listmodepicture@@#1{% +\long\def\tikzexternal@listmodepicture@@#1{\tikzexternal@listmodepicture@@@} +\def\tikzexternal@listmodepicture@@@{% \pgfkeysvalueof{/tikz/external/image discarded text}% \tikzexternal@closeenvironments } @@ -1160,15 +1245,21 @@ % check if there is already a file. % In that case, use it. If not, skip it. \def\tikzexternal@list@and@makefile@mode@picture{% + \tikzexternal@TEXDIALECT@collectpicture\tikzexternal@list@and@makefile@mode@picture@ +}% +\long\def\tikzexternal@list@and@makefile@mode@picture@#1{% + % + \tikzexternal@check@uptodate@mode{#1}% + % \gdef\pgf@filename{}% \xdef\pgf@tempa{\noexpand\pgf@findfile\pgfsys@imagesuffixlist:+{\tikzexternal@curfilename}}% \pgf@tempa \ifx\pgf@filename\pgfutil@empty% % Note: since we have no 'GRAB' mode, we do not have to deal with optimization. % there is no graphics. - \expandafter\tikzexternal@listmodepicture + \expandafter\tikzexternal@listmodepicture@@@ \else - \expandafter\tikzexternal@forcegraphics + \expandafter\tikzexternal@forcegraphics@@@ \fi }% @@ -1193,6 +1284,9 @@ \def\endtikzpicture{% \tikzexternal@origendpicture \pgf@externalend + % + \tikzexternal@ensure@nonempty@floats + % \let\tikzpicture=\tikzexternal@tikzpicture@replacement \let\endtikzpicture=\tikzexternal@origendpicture \iftikzexternal@optimize @@ -1204,6 +1298,21 @@ \tikzpicture }% +% If a sequence of floats containing JUST tikzpictures is +% externalized, this results in EMPTY floats. Empty floats, in turn, +% can confuse latex; it thinks it did something wrong. +% +% Solution: Avoid empty floats by writing junk into it. +% +% Note that this method is only invoked if \ifpgf@external@grabshipout +% is true and if the text is OUTSIDE of the original shipout routine. +% In other words: this text is being thrown away. +% +% see +% http://tex.stackexchange.com/questions/54625/why-is-fixltx2e-incompatible-with-tikzexternalize +\def\tikzexternal@ensure@nonempty@floats{% + tikzexternal: picture has been externalized. This text is required to avoid empty floats. +}% % 1. Discards the current picture in this document. % 2. Checks whether an image exists already. If that is the case: acquire it. @@ -1270,7 +1379,7 @@ \endgroup }% \long\def\tikzexternal@externalizefig@systemcall@@#1{% - \tikzexternal@externalizefig@systemcall@uptodatecheck% + \tikzexternal@externalizefig@systemcall@uptodatecheck{#1}% \iftikzexternal@file@isuptodate \iftikzexternal@verboseio \immediate\write16{===== Image '\tikzexternal@curfilename' is up-to-date. ======}% @@ -1337,6 +1446,124 @@ \fi } +\pgfutil@IfUndefined{pdfmdfivesum}{% +}{% + % predefine to this value. This does only make sense for pdftex. + % note that the latex library for 'external' loads \usepackage{pdftexcmds} which \let's this to \pdf@mdfivesum: + \let\tikzexternal@mdfivesum=\pdfmdfivesum +}% + +\long\def\tikzexternal@computemdfivesum#1{% + \t@tikzexternal@tmpb={#1}% + \edef\tikzexternal@temp{\the\t@tikzexternal@tmpb}% + % \meaning results in a string of catcode 12 - which is expandable. + \edef\pgfretval{\tikzexternal@mdfivesum{\meaning\tikzexternal@temp}}% +} +\long\def\tikzexternal@computemdfivesum@diff@fallback#1{% + \t@tikzexternal@tmpb={#1}% + \edef\tikzexternal@temp{\the\t@tikzexternal@tmpb}% + % \meaning results in a string of catcode 12 - which is expandable. + \edef\pgfretval{\meaning\tikzexternal@temp}% +} + +% Will be set dynamically, depending on 'up to date check'. +% +% It expands to code such that \tikzexternallastkey contains the +% serialized version of '#1'. +% +% It is used as argument for \write{..} +% +% #1 the hash key to serialize. +% \def\tikzexternal@hashfct@serialize +\long\def\tikzexternal@hashfct@serialize@std#1{% + \noexpand\def\noexpand\tikzexternallastkey{#1}% +}% + +% serializes using temporary token registers. Necessary if #1 contains +% executable code. +\long\def\tikzexternal@hashfct@serialize@tok#1{% + \noexpand\begingroup + % in order to allow '#' inside of the body, we have to use token registers: + \noexpand\toks0={#1}% + \noexpand\xdef\noexpand\tikzexternallastkey{\noexpand\the\noexpand\toks0 }% + \noexpand\endgroup +}% + +\def\tikzexternal@check@uptodate@ext{.md5} + +\def\tikzexternal@check@uptodate@mode@warn@fallback{% + \message{! Package tikz Warning: The key 'up to date check=md5' is impossible, there is no macro to compute MD5. Falling back to 'up to date check=diff'.}% + % + % warn only once: + \global\let\tikzexternal@check@uptodate@mode@warn@fallback=\relax +}% + +% assigns the boolean \iftikzexternal@file@isuptodate +\long\def\tikzexternal@check@uptodate@mode#1{% + \if1\tikzexternal@uptodate@mode + % up to date check=md5: + % check if we CAN compute MD5 sums: + \pgfutil@IfUndefined{tikzexternal@mdfivesum}{% + % we cannot compute md5 sums - fallback to diff. + \tikzexternal@check@uptodate@mode@warn@fallback + \def\tikzexternal@uptodate@mode{2}% + }{}% + \fi + % + \ifcase\tikzexternal@uptodate@mode + % up to date check=simple + % nothing to do -- file existance is checked anyway. + \let\tikzexternal@hashfct=\pgfutil@empty + \let\tikzexternal@hashfct@serialize=\pgfutil@empty + \or + % up to date check=md5 + \let\tikzexternal@hashfct=\tikzexternal@computemdfivesum + \let\tikzexternal@hashfct@serialize=\tikzexternal@hashfct@serialize@std + \or + \let\tikzexternal@hashfct=\tikzexternal@computemdfivesum@diff@fallback + \let\tikzexternal@hashfct@serialize=\tikzexternal@hashfct@serialize@tok + \fi + \ifx\tikzexternal@hashfct\pgfutil@empty + \else + \tikzpicturedependsonfile{\tikzexternal@curfilename\tikzexternal@check@uptodate@ext}% + \tikzexternal@hashfct{#1}% + \let\tikzexternal@lastkey@new=\pgfretval + \begingroup + % no '@' token in this macro: avoid messing up the catcodes in input files: + \global\let\tikzexternallastkey=\pgfutil@empty + \openin\r@pgf@reada=\tikzexternal@curfilename\tikzexternal@check@uptodate@ext\relax % + \ifeof\r@pgf@reada + \else + % read first line... + \endlinechar=-1 % older versions did not have a '%' at the end-of-line. Avoid spurious spaces. + \read\r@pgf@reada to\pgf@tempa + % ... and execute it. + \pgf@tempa + % it should contain a definition of \tikzexternallastkey. + \fi + \closein\r@pgf@reada + % + \let\tikzexternal@lastkey=\tikzexternallastkey + \pgfmath@smuggleone\tikzexternal@lastkey + \endgroup + % normalize catcodes. Unfortunately, they cannot be expected to be the same. + % \meaning will use catcode 12 for each token: + \edef\tikzexternal@lastkey@normalized{\meaning\tikzexternal@lastkey}% + \edef\tikzexternal@lastkey@new@normalized{\meaning\tikzexternal@lastkey@new}% + \iftikzexternal@verboseuptodate + \immediate\write16{Up-to-date check of \tikzexternal@curfilename: new \tikzexternal@lastkey@new@normalized; old \tikzexternal@lastkey@normalized.^^J}% + \fi + \ifx\tikzexternal@lastkey@normalized\tikzexternal@lastkey@new@normalized + \tikzexternal@file@isuptodatetrue + \else + \tikzexternal@file@isuptodatefalse + \immediate\openout\w@pgf@writea=\tikzexternal@curfilename\tikzexternal@check@uptodate@ext\relax% + \immediate\write\w@pgf@writea{\tikzexternal@hashfct@serialize{\tikzexternal@lastkey@new}\tikzexternal@PERCENTchar}% + \immediate\closeout\w@pgf@writea + \fi + \fi +} + % Checks whether the current picture needs to be externalized. % % This is the case if @@ -1344,9 +1571,13 @@ % b) the picture has been invalidated manually. % % It returns \iftikzexternal@file@isuptodate accordingly. -\def\tikzexternal@externalizefig@systemcall@uptodatecheck{% +% #1: the picture-content +\long\def\tikzexternal@externalizefig@systemcall@uptodatecheck#1{% \tikzexternal@checkforceremake \iftikzexternal@file@isuptodate + \tikzexternal@check@uptodate@mode{#1}% + \fi + \iftikzexternal@file@isuptodate % check if there is already a file. % In that case, use it. If that is not the case, generate it and include it afterwards. \gdef\pgf@filename{}% @@ -1365,7 +1596,7 @@ \xdef\pgf@tempa{\noexpand\pgf@findfile\pgfsys@imagesuffixlist:+{\tikzexternal@curfilename}}% \pgf@tempa \ifx\pgf@filename\pgfutil@empty% - \PackageError{tikz}{Sorry, the system call '#1' did NOT result in a usable output file '\tikzexternal@curfilename' (expected one of \pgfsys@imagesuffixlist). Please verify that you have enabled system calls. For pdflatex, this is 'pdflatex -shell-escape'. Sometimes it is also named 'write 18' or something like that. Or maybe the command simply failed? Error messages can be found in '\tikzexternal@curfilename.log'. If you continue now, I'll try to typeset the picture}% + \tikzerror{Sorry, the system call '#1' did NOT result in a usable output file '\tikzexternal@curfilename' (expected one of \pgfsys@imagesuffixlist). Please verify that you have enabled system calls. For pdflatex, this is 'pdflatex -shell-escape'. Sometimes it is also named 'write 18' or something like that. Or maybe the command simply failed? Error messages can be found in '\tikzexternal@curfilename.log'. If you continue now, I'll try to typeset the picture}{}% \fi }% @@ -1375,18 +1606,18 @@ \begingroup \tikzexternal@assemble@systemcall{\pgfactualjobname}{\pgf@tempa}% \toks0=\expandafter{\pgf@tempa}% - \PackageError{tikz}{Sorry, image externalization failed: the resulting image was EMPTY. I tried to externalize '\pgfactualjobname', but it seems there is no such image in the document!? + \tikzerror{Sorry, image externalization failed: the resulting image was EMPTY. I tried to externalize '\pgfactualjobname', but it seems there is no such image in the document!? \if\tikzexternal@opmode4 ^^J \space\space You are currently using 'mode=convert with system call'. This problem can happen if the image (or one of the images preceeding it) was declared inside of a \string\label{} (i.e. in the .aux file): 'convert with system call' has no access to the main aux file.^^J \space\space Possible solutions in this case:^^J -\space\space a) Try using 'mode=list and make',^^J -\space\space b) Issue the externalization command '\the\toks0' *manually* (also check the preceeding externalized images, perhaps the file name sequence is not correct).^^J +\space\space (a) Try using 'mode=list and make',^^J +\space\space (b) Issue the externalization command '\the\toks0' *manually* (also check the preceeding externalized images, perhaps the file name sequence is not correct).^^J \space\space Repeat: the resulting image was EMPTY, your attention is required \else \if\tikzexternal@opmode5 ^^J \space\space You are currently using 'mode=list and make'. Possible solutions:^^J -\space\space a) Try to delete `\tikzexternal@realjob.makefile'. Perhaps it is not up-to-date.^^J -\space\space b) Perhaps pictures are declared inside of \string\label{} and the .aux file is not up-to-date. Re-run latex, perhaps re-generate the graphics as well.^^J +\space\space (a) Try to delete `\tikzexternal@realjob.makefile'. Perhaps it is not up-to-date.^^J +\space\space (b) Perhaps pictures are declared inside of \string\label{} and the .aux file is not up-to-date. Re-run latex, perhaps re-generate the graphics as well.^^J \space\space Repeat: the resulting image was EMPTY, your attention is required \fi \fi}% diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary3d.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary3d.code.tex index 3d2cecc732f..c6c998e4b6a 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary3d.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary3d.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary3d.code.tex,v 1.1 2008/01/09 17:57:15 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary3d.code.tex,v 1.2 2013/07/17 10:36:34 tantau Exp $ @@ -16,13 +16,13 @@ \tikzdeclarecoordinatesystem{xyz cylindrical} {% \pgfset{/tikz/cs/.cd,angle=0,radius=0,z=0,#1}% - \pgfpointcylindrical{\tikz@cs@angle}{\tikz@cs@radius}{\tikz@cs@z}% + \pgfpointcylindrical{\tikz@cs@angle}{\tikz@cs@xradius}{\tikz@cs@z}% } \tikzdeclarecoordinatesystem{xyz spherical} {% \pgfset{/tikz/cs/.cd,angle=0,radius=0,latitude=0,longitude=0,#1}% - \pgfpointspherical{\tikz@cs@angle}{\tikz@cs@latitude}{\tikz@cs@radius}% + \pgfpointspherical{\tikz@cs@angle}{\tikz@cs@latitude}{\tikz@cs@xradius}% } \pgfset{/tikz/cs/longitude/.store in=\tikz@cs@angle} diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryangles.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryangles.code.tex new file mode 100644 index 00000000000..2ac3ebc7b22 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryangles.code.tex @@ -0,0 +1,72 @@ +% Copyright 2013 by Till Tantau +% +% This file may be distributed and/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 details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryangles.code.tex,v 1.1 2013/08/28 15:24:27 tantau Exp $ + + +\tikzset{ + pics/angle/.style = { + setup code = \tikz@lib@angle@parse#1\pgf@stop, + background code = \tikz@lib@angle@background#1\pgf@stop, + foreground code = \tikz@lib@angle@foreground#1\pgf@stop, + }, + pics/angle/.default=A--B--C, + angle eccentricity/.initial=.6, + angle radius/.initial=5mm +} + +\def\tikz@lib@angle@background#1--#2--#3\pgf@stop{% + \path [name prefix ..] [pic actions, draw=none] (#2.center) + -- ++(\tikz@start@angle@temp:\tikz@lib@angle@rad pt) + arc [start angle=\tikz@start@angle@temp, end + angle=\tikz@end@angle@temp, radius=\tikz@lib@angle@rad pt] -- cycle; +} + +\def\tikz@lib@angle@foreground#1--#2--#3\pgf@stop{% + \path [name prefix ..] [pic actions, fill=none, shade=none] + ([shift={(\tikz@start@angle@temp:\tikz@lib@angle@rad pt)}]#2.center) + arc [start angle=\tikz@start@angle@temp, end + angle=\tikz@end@angle@temp, radius=\tikz@lib@angle@rad pt]; + \ifx\tikzpictext\relax\else% + \def\pgf@temp{\node()[name prefix + ..,at={([shift={({.5*\tikz@start@angle@temp+.5*\tikz@end@angle@temp}:\pgfkeysvalueof{/tikz/angle + eccentricity}*\tikz@lib@angle@rad pt)}]#2.center)}]} + \expandafter\pgf@temp\expandafter[\tikzpictextoptions]{\tikzpictext};% + \fi +} + + +\def\tikz@lib@angle@parse#1--#2--#3\pgf@stop{% + % Compute radius: + \pgfmathsetmacro\tikz@lib@angle@rad{\pgfkeysvalueof{/tikz/angle radius}} + \ifdim\tikz@lib@angle@rad pt>0pt\else\def\tikz@lib@angle@rad{12}\fi% + % Compute first coordinate: + \pgf@process{\pgfpointanchor{#2}{center}}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{\pgfpointanchor{#1}{center}}% + \pgf@xb=\pgf@x% + \pgf@yb=\pgf@y% + \pgf@process{\pgfpointanchor{#3}{center}}% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \advance\pgf@xb by-\pgf@xa% + \advance\pgf@yb by-\pgf@ya% + \advance\pgf@xc by-\pgf@xa% + \advance\pgf@yc by-\pgf@ya% + \pgfmathsetmacro{\tikz@start@angle@temp}{atan2(\the\pgf@yb,\the\pgf@xb)} + \pgfmathsetmacro{\tikz@end@angle@temp}{atan2(\the\pgf@yc,\the\pgf@xc)} + \ifdim\tikz@end@angle@temp pt<\tikz@start@angle@temp pt% + \pgfmathsetmacro{\tikz@start@angle@temp}{\tikz@start@angle@temp-360}% + \fi% +} + + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybabel.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybabel.code.tex new file mode 100644 index 00000000000..37b5ae20231 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybabel.code.tex @@ -0,0 +1,17 @@ +% Copyright 2013 by Till Tantau +% +% This file may be distributed and/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 details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybabel.code.tex,v 1.1 2013/06/24 11:49:06 tantau Exp $ + +\tikzset{ + handle active characters in code, + handle active characters in nodes +} + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex index cd68855bbab..6302b629ae4 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex,v 1.2 2010/02/08 11:21:46 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex,v 1.3 2013/07/18 17:07:38 tantau Exp $ % Layers @@ -18,8 +18,14 @@ % Switch command \tikzset{on background layer/.style={ - execute at begin scope={\pgfonlayer{background}}, - execute at end scope={\endpgfonlayer}}} + execute at begin scope={% + \pgfonlayer{background}% + \let\tikz@options=\pgfutil@empty% + \tikzset{every on background layer/.try,#1}% + \tikz@options}, + execute at end scope={\endpgfonlayer} + } +} % Main style diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybending.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybending.code.tex new file mode 100644 index 00000000000..42a410ce4f5 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybending.code.tex @@ -0,0 +1,15 @@ +% Copyright 2013 by Till Tantau +% +% This file may be distributed and/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 details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybending.code.tex,v 1.2 2013/09/17 22:00:21 tantau Exp $ + +\usepgfmodule{bending} +\tikzset{arrows=[flex]} + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalc.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalc.code.tex index 1a0ea356c24..703494d2a64 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalc.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalc.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalc.code.tex,v 1.6 2009/09/04 17:22:59 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalc.code.tex,v 1.9 2013/07/15 12:05:31 tantau Exp $ % % @@ -48,7 +48,7 @@ \pgfutil@ifnextchar\n{% \tikz@cc@handle@num% }{% - \PackageError{tikz}{``\string\p'' or ``\string\n'' expected}{}% + \tikzerror{``\string\p'' or ``\string\n'' expected}% }% }% } @@ -112,7 +112,7 @@ \pgfutil@ifnextchar-{% \tikz@cc@sub% }{% - \PackageError{tikz}{+ or - expected}{}% + \tikzerror{+ or - expected}% \tikz@cc@end$%$ }% }% @@ -177,24 +177,52 @@ % A coordinate can be followed by !...!(...) % -\def\tikz@cc@mid@checks{ +\def\tikz@cc@mid@checks{% + \ifnum\the\catcode`\!=\active\relax + \expandafter\tikz@cc@mid@checks@active + \else + \expandafter\tikz@cc@mid@checks@nonactive + \fi} + +\def\tikz@cc@mid@checks@nonactive{% \pgfutil@ifnextchar!{% - \tikz@cc@mid% + \tikz@cc@mid@nonactive% }{% - \advance\pgf@xa by\tikz@cc@factor\pgf@xb% - \advance\pgf@ya by\tikz@cc@factor\pgf@yb% - \tikz@cc@parse% continue + \advance\pgf@xa by\tikz@cc@factor\pgf@xb + \advance\pgf@ya by\tikz@cc@factor\pgf@yb + \tikz@cc@parse% }% } -\def\tikz@cc@mid!{% +\def\tikz@cc@mid@nonactive!{% \pgfutil@ifnextchar({% \tikz@scan@one@point\tikz@cc@project% }{% - \tikz@cc@mid@num% + \tikz@cc@mid@num@nonactive% }% } +\begingroup + \catcode`\!=\active + \gdef\tikz@cc@mid@checks@active{% + \pgfutil@ifnextchar!{% + \tikz@cc@mid@active% + }{% + \advance\pgf@xa by\tikz@cc@factor\pgf@xb + \advance\pgf@ya by\tikz@cc@factor\pgf@yb + \tikz@cc@parse% + }% + } + + \gdef\tikz@cc@mid@active!{% + \pgfutil@ifnextchar({% + \tikz@scan@one@point\tikz@cc@project% + }{% + \tikz@cc@mid@num@active% + }% + } +\endgroup + % % Partway case: (coord a)!number!(coord b) % @@ -202,7 +230,15 @@ % to b. This, (a)!0!(b) is (a), (a)!.5!(b) is the middle and (a)!1!(b) % is (b) % -\def\tikz@cc@mid@num#1!{% + +\def\tikz@cc@mid@num@nonactive#1!{\tikz@cc@mid@num{#1}} + +\begingroup + \catcode`\!=\active + \gdef\tikz@cc@mid@num@active#1!{\tikz@cc@mid@num{#1}} +\endgroup + +\def\tikz@cc@mid@num#1{% \pgfmathparse{#1}% \ifpgfmathunitsdeclared% \let\tikz@cc@mid@unit=\pgfmathresult% @@ -253,10 +289,27 @@ % Save in c \pgf@xc=\pgf@x% \pgf@yc=\pgf@y% - \expandafter\tikz@cc@scan@rot\expandafter\tikz@cc@after@project\tikz@cc@scan@ex% + \begingroup + \ifnum\the\catcode`\!=\active + \def\tikz@next{% + \endgroup + \expandafter\tikz@cc@scan@rot\expandafter\tikz@cc@after@project + \tikz@cc@scan@ex@active}% + \else + \def\tikz@next{% + \endgroup + \expandafter\tikz@cc@scan@rot\expandafter\tikz@cc@after@project + \tikz@cc@scan@ex@nonactive}% + \fi + \tikz@next% } -\def\tikz@cc@scan@ex!{} +\def\tikz@cc@scan@ex@nonactive!{} + +\begingroup + \catcode`\!=\active + \gdef\tikz@cc@scan@ex@active!{} +\endgroup \def\tikz@cc@after@project#1{% \pgf@process{#1}% @@ -284,16 +337,28 @@ \tikz@scan@one@point#1% normal }% { - \def\tikz@cc@scan@rot@cmd{#1} - \tikz@cc@scan@one@rot% + \def\tikz@cc@scan@rot@cmd{#1}% + \ifnum\the\catcode`\:=\active\relax + \expandafter\tikz@cc@scan@one@rot@active% + \else + \expandafter\tikz@cc@scan@one@rot@nonactive% + \fi }% } -\def\tikz@cc@scan@one@rot#1:{% +\def\tikz@cc@scan@one@rot@nonactive#1:{% \def\tikz@cc@scan@rot@angle{#1}% \tikz@scan@one@point\tikz@cc@handle@rot% } +\begingroup + \catcode`\:=\active + \gdef\tikz@cc@scan@one@rot@active#1:{% + \def\tikz@cc@scan@rot@angle{#1}% + \tikz@scan@one@point\tikz@cc@handle@rot% + } +\endgroup + \def\tikz@cc@handle@rot#1{% \pgf@process{#1}% % Ok, now we need to rotate x/y around xb/xb by ...rot@angle @@ -328,8 +393,8 @@ {% \tikzset{cs/.cd,#1}% \expandafter\ifx\csname tikz@tangent@\tikz@cs@type\endcsname\relax% - \PackageError{tikz}{I do not know how to compute the tangent to - a \tikz@cs@type}{}% + \tikzerror{I do not know how to compute the tangent to + a \tikz@cs@type}% \pgfpointorigin% \else% \expandafter\tikz@scan@one@point\expandafter\tikz@lib@do@tangent\tikz@cs@point% diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalendar.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalendar.code.tex index 09729059297..02b4f00bb6f 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalendar.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalendar.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalendar.code.tex,v 1.1 2008/01/09 17:57:15 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalendar.code.tex,v 1.3 2013/07/15 12:05:31 tantau Exp $ \pgfutil@usemodule{pgfcalendar} @@ -366,24 +366,24 @@ execute before day scope={\ifdate{day of month=1}{% } \def\tikz@lib@cal@scanner{% - \afterassignment\tikz@lib@cal@handle\let\@let@token=% + \afterassignment\tikz@lib@cal@handle\let\pgf@let@token=% } \def\tikz@lib@cal@handle{% \let\@next=\tikz@lib@cal@expand% - \ifx\@let@token;% + \ifx\pgf@let@token;% \let\@next=\tikz@lib@cal@stop% \else% - \ifx\@let@token(%) + \ifx\pgf@let@token(%) \let\@next=\tikz@lib@cal@name% \else% - \ifx\@let@token a% + \ifx\pgf@let@token a% \let\@next=\tikz@lib@cal@at% \else% - \ifx\@let@token[% + \ifx\pgf@let@token[% \let\@next=\tikz@lib@cal@option% \else% - \ifx\@let@token i% + \ifx\pgf@let@token i% \let\@next=\tikz@lib@cal@if% \fi% \fi% @@ -395,14 +395,14 @@ execute before day scope={\ifdate{day of month=1}{% \def\tikz@lib@cal@expand{% \advance\tikz@expandcount by -1% \ifnum\tikz@expandcount<0\relax% - \PackageError{tikz}{Giving up on this calendar}{}% + \tikzerror{Giving up on this calendar}% \let\@next=\tikz@lib@cal@end% \else% \let\@next=\tikz@lib@cal@@expand \fi% \@next} -\def\tikz@lib@cal@@expand{\expandafter\tikz@lib@cal@scanner\@let@token} +\def\tikz@lib@cal@@expand{\expandafter\tikz@lib@cal@scanner\pgf@let@token} \def\tikz@lib@cal@name#1){% diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarychains.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarychains.code.tex index 24019031a36..e2d12a0931a 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarychains.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarychains.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarychains.code.tex,v 1.5 2008/02/27 09:14:09 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarychains.code.tex,v 1.6 2013/07/15 12:05:31 tantau Exp $ \usetikzlibrary{positioning} @@ -29,7 +29,7 @@ \let\tikz@lib@current@chain=\tikz@lib@chain@name% \let\chainin=\tikz@lib@chainin% \else% - \PackageError{tikz}{Chain ``\tikz@lib@chain@name'' is already active}{}% + \tikzerror{Chain ``\tikz@lib@chain@name'' is already active}% \fi% }, continue chain/.default=, @@ -39,7 +39,7 @@ \let\tikz@lib@chain@name\tikz@lib@current@chain% \fi% \expandafter\ifx\csname tikz@lib@chain@exists@\tikz@lib@chain@name\endcsname\relax% - \PackageError{tikz}{Unknown chain ``#1''}{}% + \tikzerror{Unknown chain ``#1''}% \else% \let\tikz@lib@current@chain=\tikz@lib@chain@name% \expandafter\let\csname tikz@lib@chain@active@\tikz@lib@chain@name\endcsname=\pgfutil@empty% does not matter @@ -120,7 +120,7 @@ \let\tikz@lib@chain@name\tikz@lib@current@chain% \fi% \expandafter\ifx\csname tikz@lib@chain@exists@\tikz@lib@chain@name\endcsname\relax% - \PackageError{tikz}{Unknown chain ``\tikz@lib@chain@name''}{}% + \tikzerror{Unknown chain ``\tikz@lib@chain@name''}% \else% \c@pgf@counta\csname tikz@lib@chain@count@\tikz@lib@chain@name\endcsname\relax% \ifnum\c@pgf@counta=0\relax% diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.code.tex index 4ab723f711c..b27783b0009 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.code.tex @@ -55,14 +55,17 @@ \pgfdeclaremetadecoration{tikz@internal}{pre}{ \state{pre}[width=\pgfkeysvalueof{/pgf/decoration/pre length}, next state=main] { + \tikz@dec@trans \decoration{\pgfkeysvalueof{/pgf/decoration/pre}} } \state{main}[width=\pgfmetadecoratedremainingdistance-\pgfkeysvalueof{/pgf/decoration/post length}, next state=final] { + \tikz@dec@trans \decoration{\tikz@decoration@name} } \state{final} { + \tikz@dec@trans \decoration{\pgfkeysvalueof{/pgf/decoration/post}} } } @@ -87,12 +90,13 @@ % Now, we expect a brace. \pgfutil@ifnextchar\bgroup{% \begingroup% + \tikz@auto@end@pathfalse% \aftergroup\tikz@enddecoration% \afterassignment\tikz@scan@next@command% \let\tikz@lib@next% gobble \bgroup% }% {% - \PackageError{tikz}{A decoration must begin with a brace}{}% + \tikzerror{A decoration must begin with a brace}% \tikz@enddecoration% }% } @@ -103,8 +107,8 @@ {% \pgfifdecoration{\tikz@decoration@name}% {\tikz@lib@dec@startdecoration}% - {\PackageError{tikz}{Unknown (meta-)decoration '\tikz@decoration@name'. Perhaps you - misspelled it?}{}}% + {\tikzerror{Unknown (meta-)decoration '\tikz@decoration@name'. Perhaps you + misspelled it?}}% }% \ifx\pgfdecorateexistingpath\pgfutil@empty% \pgfpathmoveto{\pgfqpoint{\the\tikz@lastxsaved}{\the\tikz@lastysaved}}% @@ -147,8 +151,8 @@ \tikz@lib@dec@stopdecoration% } { - \PackageError{tikz}{Unknown (meta-)decoration '\tikz@decoration@name'. Perhaps - you misspelled it?}{} + \tikzerror{Unknown (meta-)decoration '\tikz@decoration@name'. Perhaps + you misspelled it?} } } \fi% diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.text.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.text.code.tex index e063ba185f0..b75fcc6a562 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.text.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.text.code.tex @@ -1,4 +1,4 @@ -% Copyright 2008 by Mark Wibrow +% Copyright 2013 by Mark Wibrow % % This file may be distributed and/or modified % @@ -10,4 +10,695 @@ \usetikzlibrary{decorations} \usepgflibrary{decorations.text} + +% Code for the `text effects along path' decoration + +% Some text constants +% To do: merge these with existing text constants +\def\tikz@lib@dec@te@space@text{space} +\def\tikz@lib@dec@align@left@text{left} +\def\tikz@lib@dec@align@right@text{right} +\def\tikz@lib@dec@align@center@text{center} +\def\tikz@lib@dec@te@none@text{none} + +% Some ifs +\newif\iftikz@lib@dec@te@pathfromtext +\newif\iftikz@lib@dec@te@segmentfromwidth +\newif\iftikz@lib@dec@te@scaletexttopath +\newif\iftikz@lib@dec@te@fittexttopath +\newif\iftikz@lib@dec@te@wordsep +\newif\iftikz@lib@dec@te@finalletter + + +% Utility macros +% To do: integrate with exisiting pgf macros +\def\tikz@lib@dec@te@addto@macro#1#2{% + \expandafter\def\expandafter#1\expandafter{#1#2}% +} + +\def\tikz@lib@dec@te@namelet#1#2{% + \expandafter\expandafter\expandafter\let\expandafter\expandafter\csname\expandafter#1\expandafter\endcsname\expandafter=\csname#2\endcsname% +} + +\def\tikz@lib@dec@te@advancecountmacro#1#2{% + \pgfutil@tempcnta=#1\relax% + \advance\pgfutil@tempcnta by#2\relax% + \edef#1{\the\pgfutil@tempcnta}% +} + +\def\tikz@lib@dec@te@advancedimenmacro#1#2{% + \pgf@x=#1\relax% + \advance\pgf@x by#2\relax% + \edef#1{\the\pgf@x}% +} + +% Macros for defining and updating text parameters +\def\tikz@lib@dec@te@start@parameters#1{% + \expandafter\let\csname tikz@lib@dec@te@character@#1\endcsname=\pgfutil@empty% +} + +\def\tikz@lib@dec@te@addto@parameters#1#2{% + \expandafter\tikz@lib@dec@te@addto@macro\expandafter% + {\csname tikz@lib@dec@te@character@#1\endcsname}{#2}% +} +\def\tikz@lib@dec@te@addmacroto@parameters#1#2{% + \def\tikz@lib@dec@te@marshal{\expandafter\tikz@lib@dec@te@addto@macro\expandafter% + {\csname tikz@lib@dec@te@character@#1\endcsname}}% + \expandafter\tikz@lib@dec@te@marshal\expandafter{\expandafter\def\expandafter#2\expandafter{#2}}% +} + +\def\tikz@lib@dec@te@getparameters#1{\csname tikz@lib@dec@te@character@#1\endcsname} + + + +\let\tikz@lib@dec@te@textoptions=\pgfutil@empty +\let\tikz@lib@dec@te@widthoptions=\pgfutil@empty +\let\tikz@lib@dec@te@charactercountvar=\pgfutil@empty +\let\tikz@lib@dec@te@charactertotalvar=\pgfutil@empty +\let\tikz@lib@dec@te@lettercountvar=\pgfutil@empty +\let\tikz@lib@dec@te@lettertotalvar=\pgfutil@empty +\let\tikz@lib@dec@te@wordcountvar=\pgfutil@empty +\let\tikz@lib@dec@te@wordctotalvar=\pgfutil@empty +\let\tikz@lib@dec@te@transformtext=\pgfutil@empty% + + +% Keys... lots of them... +\pgfkeys{/pgf/decoration/text effects/.cd, + .unknown/.code={\let\tikz@lib@dec@te@key@tmp=\pgfkeyscurrentname% + \pgfkeysalso{/tikz/\tikz@lib@dec@te@key@tmp={#1}}}, + path from text/.is if=tikz@lib@dec@te@pathfromtext, + path from text angle/.store in=\tikz@lib@dec@te@pathfromtextangle, + path from text angle=0, + fit text to path/.is if=tikz@lib@dec@te@fittexttopath, + characters/.style={/pgf/decoration/text effects/every character/.style={#1}}, + characters/.append/.code={\pgfkeysalso{/pgf/decoration/text effects/every character/.append style={#1}}}, + character widths/.code={\pgfkeysalso{/pgf/decoration/text effects/every character width/.style={#1}}}, + character widths/.append/.code={\pgfkeysalso{/pgf/decoration/text effects/every character width/.append style={#1}}}, + character count/.store in=\tikz@lib@dec@te@charactercountvar, + character count=, + character total/.store in=\tikz@lib@dec@te@charactertotalvar, + character total=, + letter count/.store in=\tikz@lib@dec@te@lettercountvar, + letter count=, + letter total/.store in=\tikz@lib@dec@te@lettertotalvar, + letter total=, + word count/.store in=\tikz@lib@dec@te@wordcountvar, + word count=, + word total/.store in=\tikz@lib@dec@te@wordtotalvar, + word total=, + % + style characters/.code args={#1 with #2}{\tikz@lib@dec@te@parse@stylecharacters{#1}{#2}}, + text along path/.style={ + inner xsep=0pt, + anchor=base, + transform shape + }, + segment from width/.is if=tikz@lib@dec@te@segmentfromwidth, + segment from width=true, + word separator/.code={% + \def\tikz@lib@dec@te@tmp{#1}% + \ifx\tikz@lib@dec@te@tmp\tikz@lib@dec@te@space@text% + \let\tikz@lib@dec@te@wordsep=\tikz@lib@dec@te@spacetoken% + \else% + \def\tikz@lib@dec@te@wordsep{#1} + \fi}, + word separator=space, + character command/.code={% + \def\tikz@lib@dec@te@tmp{#1}% + \ifx\tikz@lib@dec@te@tmp\pgfutil@empty% + \def\tikz@lib@dec@te@charactercommand{\tikz@lib@dec@te@charactertypesetonly}% + \else% + \def\tikz@lib@dec@te@charactercommand{#1}% + \fi% + }, + character command=, + every character width/.style={/pgf/decoration/text effects/every character/.try}, + every character/.style={}, + reverse text/.code={\tikz@lib@dec@te@addto@macro\tikz@lib@dec@te@transformtext% + {\tikz@lib@dec@te@reversetext}}, + group letters into words/.code={\tikz@lib@dec@te@addto@macro\tikz@lib@dec@te@transformtext% + {\tikz@lib@dec@te@groupletters}}, + group letters/.code={\tikz@lib@dec@te@addto@macro\tikz@lib@dec@te@transformtext% + {\tikz@lib@dec@te@groupletters}}, + replace characters/.code args={#1 with #2}{\tikz@lib@dec@te@parse@replacecharacters{#1}{#2}}, + scale text to path/.is if=tikz@lib@dec@te@scaletexttopath, + fit text to path/.is if=tikz@lib@dec@te@fittexttopath, + repeat text/.store in=\tikz@lib@dec@te@repeattext, + repeat text/.default=-1, + repeat text=0, +} + + +\def\tikz@lib@dec@te@charactertypesetonly#1{#1} + +\tikzset{% + text effects/.code={\pgfkeysalso{/pgf/decoration/text effects/.cd,#1}}, +} + + + + + + +% Prepare the decoration text +% +% This sets up all the character/letter/word, counts/totals +% and caluclates the default width of the characters/text +% (which may be modified later). +% +\def\tikz@lib@dec@te@preparetext{% + % Step 1: scan all the characters in the decoration text + \let\tikz@lib@dec@te@text=\pgfdecorationtext% + \tikz@lib@dec@te@scancharacters{% + \expandafter\let\csname tikz@lib@dec@te@character@\tikz@lib@dec@te@scancount @token\endcsname=% + \tikz@lib@dec@te@character% + }% + \let\tikz@lib@dec@te@charactertotalcount=\tikz@lib@dec@te@scancount% + % Step 2: reverse and/or group characters/letters. + \ifx\tikz@lib@dec@te@transformtext\pgfutil@empty% + \else% + \tikz@lib@dec@te@transformtext% + \fi% + % Step 3: get the character/letter/word counts + \def\tikz@lib@dec@te@charactercount{0}% + \def\tikz@lib@dec@te@wordcount{0}% + \def\tikz@lib@dec@te@wordsepcount{0}% + \def\tikz@lib@dec@te@lettercount{0}% + \def\tikz@lib@dec@te@lastcharacter{0}% + \pgfmathloop% + \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount% + \ifnum\tikz@lib@dec@te@lettercount>0\relax% + \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@lastcharactercount}{\tikz@lib@dec@te@finallettertrue}% + \fi + \else% + \expandafter\let\expandafter\tikz@lib@dec@te@character\expandafter=\csname tikz@lib@dec@te@character@\pgfmathcounter @token\endcsname% + \tikz@lib@dec@te@advancecountmacro{\tikz@lib@dec@te@charactercount}{1}% + \tikz@lib@dec@te@start@parameters{\tikz@lib@dec@te@charactercount}% + \tikz@lib@dec@te@addmacroto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@charactercount}% + \ifx\tikz@lib@dec@te@character\tikz@lib@dec@te@wordsep% + \tikz@lib@dec@te@advancecountmacro{\tikz@lib@dec@te@wordsepcount}{1}% + \ifnum\tikz@lib@dec@te@lettercount>0\relax% + \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@lastcharactercount}{\tikz@lib@dec@te@finallettertrue}% + \fi + \def\tikz@lib@dec@te@lettercount{0}% + \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@wordseptrue}% + \else + \ifnum\tikz@lib@dec@te@lettercount=0\relax% + \tikz@lib@dec@te@advancecountmacro\tikz@lib@dec@te@wordcount{1}% + \fi% + \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@finalletterfalse}% + \tikz@lib@dec@te@advancecountmacro{\tikz@lib@dec@te@lettercount}{1}% + \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@wordsepfalse}% + \expandafter\let\csname tikz@lib@dec@te@word \tikz@lib@dec@te@wordcount @lettercount\endcsname=\tikz@lib@dec@te@lettercount% + \fi% + \tikz@lib@dec@te@addmacroto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@lettercount}% + \tikz@lib@dec@te@addmacroto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@wordcount}% + \tikz@lib@dec@te@addmacroto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@character}% + \let\tikz@lib@dec@te@lastcharactercount=\pgfmathcounter% + \repeatpgfmathloop% + \let\tikz@lib@dec@te@wordtotal=\tikz@lib@dec@te@wordcount% + % Step 4: add character/letter/word totals + \pgfmathloop + \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount% + \else% + \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@charactertotalcount}% + \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@wordtotal}% + \expandafter\let\expandafter\tikz@lib@dec@te@lettertotalcount\expandafter=\csname tikz@lib@dec@te@word \tikz@lib@dec@te@wordcount @lettercount\endcsname% + \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@lettertotalcount}% + \repeatpgfmathloop% + % Step 5: calculate the the text and character width + % but do not add to the parameters yet. + \def\tikz@lib@dec@te@textwidth{0pt}% + \pgfmathloop% + \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount% + \else% + \def\tikz@lib@dec@te@characterwidth{0pt}% + \tikz@lib@dec@te@getcharacterwidth{\pgfmathcounter}% + \expandafter\let\csname tikz@lib@dec@te@character@\pgfmathcounter @width\endcsname=\tikz@lib@dec@te@characterwidth% + \pgf@x=\tikz@lib@dec@te@characterwidth\relax% + \pgf@x=0.5\pgf@x% + \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname{\the\pgf@x}% + \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname{\the\pgf@x}% + \tikz@lib@dec@te@advancedimenmacro{\tikz@lib@dec@te@textwidth}{\tikz@lib@dec@te@characterwidth}% + \repeatpgfmathloop% +} + +% Does the category code of the space matter? +\def\tikz@lib@dec@te@spacetoken{ } + +\let\tikz@lib@dec@te@wordsep=\tikz@lib@dec@te@spacetoken + + +% Scan and count the characters in \tikz@lib@dec@te@text +% +% Create macros \tikz@lib@dec@te@character@<n>@token containing +% the nth character. +% +% Total number of characters is store in +% \tikz@lib@dec@te@chractertotal@count +% +\def\tikz@lib@dec@te@scancharacters#1{% + \def\tikz@lib@dec@te@@@scancharacters@process{#1}% + \def\tikz@lib@dec@te@scancount{0}% + \expandafter\tikz@lib@dec@te@@scancharacters\tikz@lib@dec@te@text\tikz@lib@dec@te@scancharacters}% + +\def\tikz@lib@dec@te@@scancharacters{% + \futurelet\tikz@lib@dec@te@token\tikz@lib@dec@te@@@scancharacters} + +\def\tikz@lib@dec@te@@@scancharacters{% + \ifx\tikz@lib@dec@te@token\tikz@lib@dec@te@scancharacters% + \let\tikz@lib@dec@te@next=\tikz@lib@dec@te@@@@scancharacters% + \else% + \tikz@lib@dec@te@advancecountmacro\tikz@lib@dec@te@scancount{1}% + \ifx\tikz@lib@dec@te@token\pgfutil@sptoken% + \let\tikz@lib@dec@te@next=\tikz@lib@dec@te@@@scancharacters@space% + \else% + \ifx\tikz@lib@dec@te@token\bgroup% + \let\tikz@lib@dec@te@next=\tikz@lib@dec@te@@@scancharacters@bgroup% + \else% + \let\tikz@lib@dec@te@next=\tikz@lib@dec@te@@@scancharacters@normal% + \fi% + \fi% + \fi% + \tikz@lib@dec@te@next% +} + +\def\tikz@lib@dec@te@@@scancharacters@space{% + \let\tikz@lib@dec@te@character=\tikz@lib@dec@te@spacetoken% + \tikz@lib@dec@te@@@scancharacters@process% + \pgfutil@ifnextchar x\tikz@lib@dec@te@@scancharacters\tikz@lib@dec@te@@scancharacters% +} + +\def\tikz@lib@dec@te@@@scancharacters@bgroup#1{% + \def\tikz@lib@dec@te@character{{#1}}% + \tikz@lib@dec@te@@@scancharacters@process% + \tikz@lib@dec@te@@scancharacters% +} + +\def\tikz@lib@dec@te@@@scancharacters@normal#1{% + \def\tikz@lib@dec@te@character{#1}% + \tikz@lib@dec@te@@@scancharacters@process% + \tikz@lib@dec@te@@scancharacters% +} + + +\def\tikz@lib@dec@te@@@@scancharacters#1\tikz@lib@dec@te@scancharacters{} + + +% Reverse the order of the scanned chracters in the text +% (Actually reverse the ordering of the macros containing the characters) +\def\tikz@lib@dec@te@reversetext{% + \c@pgf@counta=\tikz@lib@dec@te@charactertotalcount% + \pgfmathloop% + \ifnum\pgfmathcounter>\c@pgf@counta% + \else% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@tmp}{tikz@lib@dec@te@character@\pgfmathcounter @token}% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\pgfmathcounter @token}{tikz@lib@dec@te@character@\the\c@pgf@counta @token}% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\the\c@pgf@counta @token}{tikz@lib@dec@te@tmp}% + \advance\c@pgf@counta by-1\relax% + \repeatpgfmathloop% +} + +% Group letters (i.e., anything that isn't the word separator) +% as single characters (words). +\def\tikz@lib@dec@te@groupletters{% + \c@pgf@counta=0\relax% + \let\tikz@lib@dec@te@tmp=\pgfutil@empty% + \let\tikz@lib@dec@te@@tmp=\pgfutil@empty% + \pgfmathloop% + \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount% + \ifx\tikz@lib@dec@te@@tmp\pgfutil@empty% + \else% + \advance\c@pgf@counta by1\relax% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\the\c@pgf@counta @token}{tikz@lib@dec@te@@tmp}% + \fi% + \else% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@tmp}{tikz@lib@dec@te@character@\pgfmathcounter @token}% + \ifx\tikz@lib@dec@te@tmp\tikz@lib@dec@te@wordsep% + \advance\c@pgf@counta by1\relax% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\the\c@pgf@counta @token}{tikz@lib@dec@te@@tmp}% + \let\tikz@lib@dec@te@@tmp=\pgfutil@empty% + \advance\c@pgf@counta by1\relax% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\the\c@pgf@counta @token}{tikz@lib@dec@te@wordsep}% + \else% + \expandafter\tikz@lib@dec@te@addto@macro\expandafter{\expandafter\tikz@lib@dec@te@@tmp\expandafter}\expandafter{\tikz@lib@dec@te@tmp}% + \fi% + \repeatpgfmathloop% + \edef\tikz@lib@dec@te@charactertotalcount{\the\c@pgf@counta}% +} + + +% Get width of node containing only the current character. +\def\tikz@lib@dec@te@getcharacterwidth#1{% + \csname tikz@lib@dec@te@character@#1\endcsname% + \tikz@lib@dec@te@getoptions{every character width/.try}% + \let\tikz@lib@dec@te@lastcharacterwidth=\tikz@lib@dec@te@characterwidth% + \pgfpositionnodelater\tikz@lib@dec@te@@getcharacterwidth% + \pgfutil@ifundefined{tikz@lib@dec@te@character@replacements@\meaning\tikz@lib@dec@te@character @code}{% + \expandafter\node\expandafter[\tikz@lib@dec@te@options,scale=\tikz@lib@dec@scaledcharacterwidthfactor]% + {\hbox{\tikz@lib@dec@te@charactercommand{\tikz@lib@dec@te@character}}};% + \let\tikz@lib@dec@te@characterwidth=\tikz@lib@dec@te@characterwidth@tmp% + }{% + \tikz@lib@dec@te@getcharacter@replacementwidth{\tikz@lib@dec@te@character}% + \let\tikz@lib@dec@te@characterwidth=\tikz@lib@dec@te@character@replacementwidth% + }% +} + +% Update the character parameters with the widths. +\def\tikz@lib@dec@te@addwidthstoparameters{% + \pgfmathloop% + \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount% + \else% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@characterwidth}{tikz@lib@dec@te@character@\pgfmathcounter @width}% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@characterprewidth}{tikz@lib@dec@te@character@\pgfmathcounter @prewidth}% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@characterpostwidth}{tikz@lib@dec@te@character@\pgfmathcounter @postwidth}% + \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@characterwidth}% + \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@characterprewidth}% + \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@characterpostwidth}% + \repeatpgfmathloop% +} + +% Get the options to applied to a character node. + +\def\tikz@lib@dec@te@addoptions#1{% + \expandafter\def\expandafter\tikz@lib@dec@te@options\expandafter{\tikz@lib@dec@te@options,#1}% +} + +\def\tikz@lib@dec@te@getoptions#1{% + \let\tikz@lib@dec@te@lastcharactercommand=\tikz@lib@dec@te@charactercommand% + \def\tikz@lib@dec@te@options{/pgf/decoration/text effects/.cd}% + \tikz@lib@dec@te@addoptions{#1}% + \let\tikzdecorationcharactercount=\tikz@lib@dec@te@charactercount% + \let\tikzdecorationcharactertotal=\tikz@lib@dec@te@charactertotalcount% + \let\tikzdecorationlettercount=\tikz@lib@dec@te@lettercount% + \let\tikzdecorationlettertotal=\tikz@lib@dec@te@lettertotalcount% + \let\tikzdecorationwordcount=\tikz@lib@dec@te@wordcount% + \let\tikzdecorationwordtotal=\tikz@lib@dec@te@wordtotal% + \let\tikzdecorationcharacter=\tikz@lib@dec@te@character% + % + % Define the count variables (if required) + \ifx\tikz@lib@dec@te@charactercountvar\pgfutil@empty% + \else% + \expandafter\let\tikz@lib@dec@te@charactercountvar=\tikz@lib@dec@te@charactercount% + \fi% + % + \ifx\tikz@lib@dec@te@charactertotalvar\pgfutil@empty% + \else% + \expandafter\let\tikz@lib@dec@te@charactertotalvar=\tikz@lib@dec@te@charactertotalcount% + \fi% + % + \ifx\tikz@lib@dec@te@wordcountvar\pgfutil@empty% + \else% + \expandafter\let\tikz@lib@dec@te@wordcountvar=\tikz@lib@dec@te@wordcount% + \fi% + % + \ifx\tikz@lib@dec@te@wordtotalvar\pgfutil@empty% + \else% + \expandafter\let\tikz@lib@dec@te@wordtotalvar=\tikz@lib@dec@te@wordtotal% + \fi% + % + \ifx\tikz@lib@dec@te@lettercountvar\pgfutil@empty% + \else% + \expandafter\let\tikz@lib@dec@te@lettercountvar=\tikz@lib@dec@te@lettercount% + \fi% + % + \ifx\tikz@lib@dec@te@lettertotalvar\pgfutil@empty% + \else% + \expandafter\let\tikz@lib@dec@te@lettertotalvar=\tikz@lib@dec@te@lettetotal% + \fi% + % + \edef\tikz@lib@dec@te@tmp{character \tikz@lib@dec@te@charactercount/.try,% + character {\meaning\tikz@lib@dec@te@character}/.try}% + \expandafter\tikz@lib@dec@te@addoptions\expandafter{\tikz@lib@dec@te@tmp}% + \ifx\tikz@lib@dec@te@character\tikz@lib@dec@te@wordsep% + \tikz@lib@dec@te@addoptions{/pgf/decoration/text effects/every word separator/.try}% + \else% + \ifnum\tikz@lib@dec@te@wordcount>0\relax% + \edef\tikz@lib@dec@te@tmp{every word/.try, word \tikz@lib@dec@te@wordcount/.try}% + \expandafter\tikz@lib@dec@te@addoptions\expandafter{\tikz@lib@dec@te@tmp}% + \ifnum\tikz@lib@dec@te@lettercount>0\relax% + \edef\tikz@lib@dec@te@tmp{every letter/.try,every \tikz@lib@dec@te@lettercount\space letter/.try}% + \expandafter\tikz@lib@dec@te@addoptions\expandafter{\tikz@lib@dec@te@tmp}% + \ifnum\tikz@lib@dec@te@lettercount=1\relax% + \edef\tikz@lib@dec@te@tmp{every first letter/.try}% + \expandafter\tikz@lib@dec@te@addoptions\expandafter{\tikz@lib@dec@te@tmp}% + \fi% + \iftikz@lib@dec@te@finalletter% + \tikz@lib@dec@te@addoptions{every final letter/.try}% + \fi% + \fi% + \fi% + \fi% +} + +% Called by `late positioning' of the node +% to get the width of the bounding box +% of a character. +\def\tikz@lib@dec@te@@getcharacterwidth{% + \iftikz@lib@dec@te@segmentfromwidth% + \pgf@x=\pgfpositionnodelatermaxx\relax% + \advance\pgf@x by-\pgfpositionnodelaterminx\relax% + \else% + \pgf@x=\pgfpositionnodelatermaxy\relax% + \advance\pgf@x by-\pgfpositionnodelaterminy\relax% + \fi% + \xdef\tikz@lib@dec@te@characterwidth@tmp{\the\pgf@x}% +} + + +\def\tikz@lib@dec@te@drawcharacter{% + \csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactercount\endcsname% + \tikz@lib@dec@te@getoptions{every character/.try}% + \pgfpositionnodelater\relax% + \pgfutil@ifundefined{tikz@lib@dec@te@character@replacements@\meaning\tikz@lib@dec@te@character @code}{% + \expandafter\node\expandafter[\tikz@lib@dec@te@options, scale=\tikz@lib@dec@scaledcharacterwidthfactor]{\hbox{\tikz@lib@dec@te@charactercommand{\tikz@lib@dec@te@character}}};% + }{\tikz@lib@dec@te@drawcharacter@replacement{\tikz@lib@dec@te@character}}% +} + +% Replace the character #1 with a character@replacement +% +\def\tikz@lib@dec@te@drawcharacter@replacement#1{% + \pgfscope% + \expandafter\tikzset\expandafter{\tikz@lib@dec@te@options}% + \csname tikz@lib@dec@te@character@replacements@\meaning#1@code\endcsname% + \endpgfscope% +} + +% Get the width of the character@replacement associated with +% the character #1 +% +\newbox\tikz@lib@dec@te@box +\def\tikz@lib@dec@te@getcharacter@replacementwidth#1{% + \pgfinterruptpicture% + \setbox\tikz@lib@dec@te@box=\hbox{% + \pgfpicture + \expandafter\tikzset\expandafter{\tikz@lib@dec@te@options}% + \csname tikz@lib@dec@te@character@replacements@\meaning#1@code\endcsname% + \endpgfpicture}% + \xdef\tikz@lib@dec@te@character@replacementwidth{\the\wd\tikz@lib@dec@te@box}% + \endpgfinterruptpicture% +} + +\def\tikz@lib@dec@scaledcharacterwidthfactor{1}% + +% Set up the decoration +\def\tikz@lib@dec@te@state@setup@precomputation{% + \def\tikz@lib@te@alignshift{0pt}% + \iftikz@lib@dec@te@pathfromtext% + % The width of the text and characters has already been calculated. + \else% + \let\tikz@lib@dec@te@text=\pgfdecorationtext% + % Get the chracter tokens and the total number of characters. + \tikz@lib@dec@te@preparetext% + \iftikz@lib@dec@te@scaletexttopath% + % OK, *scaling* text to path is easy. + % Simply divide the path length by the text width to + % obtain the scaling factor which will be applied + % "at the last minute"... + \pgfmathdivide{\pgfdecoratedpathlength}{\tikz@lib@dec@te@textwidth}% + \let\tikz@lib@dec@scaledcharacterwidthfactor=\pgfmathresult% + \expandafter\pgfkeys\expandafter{\tikz@lib@dec@te@tmp}% + % ... and recalulate the (pre and post) widths. + \pgfmathloop + \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount% + \else% + \pgf@x=\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname\relax% + \pgf@x=\tikz@lib@dec@scaledcharacterwidthfactor\pgf@x% + \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname{\the\pgf@x}% + % + \pgf@x=\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname\relax% + \pgf@x=\tikz@lib@dec@scaledcharacterwidthfactor\pgf@x% + \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname{\the\pgf@x}% + \repeatpgfmathloop% + % Update parameters with thewidths. + \tikz@lib@dec@te@addwidthstoparameters% + \let\tikz@lib@dec@te@textwidth=\pgfdecoratedpathlength% + \else% + \iftikz@lib@dec@te@fittexttopath% + % *Fitting* text is less easy. + % The pre and post width of all except the first and last characters + % must be recalculated. + % Only the post width of the first character and the pre width + % of the final character are scaled as these characters should be + % fixed and the start and end of the path, respectively. + % + % We hope that the decoration engine is accurate enough to position + % the last word correctly. + \pgf@x=\pgfdecoratedpathlength% + \pgf@xa=\csname tikz@lib@dec@te@character@1@postwidth\endcsname\relax% + \pgf@xb=\csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactertotalcount @prewidth\endcsname\relax% + \advance\pgf@x by-\pgf@xa% + \advance\pgf@x by-\pgf@xb% + \pgf@y=\tikz@lib@dec@te@textwidth\relax% + \advance\pgf@y by-\pgf@xa% + \advance\pgf@y by-\pgf@xb% + % + \pgfmathdivide{\the\pgf@x}{\the\pgf@y}% + \let\tikz@lib@dec@characterwidthscale=\pgfmathresult% + \pgfmathloop + \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount\relax% + \else% + \ifnum\pgfmathcounter>1\relax% + \pgf@x=\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname\relax% + \pgf@x=\tikz@lib@dec@characterwidthscale\pgf@x% + \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname{\the\pgf@x}% + \fi% + \ifnum\pgfmathcounter<\tikz@lib@dec@te@charactertotalcount\relax% + \pgf@x=\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname\relax% + \pgf@x=\tikz@lib@dec@characterwidthscale\pgf@x% + \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname{\the\pgf@x}% + \fi% + \repeatpgfmathloop% + % Update parameters with widths. + \tikz@lib@dec@te@addwidthstoparameters% + \let\tikz@lib@dec@te@textwidth=\pgfdecoratedpathlength% + \else% + % Calculate the distance to move along the path for alignment. + \pgfkeysgetvalue{/pgf/decoration/text align/align}{\tikz@lib@dec@align}% + \ifx\tikz@lib@dec@align\tikz@lib@dec@align@center@text% + \pgf@x=\pgfdecoratedpathlength\relax% + \advance\pgf@x by-\tikz@lib@dec@te@textwidth\relax% + \ifdim\pgf@x<0pt\relax% + \pgf@x=0pt\relax% + \fi% + \divide\pgf@x by2\relax% + % Adjust the pre-width of the first character... + \pgf@xa=\csname tikz@lib@dec@te@character@1@prewidth\endcsname\relax% + \advance\pgf@xa by\pgf@x% + \expandafter\edef\csname tikz@lib@dec@te@character@1@prewidth\endcsname{\the\pgf@xa}% + % ...and the post-width of the last character. + \pgf@xa=\csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactertotalcount @postwidth\endcsname\relax% + \advance\pgf@xa by\pgf@x% + \expandafter\edef\csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactertotalcount @postwidth\endcsname{\the\pgf@xa}% + \else% + \ifx\tikz@lib@dec@align\tikz@lib@dec@align@right@text% + \pgf@x=\pgfdecoratedpathlength\relax% + \advance\pgf@x by-\tikz@lib@dec@te@textwidth\relax% + \ifdim\pgf@x<0pt\relax% + \pgf@x=0pt\relax% + \fi% + % Adjust the pre-width of the first character... + \pgf@xa=\csname tikz@lib@dec@te@character@1@prewidth\endcsname\relax% + \advance\pgf@xa by\pgf@x% + \expandafter\edef\csname tikz@lib@dec@te@character@1@prewidth\endcsname{\the\pgf@xa}% + \fi% + \fi% + \tikz@lib@dec@te@addwidthstoparameters% + \fi% + \fi% + \fi% +} + + +% Evil hack into the decoration code. +% +% If the path contains single move to and the `path from text' +% key is set to true. The width of the text is calcuated here +% and the (straight line) path automatically calculated. +% +\def\pgf@decorate@path@check@moveto#1{% + \expandafter\pgf@decorate@path@@check@moveto#1\pgf@decorate@stop\pgf@decorate@@stop} + +\def\pgf@decorate@token@stop{\pgf@decorate@stop}% +\def\pgf@decorate@path@@check@moveto#1#2#3#4\pgf@decorate@@stop#5#6{% + \def\pgf@decorate@temp{#4}% + \pgf@x=#2\relax% + \pgf@y=#3\relax% + \ifx\pgf@decorate@temp\pgf@decorate@token@stop% + \iftikz@lib@dec@te@pathfromtext% + % Get the start position... + \pgfextract@process\tikz@lib@dec@te@pathstart{}% + \tikz@lib@dec@te@preparetext% + \tikz@lib@dec@te@addwidthstoparameters% + % ... and create a lineto path of the correct length. + \pgfsetpath\pgfutil@empty% + \pgfpathmoveto{\tikz@lib@dec@te@pathstart}% + \pgfpathlineto{\pgfpointadd{\tikz@lib@dec@te@pathstart}% + {\pgfpointpolar{\tikz@lib@dec@te@pathfromtextangle}{\tikz@lib@dec@te@textwidth}}}% + \pgfgetpath\pgfdecoratedpath% + \pgfsetpath\pgfutil@empty% + \else% + #5% + \fi% + \else% + \tikz@lib@dec@te@pathfromtextfalse% + #6% + \fi% +} + + +\pgfdeclaredecoration{text effects along path}{setup}{ + \state{setup}[width=+0pt, next state=scan, persistent precomputation={% + \tikz@lib@dec@te@state@setup@precomputation% + \def\tikz@lib@dec@te@charactercount{0}% + }]{} + % +\state{scan}[width=+0pt, next state=pre token, persistent precomputation={% + \tikz@lib@dec@te@advancecountmacro\tikz@lib@dec@te@charactercount{1}% + % Usual switch to final state is based on distance. + % Here we also need it to be on the number of the + % current character. + \ifnum\tikz@lib@dec@te@charactercount>\tikz@lib@dec@te@charactertotalcount\relax% + \ifnum\tikz@lib@dec@te@repeattext=0\relax% + \def\pgf@decorate@next@state{final}% + \else% + \tikz@lib@dec@te@advancecountmacro\tikz@lib@dec@te@repeattext{-1}% + \def\tikz@lib@dec@te@charactercount{1}% + \fi% + \fi% + % Install parameters for this character. + \csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactercount\endcsname% +}]{} +% +\state{pre token}[width=+\tikz@lib@dec@te@characterprewidth, next state=token]{} +\state{token}[width=+0pt, next state=post token] +{% + \tikz@lib@dec@te@drawcharacter% +} +\state{post token}[width=+\tikz@lib@dec@te@characterpostwidth, next state=scan]{} +} + + +% Parse styles for individual characters +% #1 a string of characters (e.g., aieou{\"U}{\"a"}) +% #2 the options for to apply to each character. +% +\def\tikz@lib@dec@te@parse@stylecharacters#1#2{% + \def\tikz@lib@dec@te@text{#1}% + \tikz@lib@dec@te@scancharacters{% + \pgfkeysalso{/pgf/decoration/text effects/character {\meaning\tikz@lib@dec@te@character}/.style={#2}}% + }% +} + +% Parse replacment code for for individual characters +% #1 a string of characters (e.g., aieou{\"U}{\"a"}) +% #2 the code to execute to each character. +% +\def\tikz@lib@dec@te@parse@replacecharacters#1#2{% + \def\tikz@lib@dec@te@text{#1}% + \tikz@lib@dec@te@scancharacters{% + \expandafter\def\csname tikz@lib@dec@te@character@replacements@\meaning\tikz@lib@dec@te@character @code\endcsname{#2}% + }% +} + \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfit.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfit.code.tex index 2ae21de0420..ef6a88dc1a9 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfit.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfit.code.tex @@ -7,10 +7,10 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfit.code.tex,v 1.3 2008/06/21 18:59:25 vibrovski Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfit.code.tex,v 1.5 2013/07/12 17:33:49 tantau Exp $ \pgfkeys{/tikz/fit/.code=\tikz@lib@fit{#1}, - /tikz/rotate fit/.code=\def\tikz@lib@fit@rotate{#1}\pgfkeysalso{/tikz/rotate=#1} + /tikz/rotate fit/.code=\def\tikz@lib@fit@rotate{#1}\pgfkeysalso{/tikz/rotate=#1} } \def\tikz@lib@fit@rotate{0} @@ -37,31 +37,33 @@ \advance\pgf@xa by.5\pgf@x% \advance\pgf@ya by.5\pgf@y% \ifdim\tikz@lib@fit@rotate pt=0pt\relax% - \edef\tikz@node@at{\noexpand\pgfpoint{\the\pgf@xa}{\the\pgf@ya}}% + {% + \pgftransforminvert% + \pgf@pos@transform{\pgf@xa}{\pgf@ya}% + \global\pgf@xa\pgf@xa + \global\pgf@ya\pgf@ya + } \else% - \pgf@xc=\pgf@x% - \pgf@yc=\pgf@y% - {% - \pgf@xc=\pgf@xa% - \pgf@yc=\pgf@ya% - \pgfgettransform\tikz@lib@fit@transform% - \pgftransforminvert% - \pgf@pos@transform{\pgf@xc}{\pgf@yc}% - \pgftransformreset% - \pgftransformrotate{\tikz@lib@fit@rotate}% - \pgf@pos@transform{\pgf@xc}{\pgf@yc}% - \pgfsettransform\tikz@lib@fit@transform% - \pgf@pos@transform{\pgf@xc}{\pgf@yc}% - \global\pgf@x=\pgf@xc% - \global\pgf@y=\pgf@yc% - }% - \pgf@xa=\pgf@x% - \pgf@ya=\pgf@y% - \pgf@x=\pgf@xc% - \pgf@y=\pgf@yc% - \fi% - \edef\tikz@node@at{\noexpand\pgfpoint{\the\pgf@xa}{\the\pgf@ya}}% - \pgfkeysalso{/tikz/anchor=center,/tikz/text centered}% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + {% + \pgf@xc=\pgf@xa% + \pgf@yc=\pgf@ya% + \pgftransforminvert% + \pgf@pos@transform{\pgf@xc}{\pgf@yc}% + \pgftransformreset% + \pgftransformrotate{\tikz@lib@fit@rotate}% + \pgf@pos@transform{\pgf@xc}{\pgf@yc}% + \global\pgf@x=\pgf@xc% + \global\pgf@y=\pgf@yc% + }% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@x=\pgf@xc% + \pgf@y=\pgf@yc% + \fi% + \edef\tikz@node@at{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}% + \pgfkeysalso{/tikz/anchor=center,/tikz/text badly centered}% \pgfkeysalso{/tikz/text width/.expanded=\the\pgf@x}% \pgf@x=\pgf@y% \pgf@y=.5\pgf@y% @@ -90,25 +92,25 @@ } \def\tikz@lib@fit@adjust#1{% - \ifdim\tikz@lib@fit@rotate pt=0pt\relax% - \pgf@process{#1}% - \else% - {% - #1% - \pgf@xc=\pgf@x% - \pgf@yc=\pgf@y% - \pgfgettransform\tikz@lib@fit@transform% - \pgftransforminvert% - \pgf@pos@transform{\pgf@xc}{\pgf@yc}% - \pgftransformreset% - \pgftransformrotate{-\tikz@lib@fit@rotate}% - \pgf@pos@transform{\pgf@xc}{\pgf@yc}% - \pgfsettransform\tikz@lib@fit@transform% - \pgf@pos@transform{\pgf@xc}{\pgf@yc}% - \global\pgf@x=\pgf@xc% - \global\pgf@y=\pgf@yc% - }% - \fi% + \ifdim\tikz@lib@fit@rotate pt=0pt\relax% + \pgf@process{\pgfpointtransformed{#1}}% + \else% + {% + \pgf@process{\pgfpointtransformed{#1}}% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \pgfgettransform\tikz@lib@fit@transform% + \pgftransforminvert% + \pgf@pos@transform{\pgf@xc}{\pgf@yc}% + \pgftransformreset% + \pgftransformrotate{-\tikz@lib@fit@rotate}% + \pgf@pos@transform{\pgf@xc}{\pgf@yc}% + \pgfsettransform\tikz@lib@fit@transform% + \pgf@pos@transform{\pgf@xc}{\pgf@yc}% + \global\pgf@x=\pgf@xc% + \global\pgf@y=\pgf@yc% + }% + \fi% \ifdim\pgf@x<\pgf@xa% \pgf@xa=\pgf@x% \fi% diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfolding.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfolding.code.tex index 2ecdfeb11c7..1c45b6eac4d 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfolding.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfolding.code.tex @@ -1,4 +1,5 @@ % Copyright 2006 by Till Tantau +% Copyright 2013 by Nico Van Cleemput % % This file may be distributed and/or modified % @@ -7,7 +8,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfolding.code.tex,v 1.1 2008/01/09 17:57:16 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfolding.code.tex,v 1.3 2013/08/28 11:00:54 tantau Exp $ % @@ -18,6 +19,41 @@ \newdimen\tikz@lib@fold@length \tikz@lib@fold@length=2cm +% Faces +% ----- + +\def\tikz@lib@fold@triangle#1#2#3#4{% + \begin{scope}[xshift=.5\tikz@lib@fold@length,yshift=.28868\tikz@lib@fold@length] + #1 + \end{scope} + \begin{scope}[shift={(60:\tikz@lib@fold@length)},rotate=-60] + #2 + \end{scope} + \begin{scope}[xshift=\tikz@lib@fold@length,rotate=180] + #3 + \end{scope} + \begin{scope}[rotate=60] + #4 + \end{scope} +} + +\def\tikz@lib@fold@square#1#2#3#4#5{% + \begin{scope}[xshift=.5\tikz@lib@fold@length,yshift=.5\tikz@lib@fold@length] + #1 + \end{scope} + \begin{scope}[yshift=\tikz@lib@fold@length] + #2 + \end{scope} + \begin{scope}[xshift=\tikz@lib@fold@length,yshift=\tikz@lib@fold@length,rotate=-90] + #3 + \end{scope} + \begin{scope}[xshift=\tikz@lib@fold@length,rotate=180] + #4 + \end{scope} + \begin{scope}[rotate=90] + #5 + \end{scope} +} \def\tikz@lib@fold@pentagon#1#2#3#4#5#6{% \begin{scope}[xshift=.5\tikz@lib@fold@length,yshift=0.68819\tikz@lib@fold@length] @@ -40,13 +76,165 @@ \end{scope} } +\def\tikz@lib@fold@hexagon#1#2#3#4#5#6#7{% + \begin{scope} + [shift={(60:\tikz@lib@fold@length)}] + #1 + \end{scope} + \begin{scope} + [shift={(120:\tikz@lib@fold@length)}, + shift={(60:\tikz@lib@fold@length)}] + #2 + \end{scope} + \begin{scope} + [shift={(120:\tikz@lib@fold@length)}, + shift={(60:\tikz@lib@fold@length)}, + xshift=\tikz@lib@fold@length, + rotate=-60] + #3 + \end{scope} + \begin{scope} + [xshift=\tikz@lib@fold@length, + shift={(60:\tikz@lib@fold@length)}, + rotate=-120] + #4 + \end{scope} + \begin{scope} + [xshift=\tikz@lib@fold@length, + rotate=180] + #5 + \end{scope} + \begin{scope} + [rotate=120] + #6 + \end{scope} + \begin{scope} + [shift={(120:\tikz@lib@fold@length)}, + rotate=60] + #7 + \end{scope} +} + +\def\tikz@lib@fold@octagon#1#2#3#4#5#6#7#8#9{% + \begin{scope}[xshift=.5\tikz@lib@fold@length,yshift=1.20711\tikz@lib@fold@length] + #1 + \end{scope} + \begin{scope}[yshift=2.41421\tikz@lib@fold@length] + #2 + \end{scope} + \begin{scope}[xshift=\tikz@lib@fold@length,yshift=2.41421\tikz@lib@fold@length,rotate=-45] + #3 + \end{scope} + \begin{scope}[xshift=1.70711\tikz@lib@fold@length,yshift=1.70711\tikz@lib@fold@length,rotate=-90] + #4 + \end{scope} + \begin{scope}[xshift=1.70711\tikz@lib@fold@length,yshift=.70711\tikz@lib@fold@length,rotate=-135] + #5 + \end{scope} + \begin{scope}[xshift=\tikz@lib@fold@length,rotate=180] + #6 + \end{scope} + \begin{scope}[rotate=135] + #7 + \end{scope} + \begin{scope}[xshift=-.70711\tikz@lib@fold@length,yshift=.70711\tikz@lib@fold@length,rotate=90] + #8 + \end{scope} + \begin{scope}[xshift=-.70711\tikz@lib@fold@length,yshift=1.70711\tikz@lib@fold@length,rotate=45] + #9 + \end{scope} +} + +\def\tikz@lib@fold@decagon#1#2#3#4#5#6#7{% + \begin{scope}[shift={(72:1.61803\tikz@lib@fold@length)}] %decagon inside a circle with radius the golden ratio has side length 1 + #1 + \end{scope} + \begin{scope} + [shift={(36:\tikz@lib@fold@length)}, + shift={(72:\tikz@lib@fold@length)}, + shift={(108:\tikz@lib@fold@length)}, + shift={(144:\tikz@lib@fold@length)}] + #2 + \end{scope} + \begin{scope} + [xshift=\tikz@lib@fold@length, + shift={(36:\tikz@lib@fold@length)}, + shift={(72:\tikz@lib@fold@length)}, + shift={(108:\tikz@lib@fold@length)}, + shift={(144:\tikz@lib@fold@length)}, + rotate=-36] + #3 + \end{scope} + \begin{scope} + [xshift=\tikz@lib@fold@length, + shift={(36:\tikz@lib@fold@length)}, + shift={(72:\tikz@lib@fold@length)}, + shift={(108:\tikz@lib@fold@length)}, + rotate=-72] + #4 + \end{scope} + \begin{scope} + [xshift=\tikz@lib@fold@length, + shift={(36:\tikz@lib@fold@length)}, + shift={(72:\tikz@lib@fold@length)}, + rotate=-108] + #5 + \end{scope} + \begin{scope} + [xshift=\tikz@lib@fold@length, + shift={(36:\tikz@lib@fold@length)}, + rotate=-144] + #6 + \end{scope} + \begin{scope} + [xshift=\tikz@lib@fold@length, + rotate=180] + #7 + \end{scope} + \tikz@lib@fold@decagonbis +} + +\def\tikz@lib@fold@decagonbis#1#2#3#4{% + \begin{scope} + [rotate=144] + #1 + \end{scope} + \begin{scope} + [shift={(144:\tikz@lib@fold@length)}, + rotate=108] + #2 + \end{scope} + \begin{scope} + [shift={(144:\tikz@lib@fold@length)}, + shift={(108:\tikz@lib@fold@length)}, + rotate=72] + #3 + \end{scope} + \begin{scope} + [shift={(144:\tikz@lib@fold@length)}, + shift={(108:\tikz@lib@fold@length)}, + shift={(72:\tikz@lib@fold@length)}, + rotate=36] + #4 + \end{scope} +} \def\tikz@lib@fold@path{\draw[every fold](0,0) -- (\tikz@lib@fold@length,0pt);} \def\tikz@lib@fold@cut@path{\draw[every cut](0,0) -- (\tikz@lib@fold@length,0pt);} \def\tikz@lib@fold@ear@path{ + \path[every ear] (0,0) -- (.5\tikz@lib@fold@length,.2\tikz@lib@fold@length) --(\tikz@lib@fold@length,0pt) --(0,0) -- cycle; \draw[every fold](0,0) -- (\tikz@lib@fold@length,0pt); \draw[every cut] (0,0) -- (.5\tikz@lib@fold@length,.2\tikz@lib@fold@length) --(\tikz@lib@fold@length,0pt);} +\def\tikz@lib@fold@ear@custom@left@path#1{ + \path[every ear] (0,0) -- (#1:.66\tikz@lib@fold@length) -- (\tikz@lib@fold@length,0pt) --(0,0) -- cycle; + \draw[every fold](0,0) -- (\tikz@lib@fold@length,0pt); + \draw[every cut] (0,0) -- (#1:.66\tikz@lib@fold@length) -- (\tikz@lib@fold@length,0pt);} +\def\tikz@lib@fold@ear@custom@right@path#1{ + \path[every ear] (0,0) -- (\tikz@lib@fold@length,0pt) -- ++(-#1:-.66\tikz@lib@fold@length) --(0,0) -- cycle; + \draw[every fold](0,0) -- (\tikz@lib@fold@length,0pt); + \draw[every cut] (\tikz@lib@fold@length,0pt) -- ++(-#1:-.66\tikz@lib@fold@length) -- (0,0);} +\tikzstyle{every ear}=[] \tikzstyle{every cut}=[] \tikzstyle{every fold}=[help lines] @@ -62,6 +250,87 @@ \tikzoption{face 10}{\def\tikz@lib@fold@face@J{#1}} \tikzoption{face 11}{\def\tikz@lib@fold@face@K{#1}} \tikzoption{face 12}{\def\tikz@lib@fold@face@L{#1}} +\tikzoption{face 13}{\def\tikz@lib@fold@face@M{#1}} +\tikzoption{face 14}{\def\tikz@lib@fold@face@N{#1}} +\tikzoption{face 15}{\def\tikz@lib@fold@face@O{#1}} +\tikzoption{face 16}{\def\tikz@lib@fold@face@P{#1}} +\tikzoption{face 17}{\def\tikz@lib@fold@face@Q{#1}} +\tikzoption{face 18}{\def\tikz@lib@fold@face@R{#1}} +\tikzoption{face 19}{\def\tikz@lib@fold@face@S{#1}} +\tikzoption{face 20}{\def\tikz@lib@fold@face@T{#1}} +\tikzoption{face 21}{\def\tikz@lib@fold@face@U{#1}} +\tikzoption{face 22}{\def\tikz@lib@fold@face@V{#1}} +\tikzoption{face 23}{\def\tikz@lib@fold@face@W{#1}} +\tikzoption{face 24}{\def\tikz@lib@fold@face@X{#1}} +\tikzoption{face 25}{\def\tikz@lib@fold@face@Y{#1}} +\tikzoption{face 26}{\def\tikz@lib@fold@face@Z{#1}} +\tikzoption{face 27}{\def\tikz@lib@fold@face@AA{#1}} +\tikzoption{face 28}{\def\tikz@lib@fold@face@AB{#1}} +\tikzoption{face 29}{\def\tikz@lib@fold@face@AC{#1}} +\tikzoption{face 30}{\def\tikz@lib@fold@face@AD{#1}} +\tikzoption{face 31}{\def\tikz@lib@fold@face@AE{#1}} +\tikzoption{face 32}{\def\tikz@lib@fold@face@AF{#1}} +\tikzoption{face 33}{\def\tikz@lib@fold@face@AG{#1}} +\tikzoption{face 34}{\def\tikz@lib@fold@face@AH{#1}} +\tikzoption{face 35}{\def\tikz@lib@fold@face@AI{#1}} +\tikzoption{face 36}{\def\tikz@lib@fold@face@AJ{#1}} +\tikzoption{face 37}{\def\tikz@lib@fold@face@AK{#1}} +\tikzoption{face 38}{\def\tikz@lib@fold@face@AL{#1}} +\tikzoption{face 39}{\def\tikz@lib@fold@face@AM{#1}} +\tikzoption{face 40}{\def\tikz@lib@fold@face@AN{#1}} +\tikzoption{face 41}{\def\tikz@lib@fold@face@AO{#1}} +\tikzoption{face 42}{\def\tikz@lib@fold@face@AP{#1}} +\tikzoption{face 43}{\def\tikz@lib@fold@face@AQ{#1}} +\tikzoption{face 44}{\def\tikz@lib@fold@face@AR{#1}} +\tikzoption{face 45}{\def\tikz@lib@fold@face@AS{#1}} +\tikzoption{face 46}{\def\tikz@lib@fold@face@AT{#1}} +\tikzoption{face 47}{\def\tikz@lib@fold@face@AU{#1}} +\tikzoption{face 48}{\def\tikz@lib@fold@face@AV{#1}} +\tikzoption{face 49}{\def\tikz@lib@fold@face@AW{#1}} +\tikzoption{face 50}{\def\tikz@lib@fold@face@AX{#1}} +\tikzoption{face 51}{\def\tikz@lib@fold@face@AY{#1}} +\tikzoption{face 52}{\def\tikz@lib@fold@face@AZ{#1}} +\tikzoption{face 53}{\def\tikz@lib@fold@face@BA{#1}} +\tikzoption{face 54}{\def\tikz@lib@fold@face@BB{#1}} +\tikzoption{face 55}{\def\tikz@lib@fold@face@BC{#1}} +\tikzoption{face 56}{\def\tikz@lib@fold@face@BD{#1}} +\tikzoption{face 57}{\def\tikz@lib@fold@face@BE{#1}} +\tikzoption{face 58}{\def\tikz@lib@fold@face@BF{#1}} +\tikzoption{face 59}{\def\tikz@lib@fold@face@BG{#1}} +\tikzoption{face 60}{\def\tikz@lib@fold@face@BH{#1}} +\tikzoption{face 61}{\def\tikz@lib@fold@face@BI{#1}} +\tikzoption{face 62}{\def\tikz@lib@fold@face@BJ{#1}} +\tikzoption{face 63}{\def\tikz@lib@fold@face@BK{#1}} +\tikzoption{face 64}{\def\tikz@lib@fold@face@BL{#1}} +\tikzoption{face 65}{\def\tikz@lib@fold@face@BM{#1}} +\tikzoption{face 66}{\def\tikz@lib@fold@face@BN{#1}} +\tikzoption{face 67}{\def\tikz@lib@fold@face@BO{#1}} +\tikzoption{face 68}{\def\tikz@lib@fold@face@BP{#1}} +\tikzoption{face 69}{\def\tikz@lib@fold@face@BQ{#1}} +\tikzoption{face 70}{\def\tikz@lib@fold@face@BR{#1}} +\tikzoption{face 71}{\def\tikz@lib@fold@face@BS{#1}} +\tikzoption{face 72}{\def\tikz@lib@fold@face@BT{#1}} +\tikzoption{face 73}{\def\tikz@lib@fold@face@BU{#1}} +\tikzoption{face 74}{\def\tikz@lib@fold@face@BV{#1}} +\tikzoption{face 75}{\def\tikz@lib@fold@face@BW{#1}} +\tikzoption{face 76}{\def\tikz@lib@fold@face@BX{#1}} +\tikzoption{face 77}{\def\tikz@lib@fold@face@BY{#1}} +\tikzoption{face 78}{\def\tikz@lib@fold@face@BZ{#1}} +\tikzoption{face 79}{\def\tikz@lib@fold@face@CA{#1}} +\tikzoption{face 80}{\def\tikz@lib@fold@face@CB{#1}} +\tikzoption{face 81}{\def\tikz@lib@fold@face@CC{#1}} +\tikzoption{face 82}{\def\tikz@lib@fold@face@CD{#1}} +\tikzoption{face 83}{\def\tikz@lib@fold@face@CE{#1}} +\tikzoption{face 84}{\def\tikz@lib@fold@face@CF{#1}} +\tikzoption{face 85}{\def\tikz@lib@fold@face@CG{#1}} +\tikzoption{face 86}{\def\tikz@lib@fold@face@CH{#1}} +\tikzoption{face 87}{\def\tikz@lib@fold@face@CI{#1}} +\tikzoption{face 88}{\def\tikz@lib@fold@face@CJ{#1}} +\tikzoption{face 89}{\def\tikz@lib@fold@face@CK{#1}} +\tikzoption{face 90}{\def\tikz@lib@fold@face@CL{#1}} +\tikzoption{face 91}{\def\tikz@lib@fold@face@CM{#1}} +\tikzoption{face 92}{\def\tikz@lib@fold@face@CN{#1}} + \let\tikz@lib@fold@face@A=\pgfutil@empty \let\tikz@lib@fold@face@B=\pgfutil@empty @@ -75,69 +344,1734 @@ \let\tikz@lib@fold@face@J=\pgfutil@empty \let\tikz@lib@fold@face@K=\pgfutil@empty \let\tikz@lib@fold@face@L=\pgfutil@empty +\let\tikz@lib@fold@face@M=\pgfutil@empty +\let\tikz@lib@fold@face@N=\pgfutil@empty +\let\tikz@lib@fold@face@O=\pgfutil@empty +\let\tikz@lib@fold@face@P=\pgfutil@empty +\let\tikz@lib@fold@face@Q=\pgfutil@empty +\let\tikz@lib@fold@face@R=\pgfutil@empty +\let\tikz@lib@fold@face@S=\pgfutil@empty +\let\tikz@lib@fold@face@T=\pgfutil@empty +\let\tikz@lib@fold@face@U=\pgfutil@empty +\let\tikz@lib@fold@face@V=\pgfutil@empty +\let\tikz@lib@fold@face@W=\pgfutil@empty +\let\tikz@lib@fold@face@X=\pgfutil@empty +\let\tikz@lib@fold@face@Y=\pgfutil@empty +\let\tikz@lib@fold@face@Z=\pgfutil@empty +\let\tikz@lib@fold@face@AA=\pgfutil@empty +\let\tikz@lib@fold@face@AB=\pgfutil@empty +\let\tikz@lib@fold@face@AC=\pgfutil@empty +\let\tikz@lib@fold@face@AD=\pgfutil@empty +\let\tikz@lib@fold@face@AE=\pgfutil@empty +\let\tikz@lib@fold@face@AF=\pgfutil@empty +\let\tikz@lib@fold@face@AG=\pgfutil@empty +\let\tikz@lib@fold@face@AH=\pgfutil@empty +\let\tikz@lib@fold@face@AI=\pgfutil@empty +\let\tikz@lib@fold@face@AJ=\pgfutil@empty +\let\tikz@lib@fold@face@AK=\pgfutil@empty +\let\tikz@lib@fold@face@AL=\pgfutil@empty +\let\tikz@lib@fold@face@AM=\pgfutil@empty +\let\tikz@lib@fold@face@AN=\pgfutil@empty +\let\tikz@lib@fold@face@AO=\pgfutil@empty +\let\tikz@lib@fold@face@AP=\pgfutil@empty +\let\tikz@lib@fold@face@AQ=\pgfutil@empty +\let\tikz@lib@fold@face@AR=\pgfutil@empty +\let\tikz@lib@fold@face@AS=\pgfutil@empty +\let\tikz@lib@fold@face@AT=\pgfutil@empty +\let\tikz@lib@fold@face@AU=\pgfutil@empty +\let\tikz@lib@fold@face@AV=\pgfutil@empty +\let\tikz@lib@fold@face@AW=\pgfutil@empty +\let\tikz@lib@fold@face@AX=\pgfutil@empty +\let\tikz@lib@fold@face@AY=\pgfutil@empty +\let\tikz@lib@fold@face@AZ=\pgfutil@empty +\let\tikz@lib@fold@face@BA=\pgfutil@empty +\let\tikz@lib@fold@face@BB=\pgfutil@empty +\let\tikz@lib@fold@face@BC=\pgfutil@empty +\let\tikz@lib@fold@face@BD=\pgfutil@empty +\let\tikz@lib@fold@face@BE=\pgfutil@empty +\let\tikz@lib@fold@face@BF=\pgfutil@empty +\let\tikz@lib@fold@face@BG=\pgfutil@empty +\let\tikz@lib@fold@face@BH=\pgfutil@empty +\let\tikz@lib@fold@face@BI=\pgfutil@empty +\let\tikz@lib@fold@face@BJ=\pgfutil@empty +\let\tikz@lib@fold@face@BK=\pgfutil@empty +\let\tikz@lib@fold@face@BL=\pgfutil@empty +\let\tikz@lib@fold@face@BM=\pgfutil@empty +\let\tikz@lib@fold@face@BN=\pgfutil@empty +\let\tikz@lib@fold@face@BO=\pgfutil@empty +\let\tikz@lib@fold@face@BP=\pgfutil@empty +\let\tikz@lib@fold@face@BQ=\pgfutil@empty +\let\tikz@lib@fold@face@BR=\pgfutil@empty +\let\tikz@lib@fold@face@BS=\pgfutil@empty +\let\tikz@lib@fold@face@BT=\pgfutil@empty +\let\tikz@lib@fold@face@BU=\pgfutil@empty +\let\tikz@lib@fold@face@BV=\pgfutil@empty +\let\tikz@lib@fold@face@BW=\pgfutil@empty +\let\tikz@lib@fold@face@BX=\pgfutil@empty +\let\tikz@lib@fold@face@BY=\pgfutil@empty +\let\tikz@lib@fold@face@BZ=\pgfutil@empty +\let\tikz@lib@fold@face@CA=\pgfutil@empty +\let\tikz@lib@fold@face@CB=\pgfutil@empty +\let\tikz@lib@fold@face@CC=\pgfutil@empty +\let\tikz@lib@fold@face@CD=\pgfutil@empty +\let\tikz@lib@fold@face@CE=\pgfutil@empty +\let\tikz@lib@fold@face@CF=\pgfutil@empty +\let\tikz@lib@fold@face@CG=\pgfutil@empty +\let\tikz@lib@fold@face@CH=\pgfutil@empty +\let\tikz@lib@fold@face@CI=\pgfutil@empty +\let\tikz@lib@fold@face@CJ=\pgfutil@empty +\let\tikz@lib@fold@face@CK=\pgfutil@empty +\let\tikz@lib@fold@face@CL=\pgfutil@empty +\let\tikz@lib@fold@face@CM=\pgfutil@empty +\let\tikz@lib@fold@face@CN=\pgfutil@empty + + +\tikzstyle{numbered faces}=[% + face 1={\node{1};}, + face 2={\node{2};}, + face 3={\node{3};}, + face 4={\node{4};}, + face 5={\node{5};}, + face 6={\node{6};}, + face 7={\node{7};}, + face 8={\node{8};}, + face 9={\node{9};}, + face 10={\node{10};}, + face 11={\node{11};}, + face 12={\node{12};}, + face 13={\node{13};}, + face 14={\node{14};}, + face 15={\node{15};}, + face 16={\node{16};}, + face 17={\node{17};}, + face 18={\node{18};}, + face 19={\node{19};}, + face 20={\node{20};}, + face 21={\node{21};}, + face 22={\node{22};}, + face 23={\node{23};}, + face 24={\node{24};}, + face 25={\node{25};}, + face 26={\node{26};}, + face 27={\node{27};}, + face 28={\node{28};}, + face 29={\node{29};}, + face 30={\node{30};}, + face 31={\node{31};}, + face 32={\node{32};}, + face 33={\node{33};}, + face 34={\node{34};}, + face 35={\node{35};}, + face 36={\node{36};}, + face 37={\node{37};}, + face 38={\node{38};}, + face 39={\node{39};}, + face 40={\node{40};}, + face 41={\node{41};}, + face 42={\node{42};}, + face 43={\node{43};}, + face 44={\node{44};}, + face 45={\node{45};}, + face 46={\node{46};}, + face 47={\node{47};}, + face 48={\node{48};}, + face 49={\node{49};}, + face 50={\node{50};}, + face 51={\node{51};}, + face 52={\node{52};}, + face 53={\node{53};}, + face 54={\node{54};}, + face 55={\node{55};}, + face 56={\node{56};}, + face 57={\node{57};}, + face 58={\node{58};}, + face 59={\node{59};}, + face 60={\node{60};}, + face 61={\node{61};}, + face 62={\node{62};}, + face 63={\node{63};}, + face 64={\node{64};}, + face 65={\node{65};}, + face 66={\node{66};}, + face 67={\node{67};}, + face 68={\node{68};}, + face 69={\node{69};}, + face 70={\node{70};}, + face 71={\node{71};}, + face 72={\node{72};}, + face 73={\node{73};}, + face 74={\node{74};}, + face 75={\node{75};}, + face 76={\node{76};}, + face 77={\node{77};}, + face 78={\node{78};}, + face 79={\node{79};}, + face 80={\node{80};}, + face 81={\node{81};}, + face 82={\node{82};}, + face 83={\node{83};}, + face 84={\node{84};}, + face 85={\node{85};}, + face 86={\node{86};}, + face 87={\node{87};}, + face 88={\node{88};}, + face 89={\node{89};}, + face 90={\node{90};}, + face 91={\node{91};}, + face 92={\node{92};}] + +% The foldings defined here: + +\tikzset{ + pics/dodecahedron folding/.style = {code=\tikzfoldingdodecahedron[];}, + pics/tetrahedron folding/.style = {code=\tikzfoldingtetrahedron[];}, + pics/tetrahedron truncated folding/.style = {code=\tikzfoldingtruncatedtetrahedron[];}, + pics/cube folding/.style = {code=\tikzfoldingcube[];}, + pics/cube truncated folding/.style = {code=\tikzfoldingtruncatedcube[];}, + pics/octahedron folding/.style = {code=\tikzfoldingoctahedron[];}, + pics/octahedron truncated folding/.style = {code=\tikzfoldingtruncatedoctahedron[];}, + pics/dodecahedron folding/.style = {code=\tikzfoldingdodecahedron[];}, + pics/dodecahedron' folding/.style = {code=\tikzfoldingalternatedodecahedron[];}, + pics/cuboctahedron folding/.style = {code=\tikzfoldingoctahedron[];}, + pics/cuboctahedron truncated folding/.style = {code=\tikzfoldingtruncatedoctahedron[];}, + pics/icosahedron folding/.style = {code=\tikzfoldingicosahedron[];}, + pics/rhombicuboctahedron folding/.style = {code=\tikzfoldingrhombicuboctahedron[];}, + pics/snub cube folding/.style = {code=\tikzfoldingsnubcube[];}, + pics/icosidodecahedron folding/.style = {code=\tikzfoldingicosahedron[];} +} + + +% Platonic solids +% --------------- + \def\tikzfoldingdodecahedron#1[#2]#3;{% \begingroup% \tikzset{#2}% - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@A} - { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@B} - { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@C}{\tikz@lib@fold@ear@path}{\tikz@lib@fold@ear@path}{\tikz@lib@fold@path}{\tikz@lib@fold@ear@path}{\tikz@lib@fold@ear@path} - } - {\tikz@lib@fold@ear@path} - {\tikz@lib@fold@path} - {\tikz@lib@fold@ear@path} - {\tikz@lib@fold@ear@path} + \tikz@lib@fold@pentagon + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@I} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@J} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@K} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@L} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + \endgroup +} + +%alternative dodecahedron: larger format possible + +\def\tikzfoldingalternatedodecahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@pentagon + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + } + } + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@I} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@J} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@K} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@L} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + \endgroup +} + + +%tetrahedron + +\def\tikzfoldingtetrahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@triangle + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + \endgroup +} + +%cube + +\def\tikzfoldingcube#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@square{\tikz@lib@fold@face@A} { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@D} - { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@E}{\tikz@lib@fold@ear@path}{\tikz@lib@fold@ear@path}{\tikz@lib@fold@path}{\tikz@lib@fold@cut@path}{\tikz@lib@fold@ear@path} - } - {\tikz@lib@fold@ear@path} - {\tikz@lib@fold@path} - {\tikz@lib@fold@cut@path} - {\tikz@lib@fold@cut@path} + \tikz@lib@fold@square{\tikz@lib@fold@face@B} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} } { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@F} - { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@G}{\tikz@lib@fold@ear@path}{\tikz@lib@fold@ear@path}{\tikz@lib@fold@path}{\tikz@lib@fold@cut@path}{\tikz@lib@fold@ear@path} - } - {\tikz@lib@fold@ear@path} - {\tikz@lib@fold@path} - {\tikz@lib@fold@cut@path} - {\tikz@lib@fold@cut@path} + \tikz@lib@fold@square{\tikz@lib@fold@face@C} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} } { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@H} - { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@I}{\tikz@lib@fold@ear@path}{\tikz@lib@fold@ear@path}{\tikz@lib@fold@path}{\tikz@lib@fold@cut@path}{\tikz@lib@fold@ear@path} - } - {\tikz@lib@fold@ear@path} - {\tikz@lib@fold@path} - {\tikz@lib@fold@cut@path} - {\tikz@lib@fold@cut@path} + \tikz@lib@fold@square{\tikz@lib@fold@face@D} + { + \tikz@lib@fold@square{\tikz@lib@fold@face@E} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} } { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@J} - { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@K} + \tikz@lib@fold@square{\tikz@lib@fold@face@F} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + \endgroup +} + + +%octahedron + +\def\tikzfoldingoctahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@triangle + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + \endgroup +} + + +%icosahedron + +\def\tikzfoldingicosahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@triangle + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@I} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@J} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@K} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@L} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@M} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@N} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@O} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@P} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@Q} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@R} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@S} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@T} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + \endgroup +} + +% Archimedean solids +% ------------------ + +%truncated tetrahedron + +\def\tikzfoldingtruncatedtetrahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@hexagon + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + \endgroup +} + +%cuboctahedron + +\def\tikzfoldingcuboctahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@square + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@I} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@J} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@K} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@L} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@M} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@N} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + \endgroup +} + +%truncated cube + +\def\tikzfoldingtruncatedcube#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@octagon + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + } {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + } {\tikz@lib@fold@cut@path} - {\tikz@lib@fold@path} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@I} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@J} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@K} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@L} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } {\tikz@lib@fold@cut@path} - { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@L}{\tikz@lib@fold@cut@path}{\tikz@lib@fold@cut@path}{\tikz@lib@fold@path}{\tikz@lib@fold@cut@path}{\tikz@lib@fold@cut@path} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@M} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@N} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + \endgroup +} + + +%truncated octahedron + +\def\tikzfoldingtruncatedoctahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@hexagon + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@square + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@I} + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@J} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@square + {\tikz@lib@fold@face@K} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@L} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@M} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@square + {\tikz@lib@fold@face@N} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + \endgroup +} + + +%rhombicuboctahedron + +\def\tikzfoldingrhombicuboctahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@square + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@I} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@square + {\tikz@lib@fold@face@J} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@K} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@L} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@M} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@square + {\tikz@lib@fold@face@N} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@O} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@square + {\tikz@lib@fold@face@P} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@Q} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@R} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@S} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@T} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@square + {\tikz@lib@fold@face@U} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@V} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@W} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@X} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@square + {\tikz@lib@fold@face@Y} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@Z} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + \endgroup +} + +%truncated cuboctahedron + +\def\tikzfoldingtruncatedcuboctahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@square + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{15}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@custom@left@path{15}} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@I} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@J} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{15}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@custom@left@path{15}} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@K} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{15}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@custom@left@path{15}} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@L} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@M} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@N} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{15}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@custom@left@path{15}} + {\tikz@lib@fold@ear@path} } - } - {\tikz@lib@fold@cut@path} - {\tikz@lib@fold@path} - {\tikz@lib@fold@cut@path} - {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@O} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@P} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@Q} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@R} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@S} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@T} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{15}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@custom@left@path{15}} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@U} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{15}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@custom@left@path{15}} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@V} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@W} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@X} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@Y} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@Z} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{15}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@custom@left@path{15}} + {\tikz@lib@fold@ear@path} + } + \endgroup +} + +%snub cube + +\def\tikzfoldingsnubcube#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@square{\tikz@lib@fold@face@A} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@B} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@C} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@D} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + { + \tikz@lib@fold@square{\tikz@lib@fold@face@E} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@F} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@G} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@H} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@I} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@J} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@K} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@L} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@M} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + { + \tikz@lib@fold@square{\tikz@lib@fold@face@N} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@O} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@P} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@Q} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@R} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@S} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@T} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@U} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@V} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + { + \tikz@lib@fold@square{\tikz@lib@fold@face@W} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@X} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@Y} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@Z} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AA} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AB} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AC} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AD} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AE} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + { + \tikz@lib@fold@square{\tikz@lib@fold@face@AF} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AG} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AH} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AI} + { + \tikz@lib@fold@square{\tikz@lib@fold@face@AJ} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AK} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AL} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} } \endgroup } - +% icosidodecahedron + +\def\tikzfoldingicosidodecahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@A} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@B} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@C} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@D} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@E} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@F} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@G} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@H} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@I} + {\tikz@lib@fold@ear@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@J} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@K} + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@L} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@M} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@N} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@O} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@P} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@Q} + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@path} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@R} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@S} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@T} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@U} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@V} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@W} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@X} + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@Y} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@Z} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AA} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@AB} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AC} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@AD} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AE} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AF} + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + \endgroup +} diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex index dd842033fc8..e35633fc20d 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex @@ -9,23 +9,30 @@ \usepgflibrary{intersections} -\let\tikz@intersect@def=\def - \pgfkeys{% /tikz/name path global/.code={% - % it might have been more efficient to eliminate the storage macro - % \tikz@intersect@namedpaths. But I keep it maintain compatibility - % with mixed occurances of local/global names. - \let\tikz@intersect@def=\gdef - \pgfkeys{/tikz/name path={#1}}% + % reset any "old" variables inheritted from some other path + % - we do not accidentally want to append to an old path with the + % same name (or if someone provided the option twice)... + \expandafter\global\expandafter\let\csname tikz@intersect@path@name@#1\endcsname=\relax + \tikz@key@name@path{#1}{\gdef}% }, /tikz/name path local/.code={% - \let\tikz@intersect@def=\def \pgfkeys{/tikz/name path={#1}}% }, /tikz/name path/.code={% + % hm. Do we need this "reset old option" as in 'name path global' + % for this case as well? + \tikz@key@name@path{#1}{\def}% + }, +} + +% #1: the name to assign. +% #2: one of '\def' or '\gdef'. +\def\tikz@key@name@path#1#2{% \tikz@addmode{% - \pgfsyssoftpath@getcurrentpath\tikz@intersect@temppath% + \pgfsyssoftpath@getcurrentpath\tikz@intersect@temppath@round% + \pgfprocessround\tikz@intersect@temppath@round\tikz@intersect@temppath% \ifx\tikz@intersect@namedpaths\pgfutil@empty% \else% \tikz@intersect@namedpaths% @@ -37,28 +44,16 @@ \expandafter\expandafter\expandafter{\expandafter\tikz@intersect@temppath\tikz@intersect@temppath}% }% \fi% - \tikz@intersect@addto@path@names{#1}% + \tikz@intersect@addto@path@names{#1}{#2}% }% - } -} +}% -\def\tikz@intersect@addto@path@names#1{% - % FIXME : I have the impression that something is not correct - % here... the \tikz@intersect@def is not used correctly! - % if I am not mistaken, the \tikz@intersect@def will NOT be - % invoked until \tikz@intersect@namedpaths. CHECK IT - % It seems it works, but only partially. - \def\tikz@marshal{\expandafter\tikz@intersect@def\csname tikz@intersect@path@name@#1\endcsname}% +% #1: the name to assign. +% #2: one of '\def' or '\gdef'. +\def\tikz@intersect@addto@path@names#1#2{% + \edef\tikz@marshal{#2\expandafter\noexpand\csname tikz@intersect@path@name@#1\endcsname}% \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\tikz@marshal% \expandafter\expandafter\expandafter{\expandafter\tikz@marshal\expandafter{\tikz@intersect@temppath}}% - \ifx\tikz@intersect@def\gdef - % This here is to *ensure* that the \gdef is invoked. - % - % I think this solves the problem. - % - % Please revise this routine such that it works better. - \tikz@marshal - \fi \expandafter\pgfutil@g@addto@macro\expandafter\tikz@intersect@namedpaths\expandafter{\tikz@marshal}% } @@ -89,9 +84,9 @@ by=, #1}% \pgfutil@ifundefined{tikz@intersect@path@name@\tikz@intersect@path@a}{% - \PackageError{tikz}{I do not know the path named `\tikz@intersect@path@a'. Perhaps you misspelt it}{}}% + \tikzerror{I do not know the path named `\tikz@intersect@path@a'. Perhaps you misspelt it}}% {\pgfutil@ifundefined{tikz@intersect@path@name@\tikz@intersect@path@b}{% - \PackageError{tikz}{I do not know the path named `\tikz@intersect@path@b'. Perhaps you misspelt it}{}}% + \tikzerror{I do not know the path named `\tikz@intersect@path@b'. Perhaps you misspelt it}}% {% \pgfintersectionofpaths% {% diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymath.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymath.code.tex new file mode 100644 index 00000000000..8ccdc64493a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymath.code.tex @@ -0,0 +1,725 @@ +% Copyright 2013 by Mark Wibrow +% +% This file may be distributed and/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 details. + + + +\edef\tikz@math@at@catcode{\the\catcode`\@} +\catcode`\@=11 + +\def\tikz@math@gobblespaces#1{\pgfutil@ifnextchar x{#1}{#1}} + +\def\tikz@math@meaning@macro{macro} +\def\tikz@math@meaning@dimen{dimen} +\def\tikz@math@meaning@count{count} +\def\tikz@math@meaning@null{null} + +\def\tikz@math@getmeaning#1{\expandafter\tikz@math@@getmeaning\meaning#1\tikz@math@getmeaning@stop} + +\def\tikz@math@@getmeaning#1#2#3#4#5\tikz@math@getmeaning@stop{% + \if#1u% undefined + \let\tikz@math@meaning=\tikz@math@meaning@macro% + \else% + \if#1m% + \let\tikz@math@meaning=\tikz@math@meaning@macro% + \else% + \if#2d% + \let\tikz@math@meaning=\tikz@math@meaning@dimen% + \else% + \if#2c% + \let\tikz@math@meaning=\tikz@math@meaning@count% + \else% + \if#3k% A skip. Treat like a dimen. + \let\tikz@math@meaning=\tikz@math@meaning@dimen% + \else% + \let\tikz@math@meaning=\tikz@math@meaning@null% + \fi% + \fi% + \fi% + \fi% + \fi% +} + +\def\tikz@math@firstoftwo#1#2{#1} +\def\tikz@math@secondoftwo#1#2{#2} + + +\def\tikz@math@getvarstring#1{% + \begingroup% + \escapechar=-1\relax% + \expandafter\tikz@math@@getvarstring\string#1\tikz@math} + +\def\tikz@math@@getvarstring#1\tikz@math#2{% + \endgroup% + \def#2{#1}% +} + +\long\def\tikz@math@collecttosemicolon@other#1#2;{% + \def\tikz@math@collected{#2}#1} +\def\tikz@math@semicolon@other{;}% + +{\catcode`\;=13 +\long\gdef\tikz@math@collecttosemicolon@active#1#2;{% + \def\tikz@math@collected{#2}#1} +\gdef\tikz@math@semicolon@active{;}% +} + + +\def\tikz@math@setvartype#1#2{% + \expandafter\let\csname tikz@math@var@vartype@\string#1\endcsname=#2% +} + + +\def\tikz@math@getvartype#1#2{% + \def\tikz@math@marshal{\let#1=}% + \expandafter\tikz@math@marshal\csname + tikz@math@var@vartype@\string#2\endcsname% +} + + + +\def\tikz@math@ifvarcoordinate#1{% + \expandafter\ifx\csname + tikz@math@var@vartype@\string#1\endcsname\tikz@math@keyword@coordinate% + \let\tikz@math@next=\tikz@math@firstoftwo% + \else% + \let\tikz@math@next=\tikz@math@secondoftwo% + \fi% + \tikz@math@next% +} + +\def\tikz@math@ifvarinteger#1{% + \expandafter\ifx\csname + tikz@math@var@vartype@\string#1\endcsname\tikz@math@keyword@integer% + \let\tikz@math@next=\tikz@math@firstoftwo% + \else% + \let\tikz@math@next=\tikz@math@secondoftwo% + \fi% + \tikz@math@next% +} + + +\def\tikz@math@setvarindexed#1{% + \expandafter\let\csname + tikz@math@var@subtype@\string#1\endcsname=\tikz@math@subtype@indexed% +} + +\def\tikz@math@clearvarindexed#1{% + \expandafter\let\csname tikz@math@var@subtype@\string#1\endcsname=\relax% +} + +\def\tikz@math@ifvarindexed#1{% + \expandafter\ifx\csname tikz@math@var@subtype@\string#1\endcsname\relax% + \let\tikz@math@next=\tikz@math@secondoftwo% + \else% + \let\tikz@math@next=\tikz@math@firstoftwo% + \fi% + \tikz@math@next% +} + +\def\tikz@math@stop{@} + +\let\tikz@math@parse@hook@before=\pgfutil@empty +\let\tikz@math@parse@hook@after=\pgfutil@empty + +\def\tikz@math{% + \ifnum\catcode`\;=13\relax% + \let\tikz@math@semicolon=\tikz@math@semicolon@active% + \let\tikz@math@collecttosemicolon=\tikz@math@collecttosemicolon@active% + \else% + \let\tikz@math@semicolon=\tikz@math@semicolon@other% + \let\tikz@math@collecttosemicolon=\tikz@math@collecttosemicolon@other% + \fi% + \tikz@math@parse@hook@before% + \tikz@@math} + + + + +\long\def\tikz@@math#1{% + \def\tikz@math@marshal{\tikz@math@parse#1}% + \expandafter\expandafter\expandafter\tikz@math@marshal\expandafter\tikz@math@stop\tikz@math@semicolon} + +\def\tikz@math@parse{\pgfutil@ifnextchar\bgroup\tikz@math@@parse@bgroup\tikz@math@@parse@nobgroup} + + +\def\tikz@math@@parse@bgroup{% + \tikz@math@collecttosemicolon{% + % MW: Don't know how reliable this test is. + \ifx\pgf@selectfontorig\tikz@math@undefined% + \begingroup\tikz@math@collected\endgroup% + \else% + \begingroup\csname nullfont\endcsname\tikz@math@collected\endgroup% + \fi\tikz@math@parse}} + + + +\def\tikz@math@@parse@nobgroup{\tikz@math@collecttosemicolon{\tikz@math@@parse@@nobgroup}} + +\def\tikz@math@@parse@@nobgroup{% + \let\tikz@math@tmp=\tikz@math@collected% + \ifx\tikz@math@tmp\tikz@math@stop% + \def\tikz@math@next{\expandafter\tikz@math@parse@finish\tikz@math@semicolon}% + \else% + \def\tikz@math@next{\expandafter\expandafter\expandafter\tikz@math@parse@keyword@check\expandafter\tikz@math@tmp\tikz@math@semicolon}% + \fi% + \tikz@math@next% +} + +\def\tikz@math@parse@finish{% + \tikz@math@collecttosemicolon{\tikz@math@parse@hook@after}% +} + + + +\newif\iftikz@math@let +\def\tikz@math@parse@keyword@check#1{% + \tikz@math@letfalse% + \tikz@math@getmeaning{#1}% + \ifx\tikz@math@meaning\tikz@math@meaning@null% + \let\tikz@math@next=\tikz@math@parse@keyword% + \else% + \let\tikz@math@next=\tikz@math@parse@nokeyword% + \fi% + \tikz@math@next#1} + + +\def\tikz@math@parse@keyword{% + \let\tikz@math@parsed@keyword=\pgfutil@empty% + \futurelet\tikz@math@parse@token\tikz@math@@parse@keyword} + +\def\tikz@math@@parse@keyword{% + \ifx\tikz@math@parse@token\pgfutil@sptoken% + \let\tikz@math@next=\tikz@math@@@parse@keyword% + \else% + \ifx\tikz@math@parse@token(% + \let\tikz@math@next=\tikz@math@@@parse@keyword% + \else% + \ifx\tikz@math@parse@token\bgroup% + \let\tikz@math@next=\tikz@math@@@parse@keyword% + \else% + \let\tikz@math@next=\tikz@math@@@@parse@keyword% + \fi% + \fi% + \fi% + \tikz@math@next} + +\def\tikz@math@error#1{\pgfutil@packageerror{tikz}{tikz math library: #1}{}} + +\def\tikz@math@@@parse@keyword{% + \expandafter\ifx\csname tikz@math@process@keyword@\tikz@math@parsed@keyword\endcsname\relax% + \expandafter\ifx\csname pgfmath\tikz@math@parsed@keyword\endcsname\relax% + \tikz@math@error{Unknown function or keyword '\tikz@math@parsed@keyword'}% + \else% + \def\tikz@math@next{\tikz@math@collecttosemicolon{\tikz@math@function@noassign}}% + \fi% + \else% + \expandafter\def\expandafter\tikz@math@next\expandafter{\csname tikz@math@process@keyword@\tikz@math@parsed@keyword\endcsname}% + \fi% + \tikz@math@next} + +\def\tikz@math@@@@parse@keyword#1{% + \edef\tikz@math@parsed@keyword{\tikz@math@parsed@keyword#1}% + \futurelet\tikz@math@parse@token\tikz@math@@parse@keyword% +} + +\def\tikz@math@function@noassign{% + \pgfmathparse{\tikz@math@parsed@keyword\tikz@math@collected}% + \tikz@math@parse% +} + + + + +\def\tikz@math@process@keyword@count{\tikz@math@collecttosemicolon{\tikz@math@process@keyword@@count}} +\def\tikz@math@process@keyword@@count{% +\def\tikz@math@assign@register{\csname newcount\endcsname}% +\expandafter\tikz@math@gobblespaces\expandafter\tikz@math@process@registers\tikz@math@collected,@,} + +\def\tikz@math@process@keyword@length{\tikz@math@collecttosemicolon{\tikz@math@process@keyword@@length}} +\def\tikz@math@process@keyword@@length{% +\def\tikz@math@assign@register{\csname newdimen\endcsname}% +\show\tikz@math@collected +\expandafter\tikz@math@gobblespaces\expandafter\tikz@math@process@registers\tikz@math@collected,@,} + + +\def\tikz@math@process@registers#1#2,{% + \def\tikz@math@var{#1}% + \ifx\tikz@math@var\tikz@math@stop% + \let\tikz@math@next=\tikz@math@parse% + \else% + \tikz@math@assign@register#1\relax% + \let\tikz@math@next=\tikz@math@process@registers% + \fi% + \tikz@math@gobblespaces\tikz@math@next% +} + + +\def\tikz@math@process@keyword@if#1then{% + \def\tikz@math@if@condition{#1}% + \tikz@math@gobblespaces\tikz@math@parse@if@iftrue% +} +\def\tikz@math@parse@if@iftrue#1{% + \def\tikz@math@if@trueaction{#1}% + \pgfutil@ifnextchar e{\tikz@math@parse@else}{\tikz@math@if@doif}} + +\def\tikz@math@parse@else else{\tikz@math@gobblespaces\tikz@math@if@doifelse} + +\def\tikz@math@if@doif{\tikz@math@collecttosemicolon{\tikz@math@if@@doif}} + +\def\tikz@math@if@@doif{% + \pgfmathparse{\tikz@math@if@condition}% + \ifdim\pgfmathresult pt=0pt\relax% + \else% + \expandafter\tikz@math\expandafter{\tikz@math@if@trueaction}% + \fi% + \tikz@math@parse% +} +\def\tikz@math@if@doifelse{\tikz@math@collecttosemicolon{\tikz@math@if@@doifelse}} +\def\tikz@math@if@@doifelse{% + \pgfmathparse{\tikz@math@if@condition}% + \let\tikz@math@if@falseaction=\tikz@math@collected% + \ifdim\pgfmathresult pt=0pt\relax% + \expandafter\tikz@math\expandafter{\tikz@math@if@falseaction}% + \else% + \expandafter\tikz@math\expandafter{\tikz@math@if@trueaction}% + \fi% + \tikz@math@parse% +} +\def\tikz@math@process@keyword@let{% + \tikz@math@lettrue% + \tikz@math@gobblespaces\tikz@math@parse@nokeyword% +} + + +\def\tikz@math@parse@nokeyword#1{% + \def\tikz@math@var{#1}% + \tikz@math@getvarstring{#1}\tikz@math@varstring% + \let\tikz@math@vartype=\pgfutil@empty% + \ifx\tikz@math@var\tikz@math@stop% + \let\tikz@math@next=\tikz@math@parse@finish% + \else% + \ifx\tikz@math@semicolon\tikz@math@var% + \let\tikz@math@next=\tikz@math@parse% + \else% + \let\tikz@math@next=\tikz@math@parse@index@check% + \fi% + \fi% + \tikz@math@next} + +\def\tikz@math@parse@index@check{% + \pgfutil@ifnextchar={\tikz@math@parse@noindex}{\tikz@math@parse@index}} + +\def\tikz@math@parse@noindex{% + \expandafter\tikz@math@clearvarindexed\tikz@math@var% + \let\tikz@math@current@index=\pgfutil@empty% + \tikz@math@parse@afterindex% +} + +\def\tikz@math@parse@index#1{% + \def\tikz@math@tmp{#1}% + \expandafter\tikz@math@setvarindexed\tikz@math@var% {} + \edef\tikz@math@current@index{#1}% + \tikz@math@parse@afterindex% +} +\def\tikz@math@parse@afterindex#1={\tikz@math@gobblespaces\tikz@math@parse@assignment}% + +\def\tikz@math@parse@assignment{\tikz@math@collecttosemicolon{\tikz@math@parse@@assignment}} +\def\tikz@math@parse@@assignment{% + \expandafter\expandafter\expandafter\tikz@math@doassignment\expandafter\expandafter\expandafter% + {\expandafter\tikz@math@var\expandafter}\expandafter{\tikz@math@collected}% + \tikz@math@parse% +} + +\def\tikz@math@dollar@char{$} +\def\tikz@math@dollar@char{$}% For annoying syntax highlighters + +\def\tikz@math@doassignment#1#2{% + \tikz@math@ifvarcoordinate{#1}{% + \def\tikz@math@var{#1}% Unfortunately, we must do this again. + \tikz@math@getvarstring{#1}\tikz@math@varstring% And this + \expandafter\pgfutil@in@\tikz@math@dollar@char{#2}% + \edef\tikz@math@expression{#2}% + \ifpgfutil@in@% + \expandafter\tikz@scan@one@point\expandafter\tikz@math@assign@coordinate\tikz@math@expression% + \else% + \expandafter\ifx\csname tikz@library@calc@loaded\endcsname\relax% + \expandafter\tikz@scan@one@point\expandafter\tikz@math@assign@coordinate\tikz@math@expression% + \else% + \expandafter\tikz@scan@one@point\expandafter\tikz@math@assign@coordinate\expandafter% + (\expandafter$\tikz@math@expression$)% + \fi% + \fi% + }{% + \iftikz@math@let% Not really a let + \ifx\tikz@math@current@index\pgfutil@empty% + \edef#1{#2}% + \else% + \edef\tikz@math@tmp{#2}% + \expandafter\expandafter\expandafter\tikz@math@assign@index\expandafter\expandafter\expandafter% + {\expandafter\tikz@math@varstring\expandafter}\expandafter{\tikz@math@tmp}% + \fi% + \tikz@math@letfalse% + \else% + \ifx\tikz@math@current@index\pgfutil@empty% + \tikz@math@getmeaning{#1}% + \ifx\tikz@math@meaning\tikz@math@meaning@dimen% + \pgfmathsetlength{#1}{#2}% + \let\tikz@math@last@assigned@value=\pgfmathresult% + \else% + \ifx\tikz@math@meaning\tikz@math@meaning@count% + \pgfmathsetcount{#1}{#2}% + \let\tikz@math@last@assigned@value=\pgfmathresult% + \else% + \tikz@math@ifvarinteger{#1}{\pgfmathparse{int(#2)}}{\pgfmathparse{#2}}% + \let\tikz@math@last@assigned@value=\pgfmathresult% + \let#1=\pgfmathresult% + \fi% + \fi% + \else% + \tikz@math@ifvarinteger{#1}{\pgfmathparse{int(#2)}}{\pgfmathparse{#2}}% + \expandafter\tikz@math@assign@index\expandafter{\tikz@math@varstring}\pgfmathresult% + \let\tikz@math@last@assigned@value=\pgfmathresult% + \fi% + \fi% + }% +} + + + +\def\tikz@math@assign@index#1#2{% + \expandafter\def\csname#1\endcsname##1{\csname + tikz@math@var@indexed@#1@##1\endcsname}% + \expandafter\edef\csname + tikz@math@var@indexed@#1@\tikz@math@current@index\endcsname{#2}\relax% +} + + + +\def\tikz@math@assign@coordinate#1{% + \pgf@process{#1}% + \ifx\tikz@math@current@index\pgfutil@empty% + \expandafter\edef\csname\tikz@math@varstring\endcsname{\the\pgf@x,\the\pgf@y}% + \expandafter\edef\csname\tikz@math@varstring x\endcsname{\the\pgf@x}% + \expandafter\edef\csname\tikz@math@varstring y\endcsname{\the\pgf@y}% + \else% + \expandafter\tikz@math@assign@index\expandafter{\tikz@math@varstring}{\the\pgf@x,\the\pgf@y}% + \expandafter\tikz@math@assign@index\expandafter{\tikz@math@varstring x}{\the\pgf@x}% + \expandafter\tikz@math@assign@index\expandafter{\tikz@math@varstring y}{\the\pgf@y}% + \fi% +} + + + +\def\tikz@math@keyword@coordinate{coordinate} +\def\tikz@math@process@keyword@coordinate{% + \let\tikz@math@vartype=\tikz@math@keyword@coordinate% + \tikz@math@gobblespaces\tikz@math@process@vartypes% +} + +\def\tikz@math@keyword@integer{integer} +\def\tikz@math@process@keyword@integer{% + \let\tikz@math@vartype=\tikz@math@keyword@integer% + \tikz@math@gobblespaces\tikz@math@process@vartypes% +} +\def\tikz@math@process@keyword@int{% + \tikz@math@process@keyword@integer% +} + +\def\tikz@math@keyword@real{real} +\def\tikz@math@process@keyword@real{% + \let\tikz@math@vartype=\tikz@math@keyword@real% + \tikz@math@gobblespaces\tikz@math@process@vartypes% +} + +\def\tikz@math@process@keyword@point{\tikz@math@process@keyword@coordinate} + + +\def\tikz@math@process@vartypes{\tikz@math@collecttosemicolon{\tikz@math@process@@vartypes}} + +\def\tikz@math@process@@vartypes{% + \expandafter\tikz@math@@process@vartypes\tikz@math@collected,@,\tikz@math% +} + +\def\tikz@math@@process@vartypes#1#2,{% + \def\tikz@math@var{#1}% + \tikz@math@getvarstring{#1}\tikz@math@varstring% + \ifx\tikz@math@var\tikz@math@stop% + \let\tikz@math@next=\tikz@math@@@process@vartypes% + \else% + \expandafter\tikz@math@setvartype\tikz@math@var\tikz@math@vartype% + \def\tikz@math@next{\tikz@math@gobblespaces\tikz@math@@process@vartypes}% + \fi% + \tikz@math@next% +} + +\def\tikz@math@process@keyword@print{\tikz@math@collecttosemicolon{\tikz@math@process@keyword@@print}} +\def\tikz@math@process@keyword@@print{% + \begingroup\tikz@math@collected\endgroup\tikz@math@parse% +} + +\def\tikz@math@@@process@vartypes#1\tikz@math{% + \tikz@math@parse% +} + +\newcount\tikz@math@for@depth + +\def\tikz@math@for@namedef#1{\expandafter\def\csname tikz@math@for@def@#1@\the\tikz@math@for@depth\endcsname} +\def\tikz@math@for@nameedef#1{\expandafter\edef\csname tikz@math@for@def@#1@\the\tikz@math@for@depth\endcsname} +\def\tikz@math@for@namelet#1{\expandafter\let\csname tikz@math@for@def@#1@\the\tikz@math@for@depth\endcsname} + +\def\tikz@math@for@namegetvalue#1#2{% + \def\tikz@math@marshal{\let#2=}% + \expandafter\tikz@math@marshal\csname tikz@math@for@def@#1@\the\tikz@math@for@depth\endcsname} + +\def\tikz@math@process@keyword@for{% + \tikz@math@for% +} + +\def\tikz@math@for@external{% + \ifnum\catcode`\;=13\relax% + \let\tikz@math@semicolon=\tikz@math@semicolon@active% + \let\tikz@math@collecttosemicolon=\tikz@math@collecttosemicolon@active% + \else% + \let\tikz@math@semicolon=\tikz@math@semicolon@other% + \let\tikz@math@collecttosemicolon=\tikz@math@collecttosemicolon@other% + \fi + \advance\tikz@math@for@depth by1\relax% + \tikz@math@for@namedef{execute}{\tikz@math@for@external@execute}% + \tikz@math@for@namedef{finished}{\relax}% + \tikz@math@gobblespaces\tikz@math@for@parsevar} + +\def\tikz@math@for@external@execute#1{#1} + +\def\tikz@math@for{% + \advance\tikz@math@for@depth by1\relax% + \tikz@math@for@namedef{execute}{\tikz@math}% + \tikz@math@for@namedef{finished}{\tikz@math@parse}% + \tikz@math@gobblespaces\tikz@math@for@parsevar} + + +\def\tikz@math@for@parsevar#1{% + \tikz@math@for@namedef{var}{#1}% + \tikz@math@for@parsein} + +\def\tikz@math@getindex#1{% + \tikz@math@@getindex#1\tikz@math@getindex\tikz@math@@getindex% +} + +\def\tikz@math@@getindex#1#2\tikz@math@@getindex{#1} + +\def\tikz@math@for@parsein#1in{% + \def\tikz@math@tmp{#1}% + \ifx\tikz@math@tmp\pgfutil@empty% + \tikz@math@for@namedef{index}{}% + \else% + \tikz@math@for@nameedef{index}{\tikz@math@getindex{#1}}% + \fi% + \tikz@math@gobblespaces\tikz@math@for@parselist% +} + + +\long\def\tikz@math@for@parselist#1{% + \edef\tikz@math@for@list{#1}% + \tikz@math@collecttosemicolon{\tikz@math@for@parseaction}} + +\def\tikz@math@for@parseaction{% + \tikz@math@for@namedef{prevvalue}{}% + \tikz@math@for@namedef{prevprevvalue}{}% + \tikz@math@for@namelet{action}=\tikz@math@collected% + \expandafter\tikz@math@for@scan\tikz@math@for@list,\tikz@math,\tikz@@math% +} + +\def\tikz@math@token{\tikz@math} + + +\def\tikz@math@for@scan#1,{% + \def\tikz@math@for@value{#1}% + \ifx\tikz@math@for@value\tikz@math@token% + \let\tikz@math@next=\tikz@math@for@scan@end% + \else% + \ifx\tikz@math@for@value\pgfutil@empty% + \let\tikz@math@next=\tikz@math@for@scan@end% + \else% + \pgfutil@in@{...}{#1}% + \ifpgfutil@in@% + \let\tikz@math@next=\tikz@math@for@scan@dots% + \else% + \tikz@math@for@namegetvalue{var}{\tikz@math@var}% + \tikz@math@for@namegetvalue{index}{\tikz@math@current@index}% + \tikz@math@for@namegetvalue{action}{\tikz@math@action}% + \expandafter\tikz@math@getvarstring\expandafter{\tikz@math@var}\tikz@math@varstring% + \expandafter\tikz@math@doassignment\expandafter{\tikz@math@var}{#1}% + \tikz@math@for@namelet{value}=\tikz@math@last@assigned@value% + \tikz@math@for@namegetvalue{execute}{\tikz@math@execute}% + \expandafter\tikz@math@execute\expandafter{\tikz@math@action}% + \tikz@math@for@namegetvalue{prevvalue}{\tikz@math@prevvalue}% + \tikz@math@for@namelet{prevprevvalue}=\tikz@math@prevvalue% + \tikz@math@for@namegetvalue{value}{\tikz@math@value}% + \tikz@math@for@namelet{prevvalue}=\tikz@math@value% + \let\tikz@math@next=\tikz@math@for@scan% + \fi% + \fi% + \fi% + \tikz@math@next% +} + +\newdimen\tikz@math@dimen + +\def\tikz@math@for@scan@dots#1,{% + \pgfmathparse{#1}\let\tikz@math@value=\pgfmathresult% + \tikz@math@for@nameedef{endvalue}{\tikz@math@value}% + \tikz@math@for@namegetvalue{prevvalue}{\tikz@math@prevvalue}% + \tikz@math@for@namegetvalue{prevprevvalue}{\tikz@math@prevprevvalue}% + \tikz@math@dimen=\tikz@math@prevvalue pt\relax% + \ifx\tikz@math@prevprevvalue\pgfutil@empty% + \ifdim\tikz@math@prevvalue pt<\tikz@math@value pt\relax%% + \def\tikz@math@step{1pt}% + \else% + \def\tikz@math@step{-1pt}% + \fi% + \else% + \tikz@math@dimen=\tikz@math@prevvalue pt\relax% + \advance\tikz@math@dimen by-\tikz@math@prevprevvalue pt\relax% + \edef\tikz@math@step{\the\tikz@math@dimen}% + \fi% + \ifdim\tikz@math@step<0pt\relax% + \tikz@math@for@namedef{comparitor}{<}% + \else% + \tikz@math@for@namedef{comparitor}{>}% + \fi% + \tikz@math@for@nameedef{step}{\tikz@math@step}% + \tikz@math@for@doloop% +} + +\def\tikz@math@for@doloop{% + \tikz@math@for@namegetvalue{prevvalue}{\tikz@math@prevvalue}% + \tikz@math@for@namegetvalue{step}{\tikz@math@step}% + \tikz@math@for@namegetvalue{comparitor}{\tikz@math@comparitor}% + \tikz@math@for@namegetvalue{endvalue}{\tikz@math@endvalue}% + \tikz@math@dimen=\tikz@math@prevvalue pt\relax% + \advance\tikz@math@dimen by\tikz@math@step\relax% + \ifdim\tikz@math@dimen\tikz@math@comparitor\tikz@math@endvalue pt\relax% + \let\tikz@math@next=\tikz@math@for@endloop% + \else% + \tikz@math@for@nameedef{value}{\pgfmath@tonumber{\tikz@math@dimen}}% + \tikz@math@for@namegetvalue{var}{\tikz@math@var}% + \expandafter\tikz@math@getvarstring\expandafter{\tikz@math@var}\tikz@math@varstring% + \tikz@math@for@namegetvalue{index}{\tikz@math@current@index}% + \tikz@math@for@namegetvalue{action}{\tikz@math@action}% + \tikz@math@for@namegetvalue{value}{\tikz@math@value}% + \expandafter\expandafter\expandafter\tikz@math@doassignment\expandafter\expandafter\expandafter% + {\expandafter\tikz@math@var\expandafter}\expandafter{\tikz@math@value}% + \tikz@math@for@namegetvalue{execute}{\tikz@math@execute}% + \expandafter\tikz@math@execute\expandafter{\tikz@math@action}% + \tikz@math@for@namegetvalue{prevvalue}{\tikz@math@prevvalue}% + \tikz@math@for@namelet{prevprevvalue}=\tikz@math@prevvalue% + \tikz@math@for@namegetvalue{value}{\tikz@math@value}% + \tikz@math@for@namelet{prevvalue}=\tikz@math@value% + \let\tikz@math@next=\tikz@math@for@doloop% + \fi% + \tikz@math@next% +} + +\def\tikz@math@for@endloop{% +\tikz@math@for@scan} + + + + +\def\tikz@math@for@scan@end#1\tikz@@math{% +\tikz@math@for@namegetvalue{finished}{\tikz@math@next}% +\advance\tikz@math@for@depth by-1\relax% +\tikz@math@next} + + + + + +\def\tikz@math@process@keyword@return{% + \tikz@math@collecttosemicolon{\pgfmathparse{\tikz@math@collected}\tikz@math@parse}} + +\def\tikz@math@process@keyword@function{\tikz@math@collecttosemicolon{\tikz@math@process@keyword@@function}} +\def\tikz@math@process@keyword@@function{% + \let\tikz@math@function@name=\pgfutil@empty% + \let\tikz@math@function@arguments=\pgfutil@empty% + \let\tikz@math@function@body=\pgfutil@empty% + \expandafter\expandafter\expandafter\tikz@math@@declarefunction\expandafter\tikz@math@collected\tikz@math@semicolon% +} + +\def\tikz@math@@declarefunction{% + \pgfutil@ifnextchar\bgroup\tikz@math@@@collectbody\tikz@math@@@declarefunction} + + +\def\tikz@math@@@declarefunction#1{% + \if#1(%) + \let\tikz@math@next=\tikz@math@@@collectarguments% + \else% + \expandafter\def\expandafter\tikz@math@function@name\expandafter{\tikz@math@function@name#1}% + \let\tikz@math@next=\tikz@math@@declarefunction% + \fi% + \tikz@math@next% +} +\def\tikz@math@@@collectarguments#1){% + \def\tikz@math@function@arguments{#1}% + \tikz@math@@declarefunction% +} + +\newtoks\tikz@math@toks +\tikz@math@toks={#} +\edef\tikz@math@char@hash{\the\tikz@math@toks} +\tikz@math@toks={} + +\def\tikz@math@@@collectbody{\tikz@math@collecttosemicolon{\tikz@math@@@@collectbody}} + +\def\tikz@math@@@@collectbody{% + \tikz@math@toks={}% + \c@pgf@counta=0\relax% + \ifx\tikz@math@function@arguments\pgfutil@empty% + \else% + \expandafter\tikz@math@createargumentlist\tikz@math@function@arguments,,% + \expandafter\tikz@math@addto@toks\expandafter{\tikz@math@collected}% + \fi% + \edef\tikz@math@local@temp{% + \noexpand\pgfmathdeclarefunction{\tikz@math@function@name}{\the\c@pgf@counta}% + {\noexpand\def\noexpand\return{0}\noexpand\tikz@math{\the\tikz@math@toks}}% + }% + \tikz@math@local@temp + \tikz@math@parse% +} + +\def\tikz@math@addto@toks#1{% + \expandafter\tikz@math@toks\expandafter{\the\tikz@math@toks#1}} + +\def\tikz@math@createargumentlist{% + \pgfutil@ifnextchar + x\tikz@math@@createargumentlist\tikz@math@@createargumentlist} + +\def\tikz@math@comma{,} +\def\tikz@math@@createargumentlist#1,{% + \def\tikz@math@tmp{#1}% + \ifx\tikz@math@tmp\pgfutil@empty% + \let\tikz@math@next=\relax% + \else% + \advance\c@pgf@counta by1\relax% + \tikz@math@addto@toks{#1=}% + \expandafter\expandafter\expandafter\tikz@math@addto@toks\expandafter\expandafter\expandafter% + {\expandafter\tikz@math@char@hash\the\c@pgf@counta;}% + \let\tikz@math@next=\tikz@math@createargumentlist% + \fi% + \tikz@math@next% +} + + + +\let\tikzmath=\tikz@math +\tikzset{evaluate/.code={\tikz@math{#1}}} +\let\tikzmathfor=\tikz@math@for@external + + +\catcode`\@=\tikz@math@at@catcode\relax diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymatrix.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymatrix.code.tex index f1f03c457dd..eb2d65a33fc 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymatrix.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymatrix.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymatrix.code.tex,v 1.2 2008/06/18 23:34:49 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymatrix.code.tex,v 1.4 2013/07/12 22:01:58 tantau Exp $ % A matrix of nodes contains a node in each cell. @@ -15,30 +15,29 @@ \tikzstyle{matrix of nodes}=[% matrix,% cells={anchor=base},% - nodes={% - execute at begin node=,% - execute at end node=, - name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn% - }, execute at begin cell=\tikz@lib@matrix@start@cell,% execute at end cell=\tikz@lib@matrix@end@cell,% - execute at empty cell=\tikz@lib@matrix@empty@cell + execute at empty cell=\tikz@lib@matrix@empty@cell, + execute at begin matrix=\iftikz@handle@active@code\tikz@orig@shorthands\fi,% ] -\def\tikz@lib@matrix@empty@cell{\iftikz@lib@matrix@empty\node{};\fi} +\def\tikz@lib@matrix@empty@cell{\iftikz@lib@matrix@empty\node[name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn]{};\fi} \newif\iftikz@lib@matrix@plain \def\tikz@lib@matrix@start@cell{% \pgfutil@ifnextchar|{\tikz@lib@matrix@with@options}{\tikz@lib@matrix@normal@start@cell}} -\def\tikz@lib@matrix@with@options|#1|{\tikz@lib@matrix@plainfalse\node#1\bgroup\tikz@lib@matrix@startup} +\def\tikz@lib@matrix@with@options|#1|{\tikz@lib@matrix@plainfalse\node% + [name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn]#1\bgroup\tikz@lib@matrix@startup} -\def\tikz@lib@matrix@normal@start@cell{\pgfutil@ifnextchar\let{\tikz@lib@matrix@check}{\tikz@lib@matrix@plainfalse\node\bgroup\tikz@lib@matrix@startup}}% +\def\tikz@lib@matrix@normal@start@cell{\pgfutil@ifnextchar\let{\tikz@lib@matrix@check}{\tikz@lib@matrix@plainfalse\node + [name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn]\bgroup\tikz@lib@matrix@startup}}% \def\tikz@lib@matrix@check#1{% evil hackery to find out about start of path - \pgfutil@ifnextchar\tikz@signal@path{\tikz@lib@matrix@plaintrue\let}{\tikz@lib@matrix@plainfalse\node\bgroup\tikz@lib@matrix@startup\let}% + \pgfutil@ifnextchar\tikz@signal@path{\tikz@lib@matrix@plaintrue\let}{\tikz@lib@matrix@plainfalse\node + [name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn]\bgroup\tikz@lib@matrix@startup\let}% } \def\tikz@lib@matrix@end@cell{% diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymindmap.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymindmap.code.tex index 981d747a3e5..4b6a952ac13 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymindmap.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymindmap.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymindmap.code.tex,v 1.9 2009/11/12 09:53:02 ludewich Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymindmap.code.tex,v 1.10 2013/07/16 12:43:14 tantau Exp $ \usetikzlibrary{trees,decorations} @@ -98,7 +98,10 @@ \tikzstyle{circle connection bar}= [to path={ - \pgfextra{\tikz@compute@circle@radii\tikz@compute@segmentamplitude} + \pgfextra{% + \tikz@lib@mindmap@check{\tikztostart}% + \tikz@compute@circle@radii\tikz@compute@segmentamplitude% + } [every circle connection bar] decorate [decoration=circle connection bar] { -- (\tikztotarget) \tikztonodes} @@ -129,12 +132,31 @@ append after command={[fill=\tikz@concept@color,draw=none]} } + +% Check whether start and end are nodes! + +\def\tikz@lib@mindmap@check#1{% + \pgfutil@ifundefined{pgf@sh@ns@#1}% + {\tikzerror{You are attempting to connect two things by a circle + connection bar where one is not a node}}{% + \expandafter\ifx\csname pgf@sh@ns@#1\endcsname\tikz@lib@coordinate@text% + \tikzerror{You are attempting to connect node of shape + 'coordinate' by a circle connection bar. The shape should be + 'circle' or something similar, instead.} + \fi% + } +} + +\def\tikz@lib@coordinate@text{coordinate} + + % Switch color in a mindmap \tikzoption{circle connection bar switch color}{\tikz@parse@switch#1\pgf@unique} \def\tikz@parse@switch from (#1) to (#2)\pgf@unique{% \tikzset{to path={% \pgfextra{% + \tikz@lib@mindmap@check{\tikztostart}% \tikz@compute@circle@radii\tikz@compute@segmentamplitude% \global\let\tikz@lib@save@start=\tikztostart% \global\let\tikz@lib@save@target=\tikztotarget% diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarypetri.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarypetri.code.tex index 524bea7a28f..e67027eadfb 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarypetri.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarypetri.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarypetri.code.tex,v 1.2 2008/06/18 23:34:49 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarypetri.code.tex,v 1.3 2013/07/17 08:56:23 tantau Exp $ % Styles for places: @@ -59,7 +59,7 @@ \tikzoption{structured tokens}{% \tikzset{append after command={}% - {[children are tokens]child foreach \tikz@child@name in {#1} {node[token]{\tikz@child@name}}}}% + {[children are tokens]child foreach \tikzpetrichildname in {#1} {node[token]{\tikzpetrichildname}}}}% } diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryquotes.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryquotes.code.tex new file mode 100644 index 00000000000..4369b7e2dc2 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryquotes.code.tex @@ -0,0 +1,88 @@ +% Copyright 2011 by Till Tantau +% +% This file may be distributed and/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 details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryquotes.code.tex,v 1.3 2013/08/28 15:24:27 tantau Exp $ + +\def\tikz@quote@parser#1{\tikz@quote@@parser#1\pgf@stop} +\def\tikz@quote@@parser"#1"{% + \pgfutil@ifnextchar\bgroup{% + \tikz@quote@@parser@group{#1}}{% + \pgfutil@ifnextchar'{% + \tikz@quote@@parser@apo{#1}}{% + \tikz@quote@@parser@normal{#1}}}} +\def\tikz@quote@@parser@apo#1'{% + \pgfutil@ifnextchar\bgroup{\tikz@quote@@parser@apo@group{#1}}{\tikz@quote@@parser@apo@normal{#1}}} +\def\tikz@quote@@parser@group#1#2#3\pgf@stop{% + \expandafter\def\expandafter\tikz@temp\expandafter{\tikz@quotes@as{#1}{#2}}% + \expandafter\pgfkeysalso\expandafter{\tikz@temp}% +} +\def\tikz@quote@@parser@normal#1#2\pgf@stop{% + \expandafter\def\expandafter\tikz@temp\expandafter{\tikz@quotes@as{#1}{#2}}% + \expandafter\pgfkeysalso\expandafter{\tikz@temp}% +} +\def\tikz@quote@@parser@apo@group#1#2#3\pgf@stop{% + \expandafter\def\expandafter\tikz@temp\expandafter{\tikz@quotes@as{#1}{',#2}}% + \expandafter\pgfkeysalso\expandafter{\tikz@temp}% +} +\def\tikz@quote@@parser@apo@normal#1#2\pgf@stop{% + \expandafter\def\expandafter\tikz@temp\expandafter{\tikz@quotes@as{#1}{',#2}}% + \expandafter\pgfkeysalso\expandafter{\tikz@temp}% +} + +\pgfkeys{/handlers/first char syntax=true} + +\def\tikz@enable@node@quotes{% + \pgfkeyssetvalue{/handlers/first char syntax/the character "}{\tikz@quote@parser}% + \let\tikz@quotes@as\tikz@node@quotes@as% +} +\def\tikz@enable@edge@quotes{% + \pgfkeyssetvalue{/handlers/first char syntax/the character "}{\tikz@quote@parser}% + \let\tikz@quotes@as\tikz@edge@quotes@as% +} +\def\tikz@enable@pic@quotes{% + \pgfkeyssetvalue{/handlers/first char syntax/the character "}{\tikz@quote@parser}% + \let\tikz@quotes@as\tikz@pic@quotes@as% +} + +\tikzset{ + node quotes mean/.code={\def\tikz@node@quotes@as##1##2{#1}}, + edge quotes mean/.code={\def\tikz@edge@quotes@as##1##2{#1}}, + pic quotes mean/.code={\def\tikz@pic@quotes@as##1##2{#1}}, + quotes mean pin/.style={node quotes mean={ + pin={[direction shorthands,every pin quotes/.try,##2]##1}}}, + quotes mean label/.style={node quotes mean={ + label={[direction shorthands,every label quotes/.try,##2]##1}}}, + quotes mean label, + edge quotes mean={edge node={node [every edge quotes,#2]{#1}}}, + pic quotes mean={pic text={#1},pic text options={every pic quotes/.try,#2}}, + every edge quotes/.style={auto}, + direction shorthands/.code={% + \pgfkeyslet{/tikz/above/.@cmd}\tikz@label@@above + \pgfkeyslet{/tikz/below/.@cmd}\tikz@label@@below + \pgfkeyslet{/tikz/left/.@cmd}\tikz@label@@left + \pgfkeyslet{/tikz/right/.@cmd}\tikz@label@@right + \pgfkeyslet{/tikz/above left/.@cmd}\tikz@label@@above@left + \pgfkeyslet{/tikz/above right/.@cmd}\tikz@label@@above@right + \pgfkeyslet{/tikz/below left/.@cmd}\tikz@label@@below@left + \pgfkeyslet{/tikz/below right/.@cmd}\tikz@label@@below@right + } +} + +\def\tikz@label@@above#1\pgfeov{\pgfkeysalso{label position=90,pin position=90}} +\def\tikz@label@@below#1\pgfeov{\pgfkeysalso{label position=-90,pin position=-90}} +\def\tikz@label@@left#1\pgfeov{\pgfkeysalso{label position=180,pin position=180}} +\def\tikz@label@@right#1\pgfeov{\pgfkeysalso{label position=0,pin position=0}} +\def\tikz@label@@above@left#1\pgfeov{\pgfkeysalso{label position=135,pin position=135}} +\def\tikz@label@@below@left#1\pgfeov{\pgfkeysalso{label position=-135,pin position=-135}} +\def\tikz@label@@above@right#1\pgfeov{\pgfkeysalso{label position=45,pin position=45}} +\def\tikz@label@@below@right#1\pgfeov{\pgfkeysalso{label position=-45,pin position=-45}} + + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysnakes.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysnakes.code.tex index 363beabe4c7..3fa9d3f8f46 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysnakes.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysnakes.code.tex @@ -7,9 +7,9 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysnakes.code.tex,v 1.6 2008/02/05 13:08:05 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysnakes.code.tex,v 1.7 2013/07/15 12:05:31 tantau Exp $ -\PackageWarning{tikz}{Snakes have been superseded by +\pgfwarning{Snakes have been superseded by decorations. Please use the decoration libraries instead of the snakes library} diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryspy.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryspy.code.tex index fd45a761535..099448c5165 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryspy.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryspy.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryspy.code.tex,v 1.2 2009/12/04 11:59:38 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryspy.code.tex,v 1.4 2011/05/19 08:56:54 tantau Exp $ @@ -43,10 +43,10 @@ width/.style={minimum width=##1}, execute at begin scope={% \let\tikz@lib@spy@save=\tikz@lib@spy@collection% - \setbox\tikz@lib@spybox=\hbox\bgroup% + \setbox\tikz@lib@spybox=\hbox\bgroup\bgroup% \let\spy=\tikz@lib@spy@parse}, execute at end scope={% - \egroup% + \egroup\egroup% {% \copy\tikz@lib@spybox% \tikz@lib@spy@collection% @@ -99,13 +99,15 @@ }]{}; \node [alias=tikzspyinnode,inner sep=0pt,outer sep=0pt,at={#2},every spy in node/.try, path picture={\node[anchor=center,tikz@lib@reset@gs]{\nullfont% + \pgfpicture\relax\pgfsetbaseline{default}\pgfsettrimleft{default}\pgfsettrimright{default}% \pgftransformreset% \let\tikz@transform=\relax% \expandafter\tikzset\expandafter{\tikz@lib@spy@lens}% \pgflowlevelsynccm% \tikz@scan@one@point\tikz@lib@spy@shift#2% \pgflowlevelsynccm% - \copy\tikz@lib@spybox};}]#3{}; + \copy\tikz@lib@spybox% + \endpgfpicture};}]#3{}; \tikz@lib@spy@path \endscope } diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysvg.path.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysvg.path.code.tex index 0cee69a2fde..f0eae010424 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysvg.path.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysvg.path.code.tex @@ -7,16 +7,18 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysvg.path.code.tex,v 1.1 2009/01/24 17:07:14 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysvg.path.code.tex,v 1.2 2013/09/23 18:04:35 tantau Exp $ \usepgflibrary{svg.path} \def\tikz@svg@path vg{\pgfutil@ifnextchar[\tikz@svg@@path{\tikz@svg@@path[]}}%} -\def\tikz@svg@@path[#1]#2"#3"{% +\def\tikz@svg@@path[#1]{\pgfutil@ifnextchar"{\tikz@svg@@path@old{#1}}{\tikz@svg@@path@new{#1}}} +\def\tikz@svg@@path@new#1#2{\tikz@svg@@path@old{#1}"#2"} +\def\tikz@svg@@path@old#1"#2"{ {% \tikzset{#1}% - \pgfpathsvg{#3}% + \pgfpathsvg{#2}% }% { \pgftransforminvert diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex index e2a9cb2d649..f8c1e8792f4 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex @@ -7,9 +7,11 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/tikz.code.tex,v 1.76 2010/10/13 09:20:31 ludewich Exp $ +\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/tikz.code.tex,v 1.142 2013/12/13 15:11:58 tantau Exp $ +\def\tikzerror#1{\pgfutil@packageerror{tikz}{#1}{}} + % Always-present libraries (|\usepgflibrary| defined in % \file{pgfutil-common.tex}). \usepgflibrary{plothandlers} @@ -23,7 +25,9 @@ \newdimen\tikzsiblingdistance \newbox\tikz@figbox +\newbox\tikz@figbox@bg \newbox\tikz@tempbox +\newbox\tikz@tempbox@bg \newcount\tikztreelevel \newcount\tikznumberofchildren @@ -190,6 +194,11 @@ \tikzoption{opacity}{\tikz@addoption{\pgfsetstrokeopacity{#1}\pgfsetfillopacity{#1}}} +% Blend mode + +\tikzset{blend mode/.code={\tikz@addoption{\pgfsetblendmode{#1}}}} + + % Main color options \tikzoption{color}{% \tikz@addoption{% @@ -207,6 +216,7 @@ \fi% \pgfutil@colorlet{tikz@color}{#1}% \pgfutil@colorlet{.}{tikz@color}% + % \pgfsetcolor{.}% \pgfsys@color@reset@inordertrue% }% @@ -295,6 +305,99 @@ }% } +\tikzset{turn/.code={% + \pgf@x=0pt% + \pgf@y\pgf@x% + \pgf@process{\tikz@tangent}% + \advance\pgf@x by-\tikz@lastx% + \advance\pgf@y by-\tikz@lasty% + \pgfpointnormalised{}% x/y = normalised vector + \pgf@x=-\pgf@x% + \pgf@ya=-\pgf@y% + \pgftransformcm% + {\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@ya}}% + {\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@x}}{\pgfqpoint{\tikz@lastx}{\tikz@lasty}}% + }% +} + +\def\tikz@tangent@lookup{% + \pgfgetpath\tikz@temp% + \pgfprocesspathextractpoints\tikz@temp% + \pgfpointsecondlastonpath% +} + +% Code for rotating the xyz coordinate system +% around the x, y, or z vector. +% +\def\tikz@xyz@rotate@let{% + \let\pgf@z=\pgf@yc + \let\pgf@za=\pgf@xc% +} + +\def\tikz@xyz@rotate@xyz@xaxis#1#2#3#4{% + \tikz@xyz@rotate@let% + \pgf@x=#1\relax% + \pgf@ya=#2\relax% + \pgf@za=#3\relax% + \pgfmathsin@{#4}\let\tikz@xyz@sin=\pgfmathresult% + \pgfmathcos@{#4}\let\tikz@xyz@cos=\pgfmathresult% + \pgf@y=\tikz@xyz@cos\pgf@ya% + \advance\pgf@y by-\tikz@xyz@sin\pgf@za% + \pgf@z=\tikz@xyz@sin\pgf@ya% + \advance\pgf@z by\tikz@xyz@cos\pgf@za% +} + +\def\tikz@xyz@rotate@xyz@yaxis#1#2#3#4{% + \tikz@xyz@rotate@let% + \pgf@xa=#1\relax% + \pgf@y=#2\relax% + \pgf@za=#3\relax% + \pgfmathsin@{#4}\let\tikz@xyz@sin=\pgfmathresult% + \pgfmathcos@{#4}\let\tikz@xyz@cos=\pgfmathresult% + \pgf@x=\tikz@xyz@cos\pgf@xa% + \advance\pgf@x by\tikz@xyz@sin\pgf@za% + \pgf@z=-\tikz@xyz@sin\pgf@xa% + \advance\pgf@z by\tikz@xyz@cos\pgf@za% +} + +\def\tikz@xyz@rotate@xyz@zaxis#1#2#3#4{% + \tikz@xyz@rotate@let% + \pgf@xa=#1\relax% + \pgf@ya=#2\relax% + \pgf@z=#3\relax% + \pgfmathsin@{#4}\let\tikz@xyz@sin=\pgfmathresult% + \pgfmathcos@{#4}\let\tikz@xyz@cos=\pgfmathresult% + \pgf@x=\tikz@xyz@cos\pgf@xa% + \advance\pgf@x by-\tikz@xyz@sin\pgf@ya% + \pgf@y=\tikz@xyz@sin\pgf@xa% + \advance\pgf@y by\tikz@xyz@cos\pgf@ya% +} + +\tikzset{rotate around x/.code={% + \tikz@xyz@rotate@let% + \tikz@xyz@rotate@xyz@xaxis{0pt}{1pt}{0pt}{#1}% + \pgfextract@process\tikz@xyz@rotate@yvec{\pgfpointxyz{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@z}}}% + \tikz@xyz@rotate@xyz@xaxis{0pt}{0pt}{1pt}{#1}% + \pgfsetzvec{\pgfpointxyz{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@z}}}% + \pgfsetyvec{\tikz@xyz@rotate@yvec}% + }, + rotate around y/.code={% + \tikz@xyz@rotate@let% + \tikz@xyz@rotate@xyz@yaxis{1pt}{0pt}{0pt}{#1}% + \pgfextract@process\tikz@xyz@rotate@xvec{\pgfpointxyz{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@z}}}% + \tikz@xyz@rotate@xyz@yaxis{0pt}{0pt}{1pt}{#1}% + \pgfsetzvec{\pgfpointxyz{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@z}}}% + \pgfsetxvec{\tikz@xyz@rotate@xvec}% + }, + rotate around z/.code={% + \tikz@xyz@rotate@let% + \tikz@xyz@rotate@xyz@zaxis{1pt}{0pt}{0pt}{#1}% + \pgfextract@process\tikz@xyz@rotate@xvec{\pgfpointxyz{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@z}}}% + \tikz@xyz@rotate@xyz@zaxis{0pt}{1pt}{0pt}{#1}% + \pgfsetyvec{\pgfpointxyz{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@z}}}% + \pgfsetxvec{\tikz@xyz@rotate@xvec}% + } +} % Grid options \tikzoption{xstep}{\def\tikz@grid@x{#1}} @@ -325,7 +428,14 @@ \def\tikz@nonetext{none} \tikzoption{path only}[]{\let\tikz@mode=\pgfutil@empty} -\tikzoption{shade}[]{\tikz@addmode{\tikz@mode@shadetrue}} +\tikzset{ + shade/.is choice, + shade/.default=true, + shade/true/.code=\tikz@addmode{\tikz@mode@shadetrue}, + shade/false/.code=\tikz@addmode{\tikz@mode@shadefalse}, + shade/none/.code=\tikz@addmode{\tikz@mode@shadefalse}, +} + \tikzoption{fill}[]{% \edef\tikz@temp{#1}% \ifx\tikz@temp\tikz@nonetext% @@ -364,7 +474,7 @@ \tikzset{insert path/.code=\tikz@scan@next@command#1\pgf@stop} % Pattern options -\tikzset{pattern/.code=\PackageError{tikz}{You need to say \string\usetikzlibrary{patterns}}{}, +\tikzset{pattern/.code=\tikzerror{You need to say \string\usetikzlibrary{patterns}}, pattern color/.style=pattern} % Path pictures @@ -412,8 +522,10 @@ % Transparency groups \newif\iftikz@transparency@group -\tikzset{/tikz/transparency group/.is if=tikz@transparency@group} +\tikzset{/tikz/transparency group/.code=\tikz@transparency@grouptrue\def\tikz@transparency@group@options{isolated=true,#1}\let\tikz@blend@group\pgfutil@empty} +\tikzset{/tikz/blend group/.code=\tikz@transparency@grouptrue\def\tikz@transparency@group@options{isolated=true}\def\tikz@blend@group{\pgfsetblendmode{#1}}} +\let\tikz@blend@group\pgfutil@empty % Shading options \tikzoption{shading}{\def\tikz@shading{#1}\tikz@addmode{\tikz@mode@shadetrue}} @@ -475,7 +587,6 @@ % Pin options \tikzset{ - pin/.code={\pgfutil@ifnextchar[{\tikz@parse@pin}{\tikz@parse@pin[]}#1:\pgf@nil},%} pin distance/.store in=\tikz@pin@distance, pin distance=3ex, pin position/.store in=\tikz@pin@default@pos, @@ -489,34 +600,90 @@ }% } -\long\def\tikz@parse@pin[#1]#2:#3\pgf@nil{% +\tikzset{% + pin/.code={% + \begingroup + \ifnum\the\catcode`\:=\active\relax + \def\tikz@next{% + \endgroup + \tikz@parse@pin@active@i{#1}}% + \else + \def\tikz@next{% + \endgroup + \pgfutil@ifnextchar[%] + {\tikz@parse@pin@nonactive} + {\tikz@parse@pin@nonactive[]}#1:\pgf@nil}% + \fi + \tikz@next}} + +\begingroup + \catcode`\:=\active\relax + + \gdef\tikz@parse@pin@active@i#1{% + \pgfutil@ifnextchar[%] + {\tikz@parse@pin@active} + {\tikz@parse@pin@active[]}#1:\pgf@nil} + + \long\gdef\tikz@parse@pin@active[#1]#2:#3\pgf@nil{% + \def\tikz@temp{#3}% + \ifx\tikz@temp\pgfutil@empty + % no position, use default + \tikz@@parse@pin@active[#1]\tikz@pin@default@pos:#2:\pgf@nil% + \else + \tikz@@parse@pin@active[#1]#2:#3\pgf@nil% + \fi} + + \long\gdef\tikz@@parse@pin@active[#1]#2:#3:\pgf@nil{% + \tikzset{% + append after command = {% + \bgroup + [current point is local = true] + \pgfextra{\let\tikz@save@last@node=\tikzlastnode\tikz@node@is@a@labelfalse}% + node [every pin, + tikz@label@angle = #2, + #1, + append after command = {% + (\tikz@save@last@node) + edge [every pin edge, + tikz@pre@pin@edge, + tikz@pin@options] + (\tikzlastnode)}, + tikz@label@post = \tikz@pin@distance, + tikz@pin@post] {#3} + \egroup}}} +\endgroup + +\long\def\tikz@parse@pin@nonactive[#1]#2:#3\pgf@nil{% \def\tikz@temp{#3}% - \ifx\tikz@temp\pgfutil@empty% + \ifx\tikz@temp\pgfutil@empty % no position, use default - \tikz@@parse@pin[#1]\tikz@pin@default@pos:#2:\pgf@nil% - \else% - \tikz@@parse@pin[#1]#2:#3\pgf@nil% - \fi% -} - -\long\def\tikz@@parse@pin[#1]#2:#3:\pgf@nil{% - \tikzset{append after command={% - \bgroup - [current point is local=true] - \pgfextra{\let\tikz@save@last@node=\tikzlastnode}% - node [every pin,tikz@label@angle=#2,#1,% - append after command={(\tikz@save@last@node) edge[every pin edge,tikz@pre@pin@edge,tikz@pin@options] (\tikzlastnode)}, - tikz@label@post=\tikz@pin@distance,tikz@pin@post] - {#3} - \egroup% - }} -} + \tikz@@parse@pin@nonactive[#1]\tikz@pin@default@pos:#2:\pgf@nil% + \else + \tikz@@parse@pin@nonactive[#1]#2:#3\pgf@nil% + \fi} +\long\def\tikz@@parse@pin@nonactive[#1]#2:#3:\pgf@nil{% + \tikzset{% + append after command = {% + \bgroup + [current point is local = true] + \pgfextra{\let\tikz@save@last@node=\tikzlastnode\tikz@node@is@a@labelfalse}% + node [every pin, + tikz@label@angle = #2, + #1, + append after command = {% + (\tikz@save@last@node) + edge [every pin edge, + tikz@pre@pin@edge, + tikz@pin@options] + (\tikzlastnode)}, + tikz@label@post = \tikz@pin@distance, + tikz@pin@post] {#3} + \egroup}}} % Label and pin options \tikzset{ - label/.code={\pgfutil@ifnextchar[{\tikz@parse@label}{\tikz@parse@label[]}#1:\pgf@nil},%} label distance/.store in=\tikz@label@distance, label distance=0pt, label position/.store in=\tikz@label@default@pos, @@ -583,31 +750,86 @@ \newif\iftikz@label@simple% -\def\tikz@parse@label[#1]#2:#3\pgf@nil{% - \def\tikz@temp{#3}% - \ifx\tikz@temp\pgfutil@empty% +\tikzset{% + label/.code={% + \begingroup + \ifnum\the\catcode`\:=\active\relax + \def\tikz@next{% + \endgroup + \tikz@parse@label@active@i{#1}}% + \else + \def\tikz@next{% + \endgroup + \pgfutil@ifnextchar[%] + {\tikz@parse@label@nonactive} + {\tikz@parse@label@nonactive[]}#1:\pgf@nil}% + \fi + \tikz@next}} + +\begingroup + \catcode`\:=\active\relax + + \gdef\tikz@parse@label@active@i#1{% + \pgfutil@ifnextchar[%] + {\tikz@parse@label@active} + {\tikz@parse@label@active[]}#1:\pgf@nil} + + \gdef\tikz@parse@label@active[#1]#2:#3\pgf@nil{% + \def\tikz@temp{#3}% + \ifx\tikz@temp\pgfutil@empty % no position, use default - \tikz@@parse@label[#1]\tikz@label@default@pos:#2:\pgf@nil% - \else% - \tikz@@parse@label[#1]#2:#3\pgf@nil% - \fi% -} + \tikz@@parse@label@active[#1]\tikz@label@default@pos:#2:\pgf@nil% + \else + \def\tikz@temp{#2}% + \ifx\tikz@temp\pgfutil@empty + \tikz@@parse@label@active[#1]\tikz@label@default@pos:#3\pgf@nil% + \else + \tikz@@parse@label@active[#1]#2:#3\pgf@nil% + \fi + \fi + } -\def\tikz@@parse@label[#1]#2:#3:\pgf@nil{% - \tikzset{append after command={ - \bgroup - [current point is local=true] - \pgfextra{\let\tikz@save@last@fig@name=\tikz@last@fig@name}% - node - [every label,% - tikz@label@angle=#2,% - #1,% - tikz@label@post=\tikz@label@distance]% - {#3}% - \pgfextra{\global\let\tikz@last@fig@name=\tikz@save@last@fig@name}% - \egroup% - }} -} + \gdef\tikz@@parse@label@active[#1]#2:#3:\pgf@nil{% + \tikzset{% + append after command = {% + \bgroup + [current point is local=true] + \pgfextra{\let\tikz@save@last@fig@name=\tikz@last@fig@name\tikz@node@is@a@labelfalse} + node [every label, + tikz@label@angle = #2, + #1, + tikz@label@post = \tikz@label@distance] {\iftikz@handle@active@nodes\expandafter\scantokens\else\expandafter\pgfutil@firstofone\fi{#3}} + \pgfextra{\global\let\tikz@last@fig@name=\tikz@save@last@fig@name} + \egroup}}} +\endgroup + +\def\tikz@parse@label@nonactive[#1]#2:#3\pgf@nil{% + \def\tikz@temp{#3}% + \ifx\tikz@temp\pgfutil@empty + % no position, use default + \tikz@@parse@label@nonactive[#1]\tikz@label@default@pos:#2:\pgf@nil% + \else + \def\tikz@temp{#2}% + \ifx\tikz@temp\pgfutil@empty + \tikz@@parse@label@nonactive[#1]\tikz@label@default@pos:#3\pgf@nil% + \else + \tikz@@parse@label@nonactive[#1]#2:#3\pgf@nil% + \fi + \fi +} + +\def\tikz@@parse@label@nonactive[#1]#2:#3:\pgf@nil{% + \tikzset{% + append after command = {% + \bgroup + [current point is local=true] + \pgfextra{\let\tikz@save@last@fig@name=\tikz@last@fig@name\tikz@node@is@a@labelfalse} + node [every label, + tikz@label@angle = #2, + #1, + tikz@label@post = \tikz@label@distance] {\iftikz@handle@active@nodes\expandafter\scantokens\else\expandafter\pgfutil@firstofone\fi{#3}} + \pgfextra{\global\let\tikz@last@fig@name=\tikz@save@last@fig@name} + \egroup}}} \expandafter\def\csname tikz@label@angle@is@right\endcsname{\def\tikz@label@angle{0}} \expandafter\def\csname tikz@label@angle@is@above right\endcsname{\def\tikz@label@angle{45}} @@ -650,7 +872,24 @@ % General node options -\tikzoption{name}{\edef\tikz@fig@name{#1}} +\tikzset{ + name/.code={\edef\tikz@fig@name{\tikz@pp@name{#1}}},% + name prefix/.initial=,% + name suffix/.initial=% +} +\def\tikz@pp@name#1{\csname pgfk@/tikz/name prefix\endcsname#1\csname pgfk@/tikz/name suffix\endcsname} + + +\tikzset{ + node contents/.code=\def\tikz@node@content{#1}, + pic type/.code=\def\tikz@node@content{#1}, % alias +} + +\tikzset{ + behind path/.code=\def\tikz@whichbox{\tikz@figbox@bg}, + in front of path/.code=\def\tikz@whichbox{\tikz@figbox} +} +\def\tikz@whichbox{\tikz@figbox} \tikzoption{at}{\tikz@scan@one@point\tikz@set@at#1} \def\tikz@set@at#1{\def\tikz@node@at{#1}}% @@ -665,6 +904,17 @@ \def\tikzaddafternodepathoption#1{#1\tikzset{prefix after command={\pgfextra{#1}}}} \tikzset{after node path/.style={append after command={#1}}} + +% Pic options +\newif\iftikz@node@is@pic +\tikzset{pic text/.store in=\tikzpictext} +\let\tikzpictext\relax +\tikzset{pic text options/.store in=\tikzpictextoptions} +\let\tikzpictextoptions\pgfutil@empty + + +% Anchoring + \tikzoption{anchor}{\def\tikz@anchor{#1}\let\tikz@do@auto@anchor=\relax} \tikzoption{left}[]{\def\tikz@anchor{east}\tikz@possibly@transform{x}{-}{#1}} @@ -706,6 +956,14 @@ \def\tikz@extract@node@dist#1and#2\pgf@stop{% \def\tikz@extracted@node@distance{#1}} +\tikzset{ + transform shape nonlinear/.is choice, + transform shape nonlinear/.default=true, + transform shape nonlinear/true/.code=\let\tikz@nlt\relax, + transform shape nonlinear/false/.code=\def\tikz@nlt{\pgfapproximatenonlineartranslation}, + transform shape nonlinear=false +} + \tikzoption{transform shape}[true]{% \csname tikz@fullytransformed#1\endcsname% @@ -746,7 +1004,7 @@ \tikzoption{sloped}[true]{\csname pgfslopedattime#1\endcsname} \tikzoption{allow upside down}[true]{\csname pgfallowupsidedownattime#1\endcsname} -\tikzoption{pos}{\edef\tikz@time{#1}} +\tikzoption{pos}{\edef\tikz@time{#1}\ifx\tikz@time\pgfutil@empty\else\pgfmathsetmacro\tikz@time{\tikz@time}\fi} \tikzoption{auto}[]{\csname tikz@install@auto@anchor@#1\endcsname} \tikzoption{swap}[]{% @@ -757,6 +1015,8 @@ \def\tikz@auto@anchor@direction{left}% \fi% } +\tikzset{'/.style=swap} % shorthand + \def\tikz@install@auto@anchor@{\let\tikz@do@auto@anchor=\tikz@auto@anchor@on} \def\tikz@install@auto@anchor@false{\let\tikz@do@auto@anchor=\relax} @@ -775,30 +1035,34 @@ % Text options \tikzoption{text}{\def\tikz@textcolor{#1}} \tikzoption{font}{\def\tikz@textfont{#1}} +\tikzoption{node font}{\def\tikz@node@textfont{#1}} \tikzoption{text opacity}{\def\tikz@textopacity{#1}} \tikzoption{text width}{\def\tikz@text@width{#1}} \tikzoption{text height}{\def\tikz@text@height{#1}} \tikzoption{text depth}{\def\tikz@text@depth{#1}} \tikzoption{text ragged}[]% -{\def\tikz@text@action{\raggedright\rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax}} -\tikzoption{text badly ragged}[]{\def\tikz@text@action{\raggedright\relax}} +{\def\tikz@text@action{\pgfutil@raggedright\rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax}} +\tikzoption{text badly ragged}[]{\def\tikz@text@action{\pgfutil@raggedright\relax}} \tikzoption{text ragged left}[]% -{\def\tikz@text@action{\raggedleft\leftskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax}} -\tikzoption{text badly ragged left}[]{\def\tikz@text@action{\raggedleft\relax}} +{\def\tikz@text@action{\pgfutil@raggedleft\leftskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax}} +\tikzoption{text badly ragged left}[]{\def\tikz@text@action{\pgfutil@raggedleft\relax}} \tikzoption{text justified}[]{\def\tikz@text@action{\leftskip0pt\rightskip0pt\relax}} \tikzoption{text centered}[]{\def\tikz@text@action{% \leftskip0pt plus2em% \rightskip0pt plus2em% \spaceskip.3333em \xspaceskip.5em% \parfillskip=0pt% + \iftikz@warn@for@narrow@centered\else\hbadness10000\fi% \let\\=\@centercr% for latex \relax}} \tikzoption{text badly centered}[]% {\def\tikz@text@action{% \let\\=\@centercr% for latex \parfillskip=0pt% - \rightskip\@flushglue% - \leftskip\@flushglue\relax}} + \rightskip\pgfutil@flushglue% + \leftskip\pgfutil@flushglue\relax}} +\tikzset{badness warnings for centered text/.is if=tikz@warn@for@narrow@centered} +\newif\iftikz@warn@for@narrow@centered \let\tikz@text@width=\pgfutil@empty \let\tikz@text@height=\pgfutil@empty @@ -806,8 +1070,9 @@ \let\tikz@textcolor=\pgfutil@empty \let\tikz@textfont=\pgfutil@empty \let\tikz@textopacity=\pgfutil@empty +\let\tikz@node@textfont=\pgfutil@empty -\def\tikz@text@action{\raggedright\rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax} +\def\tikz@text@action{\pgfutil@raggedright\rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax} % Alignment @@ -832,57 +1097,22 @@ % Arrow options \tikzoption{arrows}{\tikz@processarrows{#1}} -\tikzoption{>}{% - \tikz@set@pointed{\csname pgf@arrows@invert#1\endcsname}{#1}% - \expandafter\tikz@processarrows\expandafter{\tikz@current@arrows}% -} + +\tikzoption{>}{\pgfdeclarearrow{name=<->,means={#1}}}% +\pgfdeclarearrow{name=|<->|, means={>[sep=0pt].|}} \tikzoption{shorten <}{\pgfsetshortenstart{#1}} \tikzoption{shorten >}{\pgfsetshortenend{#1}} -\def\tikz@set@pointed#1#2{% - \pgfutil@ifundefined{pgf@arrow@code@tikze@>@#2} - {% - \pgfarrowsdeclarealias{tikzs@<@#2}{tikze@>@#2}{#1}{#2}% - \pgfarrowsdeclarereversed{tikzs@>@#2}{tikze@<@#2}{#1}{#2}% - \pgfarrowsdeclarecombine*{tikz@|<@#2}{tikz@>|@#2}{#1}{#2}{|}{|}% - \pgfarrowsdeclaredouble[\pgflinewidth]{tikzs@<<@#2}{tikze@>>@#2}{#1}{#2}%<< - \pgfarrowsdeclarereversed{tikzs@>>@#2}{tikze@<<@#2}{tikzs@<<@#2}{tikze@>>@#2}%<< - }{}% - \pgfutil@namedef{tikz@special@arrow@start<}{tikzs@<@#2}% - \pgfutil@namedef{tikz@special@arrow@end>}{tikze@>@#2}% - \pgfutil@namedef{tikz@special@arrow@start>}{tikzs@>@#2}% - \pgfutil@namedef{tikz@special@arrow@end<}{tikze@<@#2}% - \pgfutil@namedef{tikz@special@arrow@start|<}{tikz@|<@#2}% - \pgfutil@namedef{tikz@special@arrow@end>|}{tikz@>|@#2}% - \pgfutil@namedef{tikz@special@arrow@start<<}{tikzs@<<@#2}% - \pgfutil@namedef{tikz@special@arrow@end>>}{tikze@>>@#2}%<< - \pgfutil@namedef{tikz@special@arrow@start>>}{tikzs@>>@#2}%<< - \pgfutil@namedef{tikz@special@arrow@end<<}{tikze@<<@#2}%<< -} - \def\tikz@processarrows#1{% \def\tikz@current@arrows{#1}% \def\tikz@temp{#1}% \ifx\tikz@temp\pgfutil@empty% \else% - \tikz@@processarrows#1\@nil - \fi% -} -\def\tikz@@processarrows#1-#2\@nil{% - \expandafter\ifx\csname tikz@special@arrow@start#1\endcsname\relax% - \pgfsetarrowsstart{#1} - \else% - \pgfsetarrowsstart{\csname tikz@special@arrow@start#1\endcsname}% - \fi% - \expandafter\ifx\csname tikz@special@arrow@end#2\endcsname\relax% - \pgfsetarrowsend{#2} - \else% - \pgfsetarrowsend{\csname tikz@special@arrow@end#2\endcsname}% + \pgfsetarrows{#1}% \fi% } -\tikz@set@pointed{\pgf@arrows@invertto}{to} \def\tikz@current@arrows{-} % Parabola options @@ -900,11 +1130,16 @@ % Axis options \tikzoption{domain}{\edef\tikz@plot@domain{#1}\expandafter\tikz@plot@samples@recalc\tikz@plot@domain\relax} \tikzoption{range}{\def\tikz@plot@range{#1}} +\tikzoption{yrange}{\def\tikz@plot@range{#1}} +\let\tikz@plot@range=\pgfutil@empty +\tikzoption{xrange}{\def\tikz@plot@xrange{#1}} +\let\tikz@plot@xrange=\pgfutil@empty % Plot options \tikzoption{smooth}[]{\let\tikz@plot@handler=\pgfplothandlercurveto} \tikzoption{smooth cycle}[]{\let\tikz@plot@handler=\pgfplothandlerclosedcurve} \tikzoption{sharp plot}[]{\let\tikz@plot@handler\pgfplothandlerlineto} +\tikzoption{sharp cycle}[]{\let\tikz@plot@handler\pgfplothandlerpolygon} \tikzoption{tension}{\pgfsetplottension{#1}} @@ -918,14 +1153,16 @@ \tikzoption{const plot}[]{\let\tikz@plot@handler=\pgfplothandlerconstantlineto} \tikzoption{const plot mark left}[]{\let\tikz@plot@handler=\pgfplothandlerconstantlineto} \tikzoption{const plot mark right}[]{\let\tikz@plot@handler=\pgfplothandlerconstantlinetomarkright} +\tikzoption{const plot mark mid}[]{\let\tikz@plot@handler=\pgfplothandlerconstantlinetomarkmid} \tikzoption{jump mark right}[]{\let\tikz@plot@handler=\pgfplothandlerjumpmarkright} +\tikzoption{jump mark mid}[]{\let\tikz@plot@handler=\pgfplothandlerjumpmarkmid} \tikzoption{jump mark left}[]{\let\tikz@plot@handler=\pgfplothandlerjumpmarkleft} \tikzoption{raw gnuplot}[true]{\csname tikz@plot@raw@gnuplot#1\endcsname} \tikzoption{prefix}{\def\tikz@plot@prefix{#1}} \tikzoption{id}{\def\tikz@plot@id{#1}} -\tikzoption{samples}{\def\tikz@plot@samples{#1}\expandafter\tikz@plot@samples@recalc\tikz@plot@domain\relax} +\tikzoption{samples}{\pgfmathsetmacro\tikz@plot@samples{max(2,#1)}\expandafter\tikz@plot@samples@recalc\tikz@plot@domain\relax} \tikzoption{samples at}{\def\tikz@plot@samplesat{#1}} \tikzoption{parametric}[true]{\csname tikz@plot@parametric#1\endcsname} @@ -963,12 +1200,28 @@ \def\tikz@plot@var{\x} \def\tikz@plot@samplesat{-5,-4.5833333,...,5} \def\tikz@plot@samples@recalc#1:#2\relax{% + \begingroup \pgfmathparse{#1}% \let\tikz@temp@start=\pgfmathresult% \pgfmathparse{#2}% \let\tikz@temp@end=\pgfmathresult% - \pgfmathparse{\tikz@temp@start+(\tikz@temp@end-\tikz@temp@start)/(\tikz@plot@samples-1)}% - \edef\tikz@plot@samplesat{\tikz@temp@start,\pgfmathresult,...,\tikz@temp@end}% + \pgfmathsetmacro\tikz@temp@diff{(\tikz@temp@end-\tikz@temp@start)/(\tikz@plot@samples-1)}% + % + % this particular item is for backwards compatibility. + % Pgfplots <= 1.8 called 'samples' in a context where the 'fpu' was + % active... and I fear there is no simple solution to replace the + % new \ifdim below. Sorry. + \pgfkeys{/pgf/fpu/output format/fixed/.try}% + % + \pgfmathsetmacro\tikz@temp@diff@abs{abs(\tikz@temp@diff)}% + \ifdim\tikz@temp@diff@abs pt<0.0001pt\relax% + \edef\tikz@plot@samplesat{\tikz@temp@start,\tikz@temp@end}% + \else% + \pgfmathparse{\tikz@temp@start+\tikz@temp@diff}% + \edef\tikz@plot@samplesat{\tikz@temp@start,\pgfmathresult,...,\tikz@temp@end}% + \fi% + \pgfmath@smuggleone\tikz@plot@samplesat + \endgroup } @@ -979,11 +1232,24 @@ \newif\iftikz@plot@raw@gnuplot -% To options +% +% To and edge options +% \tikzoption{to path}{\def\tikz@to@path{#1}} \def\tikz@to@path{-- (\tikztotarget) \tikztonodes} +\tikzset{edge macro/.store in=\tikz@edge@macro} +\let\tikz@edge@macro\pgfutil@empty + +\tikzset{ + edge node/.code={ + \expandafter\def\expandafter\tikz@tonodes\expandafter{\tikz@tonodes #1} + }, + edge label/.style={/tikz/edge node={node[auto]{#1}}}, + edge label'/.style={/tikz/edge node={node[auto,swap]{#1}}} +} + % After command options \tikzset{ @@ -1003,6 +1269,10 @@ \newif\iftikz@child@missing \pgfkeys{/tikz/missing/.is if=tikz@child@missing} +\tikzset{edge from parent macro/.initial=\tikz@edge@from@parent@macro} +\def\tikz@edge@from@parent@macro#1#2{ + [style=edge from parent, #1, /utils/exec=\tikz@node@is@a@labeltrue] \tikz@edge@to@parent@path #2} + \tikzoption{edge from parent path}{\def\tikz@edge@to@parent@path{#1}} \tikzoption{parent anchor}{\def\tikzparentanchor{.#1}\ifx\tikzparentanchor\tikz@border@text\let\tikzparentanchor\pgfutil@empty\fi} @@ -1084,10 +1354,10 @@ % Snakes are in a lib: -\tikzset{snake/.code=\PackageError{tikz}{You need to say \string\usetikzlibrary{snakes}}{}} +\tikzset{snake/.code=\tikzerror{You need to say \string\usetikzlibrary{snakes}}} % Decorations -\tikzset{decorate/.code=\PackageError{tikz}{You need to load a decoration library}{}} +\tikzset{decorate/.code=\tikzerror{You need to load a decoration library}} % Matrix options \usepgfmodule{matrix} @@ -1108,6 +1378,15 @@ \let\tikz@ampersand@replacement=\pgfutil@empty +% Automatic shorthand management +\tikzset{% + handle active characters in code/.is if=tikz@handle@active@code, + handle active characters in nodes/.is if=tikz@handle@active@nodes, +} +\newif\iftikz@handle@active@code +\newif\iftikz@handle@active@nodes + + % Execute option \tikzoption{execute at begin picture}{\expandafter\def\expandafter\tikz@atbegin@picture\expandafter{\tikz@atbegin@picture#1}} \tikzoption{execute at end picture}{\expandafter\def\expandafter\tikz@atend@picture\expandafter{\tikz@atend@picture#1}} @@ -1117,6 +1396,8 @@ \tikzoption{execute at end to}{\expandafter\def\expandafter\tikz@atend@to\expandafter{\tikz@atend@to#1}} \tikzoption{execute at begin node}{\expandafter\def\expandafter\tikz@atbegin@node\expandafter{\tikz@atbegin@node#1}} \tikzoption{execute at end node}{\expandafter\def\expandafter\tikz@atend@node\expandafter{\tikz@atend@node#1}} +\tikzoption{execute at begin matrix}{\expandafter\def\expandafter\tikz@atbegin@matrix\expandafter{\tikz@atbegin@matrix#1}} +\tikzoption{execute at end matrix}{\expandafter\def\expandafter\tikz@atend@matrix\expandafter{\tikz@atend@matrix#1}} \tikzoption{execute at begin cell}{\expandafter\def\expandafter\tikz@atbegin@cell\expandafter{\tikz@atbegin@cell#1}} \tikzoption{execute at end cell}{\expandafter\def\expandafter\tikz@atend@cell\expandafter{\tikz@atend@cell#1}} \tikzoption{execute at empty cell}{\expandafter\def\expandafter\tikz@at@emptycell\expandafter{\tikz@at@emptycell#1}} @@ -1132,6 +1413,8 @@ \let\tikz@atbegin@cell=\pgfutil@empty \let\tikz@atend@cell=\pgfutil@empty \let\tikz@at@emptycell=\pgfutil@empty +\let\tikz@atbegin@matrix=\pgfutil@empty +\let\tikz@atend@matrix=\pgfutil@empty % Pre and post actions @@ -1211,11 +1494,17 @@ \tikzstyle{densely dashed}= [dash pattern=on 3pt off 2pt] \tikzstyle{loosely dashed}= [dash pattern=on 3pt off 6pt] \tikzstyle{dashdotted}= [dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt] +\tikzstyle{dash dot}= [dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt] \tikzstyle{densely dashdotted}= [dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt] +\tikzstyle{densely dash dot}= [dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt] \tikzstyle{loosely dashdotted}= [dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt] +\tikzstyle{loosely dash dot}= [dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt] \tikzstyle{dashdotdotted}= [dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt on \the\pgflinewidth off 2pt] \tikzstyle{densely dashdotdotted}= [dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt on \the\pgflinewidth off 1pt] \tikzstyle{loosely dashdotdotted}= [dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt on \the\pgflinewidth off 4pt] +\tikzstyle{dash dot dot}= [dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt on \the\pgflinewidth off 2pt] +\tikzstyle{densely dash dot dot}= [dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt on \the\pgflinewidth off 1pt] +\tikzstyle{loosely dash dot dot}= [dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt on \the\pgflinewidth off 4pt] \tikzstyle{transparent}= [opacity=0] @@ -1258,24 +1547,26 @@ \expandafter\pgfutil@in@\expandafter!\expandafter{\tikz@key}% \ifpgfutil@in@% % this is a color! - \expandafter\tikz@addoption\expandafter{\expandafter\pgfutil@color\expandafter{\tikz@key}}% + \expandafter\tikz@addoption\expandafter{\expandafter\tikz@compat@color@set\expandafter{\tikz@key}}% \edef\tikz@textcolor{\tikz@key}% \else% \pgfutil@doifcolorelse{\tikz@key} - { % - \expandafter\tikz@addoption\expandafter{\expandafter\pgfutil@color\expandafter{\tikz@key}}% + {% + \expandafter\tikz@addoption\expandafter{\expandafter\tikz@compat@color@set\expandafter{\tikz@key}}% \edef\tikz@textcolor{\tikz@key}% }% {% % Ok, second chance: This might be an arrow specification: - \expandafter\pgfutil@in@\expandafter-\expandafter{\tikz@key} + \expandafter\pgfutil@in@\expandafter-\expandafter{\tikz@key}% \ifpgfutil@in@% % Ah, an arrow spec! \expandafter\tikz@processarrows\expandafter{\tikz@key}% \else% % Ok, third chance: A shape! \expandafter\ifx\csname pgf@sh@s@\tikz@key\endcsname\relax% - \pgfkeys{/errors/unknown key={/tikz/\tikz@key}{#1}}% + \pgfkeys{/errors/unknown key/.expand + once=\expandafter{\expandafter/\expandafter t\expandafter + i\expandafter k\expandafter z\expandafter/\tikz@key}{#1}}% \else% \edef\tikz@shape{\tikz@key}% \fi% @@ -1284,35 +1575,60 @@ \fi% \fi% } +\def\tikz@compat@color@set#1{% + \pgfutil@color{#1}\pgfutil@colorlet{pgffillcolor}{#1}% + \expandafter\expandafter\expandafter\global% + \expandafter\expandafter\expandafter\let\expandafter\csname\expandafter\string\expandafter\color@pgffillcolor\expandafter\endcsname\csname\string\color@pgffillcolor\endcsname% + \expandafter\expandafter\expandafter\global% + \expandafter\expandafter\expandafter\let\expandafter\csname\expandafter\string\expandafter\color@pgfstrokecolor\expandafter\endcsname\csname\string\color@pgffillcolor\endcsname% +} +\def\tikz@startup@env{% + \ifnum\the\catcode`\;=\active\relax\expandafter\let\expandafter\tikz@origsemi\expandafter=\tikz@activesemicolon\fi% + \ifnum\the\catcode`\:=\active\relax\expandafter\let\expandafter\tikz@origcolon\expandafter=\tikz@activecolon\fi% + \ifnum\the\catcode`\|=\active\relax\expandafter\let\expandafter\tikz@origbar\expandafter=\tikz@activebar\fi% + \tikz@deactivatthings% + \iftikz@handle@active@code% + \tikz@switchoff@shorthands% + \fi% +} % % Main TikZ Environment % -\def\tikzpicture{\pgfutil@ifnextchar[\tikz@picture{\tikz@picture[]}}%} +\def\tikzpicture{% + \begingroup% + \tikz@startup@env% + \pgfutil@ifnextchar[\tikz@picture{\tikz@picture[]}}%} \def\tikz@picture[#1]{% \pgfpicture% \let\tikz@atbegin@picture=\pgfutil@empty% \let\tikz@atend@picture=\pgfutil@empty% \let\tikz@transform=\relax% \def\tikz@time{.5}% - \tikz@installcommands\scope[every picture,#1]% + \tikz@installcommands% + \scope[every picture,#1]% + \iftikz@handle@active@code% + \tikz@switchoff@shorthands% + \fi% \expandafter\tikz@atbegin@picture% \tikz@lib@scope@check% } \def\endtikzpicture{% \tikz@atend@picture% - \global\let\pgf@shift@baseline=\pgf@baseline% - \global\let\pgf@trimleft@final=\pgf@trimleft% - \global\let\pgf@trimright@final=\pgf@trimright% + \global\let\pgf@shift@baseline@smuggle=\pgf@baseline% + \global\let\pgf@trimleft@final@smuggle=\pgf@trimleft% + \global\let\pgf@trimright@final@smuggle=\pgf@trimright% \global\let\pgf@remember@smuggle=\ifpgfrememberpicturepositiononpage% + \pgf@remember@layerlist@globally \endscope% - \let\pgf@baseline=\pgf@shift@baseline% - \let\pgf@trimleft=\pgf@trimleft@final% - \let\pgf@trimright=\pgf@trimright@final% + \let\pgf@baseline=\pgf@shift@baseline@smuggle% + \let\pgf@trimleft=\pgf@trimleft@final@smuggle% + \let\pgf@trimright=\pgf@trimright@final@smuggle% \let\ifpgfrememberpicturepositiononpage=\pgf@remember@smuggle% - \endpgfpicture} + \pgf@restore@layerlist@from@global + \endpgfpicture\endgroup} % Inlined picture @@ -1327,29 +1643,52 @@ % The rectangle \tikz{\draw (0,0) rectangle (1em,1ex)} has width 1em and % height 1ex. -% This code does not work for some inline \tikz. For example -% \tikz\foreach \x in {1,...,10} \draw (\x,0) circle (0.4cm); -% makes tikz crash. -% Begin suspected code -% \def\tikz{\pgfutil@ifnextchar[{\tikz@opt}{\tikz@opt[]}} -% \def\tikz@opt[#1]{\tikzpicture[#1]\pgfutil@ifnextchar\bgroup{\tikz@}{\tikz@@}} -% \def\tikz@{\bgroup\tikz@auto@end@pathtrue\aftergroup\endtikzpicture\let\pgf@temp=} -% \def\tikz@@{\begingroup\def\tikz@path@do@at@end{\endgroup\endtikzpicture}} -% End suspected code -% Begin old code -\def\tikz{\pgfutil@ifnextchar[{\tikz@opt}{\tikz@opt[]}} -\def\tikz@opt[#1]{\tikzpicture[#1]\pgfutil@ifnextchar\bgroup{\tikz@}{\tikz@@}} -\def\tikz@#1{#1\endtikzpicture} + +\def\tikz{% + \begingroup% + \tikz@startup@env% + \pgfutil@ifnextchar[{\tikz@opt}{\tikz@opt[]}} +\def\tikz@opt[#1]{\tikzpicture[#1]\pgfutil@ifnextchar\bgroup{\tikz@}{\tikz@@single}} +\def\tikz@{\bgroup\tikz@auto@end@pathtrue\aftergroup\endtikzpicture\aftergroup\endgroup\let\pgf@temp=} +\def\tikz@@single#1{% + \expandafter\ifx\csname tikz@protected@command\string#1\endcsname\relax% + \expandafter\tikz@@% + \else% + \begingroup\def\tikz@path@do@at@end{\endgroup\endtikzpicture\endgroup}% + \fi% + #1% +} + +\expandafter\let\csname tikz@protected@command\string\draw\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\pattern\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\fill\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\filldraw\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\shade\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\shadedraw\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\clip\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\graph\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\useasboundingbox\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\node\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\coordinate\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\matrix\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\datavisualization\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\path\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\pic\endcsname\pgfutil@empty + +% Comment by TT: I hope I fixed the \tikz \foreach problem. The new +% version will take a conservative approach and will only do fancy +% stuff when the next keyword after \tikz is one of the following: +% \draw, \fill, \filldraw, \graph, \matrix, \def\tikz@@{% \let\tikz@next=\tikz@collectnormalsemicolon% \ifnum\the\catcode`\;=\active\relax% \let\tikz@next=\tikz@collectactivesemicolon% \fi% \tikz@next} -\def\tikz@collectnormalsemicolon#1;{#1;\endtikzpicture} +\def\tikz@collectnormalsemicolon#1;{#1;\endtikzpicture\endgroup} { \catcode`\;=\active - \gdef\tikz@collectactivesemicolon#1;{#1;\endtikzpicture} + \gdef\tikz@collectactivesemicolon#1;{#1;\endtikzpicture\endgroup} } % End old code @@ -1374,7 +1713,7 @@ \tikz@transparency@groupfalse% \tikzset{every scope/.try,#1}% \tikz@options% - \iftikz@transparency@group\pgftransparencygroup\fi% + \iftikz@transparency@group\expandafter\pgftransparencygroup\expandafter[\tikz@transparency@group@options]\tikz@blend@group\fi% \expandafter\tikz@atbegin@scope% \tikz@lib@scope@check% } @@ -1386,6 +1725,31 @@ \tikz@lib@scope@check% } + +\def\tikz@scoped{\pgfutil@ifnextchar[{\tikz@scoped@opt}{\tikz@scoped@opt[]}} +\def\tikz@scoped@opt[#1]{\scope[#1]\pgfutil@ifnextchar\bgroup{\tikz@scoped@}{\tikz@scoped@@single}} +\def\tikz@scoped@{\bgroup\tikz@auto@end@pathtrue\aftergroup\endscope\let\pgf@temp=} +\def\tikz@scoped@@single#1{% + \expandafter\ifx\csname tikz@scoped@protected@command\string#1\endcsname\relax% + \expandafter\tikz@scoped@@% + \else% + \begingroup\def\tikz@scoped@path@do@at@end{\endgroup\endscope}% + \fi% + #1% +} +\def\tikz@scoped@@{% + \let\tikz@scoped@next=\tikz@scoped@collectnormalsemicolon% + \ifnum\the\catcode`\;=\active\relax% + \let\tikz@scoped@next=\tikz@scoped@collectactivesemicolon% + \fi% + \tikz@scoped@next} +\def\tikz@scoped@collectnormalsemicolon#1;{#1;\endscope} +{ + \catcode`\;=\active + \gdef\tikz@scoped@collectactivesemicolon#1;{#1;\endscope} +} + + % Install a shortcut command which is only valid inside of a % tikzpicture. % @@ -1396,7 +1760,7 @@ % #2: real command name \def\tikzaddtikzonlycommandshortcutlet#1#2{% \expandafter\def\expandafter\tikz@installcommands\expandafter{\tikz@installcommands - \let#1=#2 + \let#1=#2% }% }% @@ -1412,10 +1776,8 @@ % Install the abbreviated commands % \def\tikz@installcommands{% - \ifnum\the\catcode`\;=\active\relax\expandafter\let\expandafter\tikz@origsemi\expandafter=\tikz@activesemicolon\fi% - \ifnum\the\catcode`\:=\active\relax\expandafter\let\expandafter\tikz@origcolon\expandafter=\tikz@activecolon\fi% - \ifnum\the\catcode`\|=\active\relax\expandafter\let\expandafter\tikz@origbar\expandafter=\tikz@activebar\fi% \let\tikz@origscope=\scope% + \let\tikz@origscoped=\scoped% \let\tikz@origendscope=\endscope% \let\tikz@origstartscope=\startscope% \let\tikz@origstopscope=\stopscope% @@ -1430,15 +1792,15 @@ \let\tikz@origclip=\clip% \let\tikz@origuseasboundingbox=\useasboundingbox% \let\tikz@orignode=\node% + \let\tikz@origpic=\pic% \let\tikz@origcoordinate=\coordinate% \let\tikz@origmatrix=\matrix% \let\tikz@origcalendar=\calendar% \let\tikz@origdv=\datavisualization% \let\tikz@origgraph=\graph% % - \tikz@deactivatthings% - % \let\scope=\tikz@scope@env% + \let\scoped=\tikz@scoped% \let\endscope=\endtikz@scope@env% \let\startscope=\scope% \let\stopscope=\endscope% @@ -1455,16 +1817,17 @@ \def\graph{\path graph} \def\useasboundingbox{\path[use as bounding box]} \def\node{\tikz@path@overlay{node}} + \def\pic{\tikz@path@overlay{pic}} \def\coordinate{\tikz@path@overlay{coordinate}} \def\matrix{\tikz@path@overlay{node[matrix]}} \def\calendar{\tikz@lib@cal@calendar}% \def\datavisualization{\tikz@lib@datavisualization}% } \ifx\tikz@lib@cal@calendar\@undefined -\def\tikz@lib@cal@calendar{\PackageError{tikz}{You need to say \string\usetikzlibrary{calendar} to use the \string\calendar{} command}{}} +\def\tikz@lib@cal@calendar{\tikzerror{You need to say \string\usetikzlibrary{calendar} to use the \string\calendar{} command}} \fi \ifx\tikz@lib@datavisualization\@undefined -\def\tikz@lib@datavisualization{\PackageError{tikz}{You need to say \string\usetikzlibrary{datavisualization} to use the \string\datavisualization{} command}{}} +\def\tikz@lib@datavisualization{\tikzerror{You need to say \string\usetikzlibrary{datavisualization} to use the \string\datavisualization{} command}} \fi \def\tikz@path@overlay#1{% @@ -1473,10 +1836,8 @@ \def\tikz@path@overlayed#1<#2>{\path<#2> #1} \def\tikz@uninstallcommands{% - \ifnum\the\catcode`\;=\active\relax\expandafter\let\tikz@activesemicolon=\tikz@origsemi\fi% - \ifnum\the\catcode`\:=\active\relax\expandafter\let\tikz@activecolon=\tikz@origcolon\fi% - \ifnum\the\catcode`\|=\active\relax\expandafter\let\tikz@activebar=\tikz@origbar\fi% \let\scope=\tikz@origscope% + \let\scoped=\tikz@origscoped% \let\endscope=\tikz@origendscope% \let\startscope=\tikz@origstartscope% \let\stopscope=\tikz@origstopscope% @@ -1491,6 +1852,7 @@ \let\clip=\tikz@origclip% \let\useasboundingbox=\tikz@origuseasboundingbox% \let\node=\tikz@orignode% + \let\pic=\tikz@origpic% \let\coordinate=\tikz@origcoordinate% \let\matrix=\tikz@origmatrix% \let\calendar=\tikz@origcalendar% @@ -1517,16 +1879,49 @@ \gdef\tikz@activecolon{:}% \gdef\tikz@activebar{|}% \gdef\tikz@activequotes{"}% + \global\let\tikz@active@quotes@token="% \gdef\tikz@activeexlmark{!}% \gdef\tikz@deactivatthings{% \def;{\tikz@nonactivesemicolon}% \def:{\tikz@nonactivecolon}% \def|{\tikz@nonactivebar}% - \def!{\tikz@nonactiveexlmark}% + \def!{\tikz@nonactiveexlmark}% } } - +\let\tikz@orig@shorthands\pgfutil@empty +\def\tikz@switchoff@shorthands{% + \ifx\tikz@orig@shorthands\pgfutil@empty% + \edef\tikz@orig@shorthands{% + \catcode\noexpand`\noexpand\;\the\catcode`\;\relax% + \catcode\noexpand`\noexpand\:\the\catcode`\:\relax% + \catcode\noexpand`\noexpand\|\the\catcode`\|\relax% + \catcode\noexpand`\noexpand\!\the\catcode`\!\relax% + \catcode\noexpand`\noexpand\,\the\catcode`\,\relax% + \catcode\noexpand`\noexpand\<\the\catcode`\<\relax% + \catcode\noexpand`\noexpand\>\the\catcode`\>\relax% + \catcode\noexpand`\noexpand\"\the\catcode`\"\relax% + \catcode\noexpand`\noexpand\'\the\catcode`\'\relax% + \catcode\noexpand`\noexpand\-\the\catcode`\-\relax% + \catcode\noexpand`\noexpand\=\the\catcode`\=\relax% + \catcode\noexpand`\noexpand\.\the\catcode`\.\relax% + \catcode\noexpand`\noexpand\$\the\catcode`\$\relax% + }% + \catcode`\;12\relax% + \catcode`\:12\relax% + \catcode`\|12\relax% + \catcode`\!12\relax% + \catcode`\,12\relax% + \catcode`\<12\relax% + \catcode`\>12\relax% + \catcode`\"12\relax% + \catcode`\'12\relax% + \catcode`\-12\relax% + \catcode`\=12\relax% + \catcode`\.12\relax% + \catcode`\$3\relax% + \fi% +} @@ -1557,11 +1952,14 @@ \def\tikz@@command@path{% \edef\tikzscope@linewidth{\the\pgflinewidth}% \begingroup% + \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% \let\tikz@path@do@at@end=\tikz@lib@scope@check% \let\tikz@options=\pgfutil@empty% \let\tikz@mode=\pgfutil@empty% \let\tikz@moveto@waiting=\relax% \let\tikz@timer=\relax% + \let\tikz@tangent=\relax% \let\tikz@collected@onpath=\pgfutil@empty% \let\tikz@preactions=\pgfutil@empty% \let\tikz@postactions=\pgfutil@empty% @@ -1569,6 +1967,8 @@ \tikz@decoratepathfalse% \tikz@node@is@a@labelfalse% \tikz@expandcount=100\relax% + \pgf@path@lastx=0pt% + \pgf@path@lasty=0pt% \tikz@lastx=0pt% \tikz@lasty=0pt% \tikz@lastxsaved=0pt% @@ -1581,44 +1981,44 @@ \else% \tikz@invoke@collected@onpath% \fi% - \afterassignment\tikz@handle\let\@let@token=% + \afterassignment\tikz@handle\let\pgf@let@token=% } \newcount\tikz@expandcount % Central dispatcher for commands \def\tikz@handle{% \let\@next=\tikz@expand% - \ifx\@let@token(%) + \ifx\pgf@let@token(%) \let\@next=\tikz@movetoabs% \else% - \ifx\@let@token+% + \ifx\pgf@let@token+% \let\@next=\tikz@movetorel% \else% - \ifx\@let@token-% + \ifx\pgf@let@token-% \let\@next=\tikz@lineto% \else% - \ifx\@let@token.% + \ifx\pgf@let@token.% \let\@next=\tikz@dot% \else% - \ifx\@let@token r% + \ifx\pgf@let@token r% \let\@next=\tikz@rect% \else% - \ifx\@let@token n% + \ifx\pgf@let@token n% \let\@next=\tikz@fig% \else% - \ifx\@let@token[%] + \ifx\pgf@let@token[%] \let\@next=\tikz@parse@options% \else% - \ifx\@let@token c% + \ifx\pgf@let@token c% \let\@next=\tikz@cchar% \else% - \ifx\@let@token\bgroup% + \ifx\pgf@let@token\bgroup% \let\@next=\tikz@beginscope% \else% - \ifx\@let@token\egroup% + \ifx\pgf@let@token\egroup% \let\@next=\tikz@endscope% \else% - \ifx\@let@token;% + \ifx\pgf@let@token;% \let\@next=\tikz@finish% \else% \let\@next=\tikz@handle@more% @@ -1638,47 +2038,51 @@ % Continued... \def\tikz@handle@more{% - \ifx\@let@token a% + \ifx\pgf@let@token a% \let\@next=\tikz@arcA% \else% - \ifx\@let@token e% + \ifx\pgf@let@token e% \let\@next=\tikz@e@char% \else% - \ifx\@let@token g% + \ifx\pgf@let@token g% \let\@next=\tikz@g@char% \else% - \ifx\@let@token s% + \ifx\pgf@let@token s% \let\@next=\tikz@schar% \else% - \ifx\@let@token |% + \ifx\pgf@let@token |% \let\@next=\tikz@vh@lineto% \else% - \ifx\@let@token p% + \ifx\pgf@let@token p% \let\@next=\tikz@pchar% \pgfsetmovetofirstplotpoint% \else% - \ifx\@let@token t% + \ifx\pgf@let@token t% \let\@next=\tikz@to% \else% - \ifx\@let@token\pgfextra% + \ifx\pgf@let@token\pgfextra% \let\@next=\tikz@extra% \else% - \ifx\@let@token\foreach% + \ifx\pgf@let@token\foreach% \let\@next=\tikz@foreach% \else% - \ifx\@let@token\pgf@stop% - \let\@next=\relax% + \ifx\pgf@let@token f% + \let\@next=\tikz@fchar% \else% - \ifx\@let@token\par% - \let\@next=\tikz@scan@next@command% + \ifx\pgf@let@token\pgf@stop% + \let\@next=\relax% \else% - \ifx\@let@token d% - \let\@next=\tikz@decoration% + \ifx\pgf@let@token\par% + \let\@next=\tikz@scan@next@command% \else% - \ifx\@let@token l% - \let\@next=\tikz@l@char%\tikz@let@command% + \ifx\pgf@let@token d% + \let\@next=\tikz@decoration% \else% - \let\@next=\tikz@expand% + \ifx\pgf@let@token l% + \let\@next=\tikz@l@char%\tikz@let@command% + \else% + \let\@next=\tikz@expand% + \fi% \fi% \fi% \fi% @@ -1692,6 +2096,7 @@ \fi% \fi% \fi% + \ifx\@next\tikz@expand\else\tikz@expandcount=100\relax\fi% \@next% } @@ -1704,16 +2109,14 @@ } \def\tikz@lsystem{% - \PackageError{tikz}{You need to say \string\usetikzlibrary{lindenmayersystems} to - draw Lindenmayer systems}{} + \tikzerror{You need to say \string\usetikzlibrary{lindenmayersystems} to draw Lindenmayer systems} } \def\tikz@@lsystem{% - \PackageError{tikz}{You need to say \string\usetikzlibrary{lindenmayersystems} to - draw L-systems}{} + \tikzerror{You need to say \string\usetikzlibrary{lindenmayersystems} to draw L-systems} } -\def\tikz@pchar{\pgfutil@ifnextchar l{\tikz@plot}{\tikz@parabola}} +\def\tikz@pchar{\pgfutil@ifnextchar l{\tikz@plot}{\pgfutil@ifnextchar i{\tikz@subpicture}{\tikz@parabola}}} \def\tikz@cchar{% \pgfutil@ifnextchar i{\tikz@circle}% {\pgfutil@ifnextchar h{\tikz@children}{\tikz@cochar}}}% @@ -1729,24 +2132,27 @@ \def\tikz@g@char r{\pgfutil@ifnextchar i{\tikz@grid}{\tikz@graph}} % svg syntax -% svg[options] "..." +% svg[options] {...} \def\tikz@svg@path{% - \PackageError{tikz}{You need to say \string\usetikzlibrary{svg.path} to - use the svg path command}{} + \tikzerror{You need to say \string\usetikzlibrary{svg.path} to use the svg path command} } \def\tikz@finish{% % Rendering pipeline % - % Step 1: Decorate path + % Step 1: The path background box + % + \box\tikz@figbox@bg% + % + % Step 2: Decorate path % \iftikz@decoratepath% \tikz@lib@dec@decorate@path% \fi% % - % Step 1: Preactions + % Step 3: Preactions % \pgfsyssoftpath@getcurrentpath\tikz@actions@path% \edef\tikz@restorepathsize{% @@ -1757,7 +2163,7 @@ }% \tikz@preactions% % - % Reset modes + % Step 4: Reset modes % \let\tikz@path@picture=\pgfutil@empty% \tikz@mode@fillfalse% @@ -1776,20 +2182,27 @@ \iftikz@mode@fade@path% \tikz@addoption{% \iftikz@fade@adjust% - \pgfsetfadingforcurrentpath{\tikz@path@fading}{\tikz@do@fade@transform}% + \iftikz@mode@draw% + \pgfsetfadingforcurrentpathstroked{\tikz@path@fading}{\tikz@do@fade@transform}% + \else% + \pgfsetfadingforcurrentpath{\tikz@path@fading}{\tikz@do@fade@transform}% + \fi% \else% \pgfsetfading{\tikz@path@fading}{\tikz@do@fade@transform}% \fi% \tikz@mode@fade@pathfalse% no more fading... }% \fi% - % Rendering pipeline % - % Step 2: Install scope fading + % Step 5: Install scope fading % \iftikz@mode@fade@scope% \iftikz@fade@adjust% - \pgfsetfadingforcurrentpath{\tikz@scope@fading}{\tikz@do@fade@transform}% + \iftikz@mode@draw% + \pgfsetfadingforcurrentpathstroked{\tikz@scope@fading}{\tikz@do@fade@transform}% + \else% + \pgfsetfadingforcurrentpath{\tikz@scope@fading}{\tikz@do@fade@transform}% + \fi% \else% \pgfsetfading{\tikz@scope@fading}{\tikz@do@fade@transform}% \fi% @@ -1805,7 +2218,7 @@ \tikz@options% \fi% % - % Step 4: Do a fill if shade or a path picture follows. + % Step 6: Do a fill if shade or a path picture follows. % \iftikz@mode@fill% \iftikz@mode@shade% @@ -1828,7 +2241,7 @@ \fi% \fi% % - % Step 5: Do a shade if necessary. + % Step 7: Do a shade if necessary. % \iftikz@mode@shade% \pgfsyssoftpath@getcurrentpath\tikz@temppath @@ -1838,7 +2251,7 @@ \tikz@mode@shadefalse% no more shading... \fi% % - % Step 5a: Do a path picture if necessary. + % Step 8: Do a path picture if necessary. % \ifx\tikz@path@picture\pgfutil@empty% \else% @@ -1866,7 +2279,7 @@ \let\tikz@path@picture=\pgfutil@empty% \fi% % - % Step 6: Double stroke, if necessary + % Step 9: Double stroke, if necessary % \iftikz@mode@draw% \iftikz@mode@double% @@ -1877,17 +2290,17 @@ \fi% \fi% % - % Step 7: Do stroke/fill/clip as needed + % Step 10: Do stroke/fill/clip as needed % \edef\tikz@temp{\noexpand\pgfusepath{% \iftikz@mode@fill fill,\fi% \iftikz@mode@draw draw,\fi% - \iftikz@mode@clip clip,\fi% + \iftikz@mode@clip clip\fi% }}% \tikz@temp% \tikz@mode@fillfalse% no more filling % - % Step 8: Double stroke, if necessary + % Step 11: Double stroke, if necessary % \iftikz@mode@draw% \iftikz@mode@double% @@ -1897,22 +2310,22 @@ \fi% \tikz@mode@drawfalse% no more stroking % - % Step 9: Postactions + % Step 12: Postactions % \tikz@postactions% % - % Step 10: Add labels and nodes + % Step 13: Add labels and nodes % \box\tikz@figbox% % - % Step 11: Close option brace + % Step 14: Close option brace % \ifx\tikz@options\pgfutil@empty% \else% \endgroup% \pgfsys@endscope% \iftikz@mode@clip% - \PackageError{tikz}{Extra options not allowed for clipping path command.}{}% + \tikzerror{Extra options not allowed for clipping path command.}% \fi% \fi% \iftikz@mode@clip% @@ -1934,6 +2347,7 @@ {% \pgfsys@beginscope% \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% \path[#1];% do extra path \pgfsyssoftpath@setcurrentpath\tikz@actions@path% restore \tikz@restorepathsize% @@ -1945,6 +2359,7 @@ {% \pgfsys@beginscope% \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% \tikz@restorepathsize% \path[#1]\pgfextra{\pgfsyssoftpath@setcurrentpath\tikz@actions@path};% do extra path \pgf@resetpathsizes% @@ -1958,7 +2373,7 @@ \def\tikz@expand{% \advance\tikz@expandcount by -1% \ifnum\tikz@expandcount<0\relax% - \PackageError{tikz}{Giving up on this path. Did you forget a semicolon?}{}% + \tikzerror{Giving up on this path. Did you forget a semicolon?}% \let\@next=\tikz@finish% \else% \let\@next=\tikz@@expand @@ -1966,7 +2381,7 @@ \@next} \def\tikz@@expand{% - \expandafter\tikz@scan@next@command\@let@token} + \expandafter\tikz@scan@next@command\pgf@let@token} @@ -1981,6 +2396,8 @@ } \def\tikz@@endscope{% \global\setbox\tikz@tempbox=\box\tikz@figbox% + \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% + \global\let\tikz@tangent@temp\tikz@tangent% \edef\tikz@marshal{% \tikz@lastx=\the\tikz@lastx% \tikz@lasty=\the\tikz@lasty% @@ -2004,6 +2421,8 @@ \expandafter% \endgroup\tikz@marshal% \setbox\tikz@figbox=\box\tikz@tempbox% + \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% + \let\tikz@tangent\tikz@tangent@temp% \tikz@scan@next@command} @@ -2018,33 +2437,50 @@ \def\pgfextra{pgfextra} -% Syntax for \foreach: +% Syntax for foreach: +% +% foreach \var in {list} {path text} +% +% or +% % \foreach \var in {list} {path text} % % Example: % % \draw (0,0) \foreach \x in {1,2,3} {-- (\x,0) circle (1cm)} -- (5,5); +\def\tikz@fchar oreach{\tikz@foreach} + \def\tikz@foreach{% \def\pgffor@beginhook{% \tikz@lastx=\tikz@foreach@save@lastx% \tikz@lasty=\tikz@foreach@save@lasty% \tikz@lastxsaved=\tikz@foreach@save@lastxsaved% \tikz@lastysaved=\tikz@foreach@save@lastysaved% - \setbox\tikz@figbox=\box\tikz@tempbox\expandafter\tikz@scan@next@command\pgfutil@firstofone}% + \setbox\tikz@figbox=\box\tikz@tempbox% + \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% + \expandafter\tikz@scan@next@command\pgfutil@firstofone}% \def\pgffor@endhook{\pgfextra{% \xdef\tikz@foreach@save@lastx{\the\tikz@lastx}% \xdef\tikz@foreach@save@lasty{\the\tikz@lasty}% \xdef\tikz@foreach@save@lastxsaved{\the\tikz@lastxsaved}% \xdef\tikz@foreach@save@lastysaved{\the\tikz@lastysaved}% - \global\setbox\tikz@tempbox=\copy\tikz@figbox\pgfutil@gobble}}% + \global\setbox\tikz@tempbox=\box\tikz@figbox% + \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% + \pgfutil@gobble}}% \def\pgffor@afterhook{% \tikz@lastx=\tikz@foreach@save@lastx% \tikz@lasty=\tikz@foreach@save@lasty% \tikz@lastxsaved=\tikz@foreach@save@lastxsaved% \tikz@lastysaved=\tikz@foreach@save@lastysaved% - \setbox\tikz@figbox=\box\tikz@tempbox\tikz@scan@next@command}% - \global\setbox\tikz@tempbox=\copy\tikz@figbox% + \let\pgffor@beginhook\relax% + \let\pgffor@endhook\relax% + \let\pgffor@afterhook\relax% + \setbox\tikz@figbox=\box\tikz@tempbox% + \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% + \tikz@scan@next@command}% + \global\setbox\tikz@tempbox=\box\tikz@figbox% + \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% \xdef\tikz@foreach@save@lastx{\the\tikz@lastx}% \xdef\tikz@foreach@save@lasty{\the\tikz@lasty}% \xdef\tikz@foreach@save@lastxsaved{\the\tikz@lastxsaved}% @@ -2085,7 +2521,7 @@ \tikz@make@last@position{#1}% \iftikz@shapeborder% % ok, the moveto will have to wait. flag that we have a moveto in - % wainting: + % waiting: \edef\tikz@moveto@waiting{\tikz@shapeborder@name}% \else% \pgfpathmoveto{\tikz@last@position}% @@ -2126,7 +2562,9 @@ % Collecting labels on the path % -\def\tikz@collect@coordinate@onpath#1coordinate{% +\def\tikz@collect@coordinate@onpath#1c{% + \pgfutil@ifnextchar y{\tikz@cycle@expander@add#1}{\tikz@collect@coordinate@onpath@{#1}}} +\def\tikz@collect@coordinate@onpath@#1oordinate{% \pgfutil@ifnextchar[{\tikz@@collect@coordinate@opt#1}{\tikz@@collect@coordinate@opt#1[]}}%} \def\tikz@@collect@coordinate@opt#1[#2]{% \pgfutil@ifnextchar({\tikz@@collect@coordinate#1[#2]}{% @@ -2134,30 +2572,61 @@ \def\tikz@@collect@coordinate#1[#2](#3){% \tikz@collect@label@onpath#1node[shape=coordinate,#2](#3){}} +\newif\iftikz@collect@pic + \def\tikz@collect@label@onpath#1node{% \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath node}% - \tikz@collect@label@scan#1} - -\def\tikz@collect@label@scan#1{% - \pgfutil@ifnextchar({\tikz@collect@paran#1}% - {\pgfutil@ifnextchar[{\tikz@collect@options#1}% - {\pgfutil@ifnextchar\bgroup{\tikz@collect@arg#1}% - {#1}}}% + \let\tikz@collect@cont#1% + \tikz@collect@picfalse% + \tikz@collect@label@scan} + +\def\tikz@collect@pic@onpath#1pic{% + \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath pic}% + \let\tikz@collect@cont#1 + \tikz@collect@pictrue% + \tikz@collect@label@scan} + +\def\tikz@collect@label@scan{% + \pgfutil@ifnextchar f{\tikz@collect@nodes}{% + \pgfutil@ifnextchar({\tikz@collect@paran}% + {\pgfutil@ifnextchar[{\tikz@collect@options}% + {\pgfutil@ifnextchar\bgroup{\tikz@collect@arg}% + {\tikz@collect@cont}}}}% }%}} -\def\tikz@collect@paran#1(#2){% - \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath(#2)}% - \tikz@collect@label@scan#1% +\def\tikz@collect@nodes foreach#1in{% + \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath foreach#1in}% + \pgfutil@ifnextchar\bgroup\tikz@collect@nodes@group\tikz@collect@nodes@one% } -\def\tikz@collect@options#1[#2]{% - \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath[#2]}% - \tikz@collect@label@scan#1% +\def\tikz@collect@nodes@one#1{% + \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath #1}% + \tikz@collect@label@scan% } -\def\tikz@collect@arg#1#2{% - \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath{#2}}% - #1% +\def\tikz@collect@nodes@group#1{% + \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath{#1}}% + \tikz@collect@label@scan% } +\def\tikz@collect@paran#1){% + \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath#1)}% + \tikz@collect@label@scan% +} +\def\tikz@collect@options#1]{% + \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath#1]}% + \tikz@collect@label@scan% +} +\def\tikz@collect@arg#1{% + \iftikz@handle@active@nodes% + \iftikz@collect@pic% + \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath{#1}}% + \else% + \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath{\scantokens{#1}}}% + \fi% + \else% + \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath{#1}}% + \fi% + \tikz@collect@cont% +} \def\tikz@invoke@collected@onpath{% \tikz@node@is@a@labeltrue% @@ -2168,6 +2637,15 @@ } +% +% Macros for the cycle command +% + +\def\tikz@cycle@expander#1{\pgfutil@ifnextchar c{\tikz@cycle@expander@{#1}}{#1}} +\def\tikz@cycle@expander@#1c{\pgfutil@ifnextchar y{\tikz@cycle@expander@add{#1}}{#1c}} +\def\tikz@cycle@expander@add#1ycle{#1(current subpath start)--cycle} + + % Syntax for lineto: @@ -2182,8 +2660,11 @@ \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@lineto@mid}% {% \pgfutil@ifnextchar c{\tikz@close}{% - \pgfutil@ifnextchar p{\pgfsetlinetofirstplotpoint\expandafter\tikz@plot\pgfutil@gobble}% - {\tikz@scan@one@point{\tikz@@lineto}}}}} + \pgfutil@ifnextchar p{\tikz@lineto@plot@or@pic}{\tikz@scan@one@point{\tikz@@lineto}}}}} +\def\tikz@lineto@plot@or@pic p{% + \pgfutil@ifnextchar i{\tikz@collect@pic@onpath\tikz@lineto@mid p}{% + \pgfsetlinetofirstplotpoint\tikz@plot}% +} \def\tikz@@lineto#1{% % Record the starting point for later labels on the path: \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}} @@ -2205,6 +2686,7 @@ \edef\tikz@timer@end{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% \fi% \let\tikz@timer=\tikz@timer@line% + \let\tikz@tangent\tikz@timer@start% \tikz@scan@next@command% } @@ -2236,14 +2718,15 @@ % -| <point> \def\tikz@hv@lineto{% - \pgfutil@ifnextchar n - {\tikz@collect@label@onpath\tikz@hv@lineto} + \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@hv@lineto}{ + \pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@hv@lineto}% {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@hv@lineto}% - {\tikz@scan@one@point{\tikz@@hv@lineto}}}} + {\tikz@scan@one@point{\tikz@@hv@lineto}}}}} \def\tikz@@hv@lineto#1{% \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% \pgf@yc=\tikz@lasty% \tikz@make@last@position{#1}% + \edef\tikz@tangent{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\pgf@yc}}% \tikz@flush@moveto@toward{\pgfqpoint{\tikz@lastx}{\pgf@yc}}\pgf@x\pgf@yc% \iftikz@shapeborder% % ok, target is a shape. have to work now: @@ -2270,14 +2753,15 @@ \def\tikz@vh@lineto-{\tikz@vh@lineto@next} \def\tikz@vh@lineto@next{% - \pgfutil@ifnextchar n - {\tikz@collect@label@onpath\tikz@vh@lineto@next} + \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@vh@lineto@next}{% + \pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@vh@lineto@next}% {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@vh@lineto@next}% - {\tikz@scan@one@point\tikz@@vh@lineto}}} + {\tikz@scan@one@point\tikz@@vh@lineto}}}} \def\tikz@@vh@lineto#1{% \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% \pgf@xc=\tikz@lastx% \tikz@make@last@position{#1}% + \edef\tikz@tangent{\noexpand\pgfqpoint{\the\pgf@xc}{\the\tikz@lasty}}% \tikz@flush@moveto@toward{\pgfqpoint{\pgf@xc}{\tikz@lasty}}\pgf@xc\pgf@y% \iftikz@shapeborder% % ok, target is a shape. have to work now: @@ -2306,9 +2790,13 @@ {\tikz@@close c}}% \def\tikz@@close cycle{% \tikz@flush@moveto% + \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}} + \tikz@make@last@position{\expandafter\pgfpoint\pgfsyssoftpath@lastmoveto}% \tikz@path@close{\expandafter\pgfpoint\pgfsyssoftpath@lastmoveto}% \def\pgfstrokehook{}% - \let\tikz@timer=\@undefined% + \edef\tikz@timer@end{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% + \let\tikz@timer=\tikz@timer@line% + \let\tikz@tangent\tikz@timer@start% \tikz@scan@next@command% } @@ -2339,17 +2827,18 @@ \def\tikz@to@or@edge{\pgfutil@ifnextchar[\tikz@@to@or@edge{\tikz@@to@or@edge[]}}%} \def\tikz@@to@or@edge[#1]{% - \def\tikz@@to@local@options{[#1]}% + \def\tikz@@to@local@options{#1}% \let\tikz@collected@onpath=\pgfutil@empty% \tikz@@to@collect% } \def\tikz@@to@collect{% \pgfutil@ifnextchar(\tikz@@to@or@edge@coordinate%) {\pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@@to@collect}% - {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@@to@collect}% - {\pgfutil@ifnextchar +{\tikz@scan@one@point\tikz@@to@or@edge@math}% - {\PackageError{tikz}{(, +, coordinate, or node expected}{}%) - \tikz@@to@or@edge@coordinate()}}}}% + {\pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@@to@collect}% + {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@@to@collect}% + {\pgfutil@ifnextchar +{\tikz@scan@one@point\tikz@@to@or@edge@math}% + {\tikzerror{(, +, coordinate, pic, or node expected}%) + \tikz@@to@or@edge@coordinate()}}}}}% } \def\tikz@@to@or@edge@coordinate({% @@ -2376,34 +2865,43 @@ } \def\tikz@do@edge{% - \setbox\tikz@figbox=\hbox\bgroup% - \unhbox\tikz@figbox% - \hbox\bgroup - \bgroup% - \pgfinterruptpath% - \pgfscope% - \let\tikz@transform=\pgfutil@empty% - \let\tikz@options=\pgfutil@empty% - \let\tikz@tonodes=\tikz@collected@onpath% - \def\tikztonodes{{\pgfextra{\tikz@node@is@a@labeltrue}\tikz@tonodes}}% - \let\tikz@collected@onpath=\pgfutil@empty% - \tikz@options% - \tikz@transform% - % Typeset node: - \let\tikz@after@path\pgfutil@empty% - \tikz@atbegin@to% - \path[style=every edge]\tikz@@to@local@options(\tikztostart)\tikz@to@path - \pgfextra{\global\let\tikz@after@path@smuggle=\tikz@after@path};% - \tikz@atend@to% - \endpgfscope% - \endpgfinterruptpath% - \egroup + \ifx\tikz@edge@macro\pgfutil@empty% + \setbox\tikz@whichbox=\hbox\bgroup% + \unhbox\tikz@whichbox% + \hbox\bgroup + \bgroup% + \pgfinterruptpath% + \pgfscope% + \let\tikz@transform=\pgfutil@empty% + \let\tikz@options=\pgfutil@empty% + \let\tikz@tonodes=\tikz@collected@onpath% + \def\tikztonodes{{\pgfextra{\tikz@node@is@a@labeltrue}\tikz@tonodes}}% + \let\tikz@collected@onpath=\pgfutil@empty% + \tikz@options% + \tikz@transform% + \let\tikz@transform=\relax% + % Typeset node: + \let\tikz@after@path\pgfutil@empty% + \tikz@atbegin@to% + \tikz@enable@edge@quotes% + \path[style=every edge]\expandafter[\tikz@@to@local@options](\tikztostart)\tikz@to@path + \pgfextra{\global\let\tikz@after@path@smuggle=\tikz@after@path};% + \tikz@atend@to% + \endpgfscope% + \endpgfinterruptpath% + \egroup + \egroup% \egroup% - \egroup% - \global\setbox\tikz@tempbox=\copy\tikz@figbox% - \endgroup% - \setbox\tikz@figbox=\box\tikz@tempbox% - \expandafter\tikz@scan@next@command\tikz@after@path% + \global\setbox\tikz@tempbox=\box\tikz@whichbox% + \expandafter\endgroup% + \expandafter\setbox\tikz@whichbox=\box\tikz@tempbox% + \else% + \expandafter\expandafter\expandafter\tikz@edge@macro% + \expandafter\expandafter\expandafter{\expandafter\tikz@@to@local@options\expandafter}\expandafter{\tikz@collected@onpath}% + \endgroup% + \let\tikz@after@path@smuggle=\pgfutil@empty% + \fi% + \expandafter\tikz@scan@next@command\tikz@after@path@smuggle% } \def\tikz@do@to{% @@ -2414,7 +2912,8 @@ {% \pgfextra{\let\tikz@after@path\pgfutil@empty}% \pgfextra{\tikz@atbegin@to}% - [style=every to]\tikz@@to@local@options\tikz@to@path% + \pgfextra{\tikz@enable@edge@quotes}% + [style=every to]\expandafter[\tikz@@to@local@options]\tikz@to@path% \pgfextra{\tikz@atend@to}% \pgf@stop% \expandafter\tikz@scan@next@command\expandafter% @@ -2443,8 +2942,7 @@ \def\tikz@lib@graph@parser{\pgfutil@ifnextchar[\tikz@graph@error{\tikz@graph@error[]}}%] \def\tikz@graph@error[#1]#2{% - \PackageError{tikz}{You need to say \string\usetikzlibrary{graph} in - order to use the graph syntax}{}% + \tikzerror{You need to say \string\usetikzlibrary{graphs} in order to use the graph syntax}% \tikz@lib@graph@parser@done% } @@ -2460,8 +2958,23 @@ \def\tikz@edgetoparent from parent{\pgfutil@ifnextchar[\tikz@@edgetoparent{\tikz@@edgetoparent[]}}%} \def\tikz@@edgetoparent[#1]{% \let\tikz@edge@to@parent@needed=\pgfutil@empty% - \tikz@node@is@a@labeltrue% - \tikz@scan@next@command [style=edge from parent,#1] \tikz@edge@to@parent@path% + \def\tikz@edgetoparent@options{#1}% + \begingroup% + \let\tikz@collected@onpath=\pgfutil@empty% + \tikz@edgetoparentcollect% +} +\def\tikz@edgetoparentcollect{ + \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@edgetoparentcollect}% + {% + \expandafter% + \endgroup% + \expandafter\tikz@edgetoparent@rollout\expandafter{\tikz@collected@onpath}% + } +} + +\def\tikz@edgetoparent@rollout#1{% + \pgfkeysgetvalue{/tikz/edge from parent macro}\tikz@etop@temp + \expandafter\tikz@scan@next@command\expandafter\tikz@etop@temp\expandafter{\tikz@edgetoparent@options}{#1}% } @@ -2472,9 +2985,10 @@ \def\tikz@dot.{\tikz@@dot}% \def\tikz@@dot{% - \pgfutil@ifnextchar n% - {\tikz@collect@label@onpath\tikz@@dot}% - {\pgfutil@ifnextchar c{\tikz@curveto@double}{\tikz@curveto@auto}}} + \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@@dot}{% + \pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@@dot}% + {\pgfutil@ifnextchar c{\tikz@curveto@double}{\tikz@curveto@auto}}}% +} \def\tikz@curveto@double co{% \pgfutil@ifnextchar o{\tikz@collect@coordinate@onpath\tikz@@dot co} @@ -2485,6 +2999,8 @@ \def\tikz@curveA#1{% \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% {% + \tikz@lastxsaved=\tikz@lastx% + \tikz@lastysaved=\tikz@lasty% \tikz@make@last@position{#1}% \xdef\tikz@curve@first{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% }% @@ -2503,16 +3019,16 @@ \def\tikz@curveCdot.{% \ifx\@next.% \else% - \PackageError{tikz}{Dot expected}{}% + \tikzerror{Dot expected}% \fi% \tikz@updatecurrenttrue% \tikz@curveCcheck% } \def\tikz@curveCcheck{% - \pgfutil@ifnextchar n% - {\tikz@collect@label@onpath\tikz@curveCcheck} + \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@curveCcheck}{% + \pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@curveCcheck}% {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@curveCcheck} - {\tikz@scan@one@point\tikz@curveC}}% + {\tikz@scan@one@point\tikz@curveC}}}% } \def\tikz@curveC#1{% \tikz@make@last@position{#1}% @@ -2552,7 +3068,8 @@ \let\tikz@timer@end=\tikz@curve@third \let\tikz@moveto@waiting=\relax% \fi% - \let\tikz@timer=\tikz@timer@curve% + \let\tikz@timer=\tikz@timer@curve% + \let\tikz@tangent=\tikz@curve@second% \tikz@scan@next@command% } @@ -2564,13 +3081,13 @@ \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% \tikz@@rect}% \def\tikz@@rect{% - \pgfutil@ifnextchar n - {\tikz@collect@label@onpath\tikz@@rect} + \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@@rect}{% + \pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@@rect}% {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@@rect}% { \pgf@xa=\tikz@lastx\relax% \pgf@ya=\tikz@lasty\relax% - \tikz@scan@one@point\tikz@rectB}}} + \tikz@scan@one@point\tikz@rectB}}}} \def\tikz@rectB#1{% \tikz@make@last@position{#1}% \edef\tikz@timer@end{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% @@ -2585,6 +3102,7 @@ \pgfpathclose% \pgfpathmoveto{\pgfqpoint{\tikz@lastx}{\tikz@lasty}}% \def\pgfstrokehook{}% + \let\tikz@tangent\relax% \tikz@scan@next@command% } @@ -2599,9 +3117,10 @@ \pgfutil@ifnextchar[{\tikz@gridA}{\tikz@gridA[]}}%} \def\tikz@gridA[#1]{% \def\tikz@grid@options{#1}% - \tikz@scan@one@point\tikz@gridB}% + \tikz@cycle@expander{\tikz@scan@one@point\tikz@gridB}}% \def\tikz@gridB#1{% \tikz@make@last@position{#1}% + \let\tikz@tangent\relax% {% \let\tikz@after@path\pgfutil@empty% \expandafter\tikzset\expandafter{\tikz@grid@options} @@ -2636,6 +3155,7 @@ \tikz@flush@moveto% \pgfutil@ifnextchar[{\tikz@@plot}{\tikz@@plot[]}}%} \def\tikz@@plot[#1]{% + \let\tikz@tangent\tikz@tangent@lookup% \begingroup% \let\tikz@after@path\pgfutil@empty% \let\tikz@options=\pgfutil@empty% @@ -2644,7 +3164,7 @@ \pgfutil@ifnextchar f{\tikz@plot@f}% {\pgfutil@ifnextchar c{\tikz@plot@scan@points}% {\pgfutil@ifnextchar ({\tikz@plot@expression}{% - \PackageError{tikz}{Cannot parse this plotting data}{}% + \tikzerror{Cannot parse this plotting data}% \endgroup}}}} \def\tikz@plot@f f{\pgfutil@ifnextchar i{\tikz@plot@file}{\tikz@plot@function}} @@ -2670,11 +3190,16 @@ \def\tikz@plot@data{\pgfplotgnuplot[\tikz@plot@filename]{% set samples \tikz@plot@samples; set parametric; - plot [t=\tikz@plot@domain] #1}}% + plot [t=\tikz@plot@domain] + [\tikz@plot@xrange] + [\tikz@plot@range] + #1}}% \else% \def\tikz@plot@data{\pgfplotgnuplot[\tikz@plot@filename]{% set samples \tikz@plot@samples; - plot [x=\tikz@plot@domain] #1}}% + plot [x=\tikz@plot@domain] + \ifx\tikz@plot@range\pgfutil@empty\else[\tikz@plot@range]\fi + #1}}% \fi% \fi% \tikz@@@plot% @@ -2700,8 +3225,8 @@ \ifx\tikz@plot@mark\pgfutil@empty% \else% % Marks are drawn after the path. - \setbox\tikz@figbox=\hbox{% - \unhbox\tikz@figbox% + \setbox\tikz@whichbox=\hbox{% + \unhbox\tikz@whichbox% \hbox{{% \pgfinterruptpath% \pgfscope% @@ -2720,10 +3245,10 @@ }}% }% \fi% - \global\setbox\tikz@tempbox=\copy\tikz@figbox% + \global\setbox\tikz@tempbox=\box\tikz@whichbox% \global\let\tikz@after@path@smuggle=\tikz@after@path - \endgroup% - \setbox\tikz@figbox=\box\tikz@tempbox% + \expandafter\endgroup% + \expandafter\setbox\tikz@whichbox=\box\tikz@tempbox% \tikz@make@last@position{\tikz@@@temp}% \expandafter\tikz@scan@next@command\tikz@after@path@smuggle% } @@ -2740,8 +3265,9 @@ % Syntax for cosine curves: % cos <end of quarter-period> -\def\tikz@cosine s{\tikz@scan@one@point\tikz@@cosine} +\def\tikz@cosine s{\tikz@cycle@expander{\tikz@scan@one@point\tikz@@cosine}} \def\tikz@@cosine#1{% + \let\tikz@tangent\tikz@tangent@lookup% \tikz@flush@moveto% \pgf@process{#1}% \pgf@xc=\pgf@x% @@ -2759,8 +3285,9 @@ % Syntax for sine curves: % sin <end of quarter-period> -\def\tikz@sine in{\tikz@scan@one@point\tikz@@sine} +\def\tikz@sine in{\tikz@cycle@expander{\tikz@scan@one@point\tikz@@sine}} \def\tikz@@sine#1{% + \let\tikz@tangent\tikz@tangent@lookup% \tikz@flush@moveto% \pgf@process{#1}% \pgf@xc=\pgf@x% @@ -2779,15 +3306,16 @@ % Syntax for parabolas: % parabola[options] bend <coordinate> <coordinate> \def\tikz@parabola arabola{% + \let\tikz@tangent\tikz@tangent@lookup% \pgfutil@ifnextchar[{\tikz@parabola@options}{\tikz@parabola@options[]}}%} \def\tikz@parabola@options[#1]{% \def\tikz@parabola@option{#1}% - \pgfutil@ifnextchar b{\tikz@parabola@scan@bend}{\tikz@scan@one@point\tikz@parabola@semifinal}} + \pgfutil@ifnextchar b{\tikz@parabola@scan@bend}{\tikz@cycle@expander{\tikz@scan@one@point\tikz@parabola@semifinal}}} \def\tikz@parabola@scan@bend bend{\tikz@scan@one@point\tikz@parabola@scan@bendB} \def\tikz@parabola@scan@bendB#1{% \def\tikz@parabola@bend{#1}% - \tikz@scan@one@point\tikz@parabola@semifinal% + \tikz@cycle@expander{\tikz@scan@one@point\tikz@parabola@semifinal}% } \def\tikz@parabola@semifinal#1{% \tikz@flush@moveto% @@ -2832,6 +3360,7 @@ \def\tikz@circle ircle{\tikz@flush@moveto\tikz@@circle} \def\tikz@ellipse llipse{\tikz@flush@moveto\tikz@@circle} \def\tikz@@circle{% + \let\tikz@tangent\relax% \pgfutil@ifnextchar(\tikz@@@circle {\pgfutil@ifnextchar[\tikz@circle@opt{%]) \advance\tikz@expandcount by -10\relax% go down quickly @@ -2883,13 +3412,13 @@ \pgfpathellipse{\pgfpointorigin}{% \pgfqpoint{\tikz@ellipse@x pt}{0pt}}{\pgfpoint{0pt}{\tikz@ellipse@y pt}}% \else% - \PackageError{tikz}{You cannot mix dimensions and dimensionless values in an ellipse}{}% + \tikzerror{You cannot mix dimensions and dimensionless values in an ellipse}% \fi% \else% \pgfmathparse{#2}% \let\tikz@ellipse@y=\pgfmathresult% \ifpgfmathunitsdeclared% - \PackageError{tikz}{You cannot mix dimensions and dimensionless values in an ellipse}{}% + \tikzerror{You cannot mix dimensions and dimensionless values in an ellipse}% \else% \pgfpathellipse{\pgfpointorigin}{% \pgfpointxy{\tikz@ellipse@x}{0}}{\pgfpointxy{0}{\tikz@ellipse@y}}% @@ -2937,11 +3466,13 @@ \ifx\tikz@e\pgfutil@empty% \pgfmathsetmacro\tikz@e{\tikz@s+\tikz@d} \fi% - \fi + \fi% + \xdef\pgf@marshal{\noexpand% \tikz@do@arc{\tikz@s}{\tikz@e} {\pgfkeysvalueof{/tikz/x radius}} - {\pgfkeysvalueof{/tikz/y radius}} + {\pgfkeysvalueof{/tikz/y radius}}}% }% + \pgf@marshal% \tikz@arcfinal% } @@ -2964,6 +3495,10 @@ \tikz@do@arc{#1}{#2}{#3}{#4}% } \def\tikz@do@arc#1#2#3#4{% + \let\tikz@tangent\tikz@tangent@lookup% + \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% + \edef\tikz@timer@start@angle{#1}% + \edef\tikz@timer@end@angle{#2}% \pgfmathparse{#3}% \let\tikz@arc@x=\pgfmathresult% \ifpgfmathunitsdeclared% @@ -2973,17 +3508,23 @@ \tikz@@@arcfinal{\pgfpatharc{#1}{#2}{\tikz@arc@x pt and \tikz@arc@y pt}} {\pgfpointpolar{#1}{\tikz@arc@x pt and \tikz@arc@y pt}} {\pgfpointpolar{#2}{\tikz@arc@x pt and \tikz@arc@y pt}}% + \edef\tikz@timer@zero@axis{\noexpand\pgfqpoint{\tikz@arc@x pt}{0pt}} + \edef\tikz@timer@ninety@axis{\noexpand\pgfqpoint{0pt}{\tikz@arc@y pt}} \else% - \PackageError{tikz}{You cannot mix dimensions and dimensionless values in an arc}{}% + \tikzerror{You cannot mix dimensions and dimensionless values in an arc}% \fi% \else% \pgfmathparse{#4}% \let\tikz@arc@y=\pgfmathresult% \ifpgfmathunitsdeclared% - \PackageError{tikz}{You cannot mix dimensions and dimensionless values in an arc}{}% + \tikzerror{You cannot mix dimensions and dimensionless values in an arc}% \else% \tikz@@@arcfinal{\pgfpatharcaxes{#1}{#2}{\pgfpointxy{\tikz@arc@x}{0}}{\pgfpointxy{0}{\tikz@arc@y}}} {\pgfpointpolarxy{#1}{\tikz@arc@x and \tikz@arc@y}}{\pgfpointpolarxy{#2}{\tikz@arc@x and \tikz@arc@y}}% + \pgf@process{\pgfpointxy{\tikz@arc@x}{0}} + \edef\tikz@timer@zero@axis{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}} + \pgf@process{\pgfpointxy{0}{\tikz@arc@y}} + \edef\tikz@timer@ninety@axis{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}} \fi% \fi% } @@ -3005,6 +3546,7 @@ \advance\tikz@lasty by\pgf@y% \tikz@lastxsaved=\tikz@lastx% \tikz@lastysaved=\tikz@lasty% + \let\tikz@timer=\tikz@timer@arc% \tikz@scan@next@command% } @@ -3037,20 +3579,28 @@ % Syntax for nodes: -% node[options] (node name) {label text} +% node foreach \var in {list} ... [options] (node name) at (pos) {label text} % -% all of [options], (node name) and {label text} are optional. There -% can be multiple options before the label text as in -% node[draw] (a) [rotate=10] {text} +% all of [options], (node name), at(pos), and foreach are +% optional. There can be multiple options and the ordering is not +% important as in node[draw] (a) [rotate=10] {text}, *except* that all +% foreach statements must come first. % % A label text always ``ends'' the node. +% \def\tikz@fig ode{% + \pgfutil@ifnextchar a\tikz@test@also{ + \pgfutil@ifnextchar f{\tikz@nodes@start}\tikz@normal@fig}} +\def\tikz@test@also a{\pgfutil@ifnextchar l\tikz@node@also{\tikz@normal@fig a}}% +\def\tikz@normal@fig{% \edef\tikz@save@line@width{\the\pgflinewidth}% \begingroup% \let\tikz@fig@name=\pgfutil@empty% \begingroup% \tikz@is@matrixfalse% \let\nodepart=\tikz@nodepart% + \let\tikz@atbegin@scope=\pgfutil@empty% + \let\tikz@atend@scope=\pgfutil@empty% \let\tikz@do@after@node=\tikz@scan@next@command% \let\tikz@options=\pgfutil@empty% \let\tikz@after@path=\pgfutil@empty% @@ -3061,9 +3611,12 @@ \let\tikz@postactions=\pgfutil@empty% \let\tikz@alias=\pgfutil@empty% \def\tikz@node@at{\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% + \let\tikz@time@for@matrix\tikz@time% + \let\tikz@node@content\relax% + \pgfgetpath\tikzpathuptonow% \iftikz@node@is@a@label% \else% - \let\tikz@time=\pgfutil@empty% + \let\tikz@time\pgfutil@empty% \fi% \tikz@node@reset@hook% \tikzset{every node/.try}% @@ -3073,7 +3626,7 @@ {\pgfutil@ifnextchar({\tikz@fig@scan@name} {\pgfutil@ifnextchar[{\tikz@fig@scan@options}% {\pgfutil@ifnextchar\bgroup{\tikz@fig@main}% - {\PackageError{tikz}{A node must have a (possibly empty) label text}{}% + {\tikzerror{A node must have a (possibly empty) label text}% \tikz@fig@main{}}}}}}%}} \def\tikz@fig@scan@at at{% \tikz@scan@one@point\tikz@@fig@scan@at} @@ -3083,17 +3636,26 @@ \pgfkeysvalueof{/tikz/name/.@cmd}#1\pgfeov% CF : this is now ALWAYS consistent with 'name=' option; allows overrides. \tikz@@scan@fig}% % make it \long to allow \par in "pin" options etc: -\long\def\tikz@fig@scan@options[#1]{\tikzset{#1}\tikz@@scan@fig}% +\long\def\tikz@fig@scan@options[#1]{\iftikz@node@is@pic\tikz@enable@pic@quotes\else\tikz@enable@node@quotes\fi\tikzset{#1}\ifx\tikz@node@content\relax\expandafter\tikz@@scan@fig\else\tikz@expand@node@contents\fi}% +\def\tikz@expand@node@contents{% + \expandafter\tikz@@scan@fig\expandafter{\tikz@node@content}% +} \let\tikz@node@reset@hook=\pgfutil@empty% \let\tikz@node@begin@hook=\pgfutil@empty% -\def\tikz@fig@main{\afterassignment\tikz@@fig@main\let\next=} +\def\tikz@fig@main{% + \iftikz@node@is@pic% + \tikz@node@is@picfalse% + \expandafter\tikz@subpicture@handle% + \else% + \afterassignment\tikz@@fig@main\expandafter\let\expandafter\next\expandafter=% + \fi} \def\tikz@@fig@main{% \pgfutil@ifundefined{pgf@sh@s@\tikz@shape}% - {\PackageError{tikz}% - {Unknown shape ``\tikz@shape.'' Using ``rectangle'' instead}{}% + {\tikzerror{Unknown shape ``\tikz@shape.'' Using ``rectangle'' instead}% \def\tikz@shape{rectangle}}% {}% \tikzset{every \tikz@shape\space node/.try}% + \tikz@node@textfont% \tikz@node@begin@hook% \iftikz@is@matrix% \let\tikz@next=\tikz@do@matrix% @@ -3102,7 +3664,12 @@ \fi% \tikz@next% } +\let\tikz@nodepart@list\pgfutil@empty \def\tikz@do@fig{% + % Ok, reset all node part boxes + \pgfutil@for\tikz@temp:=\tikz@nodepart@list\do{% + \expandafter\setbox\csname pgfnodepart\tikz@temp box\endcsname=\box\pgfutil@voidb@x% + }% \setbox\pgfnodeparttextbox=\hbox% \bgroup% \tikzset{every text node part/.try}% @@ -3112,12 +3679,13 @@ \pgfsetstrokeopacity{\tikz@textopacity}% \fi% \pgfinterruptpicture% - \tikz@textfont% \ifx\tikz@text@width\pgfutil@empty% + \tikz@textfont% \else% \begingroup% \pgfmathsetlength{\pgf@x}{\tikz@text@width}% \pgfutil@minipage[t]{\pgf@x}\leavevmode\hbox{}% + \tikz@textfont% \tikz@text@action% \fi% \tikz@atbegin@node% @@ -3129,15 +3697,23 @@ \fi% \pgfsetcolor{.}% \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% \tikz@uninstallcommands% + \iftikz@handle@active@code% + \tikz@orig@shorthands% + \let\tikz@orig@shorthands\pgfutil@empty% + \fi% + \ifnum\the\catcode`\;=\active\relax\expandafter\let\tikz@activesemicolon=\tikz@origsemi\fi% + \ifnum\the\catcode`\:=\active\relax\expandafter\let\tikz@activecolon=\tikz@origcolon\fi% + \ifnum\the\catcode`\|=\active\relax\expandafter\let\tikz@activebar=\tikz@origbar\fi% \aftergroup\tikz@fig@collectresetcolor% \tikz@halign@check% \ignorespaces% } \def\tikz@fig@collectresetcolor{% - \pgfutil@ifnextchar\reset@color% - {\reset@color\afterassignment\tikz@fig@collectresetcolor\let\tikz@temp=}% - {\tikz@fig@boxdone}% + % Hacks for special packages that mess with \aftergroup + \pgfutil@ifnextchar\reset@color% hack for color package + {\reset@color\afterassignment\tikz@fig@collectresetcolor\let\tikz@temp=}\tikz@fig@boxdone% } \def\tikz@fig@boxdone{% \tikz@atend@node% @@ -3158,14 +3734,15 @@ \tikzset{every matrix/.try}% \tikz@node@transformations% \tikz@fig@mustbenamed% - \setbox\tikz@figbox=\hbox\bgroup% - \setbox\pgfutil@tempboxa=\copy\tikz@figbox% - \unhbox\pgfutil@tempboxa% + \setbox\tikz@whichbox=\hbox\bgroup% + \unhbox\tikz@whichbox% \hbox\bgroup\bgroup% \pgfinterruptpath% \pgfscope% + \ifx\tikz@time\pgfutil@empty\let\tikz@time\tikz@time@for@matrix\fi% \tikz@options% \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% \let\tikzmatrixname=\tikz@fig@name% \edef\tikz@m@anchor{\ifx\tikz@matrix@anchor\pgfutil@empty\tikz@anchor\else\tikz@matrix@anchor\fi}% \expandafter\pgfutil@in@\expandafter{\expandafter.\expandafter}\expandafter{\tikz@m@anchor}% @@ -3221,10 +3798,12 @@ \tikz@at@emptycell% \pgfsys@endscope% }% + \tikz@atbegin@matrix% \aftergroup\tikz@do@matrix@cont}% \bgroup% } -\def\tikz@do@matrix@cont{% +\def\tikz@do@matrix@cont{% + \tikz@atend@matrix% \endpgfscope \endpgfinterruptpath% \egroup\egroup% @@ -3270,16 +3849,17 @@ % % Node transformation % - \tikz@node@transformations - % - \setbox\tikz@figbox=\hbox{% - \setbox\pgfutil@tempboxa=\copy\tikz@figbox% - \unhbox\pgfutil@tempboxa% + \tikz@node@transformations% + \tikz@nlt% + % + \setbox\tikz@whichbox=\hbox{% + \unhbox\tikz@whichbox% \hbox{{% \pgfinterruptpath% \pgfscope% \tikz@options% \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% \pgfmultipartnode{\tikz@shape}{\tikz@anchor}{\tikz@fig@name}{% \pgfutil@tempdima=\pgflinewidth% {\begingroup\tikz@finish}% @@ -3303,7 +3883,7 @@ \fi% } -\def\tikz@node@transformations{ +\def\tikz@node@transformations{% % % Possibly, we are ``online'' % @@ -3325,22 +3905,35 @@ \global\let\tikz@last@fig@name=\tikz@fig@name% \global\let\tikz@after@path@smuggle=\tikz@after@path% % shift box outside group - \global\setbox\tikz@tempbox=\copy\tikz@figbox% + \global\setbox\tikz@tempbox=\box\tikz@figbox% + \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% \endgroup\endgroup% \setbox\tikz@figbox=\box\tikz@tempbox% - \pgflinewidth=\tikz@save@line@width% + \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% + \global\pgflinewidth=\tikz@save@line@width% + \tikz@do@after@path@smuggle% + \tikz@do@after@node% +} +\let\tikz@fig@continue@orig=\tikz@fig@continue + +\def\tikz@do@after@node{\tikz@scan@next@command} + +\def\tikz@do@after@path@smuggle{% \let\tikz@to@last@fig@name=\tikz@last@fig@name% \let\tikz@to@use@whom=\tikz@to@use@last@fig@name% \let\tikzlastnode=\tikz@last@fig@name% \ifx\tikz@after@path@smuggle\pgfutil@empty% \else% - \tikz@scan@next@command{\tikz@after@path@smuggle}\pgf@stop% + \ifpgflatenodepositioning% + \expandafter\expandafter\expandafter\tikz@call@late% + \expandafter\expandafter\expandafter{\expandafter\tikz@last@fig@name\expandafter}\expandafter{\tikz@after@path@smuggle}% + \else% + \tikz@scan@next@command{\tikz@after@path@smuggle}\pgf@stop% + \fi% \fi% - \tikz@do@after@node% } -\let\tikz@fig@continue@orig=\tikz@fig@continue -\def\tikz@do@after@node{\tikz@scan@next@command} +\def\tikz@call@late#1#2{\pgfnodepostsetupcode{#1}{\path[late options={name={#1},append after command={#2}}];}} \newif\iftikz@do@align @@ -3361,7 +3954,8 @@ \expandafter\tikz@start@align% \fi% } -\def\tikz@align@newline{\unskip\pgfutil@ifnextchar[\tikz@@align@newline{\tikz@@align@newline[0pt]}}%} +\def\tikz@align@newline{\pgfutil@protect\tikz@align@newline@} +\def\tikz@align@newline@{\unskip\pgfutil@ifnextchar[\tikz@@align@newline{\tikz@@align@newline[0pt]}}%} \def\tikz@@align@newline[#1]{\egroup\tikz@align@continue\pgfmathparse{#1}\let\tikz@align@temp=\pgfmathresult\tikz@start@align}% % Two safe boxes for alignment: \let\tikz@align@aligned@box=\pgfnodeparttextbox @@ -3399,6 +3993,16 @@ \let\tikz@@align@continue=\pgfutil@empty +\def\tikz@node@also lso{\pgfutil@ifnextchar[\tikz@node@also@opt{\tikz@node@also@opt[]}} +\def\tikz@node@also@opt[#1]{ + \pgfutil@ifnextchar(%) + {\tikz@node@also@opt@cont[#1]}% + {\tikzerror{Syntax error in node also: ``('' expected.}% + \tikz@scan@next@command}% +} +\def\tikz@node@also@opt@cont[#1](#2){\tikzset{late options={name=#2,#1}}\tikz@scan@next@command} + + % Syntax for parts of nodes: % node ... {... \nodepart[options]{name} ... \nodepart{name} ...} @@ -3414,18 +4018,29 @@ } \def\tikz@nodepart@continue{% \global\let\tikz@fig@continue=\tikz@fig@continue@orig% + \ifx\tikz@nodepart@list\pgfutil@empty% + \let\tikz@nodepart@list\tikz@nodepart@name% + \else% + \edef\tikz@nodepart@list{\tikz@nodepart@list,\tikz@nodepart@name}% + \fi% % Now start new box: \expandafter\setbox\csname pgfnodepart\tikz@nodepart@name box\endcsname=\hbox% \bgroup% \tikzset{every \tikz@nodepart@name\space node part/.try}% \expandafter\tikzset\expandafter{\tikz@nodepart@options}% + \ifx\tikz@textopacity\pgfutil@empty% + \else% + \pgfsetfillopacity{\tikz@textopacity}% + \pgfsetstrokeopacity{\tikz@textopacity}% + \fi% \pgfinterruptpicture% - \tikz@textfont% \ifx\tikz@text@width\pgfutil@empty% + \tikz@textfont% \else% \begingroup% - \pgfmathsetlength{\pgf@x}{\tikz@text@width}% + \pgfmathsetlength{\pgf@x}{\tikz@text@width}% \pgfutil@minipage[t]{\pgf@x}\leavevmode\hbox{}% + \tikz@textfont% \tikz@text@action% \fi% \bgroup% @@ -3436,13 +4051,92 @@ \fi% \pgfsetcolor{.}% \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% \tikz@uninstallcommands% + \iftikz@handle@active@code% + \tikz@orig@shorthands% + \let\tikz@orig@shorthands\pgfutil@empty% + \fi% + \ifnum\the\catcode`\;=\active\relax\expandafter\let\tikz@activesemicolon=\tikz@origsemi\fi% + \ifnum\the\catcode`\:=\active\relax\expandafter\let\tikz@activecolon=\tikz@origcolon\fi% + \ifnum\the\catcode`\|=\active\relax\expandafter\let\tikz@activebar=\tikz@origbar\fi% \tikz@atbegin@node% \aftergroup\tikz@fig@collectresetcolor% \tikz@halign@check% \ignorespaces% } + +% +% Node foreach +% + +\def\tikz@nodes@start{% + \let\tikz@nodes@list\pgfutil@empty% + \iftikz@node@is@pic% + \def\tikz@nodes@collect{pic }% + \else% + \def\tikz@nodes@collect{node }% + \fi% + \tikz@nodes% +} +\def\tikz@nodes foreach{\pgfutil@ifnextchar x\tikz@nodes@\tikz@nodes@}% get rid of spaces +\def\tikz@nodes@#1in{% + \expandafter\def\expandafter\tikz@nodes@list\expandafter{\tikz@nodes@list\foreach#1in}% + \pgfutil@ifnextchar\bgroup\tikz@nodes@group\tikz@nodes@one% +} +\def\tikz@nodes@one#1{% + \expandafter\def\expandafter\tikz@nodes@list\expandafter{\tikz@nodes@list#1}% + \pgfutil@ifnextchar f\tikz@nodes\tikz@nodes@scan% +} +\def\tikz@nodes@group#1{% + \expandafter\def\expandafter\tikz@nodes@list\expandafter{\tikz@nodes@list{#1}}% + \pgfutil@ifnextchar f\tikz@nodes\tikz@nodes@scan% +} +\def\tikz@nodes@scan{% + \pgfutil@ifnextchar a{\tikz@nodes@at}% + {\pgfutil@ifnextchar({\tikz@nodes@name}% + {\pgfutil@ifnextchar[{\tikz@nodes@opt}% + {\pgfutil@ifnextchar\bgroup{\tikz@nodes@main}% + {\tikzerror{Nodes must have a (possibly empty) label text}% + \tikz@fig@main{}}}}}}%}} +\def\tikz@nodes@at at#1){% + \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect at#1)}% + \tikz@nodes@scan}% +\def\tikz@nodes@name#1){% + \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect#1)}% + \tikz@nodes@scan}% +\def\tikz@nodes@opt#1]{% + \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect#1]}% + \tikz@nodes@scan}% +\def\tikz@nodes@main#1{% + \iftikz@handle@active@nodes% + \iftikz@node@is@pic% + \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect{#1}}% + \else% + \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect{\scantokens{#1}}}% + \fi% + \else% + \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect{#1}}% + \fi% + % Ok, got everything. + % Now, start building parse text. + \global\setbox\tikz@tempbox=\box\tikz@figbox% + \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% + \tikz@nodes@list{% + \setbox\tikz@figbox=\box\tikz@tempbox% + \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% + \expandafter\tikz@scan@next@command\tikz@nodes@collect\pgfextra\relax% + \global\setbox\tikz@tempbox=\box\tikz@figbox% + \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% + }% + \setbox\tikz@figbox=\box\tikz@tempbox% + \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% + \tikz@scan@next@command% +} + + + % % "late" options can be used to "redo" a node % @@ -3463,23 +4157,18 @@ \let\tikz@transform=\pgfutil@empty% \tikz@decoratepathfalse% \tikz@node@reset@hook% - \tikzset{every node/.try,#1}% + \tikz@enable@node@quotes% + \tikzset{every node/.try,#1}% \ifx\tikz@fig@name\pgfutil@empty% - \PackageError{tikz}{Late options must reference some existing - node}{}% + \tikzerror{Late options must reference some existing node}% \fi% \tikz@node@begin@hook% \tikz@alias% + \tikzgdlatenodeoptionacallback{\tikz@fig@name}% \global\let\tikz@last@fig@name=\tikz@fig@name% \global\let\tikz@after@path@smuggle=\tikz@after@path% \endgroup% - \let\tikz@to@last@fig@name=\tikz@last@fig@name% - \let\tikz@to@use@whom=\tikz@to@use@last@fig@name% - \let\tikzlastnode=\tikz@last@fig@name% - \ifx\tikz@after@path@smuggle\pgfutil@empty% - \else% - \tikz@scan@next@command{\tikz@after@path@smuggle}\pgf@stop% - \fi% + \tikz@do@after@path@smuggle% } @@ -3555,7 +4244,13 @@ } - +% +% Callbacks: Please see the documentation of the graph drawing +% lib for info on these callbacks +% +\def\tikzgdeventcallback#1#2{} +\def\tikzgdeventgroupcallback#1{} +\def\tikzgdlatenodeoptionacallback#1{} % Syntax for trees: % node {...} child [options] {...} child [options] {...} ... @@ -3595,39 +4290,48 @@ \long\def\tikz@children@collected{% \begingroup% \advance\tikztreelevel by 1\relax% + \tikzgdeventgroupcallback{descendants}% \let\tikz@options=\pgfutil@empty% \let\tikz@transform=\pgfutil@empty% \tikzset{level/.try=\the\tikztreelevel,level \the\tikztreelevel/.try}% \tikz@transform% + \let\tikz@transform=\relax% \let\tikzparentnode=\tikz@last@fig@name% - % Transform to center of node - \pgftransformshift{\pgfpointanchor{\tikzparentnode}{\tikz@growth@anchor}}% + \ifx\tikz@grow\relax\else% + % Transform to center of node + \pgftransformshift{\pgfpointanchor{\tikzparentnode}{\tikz@growth@anchor}}% + \fi% \tikznumberofcurrentchild=0\relax% \tikz@children@list% - \global\setbox\tikz@tempbox=\copy\tikz@figbox% + \global\setbox\tikz@tempbox=\box\tikz@figbox% + \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% \endgroup% \setbox\tikz@figbox=\box\tikz@tempbox% + \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% \tikz@scan@next@command% } - % Syntax for children: % % child [all children options] foreach \var in {values} [child options] {...} \def\tikz@childrennodes[#1]#2#3#4{% \c@pgf@counta=\tikznumberofcurrentchild\relax% \setbox\tikz@tempbox=\box\tikz@figbox% + \setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% \foreach#2in{#3}{% \tikznumberofcurrentchild=\c@pgf@counta\relax% \setbox\tikz@figbox=\box\tikz@tempbox% + \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% \tikz@childnode[#1]{#4}% % we must now make the current child number and the figbox survive % the group \global\c@pgf@counta=\tikznumberofcurrentchild\relax% \global\setbox\tikz@tempbox=\box\tikz@figbox% + \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% }% \tikznumberofcurrentchild=\c@pgf@counta\relax% \setbox\tikz@figbox=\box\tikz@tempbox% + \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% } @@ -3644,9 +4348,10 @@ \advance\tikznumberofcurrentchild by1\relax% {\tikzset{every child/.try,#1}\expandafter}% \iftikz@child@missing% + \tikzgdeventcallback{node}{}% \else% - \setbox\tikz@figbox=\hbox\bgroup% - \unhbox\tikz@figbox% + \setbox\tikz@whichbox=\hbox\bgroup% + \unhbox\tikz@whichbox% \hbox\bgroup\bgroup% \pgfinterruptpath% \pgfscope% @@ -3654,6 +4359,7 @@ \tikzset{every child/.try,#1}% \tikz@options% \tikz@transform% + \let\tikz@transform=\relax% \tikz@grow% % Typeset node: \edef\tikz@parent@node@name{[name=\tikzparentnode-\the\tikznumberofcurrentchild,style=every child node]}% @@ -3669,7 +4375,7 @@ \ifx\tikz@child@node@rest\pgfutil@empty% \path edge from parent;% \else% - \path (0,0) \tikz@child@node@rest \tikz@edge@to@parent@needed;% + \path \tikz@child@node@rest \tikz@edge@to@parent@needed;% \fi% }% \endpgfscope% @@ -3682,9 +4388,17 @@ \def\tikz@parse@child@node{% \pgfutil@ifnextchar n{\tikz@parse@child@node@n}% {\pgfutil@ifnextchar c{\tikz@parse@child@node@c}% - {\tikz@parse@child@node@rest}}} -\def\tikz@parse@child@node@rest#1\pgf@stop{\def\tikz@child@node@rest{#1}} -\def\tikz@parse@child@node@c c{\pgfutil@ifnextchar o{\tikz@parse@child@node@co}{\tikz@parse@child@node@rest c}} + {\pgfutil@ifnextchar\pgf@stop\tikz@parse@child@node@rest\tikz@parse@child@node@expand}}} +\def\tikz@parse@child@node@expand{% + \advance\tikz@expandcount by-1\relax% + \ifnum\tikz@expandcount<0\relax% + \expandafter\tikz@parse@child@node@rest% + \else% + \expandafter\expandafter\expandafter\tikz@parse@child@node% + \fi% +} +\def\tikz@parse@child@node@rest#1\pgf@stop{\tikz@expandcount=100\relax\def\tikz@child@node@rest{#1}} +\def\tikz@parse@child@node@c c{\tikz@expandcount=100\pgfutil@ifnextchar o{\tikz@parse@child@node@co}{\tikz@parse@child@node@rest c}} \def\tikz@parse@child@node@co o{\pgfutil@ifnextchar o{\tikz@parse@child@node@coordinate}{\tikz@parse@child@node@rest co}} \def\tikz@parse@child@node@coordinate ordinate{% \pgfutil@ifnextchar ({\tikz@@parse@child@node@coordinate}{% @@ -3706,7 +4420,7 @@ \expandafter\expandafter\expandafter{\expandafter\tikz@child@node@text@pre\tikz@marshal}% \tikz@parse@child@node@rest% } -\def\tikz@parse@child@node@n node{% +\def\tikz@parse@child@node@n node{\tikz@expandcount=100% \let\tikz@child@node@text=\pgfutil@empty% \tikz@p@c@s}% \def\tikz@p@c@s{% @@ -3714,7 +4428,7 @@ {\pgfutil@ifnextchar ({\tikz@p@c@s@paran} {\pgfutil@ifnextchar [{\tikz@p@c@s@bra} {\pgfutil@ifnextchar \bgroup{\tikz@p@c@s@group} - {\PackageError{tikz}{Cannot parse this node}{}}}}}}%}} + {\tikzerror{Cannot parse this node}}}}}}%}} \def\tikz@p@c@s@at at#1({% \tikz@scan@one@point\tikz@p@c@s@at@math(% } @@ -3732,8 +4446,13 @@ \expandafter\def\expandafter\tikz@child@node@text\expandafter{\tikz@child@node@text[#1]} \tikz@p@c@s} \def\tikz@p@c@s@group#1{% - \expandafter\def\expandafter\tikz@child@node@text\expandafter{\tikz@child@node@text{#1}} - \tikz@parse@child@node@rest} + \iftikz@handle@active@nodes% + \expandafter\def\expandafter\tikz@child@node@text\expandafter{\tikz@child@node@text{\scantokens{#1}}}% + \else% + \expandafter\def\expandafter\tikz@child@node@text\expandafter{\tikz@child@node@text{#1}} + \fi% + \tikz@parse@child@node@rest% +} @@ -3746,10 +4465,10 @@ \pgfutil@ifnextchar[{\tikz@lib@decoration}{\tikz@lib@decoration[]}%] } -\def\tikz@lib@decoration[#1]#2{\PackageError{tikz}{You need to load a decoration library}{}} +\def\tikz@lib@decoration[#1]#2{\tikzerror{You need to load a decoration library}} % The decorate path command: -\def\tikz@lib@dec@decorate@path{\PackageError{tikz}{You need to load a decoration library}{}} +\def\tikz@lib@dec@decorate@path{\tikzerror{You need to load a decoration library}} @@ -3759,10 +4478,121 @@ % let \p1 = (coordinate), \p2 = (coordinate),... in % \def\tikz@let@command et#1in{% - \PackageError{tikz}{You need to say \string\usetikzlibrary{calc} to use the let command}{}% + \tikzerror{You need to say \string\usetikzlibrary{calc} to use the let command}% } +% +% Syntax for pictures: +% +% as for nodes, but with "pic" instead of "node" +% +\newif\iftikz@node@is@pic +\def\tikz@subpicture ic{\tikz@node@is@pictrue\tikz@scan@next@command node} +\def\tikz@subpicture@handle#1{% + \pgfkeys@spdef\tikz@temp{#1}% + \expandafter\tikz@subpicture@handle@\expandafter{\tikz@temp}% +} +\def\tikz@subpicture@handle@#1{ + \pgfkeys{/tikz/pics/.cd,#1} + \tikz@node@transformations% + \let\tikz@transform=\relax% + \let\tikz@picmode\tikz@mode% + \tikzset{name prefix ../.style/.expanded={/tikz/name prefix=\pgfkeysvalueof{/tikz/name prefix}}}% + \ifx\tikz@fig@name\pgfutil@empty\else% + \tikzset{name prefix/.prefix/.expanded=\tikz@fig@name}% + \fi% + \pgfkeysvalueof{/tikz/pics/setup code}% + \pgfkeysgetvalue{/tikz/pics/code}{\tikz@pic@code} + \ifx\tikz@pic@code\pgfutil@empty\else% + \setbox\tikz@whichbox=\hbox\bgroup% + \unhbox\tikz@whichbox% + \hbox\bgroup + \bgroup% + \pgfinterruptpath% + \pgfscope% + \tikz@options% + \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% + \tikz@atbegin@scope% + \scope[every pic/.try]% + \tikz@pic@code% + \endscope% + \tikz@atend@scope% + \endpgfscope% + \endpgfinterruptpath% + \egroup + \egroup% + \egroup% + \fi% + \pgfkeysgetvalue{/tikz/pics/foreground code}{\tikz@pic@code} + \ifx\tikz@pic@code\pgfutil@empty\else% + \setbox\tikz@figbox=\hbox\bgroup% + \unhbox\tikz@figbox% + \hbox\bgroup + \bgroup% + \pgfinterruptpath% + \pgfscope% + \tikz@options% + \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% + \tikz@atbegin@scope% + \scope[every front pic/.try]% + \tikz@pic@code% + \endscope% + \tikz@atend@scope% + \endpgfscope% + \endpgfinterruptpath% + \egroup + \egroup% + \egroup% + \fi% + \pgfkeysgetvalue{/tikz/pics/background code}{\tikz@pic@code} + \ifx\tikz@pic@code\pgfutil@empty\else% + \setbox\tikz@figbox@bg=\hbox\bgroup% + \unhbox\tikz@figbox@bg% + \hbox\bgroup + \bgroup% + \pgfinterruptpath% + \pgfscope% + \tikz@options% + \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% + \tikz@atbegin@scope% + \scope[every behind pic/.try]% + \tikz@pic@code% + \endscope% + \tikz@atend@scope% + \endpgfscope% + \endpgfinterruptpath% + \egroup + \egroup% + \egroup% + \fi% + \tikz@node@finish% +} +\tikzset{ + pic actions/.code=\tikz@addmode{\tikz@picmode} +} + +% Setting up the picture codes: +\tikzset{ + pics/setup code/.initial=, + pics/code/.initial=, + pics/background code/.initial=, + pics/foreground code/.initial= +} + +% Defining pictures: + +\def\tikzdeclarepic#1#2{\pgfkeys{/tikz/#1/.cd,#2}} + +\pgfkeysdef{/handlers/.pic}{% + \edef\pgf@temp{\pgfkeyscurrentpath}% + \edef\pgf@temp{\expandafter\tikz@smuggle@pics@in\pgf@temp\pgf@stop}% + \expandafter\pgfkeys\expandafter{\pgf@temp/.style={code={#1}}} +} +\def\tikz@smuggle@pics@in/tikz/#1\pgf@stop{/tikz/pics/#1} % % Timers @@ -3827,6 +4657,27 @@ } +\def\tikz@timer@arc{% + \pgfmathcos@{\tikz@timer@start@angle}% + \let\tikz@angle@cos\pgfmathresult% + \pgfmathsin@{\tikz@timer@start@angle}% + \let\tikz@angle@sin\pgfmathresult% + \pgftransformarcaxesattime{\tikz@time}{% + \pgfpointdiff{% + \pgfpointadd{% + \pgfpointscale{\tikz@angle@cos}{\tikz@timer@zero@axis}% + }{% + \pgfpointscale{\tikz@angle@sin}{\tikz@timer@ninety@axis}% + }% + }% + {\tikz@timer@start}% + }% + {\tikz@timer@zero@axis}% + {\tikz@timer@ninety@axis}% + {\tikz@timer@start@angle}{\tikz@timer@end@angle}% +} + + % % Coordinate systems @@ -3885,14 +4736,14 @@ \expandafter\ifx\csname pgf@sh@ns@\tikz@cs@node\endcsname\tikz@coordinate@text% \else \aftergroup\tikz@shapebordertrue% - \edef\tikz@shapeborder@name{\tikz@cs@node}% + \edef\tikz@shapeborder@name{\tikz@pp@name{\tikz@cs@node}}% \fi% - \pgfpointanchor{\tikz@cs@node}{center}% + \pgfpointanchor{\tikz@pp@name{\tikz@cs@node}}{center}% \else% - \pgfpointanchor{\tikz@cs@node}{\tikz@cs@angle}% + \pgfpointanchor{\tikz@pp@name{\tikz@cs@node}}{\tikz@cs@angle}% \fi% \else% - \pgfpointanchor{\tikz@cs@node}{\tikz@cs@anchor}% + \pgfpointanchor{\tikz@pp@name{\tikz@cs@node}}{\tikz@cs@anchor}% \fi% } @@ -3905,7 +4756,7 @@ \def\tikz@cs@unpack#1#2#3{% \expandafter\ifx\csname pgf@sh@ns@#3\endcsname\relax% - \PackageError{tikz}{Undefined node ``#3''}{}% + \tikzerror{Undefined node ``#3''}% \else% \def#1{#3}% \edef#2{\csname pgf@sh@ns@#3\endcsname}% @@ -3921,9 +4772,9 @@ {% \tikzset{cs/.cd,#1}% \expandafter\ifx\csname tikz@intersect@\tikz@cs@type@a @and@\tikz@cs@type@b\endcsname\relax% - \PackageError{tikz}{I do not know how to compute the intersection + \tikzerror{I do not know how to compute the intersection of a \tikz@cs@type@a and a \tikz@cs@type@b. Try saying - \string\usetikzlibrary{calc}}{}% + \string\usetikzlibrary{calc}}% \pgfpointorigin% \else% \csname tikz@intersect@\tikz@cs@type@a @and@\tikz@cs@type@b\endcsname% @@ -4047,7 +4898,7 @@ }% } \def\tikz@@scanexpand#1{\expandafter\tikz@scan@one@point\expandafter#1} -\def\tikz@@scangiveup#1{\PackageError{tikz}{Cannot parse this coordinate}{}#1{\pgfpointorigin}} +\def\tikz@@scangiveup#1{\tikzerror{Cannot parse this coordinate}#1{\pgfpointorigin}} \def\tikz@scan@@absolute#1({% \pgfutil@ifnextchar[% uhoh... options! {\def\tikz@scan@point@recall{#1}\tikz@scan@options}% @@ -4073,7 +4924,19 @@ \tikz@marshal% } +\def\tikz@ensure@dollar@catcode{% + \ifnum\catcode`\$=3 % + \else + \tikzerror{Sorry, some package has redefined the meaning of the + math-mode dollar sign. This is incompatible with tikz and its calc + library and might cause unrecoverable errors}% + % only show error once: + \global\let\tikz@ensure@dollar@catcode=\relax + \fi +}% + \def\tikz@@@scan@@absolute#1({% + \tikz@ensure@dollar@catcode \pgfutil@ifnextchar{$}%$ {\tikz@parse@calculator#1(} {\tikz@scan@no@calculator#1(}% @@ -4118,15 +4981,14 @@ } \def\tikz@parse@calculator#1($#2$){% - \PackageError{tikz}{You need to say \string\usetikzlibrary{calc} for - coordinate calculation}{}% + \tikzerror{You need to say \string\usetikzlibrary{calc} for coordinate calculation}% #1{\pgfpointorigin}% } \def\tikz@parse@coordinatesystem#1(#2 cs:#3){% \let\tikz@return@coordinate=\pgfpointorigin% \pgfutil@ifundefined{tikz@parse@cs@#2} - {\PackageError{tikz}{Unknown coordinate system '#2'}{}} + {\tikzerror{Unknown coordinate system '#2'}} {\csname tikz@parse@cs@#2\endcsname(#3)}% \expandafter#1\expandafter{\tikz@return@coordinate}% } @@ -4140,15 +5002,15 @@ \def\tikz@parse@polar#1(#2:#3){% \pgfutil@ifundefined{tikz@polar@dir@#2} - {\tikz@@parse@polar#1(#2:#3)} - {\tikz@@parse@polar#1(\csname tikz@polar@dir@#2\endcsname:#3)}% + {\tikz@@parse@polar#1({#2}:{#3})} + {\tikz@@parse@polar#1(\csname tikz@polar@dir@#2\endcsname:{#3})}% } \def\tikz@@parse@polar#1(#2:#3){% \pgfutil@in@{ and }{#3}% \ifpgfutil@in@% - \edef\tikz@args{(#2:#3)}% + \edef\tikz@args{({#2}:#3)}% \else% - \edef\tikz@args{(#2:#3 and #3)}% + \edef\tikz@args{({#2}:{#3} and {#3})}% \fi% \expandafter\tikz@@@parse@polar\expandafter#1\tikz@args% } @@ -4159,13 +5021,13 @@ \iftikz@isdimension% \def\tikz@next{#1{\pgfpointpolar{#2}{#3 and #4}}}% \else% - \PackageError{tikz}{You cannot mix dimension and dimensionless values for polar coordinates}{} + \tikzerror{You cannot mix dimension and dimensionless values for polar coordinates} \def\tikz@next{#1{\pgfpointorigin}}% \fi% \else% \tikz@checkunit{#4}% \iftikz@isdimension% - \PackageError{tikz}{You cannot mix dimension and dimensionless values for polar coordinates}{} + \tikzerror{You cannot mix dimension and dimensionless values for polar coordinates} \def\tikz@next{#1{\pgfpointorigin}}% \else% \def\tikz@next{#1{\pgfpointpolarxy{#2}{#3 and #4}}}% @@ -4246,7 +5108,7 @@ \expandafter\ifx\csname pgf@sh@ns@#2\endcsname\tikz@coordinate@text% \else \tikz@shapebordertrue% - \def\tikz@shapeborder@name{#2}% + \def\tikz@shapeborder@name{\tikz@pp@name{#2}}% \fi% \fi% \edef\tikz@marshal{\noexpand#1{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}% @@ -4254,7 +5116,7 @@ } \def\tikz@calc@anchor#1.#2\tikz@stop{% - \pgfpointanchor{#1}{#2}% + \pgfpointanchor{\tikz@pp@name{#1}}{#2}% } @@ -4276,10 +5138,10 @@ \fi% \fi% \tikz@next#1(#2)} -\def\tikz@parse@hvboth#1(#2 -| #3){\tikz@parse@vhdone#1(#3|-#2)} -\def\tikz@parse@hvleft#1(#2 -|#3){\tikz@parse@vhdone#1(#3|-#2)} -\def\tikz@parse@hvright#1(#2-| #3){\tikz@parse@vhdone#1(#3|-#2)} -\def\tikz@parse@hvdone#1(#2-|#3){\tikz@parse@vhdone#1(#3|-#2)} +\def\tikz@parse@hvboth#1(#2 -| #3){\tikz@parse@vhdone#1({#3}|-{#2})} +\def\tikz@parse@hvleft#1(#2 -|#3){\tikz@parse@vhdone#1({#3}|-{#2})} +\def\tikz@parse@hvright#1(#2-| #3){\tikz@parse@vhdone#1({#3}|-{#2})} +\def\tikz@parse@hvdone#1(#2-|#3){\tikz@parse@vhdone#1({#3}|-{#2})} \def\tikz@parse@vh#1(#2){% \pgfutil@in@{ |- }{#2}% @@ -4299,9 +5161,9 @@ \fi% \fi% \tikz@next#1(#2)} -\def\tikz@parse@vhboth#1(#2 |- #3){\tikz@parse@vhdone#1(#2|-#3)} -\def\tikz@parse@vhleft#1(#2 |-#3){\tikz@parse@vhdone#1(#2|-#3)} -\def\tikz@parse@vhright#1(#2|- #3){\tikz@parse@vhdone#1(#2|-#3)} +\def\tikz@parse@vhboth#1(#2 |- #3){\tikz@parse@vhdone#1({#2}|-{#3})} +\def\tikz@parse@vhleft#1(#2 |-#3){\tikz@parse@vhdone#1({#2}|-{#3})} +\def\tikz@parse@vhright#1(#2|- #3){\tikz@parse@vhdone#1({#2}|-{#3})} \def\tikz@parse@vhdone#1(#2|-#3){% {% \tikz@@@scan@@absolute\tikz@parse@vh@mid(#2)% @@ -4363,6 +5225,17 @@ } + +% +% Quote handling +% + +\let\tikz@enable@node@quotes\relax +\let\tikz@enable@edge@quotes\relax +\let\tikz@enable@pic@quotes\relax + + + % Loading further libraries % Include a library file. @@ -4377,6 +5250,10 @@ % % For the convenience of Context users, both round and square brackets % are possible for the argument. +% +% If no file tikzlibraryX.code.tex exists, the file +% pgflibraryX.code.tex is tried instead. If this file, also, does not +% exist, an error message is printed. % % Example: % @@ -4388,20 +5265,32 @@ \def\use@@tikzlibrary#1{% \edef\pgf@list{#1}% \pgfutil@for\pgf@temp:=\pgf@list\do{% - \expandafter\pgfkeys@spdef\expandafter\pgf@temp\expandafter{\pgf@temp}% - \ifx\pgf@temp\pgfutil@empty - \else - \expandafter\ifx\csname tikz@library@\pgf@temp @loaded\endcsname\relax% - \expandafter\global\expandafter\let\csname tikz@library@\pgf@temp @loaded\endcsname=\pgfutil@empty% - \expandafter\edef\csname tikz@library@#1@atcode\endcsname{\the\catcode`\@} - \expandafter\edef\csname tikz@library@#1@barcode\endcsname{\the\catcode`\|} - \catcode`\@=11 - \catcode`\|=12 - \input tikzlibrary\pgf@temp.code.tex - \catcode`\@=\csname tikz@library@#1@atcode\endcsname - \catcode`\|=\csname tikz@library@#1@barcode\endcsname - \fi% - \fi + \expandafter\pgfkeys@spdef\expandafter\pgf@temp\expandafter{\pgf@temp}% + \ifx\pgf@temp\pgfutil@empty + \else + \expandafter\ifx\csname tikz@library@\pgf@temp @loaded\endcsname\relax% + \expandafter\global\expandafter\let\csname tikz@library@\pgf@temp @loaded\endcsname=\pgfutil@empty% + \expandafter\edef\csname tikz@library@#1@atcode\endcsname{\the\catcode`\@} + \expandafter\edef\csname tikz@library@#1@barcode\endcsname{\the\catcode`\|} + \expandafter\edef\csname tikz@library@#1@dollarcode\endcsname{\the\catcode`\$} + \catcode`\@=11 + \catcode`\|=12 + \catcode`\$=3 + \pgfutil@InputIfFileExists{tikzlibrary\pgf@temp.code.tex}{}{ + \pgfutil@IfFileExists{pgflibrary\pgf@temp.code.tex}{% + \expandafter\usepgflibrary\expandafter{\pgf@temp}% + }{% + \tikzerror{I did not find the tikz library + '\pgf@temp'. I looked for files named + tikzlibrary\pgf@temp.code.tex and + pgflibrary\pgf@temp.code.tex, but neither + could be found in the current texmf trees.} + }}% + \catcode`\@=\csname tikz@library@#1@atcode\endcsname + \catcode`\|=\csname tikz@library@#1@barcode\endcsname + \catcode`\$=\csname tikz@library@#1@dollarcode\endcsname + \fi% + \fi }% } diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/LUA_CODING_STYLE b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/LUA_CODING_STYLE new file mode 100644 index 00000000000..295a8b2ed11 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/LUA_CODING_STYLE @@ -0,0 +1,27 @@ +Lua coding style for the graphdrawing library +============================================= + +General naming rules and indentation: + + * 2 spaces indentation + * variable_names_with_underscores + * namespaced.low_level_functions_with_underscores(foo, bar) + * CamelCaseClassNames + * CamelCaseClassNames.nameOfStaticFunctionLikeNewOrClone(foo, bar) + * CamelCaseClass:functionNamesLikeThis(foo, bar) + * never use global variables + * Use . for static functions and : for member functions + +LuaDoc comments: + + --- + -- A function to do this and that. + -- + -- @param first Description of the first parameter. + -- @param second Description of the second parameter. + -- + -- @return This function returns something. + -- + function myClass:myFunction(first, second) + ... + end diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf.lua new file mode 100644 index 00000000000..0ffbaf53c13 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf.lua @@ -0,0 +1,72 @@ +-- 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.lua,v 1.3 2013/04/04 20:43:44 tantau Exp $ + + +--- +-- The |pgf| namespace lies in the global namespace. It is the only +-- global table defined by \pgfname. The whole graph drawing system, +-- in turn, lies in the table |pgf.gd|. + +pgf = {} + + + +-- Forward +local tostring_table + +--- +-- Writes debug info on the \TeX\ output, separating the parameters +-- by spaces. The debug information will include a complete traceback +-- of the stack, allowing you to see ``where you are'' inside the Lua +-- program. +-- +-- Note that this function resides directly in the |pgf| table. The +-- reason for this is that you can ``always use it'' since |pgf| is +-- always available in the global name space. +-- +-- @param ... List of parameters to write to the \TeX\ output. + +function pgf.debug(...) + local stacktrace = debug.traceback("",2) + texio.write_nl(" ") + texio.write_nl("Debug called for: ") + -- this is to even print out nil arguments in between + local args = {...} + for i = 1, #args do + if i ~= 1 then texio.write(", ") end + texio.write(tostring_table(args[i], "", 5)) + end + texio.write_nl('') + for w in string.gmatch(stacktrace, "/.-:.-:.-%c") do + texio.write('by ', string.match(w,".*/(.*)")) + end +end + + +-- Helper function + +function tostring_table(t, prefix, depth) + if type(t) ~= "table" or (getmetatable(t) and getmetatable(t).__tostring) or depth <= 0 then + return type(t) == "string" and ('"' .. t .. '"') or tostring(t) + else + local r = "{\n" + for k,v in pairs(t) do + r = r .. prefix .. " " .. tostring(k) .. "=" .. + (v==t and "self" or tostring_table(v, prefix .. " ", depth-1)) .. ",\n" + end + return r .. prefix .. "}" + end +end + + + + +return pgf
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd.lua new file mode 100644 index 00000000000..b813ccab603 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd.lua @@ -0,0 +1,72 @@ +-- 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.lua,v 1.1 2012/11/27 17:24:23 tantau Exp $ + + + + +-- Declare the gd namespace + +local gd = {} +require("pgf").gd = gd + + + + + + + +-- Deprecated: +-- +-- +-- Helping function for creating new algorithm classes +-- +-- This function creates a new algorithm class. This class will have a +-- new method, that takes a graph and, optionally, a parent algorithm +-- as inputs. They will be stored in the "graph" and "parent_algorithm" +-- fields, respectively. +-- +-- @param info This table is used to configure the new class. It has +-- the following fields: First, there is the "properties" table. If +-- this table is present, it will be used as the default table. Second, +-- it can have a graph_parameters table. This table will be used in the +-- constructor to preload graph parameters from the pgf layer. For +-- this, each entry of the table should be of the form +-- +-- key = 'string' +-- +-- What happens is that upon the creation of a new algorithm object, +-- for each key we lookup the graph option 'string' and +-- store its value in the key of the new algorithm object. +-- +-- @return A table that is a class with a new function setup. + +function gd.new_algorithm_class (class) + class.__index = class + class.new = + function (initial) + + -- Create new object + local obj = {} + for k,v in pairs(initial) do + obj[k] = v + end + setmetatable(obj, class) + + return obj + end + class.preconditions = {} + class.postconditions = {} + + return class +end + + +return gd
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings.lua new file mode 100644 index 00000000000..8f72092e4e9 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings.lua @@ -0,0 +1,26 @@ +-- 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/bindings.lua,v 1.1 2012/11/27 17:24:23 tantau Exp $ + + + +-- Imports + +require "pgf" +require "pgf.gd" + + +-- Declare namespace +pgf.gd.bindings = {} + + +-- Done + +return pgf.gd.bindings
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/Binding.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/Binding.lua new file mode 100644 index 00000000000..f062c7a54c5 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/Binding.lua @@ -0,0 +1,264 @@ +-- 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/bindings/Binding.lua,v 1.6 2013/04/04 20:43:45 tantau Exp $ + + +-- Imports +local Storage = require "pgf.gd.lib.Storage" + + +--- +-- This class provides a (non-functional) default implementation of a +-- binding between a display layer and the algorithm layer. Subclasses +-- must implement most of the member functions declared in this class. +-- +-- A instance of a subclass of this class encapsulates the complete +-- implementation of all specific code needed for the communication +-- between the display layer and the graph drawing engine. +-- +-- Note that you never call the methods of a |Binding| object +-- directly, neither from the display layer nor from the algorithm +-- layer. Instead, you use the more powerful and more easy to use +-- functions from |InterfaceToDisplay| and +-- |InterfaceToAlgorithms|. They call the appropriate |Binding| +-- methods internally. +-- +-- Because of the above, in order to use the graph drawing system +-- inside a new display layer, you need to subclass |Binding| and +-- implement all the functions. Then you need to write the display +-- layer in such a way that it calls the appropriate functions from +-- |InterfaceToDisplay|. +-- +-- @field storage A |Storage| storing the information passed from the +-- display layer. The interpretation of this left to the actual +-- binding. + +local Binding = { + storage = Storage.newTableStorage () +} +Binding.__index = Binding + +-- Namespace +require("pgf.gd.bindings").Binding = Binding + + + + + +-- +-- This method gets called whenever the graph drawing coroutine should +-- be resumed. First, the binding layer should ask the display layer +-- to execute the |code|, then, after this is done, the function +-- |InterfaceToDisplay.resumeGraphDrawingCoroutine| should be called +-- by this function. +-- +-- @param code Some code to be executed by the display layer. + +function Binding:resumeGraphDrawingCoroutine(code) + -- Does nothing by default +end + + +--- +-- Declare a new key. This callback is called by |declare|. It is the job +-- of the display layer to make the parameter |t.key| available to the +-- parsing process. Furthermore, if |t.initial| is not |nil|, the +-- display layer must convert it into a value that is stored as the +-- initial value and call |InterfaceToDisplay.setOptionInitial|. +-- +-- @param t See |InterfaceToAlgorithms.declare| for details. + +function Binding:declareCallback(t) + -- Does nothing by default +end + + + + +-- Rendering + +--- +-- This function and, later on, |renderStop| are called whenever the +-- rendering of a laid-out graph starts or stops. See +-- |InterfaceToDisplay.render| for details. + +function Binding:renderStart() + -- Does nothing by default +end + +--- +-- See |renderStart|. + +function Binding:renderStop() + -- Does nothing by default +end + + + + + +--- +-- This function and the correspoding |...Stop...| functions are +-- called whenever a collection kind should be rendered. See +-- |InterfaceToDisplay.render_collections| for details. +-- +-- @param kind The kind (a string). +-- @param layer The kind's layer (a number). + +function Binding:renderCollectionStartKind(kind, layer) + -- Does nothing by default +end + + +--- +-- The counterpart to |renderCollectionStartKind|. +-- +-- @param kind The kind. +-- @param layer The kind's layer. + +function Binding:renderCollectionStopKind(kind, layer) + -- Does nothing by default +end + + +--- +-- Renders a single collection, see |renderCollectionStartKind| for +-- details. +-- +-- @param collection The collection object. + +function Binding:renderCollection(collection) + -- Does nothing by default +end + + + +--- +-- This function and the correspoding |...Stop...| functions are +-- called whenever a vertex should be rendered. See +-- |InterfaceToDisplay.render_vertices| for details. +-- + +function Binding:renderVerticesStart() + -- Does nothing by default +end + + +--- +-- The counterpart to |renderVerticesStop|. +-- + +function Binding:renderVerticesStop() + -- Does nothing by default +end + + +--- +-- Renders a single vertex, see |renderVertexStartKind| for +-- details. +-- +-- @param vertex The |Vertex| object. + +function Binding:renderVertex(vertex) + -- Does nothing by default +end + + + +--- +-- This method is called by the interface to the display layer after +-- the display layer has called |createVertex| to create a new +-- vertex. After having done its internal bookkeeping, the interface +-- calls this function to allow the binding to perform further +-- bookkeeping on the node. Typically, this will be done using the +-- information stored in |Binding.infos|. +-- +-- @param v The vertex. + +function Binding:everyVertexCreation(v) + -- Does nothing by default +end + + + + + +--- +-- This function and the correspoding |...Stop...| functions are +-- called whenever an edge should be rendered. See +-- |InterfaceToDisplay.render_edges| for details. +-- + +function Binding:renderEdgesStart() + -- Does nothing by default +end + + +--- +-- The counterpart to |renderEdgesStop|. +-- + +function Binding:renderEdgesStop() + -- Does nothing by default +end + + +--- +-- Renders a single vertex, see |renderEdgeStartKind| for +-- details. +-- +-- @param edge The |Edge| object. + +function Binding:renderEdge(edge) + -- Does nothing by default +end + + +--- +-- Like |everyVertexCreation|, only for edges. +-- +-- @param e The edge. + +function Binding:everyEdgeCreation(e) + -- Does nothing by default +end + + +--- +-- Generate a new vertex. This method will be called when the +-- \emph{algorithm} layer wishes to trigger the creation of a new +-- vertex. This call will be made while an algorithm is running. It is +-- now the job of the binding to cause the display layer to create the +-- node. This is done by calling the |yield| method of the scope's +-- coroutine. +-- +-- @param init A table of initial values for the node. The following +-- fields will be used: +-- \begin{itemize} +-- \item |name| If present, this name will be given to the +-- node. If not present, an iternal name is generated. Note that, +-- unless the node is a subgraph node, this name may not be the name +-- of an already present node of the graph; in this case an error +-- results. +-- \item |shape| If present, a shape of the node. +-- \item |generated_options| A table that is passed back to the +-- display layer as a list of key-value pairs. +-- \item |text| The text of the node, to be passed back to the +-- higher layer. This is what should be displayed as the node's text. +-- \end{itemize} + +function Binding:createVertex(init) + -- Does nothing by default +end + + + + +return Binding
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua new file mode 100644 index 00000000000..5a1337a1327 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua @@ -0,0 +1,280 @@ +-- 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/bindings/BindingToPGF.lua,v 1.10 2013/12/20 14:44:46 tantau Exp $ + + + +-- Imports +local Storage = require "pgf.gd.lib.Storage" + + +--- +-- This class, which is a subclass of |Binding|, binds the graph +-- drawing system to the \pgfname\ display system by overriding (that +-- is, implementing) the methods of the |Binding| class. As a typical +-- example, consider the implementation of the function |renderVertex|: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--function BindingToPGF:renderVertex(v) +-- local info = assert(self.infos[v], "thou shalt not modify the syntactic digraph") +-- tex.print( +-- string.format( +-- "\\pgfgdcallbackrendernode{%s}{%fpt}{%fpt}{%fpt}{%fpt}{%fpt}{%fpt}{%s}", +-- 'not yet positionedPGFINTERNAL' .. v.name, +-- info.x_min, +-- info.x_max, +-- info.y_min, +-- info.y_max, +-- v.pos.x, +-- v.pos.y, +-- info.box_count)) +--end +--\end{codeexample} +-- +-- As can be seen, the main job of this function is to call a function +-- on the \TeX\ layer that is called |\pgfgdcallbackrendernode|, which gets +-- several parameters like the name of the to-be-rendered node or the +-- (new) position for the node. For almost all methods of the +-- |Binding| class there is a corresponding ``callback'' macro on the +-- \TeX\ layer, all of which are implemented in the \pgfname\ library +-- |graphdrawing|. For details on these callbacks, +-- please consult the code of that file and of the class +-- |BindingToPGF| (they are not documented here since they are local +-- to the binding and should not be called by anyone other than the +-- binding class). + +local BindingToPGF = { + storage = Storage.newTableStorage () -- overwrite default storage +} +BindingToPGF.__index = BindingToPGF +setmetatable(BindingToPGF, require "pgf.gd.bindings.Binding") -- subclass of Binding + + +-- Namespace +require("pgf.gd.bindings").BindingToPGF = BindingToPGF + +-- Imports +local lib = require "pgf.gd.lib" + +-- The implementation + +-- Forward +local table_in_pgf_syntax + + + + +-- Scope handling + +function BindingToPGF:resumeGraphDrawingCoroutine(text) + tex.print(text) + tex.print("\\directlua{pgf.gd.interface.InterfaceToDisplay.resumeGraphDrawingCoroutine()}") +end + + +-- Declarations + +function BindingToPGF:declareCallback(t) + tex.print("\\pgfgdcallbackdeclareparameter{" .. t.key .. "}{" .. (t.type or "nil") .. "}") +end + + + +-- Rendering + +function BindingToPGF:renderStart() + tex.print("\\pgfgdcallbackbeginshipout") +end + +function BindingToPGF:renderStop() + tex.print("\\pgfgdcallbackendshipout") +end + + +-- Rendering collections + +function BindingToPGF:renderCollection(collection) + tex.print("\\pgfgdcallbackrendercollection{".. collection.kind .. "}{" + .. table_in_pgf_syntax(collection.generated_options) .. "}") +end + +function BindingToPGF:renderCollectionStartKind(kind, layer) + tex.print("\\pgfgdcallbackrendercollectionkindstart{" .. kind .. "}{" .. tostring(layer) .. "}") +end + +function BindingToPGF:renderCollectionStopKind(kind, layer) + tex.print("\\pgfgdcallbackrendercollectionkindstop{" .. kind .. "}{" .. tostring(layer) .. "}") +end + +-- Printing points + +local function to_pt(x) + return string.format("%.12fpt", x) +end + + +-- Managing vertices (pgf nodes) + +local boxes = {} +local box_count = 0 + +function BindingToPGF:everyVertexCreation(v) + local info = self.storage[v] + + -- Save the box! + box_count = box_count + 1 + boxes[box_count] = node.copy_list(tex.box[info.tex_box_number]) + + -- Special tex stuff, should not be considered by gd algorithm + info.box_count = box_count +end + +function BindingToPGF:renderVertex(v) + local info = assert(self.storage[v], "thou shalt not modify the syntactic digraph") + tex.print( + string.format( + "\\pgfgdcallbackrendernode{%s}{%.12fpt}{%.12fpt}{%.12fpt}{%.12fpt}{%.12fpt}{%.12fpt}{%s}", + 'not yet positionedPGFINTERNAL' .. v.name, + info.x_min, + info.x_max, + info.y_min, + info.y_max, + v.pos.x, + v.pos.y, + info.box_count)) +end + +function BindingToPGF:retrieveBox(index, box_num) + tex.box[box_num] = assert(boxes[index], "no box stored at given index") + boxes[index] = nil -- remove from memory +end + +function BindingToPGF:renderVerticesStart() + tex.print("\\pgfgdcallbackbeginnodeshipout") +end + +function BindingToPGF:renderVerticesStop() + tex.print("\\pgfgdcallbackendnodeshipout") +end + + +local function rigid(x) + if type(x) == "function" then + return x() + else + return x + end +end + + +-- Managing edges + +function BindingToPGF:renderEdge(e) + local info = assert(self.storage[e], "thou shalt not modify the syntactic digraph") + + local function get_anchor(e, anchor) + local a = e.options[anchor] + if a and a ~= "" then + return "." .. a + else + return "" + end + end + + local callback = { + '\\pgfgdcallbackedge', + '{', e.tail.name .. get_anchor(e, "tail anchor"), '}', + '{', e.head.name .. get_anchor(e, "head anchor"), '}', + '{', e.direction, '}', + '{', info.pgf_options or "", '}', + '{', info.pgf_edge_nodes or "", '}', + '{', table_in_pgf_syntax(e.generated_options), '}', + '{' + } + + local i = 1 + while i <= #e.path do + local c = e.path[i] + assert (type(c) == "string", "illegal path operand") + + if c == "lineto" then + i = i + 1 + local d = rigid(e.path[i]) + callback [#callback + 1] = '--(' .. to_pt(d.x) .. ',' .. to_pt(d.y) .. ')' + i = i + 1 + elseif c == "moveto" then + i = i + 1 + local d = rigid(e.path[i]) + callback [#callback + 1] = '(' .. to_pt(d.x) .. ',' .. to_pt(d.y) .. ')' + i = i + 1 + elseif c == "closepath" then + callback [#callback + 1] = '--cycle' + i = i + 1 + elseif c == "curveto" then + local d1, d2, d3 = rigid(e.path[i+1]), rigid(e.path[i+2]), rigid(e.path[i+3]) + i = i + 3 + callback [#callback + 1] = '..controls(' .. to_pt(d1.x) .. ',' .. to_pt(d1.y) .. ')and(' + .. to_pt(d2.x) .. ',' .. to_pt(d2.y) .. ')..' + callback [#callback + 1] = '(' .. to_pt(d3.x) .. ',' .. to_pt(d3.y) .. ')' + i = i + 1 + else + error("illegal operation in edge path") + end + end + + callback [#callback + 1] = '}' + + -- hand TikZ code over to TeX + tex.print(table.concat(callback)) +end + + +function BindingToPGF:renderEdgesStart() + tex.print("\\pgfgdcallbackbeginedgeshipout") +end + +function BindingToPGF:renderEdgesStop() + tex.print("\\pgfgdcallbackendedgeshipout") +end + + +-- Vertex creation + +function BindingToPGF:createVertex(init) + -- Now, go back to TeX... + coroutine.yield( + table.concat({ + "\\pgfgdcallbackcreatevertex{", init.name, "}", + "{", init.shape, "}", + "{", table_in_pgf_syntax(init.generated_options), ",", init.pgf_options or "", "}", + "{", (init.text or ""), "}" + })) + -- ... and come back with a new node! +end + + + +-- Local helpers + +function table_in_pgf_syntax (t) + local prefix = "/graph drawing/" + local suffix = "/.try" + return table.concat( lib.imap( t, function(table) + if table.value then + return prefix .. table.key .. suffix .. "={" .. tostring(table.value) .. "}" + else + return prefix .. table.key .. suffix + end + end), ",") +end + + + +return BindingToPGF
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular.lua new file mode 100644 index 00000000000..0249c9130af --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular.lua @@ -0,0 +1,22 @@ +-- 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/circular.lua,v 1.1 2012/11/27 17:24:23 tantau Exp $ + + + +local circular = {} + +-- Declare namespace +require("pgf.gd").circular = circular + + +-- Done + +return circular
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular/Tantau2012.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular/Tantau2012.lua new file mode 100644 index 00000000000..774bdc907be --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular/Tantau2012.lua @@ -0,0 +1,144 @@ +-- 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/circular/Tantau2012.lua,v 1.7 2013/05/23 20:01:25 tantau Exp $ + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + +-- The algorithm class +local Tantau2012 = {} + +--- +declare { + key = "simple necklace layout", + algorithm = Tantau2012, + + postconditions = { + upward_oriented = true + }, + + documentation_in = "pgf.gd.doc.circular.Tantau2012" +} + + + +-- Imports + +local Coordinate = require "pgf.gd.model.Coordinate" + +local lib = require "pgf.gd.lib" + + +-- The implementation + +function Tantau2012:run() + local g = self.digraph + local vertices = g.vertices + local n = #vertices + + local sib_dists = self:computeNodeDistances () + local radii = self:computeNodeRadii() + local diam, adjusted_radii = self:adjustNodeRadii(sib_dists, radii) + + -- Compute total necessary length. For this, iterate over all + -- consecutive pairs and keep track of the necessary space for + -- this node. We imagine the nodes to be aligned from left to + -- right in a line. + local carry = 0 + local positions = {} + local function wrap(i) return (i-1)%n + 1 end + local ideal_pos = 0 + for i = 1,n do + positions[i] = ideal_pos + carry + ideal_pos = ideal_pos + sib_dists[i] + local node_sep = + lib.lookup_option('node post sep', vertices[i], g) + + lib.lookup_option('node pre sep', vertices[wrap(i+1)], g) + local arc = node_sep + adjusted_radii[i] + adjusted_radii[wrap(i+1)] + local needed = carry + arc + local dist = math.sin( arc/diam ) * diam + needed = needed + math.max ((radii[i] + radii[wrap(i+1)]+node_sep)-dist, 0) + carry = math.max(needed-sib_dists[i],0) + end + local length = ideal_pos + carry + + local radius = length / (2 * math.pi) + for i,vertex in ipairs(vertices) do + vertex.pos.x = radius * math.cos(2 * math.pi * (positions[i] / length + 1/4)) + vertex.pos.y = -radius * math.sin(2 * math.pi * (positions[i] / length + 1/4)) + end +end + + +function Tantau2012:computeNodeDistances() + local sib_dists = {} + local sum_length = 0 + local vertices = self.digraph.vertices + for i=1,#vertices do + sib_dists[i] = lib.lookup_option('node distance', vertices[i], self.digraph) + sum_length = sum_length + sib_dists[i] + end + + local missing_length = self.digraph.options['radius'] * 2 * math.pi - sum_length + if missing_length > 0 then + -- Ok, the sib_dists to not add up to the desired minimum value. + -- What should we do? Hmm... We increase all by the missing amount: + for i=1,#vertices do + sib_dists[i] = sib_dists[i] + missing_length/#vertices + end + end + + sib_dists.total = math.max(self.digraph.options['radius'] * 2 * math.pi, sum_length) + + return sib_dists +end + + +function Tantau2012:computeNodeRadii() + local radii = {} + for i,v in ipairs(self.digraph.vertices) do + local min_x, min_y, max_x, max_y = v:boundingBox() + local w, h = max_x-min_x, max_y-min_y + if v.shape == "circle" or v.shape == "ellipse" then + radii[i] = math.max(w,h)/2 + else + radii[i] = math.sqrt(w*w + h*h)/2 + end + end + return radii +end + + +function Tantau2012:adjustNodeRadii(sib_dists,radii) + local total = 0 + local max_rad = 0 + for i=1,#radii do + total = total + 2*radii[i] + + lib.lookup_option('node post sep', self.digraph.vertices[i], self.digraph) + + lib.lookup_option('node pre sep', self.digraph.vertices[i], self.digraph) + max_rad = math.max(max_rad, radii[i]) + end + total = math.max(total, sib_dists.total, max_rad*math.pi) + local diam = total/(math.pi) + + -- Now, adjust the radii: + local adjusted_radii = {} + for i=1,#radii do + adjusted_radii[i] = (math.pi - 2*math.acos(radii[i]/diam))*diam/2 + end + + return diam, adjusted_radii +end + + +-- done + +return Tantau2012
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular/library.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular/library.lua new file mode 100644 index 00000000000..ac229a8e0d0 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular/library.lua @@ -0,0 +1,30 @@ +-- 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/circular/library.lua,v 1.2 2013/04/04 20:43:45 tantau Exp $ + + +-- Imports +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + +--- +-- ``Circular'' graph drawing algorithms arrange the nodes of a graph +-- on one of more circles. +-- +-- @library + +local circular -- Library name + +-- Load declarations from: + +-- Load algorithms from: +require "pgf.gd.circular.Tantau2012" + + +-- General declarations diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control.lua new file mode 100644 index 00000000000..3492510d242 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control.lua @@ -0,0 +1,26 @@ +-- 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/control.lua,v 1.1 2012/11/27 17:24:23 tantau Exp $ + + + +-- Imports + +require "pgf" +require "pgf.gd" + + +-- Declare namespace +pgf.gd.control = {} + + +-- Done + +return pgf.gd.control
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Anchoring.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Anchoring.lua new file mode 100644 index 00000000000..e4364d695cd --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Anchoring.lua @@ -0,0 +1,104 @@ +-- 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/control/Anchoring.lua,v 1.6 2013/05/23 20:01:25 tantau Exp $ + + + +--- +-- @section subsection {Anchoring a Graph} +-- +-- \label{subsection-library-graphdrawing-anchoring} +-- +-- A graph drawing algorithm must compute positions of the nodes of a +-- graph, but the computed positions are only \emph{relative} (``this +-- node is left of this node, but above that other node''). It is not +-- immediately obvious where the ``the whole graph'' should be placed +-- \emph{absolutely} once all relative positions have been computed. In +-- case that the graph consists of several unconnected components, the +-- situation is even more complicated. +-- +-- The order in which the algorithm layer determines the node at which +-- the graph should be anchored: +-- +-- \begin{enumerate} +-- \item If the |anchor node=|\meta{node name} option given to the graph +-- as a whole, the graph is anchored at \meta{node name}, provided +-- there is a node of this name in the graph. (If there is no node of +-- this name or if it is misspelled, the effect is the same as if this +-- option had not been given at all.) +-- \item Otherwise, if there is a node where the |anchor here| option is +-- specified, the first node with this option set is used. +-- \item Otherwise, if there is a node where the |desired at| option is +-- set (perhaps implicitly through keys like |x|), the first such node +-- is used. +-- \item Finally, in all other cases, the first node is used. +-- \end{enumerate} +-- +-- In the above description, the ``first'' node refers to the node first +-- encountered in the specification of the graph. +-- +-- Once the node has been determined, the graph is shifted so that +-- this node lies at the poistion specified by |anchor at|. +-- +-- @end + + + +local Anchoring = {} + + +-- Namespace +require("pgf.gd.control").Anchoring = Anchoring + + +-- Imports +local Coordinate = require("pgf.gd.model.Coordinate") +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + + + +--- +declare { + key = "desired at", + type = "coordinate", + documentation_in = "pgf.gd.doc.control.Anchoring" +} + +--- +declare { + key = "anchor node", + type = "string", + documentation_in = "pgf.gd.doc.control.Anchoring" +} + + +--- +declare { + key = "anchor at", + type = "canvas coordinate", + initial = "(0pt,0pt)", + documentation_in = "pgf.gd.doc.control.Anchoring" +} + + +--- +declare { + key = "anchor here", + type = "boolean", + documentation_in = "pgf.gd.doc.control.Anchoring" +} + + + + + +-- Done + +return Anchoring
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentAlign.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentAlign.lua new file mode 100644 index 00000000000..f5475227245 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentAlign.lua @@ -0,0 +1,521 @@ +-- 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/control/ComponentAlign.lua,v 1.4 2013/05/23 20:01:25 tantau Exp $ + + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + + +--- +-- @section subsubsection {Aligning Components} +-- +-- When components are placed next to each from left to right, it +-- is not immediately clear how the components should be aligned +-- vertically. What happens is that in each component a horizontal line is +-- determined and then all components are shifted vertically so that the +-- lines are aligned. There are different strategies for choosing these +-- ``lines'', see the description of the options described later on. +-- When the |component direction| option is used to change the direction +-- in which components are placed, it certainly make no longer sense to +-- talk about ``horizontal'' and ``vertical'' lines. Instead, what +-- actually happens is that the alignment does not consider +-- ``horizontal'' lines, but lines that go in the direction specified by +-- |component direction| and aligns them by moving components along a +-- line that is perpendicular to the line. For these reasons, let us call +-- the line in the component direction the \emph{alignment line} and a +-- line that is perpendicular to it the \emph{shift line}. +-- +-- The first way of specifying through which point of a component the +-- alignment line should get is to use the option |align here|. +-- In many cases, however, you will not wish to specify an alignment node +-- manually in each component. Instead, you will use the +-- |component align| key to specify a \emph{strategy} that should be used to +-- automatically determine such a node. +-- +-- Using a combination of |component direction| and |component align|, +-- numerous different packing strategies can be configured. However, +-- since names like |counterclockwise| are a bit hard to remember and to +-- apply in practice, a number of easier-to-remember keys are predefined +-- that combine an alignment and a direction. +-- +-- @end + + +--- + +declare { + key = "align here", + type = "boolean", + + summary = [[" + When this option is given to a node, this alignment line will go + through the origin of this node. If this option is passed to more + than one node of a component, the node encountered first in the + component is used. + "]], + examples = [[" + \tikz \graph [binary tree layout, nodes={draw}] + { a, b -- c[align here], d -- e[second, align here] -- f }; + "]] +} + +--- + +declare { + key = "component align", + type = "string", + initial = "first node", + + summary = [[" + Specifies a ``strategy'' for the alignment of components. + "]], + documentation = [[" + The following values are permissible: + \begin{itemize} + \item \declare{|first node|} + In each component, the alignment line goes through the center of + the first node of the component encountered during specification + of the component. +\begin{codeexample}[] +\tikz \graph [binary tree layout, nodes={draw}, + component align=first node] + { a, b -- c, d -- e[second] -- f }; +\end{codeexample} + \item \declare{|center|} + + The nodes of the component are projected onto the shift line. The + alignment line is now chosen so that it is exactly in the middle + between the maximum and minimum value that the projected nodes + have on the shift line. +\begin{codeexample}[] +\tikz \graph [binary tree layout, nodes={draw}, + component align=center] + { a, b -- c, d -- e[second] -- f }; +\end{codeexample} +\begin{codeexample}[] +\tikz \graph [binary tree layout, nodes={draw}, + component direction=90, + component align=center] + { a, b -- c, d -- e[second] -- f }; +\end{codeexample} + \item \declare{|counterclockwise|} + + As for |center|, we project the nodes of the component onto the + shift line. The alignment line is now chosen so that it goes + through the center of the node whose center has the highest + projected value. +\begin{codeexample}[] +\tikz \graph [binary tree layout, nodes={draw}, + component align=counterclockwise] + { a, b -- c, d -- e[second] -- f }; +\end{codeexample} +\begin{codeexample}[] +\tikz \graph [binary tree layout, nodes={draw}, + component direction=90, + component align=counterclockwise] + { a, b -- c, d -- e[second] -- f }; +\end{codeexample} + The name |counterclockwise| is intended to indicate that the align + line goes through the node that comes last if we go from the + alignment direction in a counter-clockwise direction. + \item \declare{|clockwise|} + + Works like |counterclockwise|, only in the other direction: +\begin{codeexample}[] +\tikz \graph [binary tree layout, nodes={draw}, + component align=clockwise] + { a, b -- c, d -- e[second] -- f }; +\end{codeexample} +\begin{codeexample}[] +\tikz \graph [binary tree layout, nodes={draw}, + component direction=90, + component align=clockwise] + { a, b -- c, d -- e[second] -- f }; +\end{codeexample} + \item \declare{|counterclockwise bounding box|} + + This method is quite similar to |counterclockwise|, only the + alignment line does not go through the center of the node with a + maximum projected value on the shift line, but through the maximum + value of the projected bounding boxes. For a left-to-right + packing, this means that the components are aligned so that the + bounding boxes of the components are aligned at the top. +\begin{codeexample}[] +\tikz \graph [tree layout, nodes={draw, align=center}, + component sep=0pt, + component align=counterclockwise] + { a, "high\\node" -- b};\quad +\tikz \graph [tree layout, nodes={draw, align=center}, + component sep=0pt, + component align=counterclockwise bounding box] + { a, "high\\node" -- b}; +\end{codeexample} + \item \declare{|clockwise bounding box|} + + Works like |counterclockwise bounding box|. + \end{itemize} + "]] +} + +--- + +declare { + key = "components go right top aligned", + use = { + { key = "component direction", value = 0}, + { key = "component align", value = "counterclockwise"}, + }, + + summary = [[" + Shorthand for |component direction=right| and + |component align=counterclockwise|. This means that, as the name + suggest, the components will be placed left-to-right and they are + aligned such that their top nodes are in a line. + "]], + examples = [[" + \tikz \graph [tree layout, nodes={draw, align=center}, + components go right top aligned] + { a, "high\\node" -- b}; + "]] +} + +--- + +declare { + key = "components go right absolute top aligned", + use = { + { key = "component direction", value=0}, + { key = "component align", value = "counterclockwise bounding box"}, + }, + + summary = [[" + Like |components go right top aligned|, but with + |component align| set to |counterclockwise| |bounding box|. This means that the + components will be aligned with their bounding boxed being + top-aligned. + "]], + examples = [[" + \tikz \graph [tree layout, nodes={draw, align=center}, + components go right absolute top aligned] + { a, "high\\node" -- b}; + "]] +} + +--- + +declare { + key = "components go right bottom aligned", + use = { + { key = "component direction", value=0}, + { key = "component align", value = "clockwise"}, + }, + + summary = "See the other |components go ...| keys." +} + +--- +-- + +declare { + key = "components go right absolute bottom aligned", + use = { + { key = "component direction", value=0}, + { key = "component align", value = "clockwise bounding box"}, + }, + + summary = "See the other |components go ...| keys." +} + + +--- + +declare { + key = "components go right center aligned", + use = { + { key = "component direction", value=0}, + { key = "component align", value = "center"}, + }, + + summary = "See the other |components go ...| keys." +} + + +--- + +declare { + key = "components go right", + use = { + { key = "component direction", value=0}, + { key = "component align", value = "first node"}, + }, + + summary = [[" + Shorthand for |component direction=right| and + |component align=first node|. + "]] + } + + +--- + +declare { + key = "components go left top aligned", + use = { + { key = "component direction", value=180}, + { key = "component align", value = "clockwise"}, + }, + + summary = "See the other |components go ...| keys.", + + examples = [[" + \tikz \graph [tree layout, nodes={draw, align=center}, + components go left top aligned] + { a, "high\\node" -- b}; + "]] +} + +--- +-- + +declare { + key = "components go left absolute top aligned", + use = { + { key = "component direction", value=180}, + { key = "component align", value = "clockwise bounding box"}, + }, + + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go left bottom aligned", + use = { + { key = "component direction", value=180}, + { key = "component align", value = "counterclockwise"}, + }, + + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go left absolute bottom aligned", + use = { + { key = "component direction", value=180}, + { key = "component align", value = "counterclockwise bounding box"}, + }, + + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go left center aligned", + use = { + { key = "component direction", value=180}, + { key = "component align", value = "center"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go left", + use = { + { key = "component direction", value=180}, + { key = "component align", value = "first node"}, + }, + summary = "See the other |components go ...| keys." +} + + + +--- + +declare { + key = "components go down right aligned", + use = { + { key = "component direction", value=270}, + { key = "component align", value = "counterclockwise"}, + }, + summary = "See the other |components go ...| keys.", + + examples = { + [[" + \tikz \graph [tree layout, nodes={draw, align=center}, + components go down left aligned] + { a, hello -- {world,s} }; + "]], + [[" + \tikz \graph [tree layout, nodes={draw, align=center}, + components go up absolute left aligned] + { a, hello -- {world,s}}; + "]] + } +} + +--- +-- + +declare { + key = "components go down absolute right aligned", + use = { + { key = "component direction", value=270}, + { key = "component align", value = "counterclockwise bounding box"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go down left aligned", + use = { + { key = "component direction", value=270}, + { key = "component align", value = "clockwise"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go down absolute left aligned", + use = { + { key = "component direction", value=270}, + { key = "component align", value = "clockwise bounding box"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go down center aligned", + use = { + { key = "component direction", value=270}, + { key = "component align", value = "center"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go down", + use = { + { key = "component direction", value=270}, + { key = "component align", value = "first node"}, + }, + summary = "See the other |components go ...| keys." +} + +--- +-- + +declare { + key = "components go up right aligned", + use = { + { key = "component direction", value=90}, + { key = "component align", value = "clockwise"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go up absolute right aligned", + use = { + { key = "component direction", value=90}, + { key = "component align", value = "clockwise bounding box"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go up left aligned", + use = { + { key = "component direction", value=90}, + { key = "component align", value = "counterclockwise"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go up absolute left aligned", + use = { + { key = "component direction", value=90}, + { key = "component align", value = "counterclockwise bounding box"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go up center aligned", + use = { + { key = "component direction", value=90}, + { key = "component align", value = "center"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go up", + use = { + { key = "component direction", value=90}, + { key = "component align", value = "first node"}, + }, + summary = "See the other |components go ...| keys." +} + + + + +return Components
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentDirection.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentDirection.lua new file mode 100644 index 00000000000..39df30ab248 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentDirection.lua @@ -0,0 +1,61 @@ +-- 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/control/ComponentDirection.lua,v 1.2 2013/05/23 20:01:25 tantau Exp $ + + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + + +--- +-- @section subsubsection {Arranging Components in a Certain Direction} +-- +-- @end + +--- + +declare { + key = "component direction", + type = "direction", + initial = "0", + + summary = [[" + The \meta{angle} is used to determine the relative position of each + component relative to the previous one. The direction need not be a + multiple of |90|. As usual, you can use texts like |up| or + |right| instead of a number. + "]], + documentation = [[" + As the examples show, the direction only has an influence on the + relative positions of the components, not on the direction of growth + inside the components. In particular, the components are not rotated + by this option in any way. You can use the |grow| option or |orient| + options to orient individual components. + "]], + examples = { + [[" + \tikz \graph [tree layout, nodes={inner sep=1pt,draw,circle}, + component direction=left] + { a, b, c -- d -- e, f -- g }; + "]], + [[" + \tikz \graph [tree layout, nodes={inner sep=1pt,draw,circle}, + component direction=10] + { a, b, c -- d -- e, f -- g }; + "]], + [[" + \tikz \graph [tree layout, nodes={inner sep=1pt,draw,circle}, + component direction=up] + { a, b, c [grow=right] -- d -- e, f[grow=45] -- g }; + "]] + } +} + + +return Components
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentDistance.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentDistance.lua new file mode 100644 index 00000000000..30f5630ce52 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentDistance.lua @@ -0,0 +1,102 @@ +-- 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/control/ComponentDistance.lua,v 1.2 2013/05/23 20:01:25 tantau Exp $ + + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + + +--- +-- @section subsubsection {The Distance Between Components} +-- +-- Once the components of a graph have been oriented, sorted, aligned, +-- and a direction has been chosen, it remains to determine the distance +-- between adjacent components. Two methods are available for computing +-- this distance, as specified by the following option: +-- +-- @end + + +--- + +declare { + key = "component packing", + type = "string", + initial = "skyline", + + documentation = [[" + Given two components, their distance is computed as follows in + depencende of \meta{method}: + \begin{itemize} + \item \declare{|rectangular|} + + Imagine a bounding box to be drawn around both components. They + are then shifted such that the padding (separating distance) + between the two boxes is the current value of |component sep|. + \begin{codeexample}[] + \tikz \graph [tree layout, nodes={draw}, component sep=0pt, + component packing=rectangular] + { a -- long text, longer text -- b}; + \end{codeexample} + \item \declare{|skyline|} + + The ``skyline method'' is used to compute the distance. It works + as follows: For simplicity, assume that the component direction is + right (other case work similary, only everything is + rotated). Imaging the second component to be placed far right + beyond the first component. Now start moving the second component + back to the left until one of the nodes of the second component + touches a node of the first component, and stop. Again, the + padding |component sep| can be used to avoid the nodes actually + touching each other. + + \begin{codeexample}[] + \tikz \graph [tree layout, nodes={draw}, component sep=0pt, + level distance=1.5cm, + component packing=skyline] + { a -- long text, longer text -- b}; + \end{codeexample} + + In order to avoid nodes of the second component ``passing through + a hole in the first component,'' the actual algorithm is a bit + more complicated: For both components, a ``skyline'' is + computed. For the first component, consider an arbitrary + horizontal line. If there are one or more nodes on this line, the + rightmost point on any of the bounding boxes of these nodes will + be the point on the skyline of the first component for this + line. Similarly, for the second component, for each horizontal + level the skyline is given by the leftmost point on any of the + bounding boxes intersecting the line. + + Now, the interesting case are horizontal lines that do not + intersect any of the nodes of the first and/or second + component. Such lines represent ``holes'' in the skyline. For + them, the following rule is used: Move the horizontal line upward + and downward as little as possible until a height is reached where + there is a skyline defined. Then the skyline position on the + original horizontal line is the skyline position at the reached + line, minus (or, for the second component, plus) the distance by + which the line was moved. This means that the holes are ``filled + up by slanted roofs.'' + \begin{codeexample}[] + \begin{tikzpicture} + \graph [tree layout, nodes={draw}, component sep=0pt, + component packing=skyline] + { a -- long text, longer text -- b}; + \draw[red] (long text.north east) -- ++(north west:1cm); + \end{tikzpicture} + \end{codeexample} + + \end{itemize} + "]] +} + + +return Components
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentOrder.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentOrder.lua new file mode 100644 index 00000000000..63a8896e8a4 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentOrder.lua @@ -0,0 +1,107 @@ +-- 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/control/ComponentOrder.lua,v 1.3 2013/05/23 20:01:25 tantau Exp $ + + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + + + + +--- +-- @section subsubsection {Ordering the Components} +-- +-- The different connected components of the graph are collected in a +-- list. The ordering of the nodes in this list can be configured using +-- the following key. +-- +-- @end + + +--- + +declare { + key = "component order", + type = "string", + initial = "by first specified node", + + summary = [[" + Selects a ``strategy'' for ordering the components. By default, + they are ordered in the way they appear in the input. + "]], + documentation = [[" + The following values are permissible for \meta{strategy} + \begin{itemize} + \item \declare{|by first specified node|} + + The components are ordered ``in the way they appear in the input + specification of the graph''. More precisely, for each component + consider the node that is first encountered in the description + of the graph. Order the components in the same way as these nodes + appear in the graph description. + + \item \declare{|increasing node number|} + + The components are ordered by increasing number of nodes. For + components with the same number of nodes, the first node in each + component is considered and they are ordered according to the + sequence in which these nodes appear in the input. + + \item \declare{|decreasing node number|} + As above, but in decreasing order. + \end{itemize} + "]], + examples = { + [[" + \tikz \graph [tree layout, nodes={inner sep=1pt,draw,circle}, + component order=by first specified node] + { a, b, c, f -- g, c -- d -- e }; + "]], + [[" + \tikz \graph [tree layout, nodes={inner sep=1pt,draw,circle}, + component order=increasing node number] + { a, b, c -- d -- e, f -- g }; + "]] + } +} + + +--- + +declare { + key = "small components first", + use = { + { key = "component order", value = "increasing node number" } + }, + + summary = [[" + A shorthand for |component order=increasing node number|. + "]] + } + +--- + +declare { + key = "large components first", + use = { + { key = "component order", value = "decreasing node number" }, + }, + summary = [[" + A shorthand for |component order=decreasing node number|. + "]], + examples = [[" + \tikz \graph [tree layout, nodes={inner sep=1pt,draw,circle}, + large components first] + { a, b, c -- d -- e, f -- g }; + "]] +} + + +return Components
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Components.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Components.lua new file mode 100644 index 00000000000..0d1d2b1bf48 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Components.lua @@ -0,0 +1,129 @@ +-- 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/control/Components.lua,v 1.3 2013/05/23 20:01:25 tantau Exp $ + + +-- Imports + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + + +--- +-- @section subsection {Packing of Connected Components} +-- +-- \label{subsection-gd-component-packing} +-- \label{section-gd-packing} +-- +-- Graphs may be composed of subgraphs or \emph{components} that are not +-- connected to each other. In order to draw these nicely, most graph +-- drawing algorithms split them into separate graphs, compute +-- their layouts with the same graph drawing algorithm independently and, +-- in a postprocessing step, arrange them next to each other. Note, +-- however, that some graph drawing algorithms can also arrange the nodes +-- of the graph in a uniform way even for unconnected components (the +-- |simple necklace layout| is a case in point); for such algorithms you can +-- choose whether they should be applied to each component individually +-- or not (if not, the following options do not apply). To configure +-- which is the case, use the |componentwise| key. +-- +-- The default method for placing the different components works as +-- follows: +-- +-- \begin{enumerate} +-- \item For each component, a layout is determined and the component is +-- oriented as described +-- Section~\ref{subsection-library-graphdrawing-standard-orientation} +-- on the orientation of graphs. +-- \item The components are sorted as prescribed by the +-- |component order| key. +-- \item The first component is now placed (conceptually) at the +-- origin. (The final position of this and all other components will be +-- determined later, namely in the anchoring phase, but let us imagine +-- that the first component lies at the origin at this point.) +-- \item The second component is now positioned relative to the first +-- component. The ``direction'' in which the next component is placed +-- relative to the first one is determined by the |component direction| +-- key, so components can be placed from left to right or up to down or +-- in any other direction (even something like $30^\circ$). However, +-- both internally and in the following description, we assume that the +-- components are placed from left to right; other directions are +-- achieved by doing some (clever) rotating of the arrangement achieved +-- in this way. +-- +-- So, we now wish to place the second component to the right of the +-- first component. The component is first shifted vertically according +-- to some alignment strategy. For instance, it can be shifted so that +-- the topmost node of the first component and the topmost node of the +-- second component have the same vertical position. Alternatively, we +-- might require that certain ``alignment nodes'' in both components +-- have the same vertical position. There are several other strategies, +-- which can be configured using the |component align| key. +-- +-- One the vertical position has been fixed, the horizontal position is +-- computed. Here, two different strategies are available: First, image +-- rectangular bounding boxed to be drawn around both components. Then +-- we shift the second component such that the right border of the +-- bounding box of the first component touches the left border of the +-- bounding box of the second component. Instead of having the bounding +-- boxes ``touch,'' we can also have a padding of |component sep| +-- between them. The second strategy is more involved and also known as +-- a ``skyline'' strategy, where (roughly) the components are +-- ``moved together as near as possible so that nodes do not touch''. +-- \item +-- After the second component has been placed, the third component is +-- considered and positioned relative to the second one, and so on. +-- \item +-- At the end, as hinted at earlier, the whole arrangement is rotate so +-- that instead of ``going right'' the component go in the direction of +-- |component direction|. Note, however, that this rotation applies only +-- to the ``shift'' of the components; the components themselves are +-- not rotated. Fortunately, this whole rotation process happens in the +-- background and the result is normally exactly what you would expect. +-- \end{enumerate} +-- +-- In the following, we go over the different keys that can be used to +-- configure the component packing. +-- +-- @end + + +--- + +declare { + key = "componentwise", + type = "boolean", + + summary = [[" + For algorithms that also support drawing unconnected graphs, use + this key to enforce that the components of the graph are, + nevertheless, laid out individually. For algorithms that do not + support laying out unconnected graphs, this option has no effect; + rather it works as if this option were always set. + "]], + examples = { + [[" + \tikz \graph [simple necklace layout] + { + a -- b -- c -- d -- a, + 1 -- 2 -- 3 -- 1 + }; + "]], + [[", + \tikz \graph [simple necklace layout, componentwise] + { + a -- b -- c -- d -- a, + 1 -- 2 -- 3 -- 1 + }; + "]] + } +} + + + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Distances.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Distances.lua new file mode 100644 index 00000000000..046940d84f3 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Distances.lua @@ -0,0 +1,461 @@ +-- 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/control/Distances.lua,v 1.5 2013/05/23 20:01:25 tantau Exp $ + + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare +local lib = require "pgf.gd.lib" + +--- +-- @section subsection {Padding and Node Distances} +-- +-- \label{subsection-gd-dist-pad} +-- +-- In many drawings, you may wish to specify how ``near'' two nodes should +-- be placed by a graph drawing algorithm. Naturally, this depends +-- strongly on the specifics of the algorithm, but there are a number of +-- general keys that will be used by many algorithms. +-- +-- There are different kinds of objects for which you can specify +-- distances and paddings: +-- +-- \begin{itemize} +-- \item You specify the ``natural'' distance between nodes +-- connected by an edge using |node distance|, which is also available in +-- normal \tikzname\ albeit for a slightly different purpose. However, +-- not every algorithm will (or can) honour the key; see the description +-- of each algorithm what it will ``make of this option''. +-- \item A number of graph drawing algorithms arrange nodes in layers +-- (or levels); we refer +-- to the nodes on the same layer as siblings (although, in a tree, +-- siblings are only nodes with the same parent; nevertheless we use +-- ``sibling'' loosely also for nodes that are more like ``cousins''). +-- \item When a graph consists of several connected component, many graph +-- drawing algorithms will layout these components individually. The +-- different components will then be arranged next to each other, see +-- Section~\ref{section-gd-packing} for the details, such that between +-- the nodes of any two components a padding is avaiable. +-- \end{itemize} +-- +-- @end + + + + +--- + +declare { + key = "node distance", + type = "length", + initial = "1cm", + + summary = [[" + This is minimum distance that the centers of nodes connected by an + edge should have. It will not always be possible to satisfy this + desired distance, for instance in case the nodes are too big. In + this case, the \meta{length} is just considered as a lower bound. + "]], + examples = [[" + \begin{tikzpicture} + \graph [simple necklace layout, node distance=1cm, node sep=0pt, + nodes={draw,circle,as=.}] + { + 1 -- 2 [minimum size=2cm] -- 3 -- + 4 -- 5 -- 6 -- 7 --[orient=up] 8 + }; + \draw [red,|-|] (1.center) -- ++(0:1cm); + \draw [red,|-|] (5.center) -- ++(180:1cm); + \end{tikzpicture} + "]] +} + + +--- + +declare { + key = "node pre sep", + type = "length", + initial = ".333em", + + summary = [[" + This is a minimum ``padding'' or ``separation'' between the border + of nodes connected by an edge. Thus, if nodes are so big that nodes + with a distance of |node distance| would overlap (or + just come with \meta{dimension} distance of one another), their + distance is enlarged so that this distance is still satisfied. + The |pre| means that the padding is added to the node ``at the + front.'' This make sense only for some algorithms, like for a + simple necklace layout. + "]], + examples = { + [[" + \tikz \graph [simple necklace layout, node distance=0cm, nodes={circle,draw}] + { 1--2--3--4--5--1 }; + "]], + [[" + \tikz \graph [simple necklace layout, node distance=0cm, node sep=0mm, + nodes={circle,draw}] + { 1--2--3[node pre sep=5mm]--4--5[node pre sep=1mm]--1 }; + "]] + } +} + +--- + +declare { + key = "node post sep", + type = "length", + initial = ".333em", + + summary = [[" + Works like |node pre sep|. + "]] +} + + + +--- +-- @param length A length. + +declare { + key = "node sep", + type = "length", + use = { + { key = "node pre sep", value = function(v) return v/2 end }, + { key = "node post sep", value = function(v) return v/2 end }, + }, + summary = [[" + A shorthand for setting both |node pre sep| and |node post sep| to + $\meta{length}/2$. + "]] +} + + +--- + +declare { + key = "level distance", + type = "length", + initial = "1cm", + + summary = [[" + This is minimum distance that the centers of nodes on one + level should have from the centers of nodes on the next level. It + will not always be possible to satisfy this desired distance, for + instance in case the nodes are too big. In this case, the + \meta{length} is just considered as a lower bound. + "]], + examples = [[" + \begin{tikzpicture}[inner sep=2pt] + \draw [help lines] (0,0) grid (3.5,2); + \graph [layered layout, level distance=1cm, level sep=0] + { 1 [x=1,y=2] -- 2 -- 3 -- 1 }; + \graph [layered layout, level distance=5mm, level sep=0] + { 1 [x=3,y=2] -- 2 -- 3 -- 1, 3 -- {4,5} -- 6 -- 3 }; + \end{tikzpicture} + "]] +} + +--- +declare { + key = "layer distance", + type = "length", + use = { + { key = "level distance", value = lib.id }, + }, + summary = "An alias for |level distance|" +} + +--- +declare { + key = "level pre sep", + type = "length", + initial = ".333em", + + summary = [[" + This is a minimum ``padding'' or ``separation'' between the border + of the nodes on a level to any nodes on the previous level. Thus, if + nodes are so big that nodes on consecutive levels would overlap (or + just come with \meta{lrngth} distance of one another), their + distance is enlarged so that this distance is still satisfied. + If a node on the previous level also has a |level post sep|, this + post padding and the \meta{dimension} add up. Thus, these keys + behave like the ``padding'' keys rather + than the ``margin'' key of cascading style sheets. + "]], + examples = [[" + \begin{tikzpicture}[inner sep=2pt, level sep=0pt, sibling distance=0pt] + \draw [help lines] (0,0) grid (3.5,2); + \graph [layered layout, level distance=0cm, nodes=draw] + { 1 [x=1,y=2] -- {2,3[level pre sep=1mm],4[level pre sep=5mm]} -- 5 }; + \graph [layered layout, level distance=0cm, nodes=draw] + { 1 [x=3,y=2] -- {2,3,4} -- 5[level pre sep=5mm] }; + \end{tikzpicture} + "]] +} + +--- + +declare { + key = "level post sep", + type = "length", + initial = ".333em", + + summary = [[" + Works like |level pre sep|. + "]] +} + +--- +declare { + key = "layer pre sep", + type = "length", + use = { + { key = "level pre sep", value = lib.id }, + }, + summary = "An alias for |level pre sep|." +} + +--- +declare { + key = "layer post sep", + type = "length", + use = { + { key = "level post sep", value = lib.id }, + }, + summary = "An alias for |level post sep|." +} + + + + +--- +-- @param length A length + +declare { + key = "level sep", + type = "length", + use = { + { key = "level pre sep", value = function (v) return v/2 end }, + { key = "level post sep", value = function (v) return v/2 end }, + }, + + summary = [[" + A shorthand for setting both |level pre sep| and |level post sep| to + $\meta{length}/2$. Note that if you set |level distance=0| and + |level sep=1em|, you get a layout where any two consecutive layers + are ``spaced apart'' by |1em|. + "]] +} + + +--- +declare { + key = "layer sep", + type = "number", + use = { + { key = "level sep", value = lib.id }, + }, + summary = "An alias for |level sep|." +} + + +--- +declare { + key = "sibling distance", + type = "length", + initial = "1cm", + + summary = [[" + This is minimum distance that the centers of node should have to the + center of the next node on the same level. As for levels, this is + just a lower bound. + For some layouts, like a simple necklace layout, the \meta{length} is + measured as the distance on the circle. + "]], + examples = { + [[" + \tikz \graph [tree layout, sibling distance=1cm, nodes={circle,draw}] + { 1--{2,3,4,5} }; + "]], + [[" + \tikz \graph [tree layout, sibling distance=0cm, sibling sep=0pt, + nodes={circle,draw}] + { 1--{2,3,4,5} }; + "]], + [[" + \tikz \graph [tree layout, sibling distance=0cm, sibling sep=0pt, + nodes={circle,draw}] + { 1--{2,3[sibling distance=1cm],4,5} }; + "]] + } +} + + +--- + +declare { + key = "sibling pre sep", + type = "length", + initial = ".333em", + + summary = [[" + Works like |level pre sep|, only for siblings. + "]], + examples = [[" + \tikz \graph [tree layout, sibling distance=0cm, nodes={circle,draw}, + sibling sep=0pt] + { 1--{2,3[sibling pre sep=1cm],4,5} }; + "]] +} + +--- + +declare { + key = "sibling post sep", + type = "length", + initial = ".333em", + + summary = [[" + Works like |sibling pre sep|. + "]] + } + + + +--- +-- @param length A length + +declare { + key = "sibling sep", + type = "length", + use = { + { key = "sibling pre sep", value = function(v) return v/2 end }, + { key = "sibling post sep", value = function(v) return v/2 end }, + }, + + summary = [[" + A shorthand for setting both |sibling pre sep| and |sibling post sep| to + $\meta{length}/2$. + "]] +} + + + + + + +--- +declare { + key = "part distance", + type = "length", + initial = "1.5cm", + + summary = [[" + This is minimum distance between the centers of ``parts'' of a + graph. What a ``part'' is depends on the algorithm. + "]] +} + + +--- + +declare { + key = "part pre sep", + type = "length", + initial = "1em", + summary = "A pre-padding for parts." +} + +--- + +declare { + key = "part post sep", + type = "length", + initial = "1em", + summary = "A post-padding for pars." + } + + + +--- +-- @param length A length + +declare { + key = "part sep", + type = "length", + use = { + { key = "part pre sep", value = function(v) return v/2 end }, + { key = "part post sep", value = function(v) return v/2 end }, + }, + + summary = [[" + A shorthand for setting both |part pre sep| and |part post sep| to + $\meta{length}/2$. + "]] +} + + + + +--- + +declare { + key = "component sep", + type = "length", + initial = "1.5em", + + summary = [[" + This is pading between the bounding boxes that nodes of different + connected components will have when they are placed next to each + other. + "]], + examples = { + [[" + \tikz \graph [binary tree layout, sibling distance=4mm, level distance=8mm, + components go right top aligned, + component sep=1pt, nodes=draw] + { + 1 -> 2 -> {3->4[second]->5,6,7}; + a -> b[second] -> c[second] -> d -> e; + x -> y[second] -> z -> u[second] -> v; + }; + "]], + [[" + \tikz \graph [binary tree layout, sibling distance=4mm, level distance=8mm, + components go right top aligned, + component sep=1em, nodes=draw] + { + 1 -> 2 -> {3->4[second]->5,6,7}; + a -> b[second] -> c[second] -> d -> e; + x -> y[second] -> z -> u[second] -> v; + }; + "]] + } +} + + + +--- + +declare { + key = "component distance", + type = "length", + initial = "2cm", + + summary = [[" + This is the minimum distance between the centers of bounding + boxes of connected components when they are placed next to each + other. (Not used, currently.) + "]] +} + + +return Distances
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/FineTune.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/FineTune.lua new file mode 100644 index 00000000000..bb2fd065b24 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/FineTune.lua @@ -0,0 +1,164 @@ +-- 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/control/FineTune.lua,v 1.3 2013/05/23 20:01:25 tantau Exp $ + + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + +local Coordinate = require "pgf.gd.model.Coordinate" +local lib = require "pgf.gd.lib" + +--- +-- @section subsection {Fine-Tuning Positions of Nodes} +-- +-- @end + + + +--- +declare { + key = "nudge", + type = "canvas coordinate", + + summary = [[" + This option allows you to slightly ``nudge'' (move) nodes after + they have been positioned by the given offset. The idea is that + this nudging is done after the position of the node has been + computed, so nudging has no influence on the actual graph + drawing algorithms. This, in turn, means that you can use + nudging to ``correct'' or ``optimize'' the positioning of nodes + after the algorithm has computed something. + "]], + + examples = [[" + \tikz \graph [edges=rounded corners, nodes=draw, + layered layout, sibling distance=0] { + a -- {b, c, d[nudge=(up:2mm)]} -- e -- a; + }; + "]] +} + + +--- +-- @param distance A distance by which the node is nudges. + +declare { + key = "nudge up", + type = "length", + use = { + { key = "nudge", value = function (v) return Coordinate.new(0,v) end } + }, + + summary = "A shorthand for nudging a node upwards.", + examples = [[" + \tikz \graph [edges=rounded corners, nodes=draw, + layered layout, sibling distance=0] { + a -- {b, c, d[nudge up=2mm]} -- e -- a; + }; + "]] +} + + +--- +-- @param distance A distance by which the node is nudges. + +declare { + key = "nudge down", + type = "length", + use = { + { key = "nudge", value = function (v) return Coordinate.new(0,-v) end } + }, + + summary = "Like |nudge up|, but downwards." +} + +--- +-- @param distance A distance by which the node is nudges. + +declare { + key = "nudge left", + type = "length", + use = { + { key = "nudge", value = function (v) return Coordinate.new(-v,0) end } + }, + + summary = "Like |nudge up|, but left.", + examples = [[" + \tikz \graph [edges=rounded corners, nodes=draw, + layered layout, sibling distance=0] { + a -- {b, c, d[nudge left=2mm]} -- e -- a; + }; + "]] +} + +--- +-- @param distance A distance by which the node is nudges. + +declare { + key = "nudge right", + type = "length", + use = { + { key = "nudge", value = function (v) return Coordinate.new(v,0) end } + }, + + summary = "Like |nudge left|, but right." +} + + +--- +declare { + key = "regardless at", + type = "canvas coordinate", + + summary = [[" + Using this option you can provide a position for a node to wish + it will be forced after the graph algorithms have run. So, the node + is positioned normally and the graph drawing algorithm does not know + about the position specified using |regardless at|. However, + afterwards, the node is placed there, regardless of what the + algorithm has computed (all other nodes are unaffected). + "]], + examples = [[" + \tikz \graph [edges=rounded corners, nodes=draw, + layered layout, sibling distance=0] { + a -- {b,c,d[regardless at={(1,0)}]} -- e -- a; + }; + "]] +} + + + + +--- +-- @param pos A canvas position (a coordinate). + +declare { + key = "nail at", + type = "canvas coordinate", + use = { + { key = "desired at", value = lib.id }, + { key = "regardless at", value = lib.id }, + }, + + summary = [[" + This option combines |desired at| and |regardless at|. Thus, the + algorithm is ``told'' about the desired position. If it fails to place + the node at the desired position, it will be put there + regardless. The name of the key is intended to remind one of a node + being ``nailed'' to the canvas. + "]], + examples = [[" + \tikz \graph [edges=rounded corners, nodes=draw, + layered layout, sibling distance=0] { + a -- {b,c,d[nail at={(1,0)}]} -- e[nail at={(1.5,-1)}] -- a; + }; + "]] +} + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/LayoutPipeline.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/LayoutPipeline.lua new file mode 100644 index 00000000000..c32f9d084f6 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/LayoutPipeline.lua @@ -0,0 +1,1282 @@ +-- 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/control/LayoutPipeline.lua,v 1.11 2013/10/09 19:46:59 tantau Exp $ + + +--- +-- This class controls the running of graph drawing algorithms on +-- graphs. In particular, it performs pre- and posttransformations and +-- also invokes the collapsing of sublayouts. +-- +-- You do not call any of the methods of this class directly, the +-- whole class is included only for documentation purposes. +-- +-- Before an algorithm is applied, a number of transformations will +-- have been applied, depending on the algorithm's |preconditions| +-- field: +-- +-- \begin{itemize} +-- \item |connected| +-- +-- If this property is set for an algorithm (that is, in the +-- |declare| statement for the algorithm the |predconditions| field +-- has the entry |connected=true| set), then the graph will be +-- decomposed into connected components. The algorithm is run on each +-- component individually. +-- \item |tree| +-- +-- When set, the field |spanning_tree| of the algorithm will be set +-- to a spanning tree of the graph. This option implies |connected|. +-- \item |loop_free| +-- +-- When set, all loops (arcs from a vertex to itself) will have been +-- removed when the algorithm runs. +-- +-- \item |at_least_two_nodes| +-- +-- When explicitly set to |false| (this precondition is |true| by +-- default), the algorithm will even be run if there is only a +-- single vertex in the graph. +-- \end{itemize} +-- +-- Once the algorithm has run, the algorithm's |postconditions| will +-- be processed: +-- +-- \begin{itemize} +-- \item |upward_oriented| +-- +-- When set, the algorithm tells the layout pipeline that the graph +-- has been laid out in a layered manner with each layer going from +-- left to right and layers at a whole going upwards (positive +-- $y$-coordinates). The graph will then be rotated and possibly +-- swapped in accordance with the |grow| key set by the user. +-- \item |fixed| +-- +-- When set, no rotational postprocessing will be done after the +-- algorithm has run. Usually, a graph is rotated to meet a user's +-- |orient| settings. However, when the algorithm has already +-- ``ideally'' rotated the graph, set this postcondition. +-- \end{itemize} +-- + +local LayoutPipeline = {} + + +-- Namespace +require("pgf.gd.control").LayoutPipeline = LayoutPipeline + + +-- Imports +local Direct = require "pgf.gd.lib.Direct" +local Storage = require "pgf.gd.lib.Storage" +local Simplifiers = require "pgf.gd.lib.Simplifiers" +local LookupTable = require "pgf.gd.lib.LookupTable" +local Transform = require "pgf.gd.lib.Transform" + +local Arc = require "pgf.gd.model.Arc" +local Vertex = require "pgf.gd.model.Vertex" +local Digraph = require "pgf.gd.model.Digraph" +local Coordinate = require "pgf.gd.model.Coordinate" +local Path = require "pgf.gd.model.Path" + +local Sublayouts = require "pgf.gd.control.Sublayouts" + +local lib = require "pgf.gd.lib" + +local InterfaceCore = require "pgf.gd.interface.InterfaceCore" + + + + +-- Forward definitions + +local prepare_events + + + +-- The main ``graph drawing pipeline'' that handles the pre- and +-- postprocessing for a graph. This method is called by the diplay +-- interface. +-- +-- @param scope A graph drawing scope. + +function LayoutPipeline.run(scope) + + -- The pipeline... + + -- Step 1: Preparations + + -- Prepare events + prepare_events(scope.events) + + -- Step 2: Recursively layout the graph, starting with the root layout + local root_layout = assert(scope.collections[InterfaceCore.sublayout_kind][1], "no layout in scope") + + scope.syntactic_digraph = + Sublayouts.layoutRecursively (scope, + root_layout, + LayoutPipeline.runOnLayout, + { root_layout }) + + -- Step 3: Anchor the graph + LayoutPipeline.anchor(scope.syntactic_digraph, scope) + + -- Step 4: Apply regardless transforms + Sublayouts.regardless(scope.syntactic_digraph) + + -- Step 5: Cut edges + LayoutPipeline.cutEdges(scope.syntactic_digraph) + +end + + + +-- +-- This method is called by the sublayout rendering pipeline when the +-- algorithm should be invoked for an individual graph. At this point, +-- the sublayouts will already have been collapsed. +-- +-- @param scope The graph drawing scope. +-- @param algorithm_class The to-be-applied algorithm class. +-- @param layout_graph A subgraph of the syntactic digraph which is +-- restricted to the current layout and in which sublayouts have +-- been contracted to single nodes. +-- @param layout The layout to which the graph belongs. +-- +function LayoutPipeline.runOnLayout(scope, algorithm_class, layout_graph, layout) + + if #layout_graph.vertices < 1 then + return + end + + -- The involved main graphs: + local layout_copy = Digraph.new (layout_graph) --Direct.digraphFromSyntacticDigraph(layout_graph) + for _,a in ipairs(layout_graph.arcs) do + local new_a = layout_copy:connect(a.tail,a.head) + new_a.syntactic_edges = a.syntactic_edges + end + + -- Step 1: Decompose the graph into connected components, if necessary: + local syntactic_components + if algorithm_class.preconditions.tree or algorithm_class.preconditions.connected or layout_graph.options.componentwise then + syntactic_components = LayoutPipeline.decompose(layout_copy) + LayoutPipeline.sortComponents(layout_graph.options['component order'], syntactic_components) + else + -- Only one component: The graph itself... + syntactic_components = { layout_copy } + end + + -- Step 2: For all components do: + for i,syntactic_component in ipairs(syntactic_components) do + + -- Step 2.1: Reset random number generator to make sure that the + -- same graph is always typeset in the same way. + math.randomseed(layout_graph.options['random seed']) + + local digraph = Direct.digraphFromSyntacticDigraph(syntactic_component) + + -- Step 2.3: If requested, remove loops + if algorithm_class.preconditions.loop_free then + for _,v in ipairs(digraph.vertices) do + digraph:disconnect(v,v) + end + end + + -- Step 2.4: Precompute the underlying undirected graph + local ugraph = Direct.ugraphFromDigraph(digraph) + + -- Step 2.5: Create an algorithm object + local algorithm = algorithm_class.new{ + digraph = digraph, + ugraph = ugraph, + scope = scope, + layout = layout, + layout_graph = layout_graph, + syntactic_component = syntactic_component, + } + + -- Step 2.7: Compute a spanning tree, if necessary + if algorithm_class.preconditions.tree then + local spanning_algorithm_class = syntactic_component.options.algorithm_phases["spanning tree computation"] + algorithm.spanning_tree = + spanning_algorithm_class.new{ + ugraph = ugraph, + events = scope.events + }:run() + end + + -- Step 2.8: Compute growth-adjusted sizes + algorithm.rotation_info = LayoutPipeline.prepareRotateAround(algorithm.postconditions, syntactic_component) + algorithm.adjusted_bb = Storage.newTableStorage() + LayoutPipeline.prepareBoundingBoxes(algorithm.rotation_info, algorithm.adjusted_bb, syntactic_component, syntactic_component.vertices) + + -- Step 2.9: Finally, run algorithm on this component! + if #digraph.vertices > 1 or algorithm_class.run_also_for_single_node + or algorithm_class.preconditions.at_least_two_nodes == false then + -- Main run of the algorithm: + if algorithm_class.old_graph_model then + LayoutPipeline.runOldGraphModel(scope, digraph, algorithm_class, algorithm) + else + algorithm:run () + end + end + + -- Step 2.10: Sync the graphs + digraph:sync() + ugraph:sync() + if algorithm.spanning_tree then + algorithm.spanning_tree:sync() + end + + -- Step 2.11: Orient the graph + LayoutPipeline.orient(algorithm.rotation_info, algorithm.postconditions, syntactic_component, scope) + end + + -- Step 3: Packing: + LayoutPipeline.packComponents(layout_graph, syntactic_components) +end + + + + + + +--- +-- This function is called internally to perform the graph anchoring +-- procedure described in +-- Section~\ref{subsection-library-graphdrawing-anchoring}. These +-- transformations are always performed. +-- +-- @param graph A graph +-- @param scope The scope + +function LayoutPipeline.anchor(graph, scope) + + -- Step 1: Find anchor node: + local anchor_node + + local anchor_node_name = graph.options['anchor node'] + if anchor_node_name then + anchor_node = scope.node_names[anchor_node_name] + end + + if not graph:contains(anchor_node) then + anchor_node = + lib.find (graph.vertices, function (v) return v.options['anchor here'] end) or + lib.find (graph.vertices, function (v) return v.options['desired at'] end) or + graph.vertices[1] + end + + -- Sanity check + assert(graph:contains(anchor_node), "anchor node is not in graph!") + + local desired = anchor_node.options['desired at'] or graph.options['anchor at'] + local delta = desired - anchor_node.pos + + -- Step 3: Shift nodes + for _,v in ipairs(graph.vertices) do + v.pos:shiftByCoordinate(delta) + end + for _,a in ipairs(graph.arcs) do + if a.path then a.path:shiftByCoordinate(delta) end + for _,e in ipairs(a.syntactic_edges) do + e.path:shiftByCoordinate(delta) + end + end +end + + + +--- +-- This method tries to determine in which direction the graph is supposed to +-- grow and in which direction the algorithm will grow the graph. These two +-- pieces of information togehter produce a necessary rotation around some node. +-- This rotation is returned in a table. +-- +-- Note that this method does not actually cause a rotation to happen; this is +-- left to other method. +-- +-- @param postconditions The algorithm's postconditions. +-- @param graph An undirected graph +-- @return A table containing the computed information. + +function LayoutPipeline.prepareRotateAround(postconditions, graph) + + -- Find the vertex from which we orient + local swap = true + + local v,_,grow = lib.find (graph.vertices, function (v) return v.options["grow"] end) + + if not v and graph.options["grow"] then + v,grow,swap = graph.vertices[1], graph.options["grow"], true + end + + if not v then + v,_,grow = lib.find (graph.vertices, function (v) return v.options["grow'"] end) + swap = false + end + + if not v and graph.options["grow'"] then + v,grow,swap = graph.vertices[1], graph.options["grow'"], false + end + + if not v then + v, grow, swap = graph.vertices[1], -90, true + end + + -- Now compute the rotation + local info = {} + local growth_direction = (postconditions.upward_oriented and 90) or (postconditions.upward_oriented_swapped and 90) + + if postconditions.upward_oriented_swapped then + swap = not swap + end + + if growth_direction == "fixed" then + info.angle = 0 -- no rotation + elseif growth_direction then + info.from_node = v + info.from_angle = growth_direction/360*2*math.pi + info.to_angle = grow/360*2*math.pi + info.swap = swap + info.angle = info.to_angle - info.from_angle + else + info.from_node = v + local other = lib.find_min( + graph:outgoing(v), + function (a) + if a.head ~= v and a:eventIndex() then + return a, a:eventIndex() + end + end) + info.to_node = (other and other.head) or + (graph.vertices[1] == v and graph.vertices[2] or graph.vertices[1]) + info.to_angle = grow/360*2*math.pi + info.swap = swap + info.angle = info.to_angle - math.atan2(info.to_node.pos.y - v.pos.y, info.to_node.pos.x - v.pos.x) + end + + return info +end + + + +--- +-- Compute growth-adjusted node sizes. +-- +-- For each node of the graph, compute bounding box of the node that +-- results when the node is rotated so that it is in the correct +-- orientation for what the algorithm assumes. +-- +-- The ``bounding box'' actually consists of the fields +-- \begin{itemize} +-- \item |sibling_pre|, +-- \item |sibling_post|, +-- \item |layer_pre|, and +-- \item |layer_post|, +-- \end{itemize} +-- which correspond to ``min x'', ``min y'', ``min y'', and ``max y'' +-- for a tree growing up. +-- +-- The computation of the ``bounding box'' treats a centered circle in +-- a special way, all other shapes are currently treated like a +-- rectangle. +-- +-- @param rotation_info The table computed by the function prepareRotateAround +-- @param packing_storage A storage in which the computed distances are stored. +-- @param graph An graph +-- @param vertices An array of to-be-prepared vertices inside graph + +function LayoutPipeline.prepareBoundingBoxes(rotation_info, adjusted_bb, graph, vertices) + + local angle = assert(rotation_info.angle, "angle field missing") + local swap = rotation_info.swap + + for _,v in ipairs(vertices) do + local bb = adjusted_bb[v] + local a = angle + + if v.shape == "circle" then + a = 0 -- no rotation for circles. + end + + -- Fill the bounding box field, + bb.sibling_pre = math.huge + bb.sibling_post = -math.huge + bb.layer_pre = math.huge + bb.layer_post = -math.huge + + local c = math.cos(angle) + local s = math.sin(angle) + for _,p in ipairs(v.path:coordinates()) do + local x = p.x*c + p.y*s + local y = -p.x*s + p.y*c + + bb.sibling_pre = math.min (bb.sibling_pre, x) + bb.sibling_post = math.max (bb.sibling_post, x) + bb.layer_pre = math.min (bb.layer_pre, y) + bb.layer_post = math.max (bb.layer_post, y) + end + + -- Flip sibling per and post if flag: + if swap then + bb.sibling_pre, bb.sibling_post = -bb.sibling_post, -bb.sibling_pre + end + end +end + + + + + +-- +-- Rotate the whole graph around a point +-- +-- Causes the graph to be rotated around \meta{around} so that what +-- used to be the |from_angle| becomes the |to_angle|. If the flag |swap| +-- is set, the graph is additionally swapped along the |to_angle|. +-- +-- @param graph The to-be-rotated (undirected) graph +-- @param around_x The $x$-coordinate of the point around which the graph should be rotated +-- @param around_y The $y$-coordinate +-- @param from An ``old'' angle +-- @param to A ``new'' angle +-- @param swap A boolean that, when true, requests that the graph is +-- swapped (flipped) along the new angle + +function LayoutPipeline.rotateGraphAround(graph, around_x, around_y, from, to, swap) + + -- Translate to origin + local t = Transform.new_shift(-around_x, -around_y) + + -- Rotate to zero degrees: + t = Transform.concat(Transform.new_rotation(-from), t) + + -- Swap + if swap then + t = Transform.concat(Transform.new_scaling(1,-1), t) + end + + -- Rotate to from degrees: + t = Transform.concat(Transform.new_rotation(to), t) + + -- Translate back + t = Transform.concat(Transform.new_shift(around_x, around_y), t) + + for _,v in ipairs(graph.vertices) do + v.pos:apply(t) + end + for _,a in ipairs(graph.arcs) do + for _,p in ipairs(a:pointCloud()) do + p:apply(t) + end + end +end + + + +-- +-- Orient the whole graph using two nodes +-- +-- The whole graph is rotated so that the line from the first node to +-- the second node has the given angle. If swap is set to true, the +-- graph is also flipped along this line. +-- +-- @param graph +-- @param first_node +-- @param seond_node +-- @param target_angle +-- @param swap + +function LayoutPipeline.orientTwoNodes(graph, first_node, second_node, target_angle, swap) + if first_node and second_node then + -- Compute angle between first_node and second_node: + local x = second_node.pos.x - first_node.pos.x + local y = second_node.pos.y - first_node.pos.y + + local angle = math.atan2(y,x) + LayoutPipeline.rotateGraphAround(graph, first_node.pos.x, + first_node.pos.y, angle, target_angle, swap) + end +end + + + +--- +-- Performs a post-layout orientation of the graph by performing the +-- steps documented in Section~\ref{subsection-library-graphdrawing-standard-orientation}. +-- +-- @param rotation_info The info record computed by the function |prepareRotateAround|. +-- @param postconditions The algorithm's postconditions. +-- @param graph A to-be-oriented graph. +-- @param scope The graph drawing scope. + +function LayoutPipeline.orient(rotation_info, postconditions, graph, scope) + + -- Sanity check + if #graph.vertices < 2 then return end + + -- Step 1: Search for global graph orient options: + local function f (orient, tail, head, flag) + if orient and head and tail then + local n1 = scope.node_names[tail] + local n2 = scope.node_names[head] + if graph:contains(n1) and graph:contains(n2) then + LayoutPipeline.orientTwoNodes(graph, n1, n2, orient/360*2*math.pi, flag) + return true + end + end + end + if f(graph.options["orient"], graph.options["orient tail"],graph.options["orient head"], false) then return end + if f(graph.options["orient'"], graph.options["orient tail"],graph.options["orient head"], true) then return end + local tail, head = string.match(graph.options["horizontal"] or "", "^(.*) to (.*)$") + if f(0, tail, head, false) then return end + local tail, head = string.match(graph.options["horizontal'"] or "", "^(.*) to (.*)$") + if f(0, tail, head, true) then return end + local tail, head = string.match(graph.options["vertical"] or "", "^(.*) to (.*)$") + if f(-90, tail, head, false) then return end + local tail, head = string.match(graph.options["vertical'"] or "", "^(.*) to (.*)$") + if f(-90, tail, head, true) then return end + + -- Step 2: Search for a node with the orient option: + for _, v in ipairs(graph.vertices) do + local function f (key, flag) + local orient = v.options[key] + local head = v.options["orient head"] + local tail = v.options["orient tail"] + + if orient and head then + local n2 = scope.node_names[head] + if graph:contains(n2) then + LayoutPipeline.orientTwoNodes(graph, v, n2, orient/360*2*math.pi, flag) + return true + end + elseif orient and tail then + local n1 = scope.node_names[tail] + if graph:contains(n1) then + LayoutPipeline.orientTwoNodes(graph, n1, v, orient/360*2*math.pi, flag) + return true + end + end + end + if f("orient", false) then return end + if f("orient'", true) then return end + end + + -- Step 3: Search for an edge with the orient option: + for _, a in ipairs(graph.arcs) do + if a:options("orient",true) then + return LayoutPipeline.orientTwoNodes(graph, a.tail, a.head, a:options("orient")/360*2*math.pi, false) + end + if a:options("orient'",true) then + return LayoutPipeline.orientTwoNodes(graph, a.tail, a.head, a:options("orient'")/360*2*math.pi, true) + end + end + + -- Step 4: Search two nodes with a desired at option: + local first, second, third + + for _, v in ipairs(graph.vertices) do + if v.options['desired at'] then + if first then + if second then + third = v + break + else + second = v + end + else + first = v + end + end + end + + if second then + local a = first.options['desired at'] + local b = second.options['desired at'] + return LayoutPipeline.orientTwoNodes(graph, first, second, math.atan2(b.y-a.y,b.x-a.x), false) + end + + -- Computed during preprocessing: + if rotation_info.from_node and postconditions.fixed ~= true then + local x = rotation_info.from_node.pos.x + local y = rotation_info.from_node.pos.y + local from_angle = rotation_info.from_angle or math.atan2(rotation_info.to_node.pos.y - y, rotation_info.to_node.pos.x - x) + + LayoutPipeline.rotateGraphAround(graph, x, y, from_angle, rotation_info.to_angle, rotation_info.swap) + end +end + + + + +--- +-- This internal function is called to decompose a graph into its +-- components. Whether or not this function is called depends on +-- whether the precondition |connected| is set for the algorithm class +-- and whether the |componentwise| key is used. +-- +-- @param graph A to-be-decomposed graph +-- +-- @return An array of graph objects that represent the connected components of the graph. + +function LayoutPipeline.decompose (digraph) + + -- The list of connected components (node sets) + local components = {} + + -- Remember, which graphs have already been visited + local visited = {} + + for _,v in ipairs(digraph.vertices) do + if not visited[v] then + -- Start a depth-first-search of the graph, starting at node n: + local stack = { v } + local component = Digraph.new { + syntactic_digraph = digraph.syntactic_digraph, + options = digraph.options + } + + while #stack >= 1 do + local tos = stack[#stack] + stack[#stack] = nil -- pop + + if not visited[tos] then + + -- Visit pos: + component:add { tos } + visited[tos] = true + + -- Push all unvisited neighbors: + for _,a in ipairs(digraph:incoming(tos)) do + local neighbor = a.tail + if not visited[neighbor] then + stack[#stack+1] = neighbor -- push + end + end + for _,a in ipairs(digraph:outgoing(tos)) do + local neighbor = a.head + if not visited[neighbor] then + stack[#stack+1] = neighbor -- push + end + end + end + end + + -- Ok, vertices will now contain all vertices reachable from n. + components[#components+1] = component + end + end + + if #components < 2 then + return { digraph } + end + + for _,c in ipairs(components) do + table.sort (c.vertices, function (u,v) return u.event.index < v.event.index end) + for _,v in ipairs(c.vertices) do + for _,a in ipairs(digraph:outgoing(v)) do + local new_a = c:connect(a.tail, a.head) + new_a.syntactic_edges = a.syntactic_edges + end + for _,a in ipairs(digraph:incoming(v)) do + local new_a = c:connect(a.tail, a.head) + new_a.syntactic_edges = a.syntactic_edges + end + end + end + + return components +end + + + + +-- Handling of component order +-- +-- LayoutPipeline are ordered according to a function that is stored in +-- a key of the |LayoutPipeline.component_ordering_functions| table +-- whose name is the graph option |component order|. +-- +-- @param component_order An ordering method +-- @param subgraphs A list of to-be-sorted subgraphs + +function LayoutPipeline.sortComponents(component_order, subgraphs) + if component_order then + local f = LayoutPipeline.component_ordering_functions[component_order] + if f then + table.sort (subgraphs, f) + end + end +end + + +-- Right now, we hardcode the functions here. Perhaps make this +-- dynamic in the future. Could easily be done on the tikzlayer, +-- acutally. + +LayoutPipeline.component_ordering_functions = { + ["increasing node number"] = + function (g,h) + if #g.vertices == #h.vertices then + return g.vertices[1].event.index < h.vertices[1].event.index + else + return #g.vertices < #h.vertices + end + end, + ["decreasing node number"] = + function (g,h) + if #g.vertices == #h.vertices then + return g.vertices[1].event.index < h.vertices[1].event.index + else + return #g.vertices > #h.vertices + end + end, + ["by first specified node"] = nil, +} + + + + +local function compute_rotated_bb(vertices, angle, sep, bb) + + local r = Transform.new_rotation(-angle) + + for _,v in ipairs(vertices) do + -- Find the rotated bounding box field, + local t = Transform.concat(r,Transform.new_shift(v.pos.x, v.pos.y)) + + local min_x = math.huge + local max_x = -math.huge + local min_y = math.huge + local max_y = -math.huge + + for _,e in ipairs(v.path) do + if type(e) == "table" then + local c = e:clone() + c:apply(t) + + min_x = math.min (min_x, c.x) + max_x = math.max (max_x, c.x) + min_y = math.min (min_y, c.y) + max_y = math.max (max_y, c.y) + end + end + + -- Enlarge by sep: + min_x = min_x - sep + max_x = max_x + sep + min_y = min_y - sep + max_y = max_y + sep + + local _,_,_,_,c_x,c_y = v:boundingBox() + local center = Coordinate.new(c_x,c_y) + + center:apply(t) + + bb[v].min_x = min_x + bb[v].max_x = max_x + bb[v].min_y = min_y + bb[v].max_y = max_y + bb[v].c_y = center.y + end +end + + + +--- +-- This internal function packs the components of a graph. See +-- Section~\ref{subsection-gd-component-packing} for details. +-- +-- @param graph The graph +-- @param components A list of components + +function LayoutPipeline.packComponents(syntactic_digraph, components) + + local vertices = Storage.newTableStorage() + local bb = Storage.newTableStorage() + + -- Step 1: Preparation, rotation to target direction + local sep = syntactic_digraph.options['component sep'] + local angle = syntactic_digraph.options['component direction']/180*math.pi + + local mark = {} + for _,c in ipairs(components) do + + -- Setup the lists of to-be-considered nodes + local vs = {} + for _,v in ipairs(c.vertices) do + vs [#vs + 1] = v + end + + for _,a in ipairs(c.arcs) do + for _,p in ipairs(a:pointCloud()) do + vs [#vs + 1] = Vertex.new { pos = p } + end + end + vertices[c] = vs + + compute_rotated_bb(vs, angle, sep/2, bb) + end + + local x_shifts = { 0 } + local y_shifts = {} + + -- Step 2: Vertical alignment + for i,c in ipairs(components) do + local max_max_y = -math.huge + local max_center_y = -math.huge + local min_min_y = math.huge + local min_center_y = math.huge + + for _,v in ipairs(c.vertices) do + local info = bb[v] + max_max_y = math.max(info.max_y, max_max_y) + max_center_y = math.max(info.c_y, max_center_y) + min_min_y = math.min(info.min_y, min_min_y) + min_center_y = math.min(info.c_y, min_center_y) + end + + -- Compute alignment line + local valign = syntactic_digraph.options['component align'] + local line + if valign == "counterclockwise bounding box" then + line = max_max_y + elseif valign == "counterclockwise" then + line = max_center_y + elseif valign == "center" then + line = (max_max_y + min_min_y) / 2 + elseif valign == "clockwise" then + line = min_center_y + elseif valign == "first node" then + line = bb[c.vertices[1]].c_y + else + line = min_min_y + end + + -- Overruled? + for _,v in ipairs(c.vertices) do + if v.options['align here'] then + line = bb[v].c_y + break + end + end + + -- Ok, go! + y_shifts[i] = -line + + -- Adjust nodes: + for _,v in ipairs(vertices[c]) do + local info = bb[v] + info.min_y = info.min_y - line + info.max_y = info.max_y - line + info.c_y = info.c_y - line + end + end + + -- Step 3: Horizontal alignment + local y_values = {} + + for _,c in ipairs(components) do + for _,v in ipairs(vertices[c]) do + local info = bb[v] + y_values[#y_values+1] = info.min_y + y_values[#y_values+1] = info.max_y + y_values[#y_values+1] = info.c_y + end + end + + table.sort(y_values) + + local y_ranks = {} + local right_face = {} + for i=1,#y_values do + y_ranks[y_values[i]] = i + right_face[i] = -math.huge + end + + + + for i=1,#components-1 do + -- First, update right_face: + local touched = {} + + for _,v in ipairs(vertices[components[i]]) do + local info = bb[v] + local border = info.max_x + + for i=y_ranks[info.min_y],y_ranks[info.max_y] do + touched[i] = true + right_face[i] = math.max(right_face[i], border) + end + end + + -- Fill up the untouched entries: + local right_max = -math.huge + for i=1,#y_values do + if not touched[i] then + -- Search for next and previous touched + local interpolate = -math.huge + for j=i+1,#y_values do + if touched[j] then + interpolate = math.max(interpolate,right_face[j] - (y_values[j] - y_values[i])) + break + end + end + for j=i-1,1,-1 do + if touched[j] then + interpolate = math.max(interpolate,right_face[j] - (y_values[i] - y_values[j])) + break + end + end + right_face[i] = math.max(interpolate,right_face[i]) + end + right_max = math.max(right_max, right_face[i]) + end + + -- Second, compute the left face + local touched = {} + local left_face = {} + for i=1,#y_values do + left_face[i] = math.huge + end + for _,v in ipairs(vertices[components[i+1]]) do + local info = bb[v] + local border = info.min_x + + for i=y_ranks[info.min_y],y_ranks[info.max_y] do + touched[i] = true + left_face[i] = math.min(left_face[i], border) + end + end + + -- Fill up the untouched entries: + local left_min = math.huge + for i=1,#y_values do + if not touched[i] then + -- Search for next and previous touched + local interpolate = math.huge + for j=i+1,#y_values do + if touched[j] then + interpolate = math.min(interpolate,left_face[j] + (y_values[j] - y_values[i])) + break + end + end + for j=i-1,1,-1 do + if touched[j] then + interpolate = math.min(interpolate,left_face[j] + (y_values[i] - y_values[j])) + break + end + end + left_face[i] = interpolate + end + left_min = math.min(left_min, left_face[i]) + end + + -- Now, compute the shift. + local shift = -math.huge + + if syntactic_digraph.options['component packing'] == "rectangular" then + shift = right_max - left_min + else + for i=1,#y_values do + shift = math.max(shift, right_face[i] - left_face[i]) + end + end + + -- Adjust nodes: + x_shifts[i+1] = shift + for _,v in ipairs(vertices[components[i+1]]) do + local info = bb[v] + info.min_x = info.min_x + shift + info.max_x = info.max_x + shift + end + end + + -- Now, rotate shifts + for i,c in ipairs(components) do + local x = x_shifts[i]*math.cos(angle) - y_shifts[i]*math.sin(angle) + local y = x_shifts[i]*math.sin(angle) + y_shifts[i]*math.cos(angle) + + for _,v in ipairs(vertices[c]) do + v.pos.x = v.pos.x + x + v.pos.y = v.pos.y + y + end + end +end + + + + + + + +-- +-- Store for each begin/end event the index of +-- its corresponding end/begin event +-- +-- @param events An event list + +prepare_events = + function (events) + local stack = {} + + for i=1,#events do + if events[i].kind == "begin" then + stack[#stack + 1] = i + elseif events[i].kind == "end" then + local tos = stack[#stack] + stack[#stack] = nil -- pop + + events[tos].end_index = i + events[i].begin_index = tos + end + end + end + + + +--- +-- Cut the edges. This function handles the ``cutting'' of edges. The +-- idea is that every edge is a path going from the center of the from +-- node to the center of the target node. Now, we intersect this path +-- with the path of the start node and cut away everything before this +-- intersection. Likewise, we intersect the path with the head node +-- and, again, cut away everything following the intersection. +-- +-- These cuttings are not done if appropriate options are set. + +function LayoutPipeline.cutEdges(graph) + + for _,a in ipairs(graph.arcs) do + for _,e in ipairs(a.syntactic_edges) do + local p = e.path + p:makeRigid() + local orig = p:clone() + + if e.options['tail cut'] and e.tail.options['cut policy'] == "as edge requests" + or e.tail.options['cut policy'] == "all" then + + local vpath = e.tail.path:clone() + vpath:shiftByCoordinate(e.tail.pos) + + local x = p:intersectionsWith (vpath) + + if #x > 0 then + p:cutAtBeginning(x[1].index, x[1].time) + end + end + + if e.options['head cut'] and e.head.options['cut policy'] == "as edge requests" + or e.head.options['cut policy'] == "all" then + + local vpath = e.head.path:clone() + vpath:shiftByCoordinate(e.head.pos) + x = p:intersectionsWith (vpath) + if #x > 0 then + p:cutAtEnd(x[#x].index, x[#x].time) + else + -- Check whether there was an intersection with the original + --path: + local x2 = orig:intersectionsWith (vpath) + if #x2 > 0 then + -- Ok, after cutting the tail vertex, there is no longer + -- an intersection with the head vertex, but there used to + -- be one. This means that the vertices overlap and the + -- path should be ``inside'' them. Hmm... + if e.options['allow inside edges'] and #p > 1 then + local from = p[2] + local to = x2[1].point + p:clear() + p:appendMoveto(from) + p:appendLineto(to) + else + p:clear() + end + end + end + end + end + end +end + + + + + + +-- Deprecated stuff + +local Node = require "pgf.gd.deprecated.Node" +local Graph = require "pgf.gd.deprecated.Graph" +local Edge = require "pgf.gd.deprecated.Edge" +local Cluster = require "pgf.gd.deprecated.Cluster" + + + + + +local unique_count = 0 + +local function compatibility_digraph_to_graph(scope, g) + local graph = Graph.new() + + -- Graph options + graph.options = g.options + graph.orig_digraph = g + + -- Events + for i,e in ipairs(scope.events) do + graph.events[i] = e + end + + -- Nodes + for _,v in ipairs(g.vertices) do + if not v.name then + -- compat needs unique name + v.name = "auto generated node nameINTERNAL" .. unique_count + unique_count = unique_count + 1 + end + local minX, minY, maxX, maxY = v:boundingBox() + local node = Node.new{ + name = v.name, + tex = { + tex_node = v.tex and v.tex.stored_tex_box_number, + shape = v.shape, + minX = minX, + maxX = maxX, + minY = minY, + maxY = maxY, + }, + options = v.options, + event_index = v.event.index, + index = v.event.index, + orig_vertex = v, + } + graph:addNode(node) + graph.events[v.event.index or (#graph.events+1)] = { kind = 'node', parameters = node } + end + + -- Edges + local mark = Storage.new() + for _,a in ipairs(g.arcs) do + local da = g.syntactic_digraph:arc(a.tail, a.head) + if da then + for _,m in ipairs(da.syntactic_edges) do + if not mark[m] then + mark[m] = true + local from_node = graph:findNode(da.tail.name) + local to_node = graph:findNode(da.head.name) + local edge = graph:createEdge(from_node, to_node, m.direction, nil, m.options, nil) + edge.event_index = m.event.index + edge.orig_m = m + graph.events[m.event.index] = { kind = 'edge', parameters = edge } + end + end + end + local da = g.syntactic_digraph:arc(a.head, a.tail) + if da then + for _,m in ipairs(da.syntactic_edges) do + if not mark[m] then + mark[m] = true + local from_node = graph:findNode(da.tail.name) + local to_node = graph:findNode(da.head.name) + local edge = graph:createEdge(from_node, to_node, m.direction, nil, m.options, nil) + edge.event_index = m.event.index + edge.orig_m = m + graph.events[m.event.index] = { kind = 'edge', parameters = edge } + end + end + end + end + + table.sort(graph.edges, function(e1,e2) return e1.event_index < e2.event_index end) + for _,n in ipairs (graph.nodes) do + table.sort(n.edges, function(e1,e2) return e1.event_index < e2.event_index end) + end + + + -- Clusters + for _, c in ipairs(scope.collections['same layer'] or {}) do + cluster = Cluster.new("cluster" .. unique_count) + unique_count = unique_count+1 + graph:addCluster(cluster) + for _,v in ipairs(c.vertices) do + if g:contains(v) then + cluster:addNode(graph:findNode(v.name)) + end + end + end + + return graph +end + + +local function compatibility_graph_to_digraph(graph) + for _,n in ipairs(graph.nodes) do + n.orig_vertex.pos.x = n.pos.x + n.orig_vertex.pos.y = n.pos.y + end + for _,e in ipairs(graph.edges) do + if #e.bend_points > 0 then + local c = {} + for _,x in ipairs(e.bend_points) do + c[#c+1] = Coordinate.new (x.x, x.y) + end + e.orig_m:setPolylinePath(c) + end + end +end + + + + + +function LayoutPipeline.runOldGraphModel(scope, digraph, algorithm_class, algorithm) + + local graph = compatibility_digraph_to_graph(scope, digraph) + + algorithm.graph = graph + graph:registerAlgorithm(algorithm) + + -- If requested, remove loops + if algorithm_class.preconditions.loop_free then + Simplifiers:removeLoopsOldModel(algorithm) + end + + -- If requested, collapse multiedges + if algorithm_class.preconditions.simple then + Simplifiers:collapseMultiedgesOldModel(algorithm) + end + + if #graph.nodes > 1 then + -- Main run of the algorithm: + algorithm:run () + end + + -- If requested, expand multiedges + if algorithm_class.preconditions.simple then + Simplifiers:expandMultiedgesOldModel(algorithm) + end + + -- If requested, restore loops + if algorithm_class.preconditions.loop_free then + Simplifiers:restoreLoopsOldModel(algorithm) + end + + compatibility_graph_to_digraph(graph) +end + + + + +-- Done + +return LayoutPipeline
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/NodeAnchors.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/NodeAnchors.lua new file mode 100644 index 00000000000..b159f21eef2 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/NodeAnchors.lua @@ -0,0 +1,174 @@ +-- 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/control/NodeAnchors.lua,v 1.3 2013/10/08 09:21:17 tantau Exp $ + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + + + +--- +-- @section subsection {Anchoring Edges} +-- +-- \label{section-gd-anchors} +-- +-- When a graph has been layed out completely, the edges between the +-- nodes must be drawn. Conceptually, an edge is ``between two +-- nodes,'' but when we actually draw the node, we do not really want +-- the edge's path to start ``in the middle'' of the node; rather, we +-- want it to start ``on the border'' and also end there. +-- +-- Normally, computing such border positions for nodes is something we +-- would leave to the so-called display layer (which is typically +-- \tikzname\ and \tikzname\ is reasonably good at computing border +-- positions). However, different display layers may behave +-- differently here and even \tikzname\ fails when the node shapes are +-- very involved and the paths also. +-- +-- For these reasons, computing the anchor positions where edges start +-- and end is done inside the graph drawing system. As a user, you +-- specify a |tail anchor| and a |head anchor|, which are points +-- inside the tail and head nodes, respectively. The edge path will +-- then start and end at these points, however, they will usually be +-- shortened so that they actually start and end on the intersection +-- of the edge's path with the nodes' paths. + + +--- + +declare { + key = "tail anchor", + type = "string", + initial = "", + + summary = [[" + Specifies where in the tail vertex the edge should start. + "]], + + documentation = [[" + This is either a string or a number, interpreted as an angle + (with 90 meaning ``up''). If it is a string, when the start of + the edge is computed, we try to look up the anchor in the tail + vertex's table of anchors (some anchors get installed in this + table by the display system). If it is not found, we test + whether it is one of the special ``direction anchors'' like + |north| or |south east|. If so, we convert them into points on + the border of the node that lie in the direction of a line + starting at the center to a point on the bounding box of the + node in the designated direction. Finally, if the anchor is a + number, we use a point on the border of the node that is on a + line from the center in the specified direction. + + If the anchor is set to the empty string (which is the default), + the anchor is interpreted as the |center| anchor inside the + graph drawing system. However, a display system may choose to + make a difference between the |center| anchor and an empty + anchor (\tikzname\ does: for options like |bend left| if the + anchor is empty, the bend line starts at the border of the node, + while for the anchor set explicitly to |center| it starts at the + center). + + Note that graph drawing algorithms need not take the + setting of this option into consideration. However, the final + rendering of the edge will always take it into consideration + (only, the setting may not be very sensible if the algorithm + ignored it). + "]] +} + +--- + +declare { + key = "head anchor", + type = "string", + initial = "", + + summary = "See |tail anchor|" +} + + +--- + +declare { + key = "tail cut", + type = "boolean", + initial = true, + + summary = [[" + Decides whether the tail of an edge is ``cut'', meaning + that the edge's path will be shortened at the beginning so that + it starts only of the node's border rather than at the exact + position of the |tail anchor|, which may be inside the node. + "]] +} + + +--- + +declare { + key = "head cut", + type = "boolean", + initial = true, + + summary = "See |tail cut|." +} + + +--- + +declare { + key = "cut policy", + type = "string", + initial = "as edge requests", + + summary = "The policy for cutting edges entering or leaving a node.", + + documentation = [[" + This option is important for nodes only. It can have three + possible values: + \begin{itemize} + \item |as edge requests| Whether or not an edge entering or + leaving the node is cut depends on the setting of the edge's + |tail cut| and |head cut| options. This is the default. + \item |all| All edges entering or leaving the node are cut, + regardless of the edges' cut values. + \item |none| No edge entering or leaving the node is cut, + regardless of the edges' cut values. + \end{itemize} + "]] +} + + +--- +declare { + key = "allow inside edges", + type = "boolean", + initial = "true", + + summary = "Decides whether an edge between overlapping nodes should be drawn.", + + documentation = [[" + If two vertices overlap, it may happen that when you draw an + edge between them, this edges would be completely inside the two + vertices. In this case, one could either not draw them or one + could draw a sort of ``inside edge''. + "]], + + examples = { [[" + \tikz \graph [no layout, nodes={draw, minimum size=20pt}] { + a [x=0, y=0] -- b [x=15pt, y=10pt] -- c[x=40pt] + }; + "]], [[" + \tikz \graph [no layout, nodes={draw, minimum size=20pt}, + allow inside edges=false] { + a [x=0, y=0] -- b [x=15pt, y=10pt] -- c[x=40pt] + }; + "]] + } +}
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Orientation.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Orientation.lua new file mode 100644 index 00000000000..a3205a06dbe --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Orientation.lua @@ -0,0 +1,314 @@ +-- 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/control/Orientation.lua,v 1.2 2013/05/23 20:01:26 tantau Exp $ + + + + +--- +-- @section subsection {Orienting a Graph} +-- +-- \label{subsection-library-graphdrawing-standard-orientation} +-- +-- Just as a graph drawing algorithm cannot know \emph{where} a graph +-- should be placed on a page, it is also often unclear which +-- \emph{orientation} it should have. Some graphs, like trees, have a +-- natural direction in which they ``grow'', but for an ``arbitrary'' +-- graph the ``natural orientation'' is, well, arbitrary. +-- +-- There are two ways in which you can specify an orientation: First, +-- you can specify that the line from a certain vertex to another +-- vertex should have a certain slope. How these vertices and slopes +-- are specified in explained momentarily. Second, you can specify a +-- so-called ``growth direction'' for trees. +-- +-- @end + + +-- Namespace +require("pgf.gd.control").Orientation = Orientation + + + +-- Imports +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + + +--- + +declare { + key = "orient", + type = "direction", + default = 0, + + summary = [[" + This key specifies that the straight line from the |orient tail| to + the |orient head| should be at an angle of \meta{direction} relative to + the right-going $x$-axis. Which vertices are used as tail an head + depends on where the |orient| option is encountered: When used with + an edge, the tail is the edge's tail und the head is the edge's + head. When used with a node, the tail or the head must be specified + explicitly and the node is used as the node missing in the + specification. When used with a graph as a whole, both the head and + tail nodes must be specified explicitly. + "]], + documentation = [[" + Note that the \meta{direction} is independent of the actual to-path + of an edge, which might define a bend or more complicated shapes. For + instance, a \meta{angle} of |45| requests that the end node is ``up + and right'' relative to the start node. + + You can also specify the standard direction texts |north| or |south east| + and so forth as \meta{direction} and also |up|, |down|, |left|, and |right|. Also, you + can specify |-| for ``right'' and \verb!|! for ``down.'' + "]], + examples = { + [[" + \tikz \graph [spring layout] + { + a -- { b, c, d, e -- {f, g, h} }; + h -- [orient=30] a; + }; + "]], + [[" + \tikz \graph [spring layout] + { + a -- { b, c, d[> orient=right], e -- {f, g, h} }; + h -- a; + }; + "]] + } +} + + +--- + +declare { + key = "orient'", + type = "direction", + default = 0, + + summary = [[" + Same as |orient|, only the rest of the graph should be + flipped relative to the connection line. + "]], + examples = [[" + \tikz \graph [spring layout] + { + a -- { b, c, d[> orient'=right], e -- {f, g, h} }; + h -- a; + }; + "]] +} + +--- + +declare { + key = "orient tail", + type = "string", + + summary = [[" + Specifies the tail vertex for the orientation of a graph. See + |orient| for details. + "]], + examples = { + [[" + \tikz \graph [spring layout] { + a [orient=|, orient tail=f] -- { b, c, d, e -- {f, g, h} }; + { h, g } -- a; + }; + "]], + [[" + \tikz \graph [spring layout] { + a [orient=down, orient tail=h] -- { b, c, d, e -- {f, g, h} }; + { h, g } -- a; + }; + "]] + } +} + + + + + +--- + +declare { + key = "orient head", + type = "string", + + summary = [[" + Specifies the head vertex for the orientation of a graph. See + |orient| for details. + "]], + examples = { + [[" + \tikz \graph [spring layout] + { + a [orient=|, orient head=f] -- { b, c, d, e -- {f, g, h} }; + { h, g } -- a; + }; + "]], + [[" + \tikz \graph [spring layout] { a -- b -- c -- a }; + \tikz \graph [spring layout, orient=10, + orient tail=a, orient head=b] { a -- b -- c -- a }; + "]] + } +} + +--- + +declare { + key = "horizontal", + type = "string", + + summary = [[" + A shorthand for specifying |orient tail|, |orient head| and + |orient=0|. The tail will be everything before the part ``| to |'' + and the head will be everything following it. + "]], + examples = [[" + \tikz \graph [spring layout] { a -- b -- c -- a }; + \tikz \graph [spring layout, horizontal=a to b] { a -- b -- c -- a }; + "]] +} + + + + +--- + +declare { + key = "horizontal'", + type = "string", + + summary = [[" + Like |horizontal|, but with a flip. + "]] +} + + + + + + + +--- + +declare { + key = "vertical", + type = "string", + + summary = [[" + A shorthand for specifying |orient tail|, |orient head| and + |orient=-90|. + "]], + examples = [[" + \tikz \graph [spring layout] { a -- b -- c -- a }; + \tikz \graph [spring layout, vertical=a to b] { a -- b -- c -- a }; + "]] +} + + + + + +--- + +declare { + key = "vertical'", + type = "string", + + summary = [[" + Like |vertical|, but with a flip. + "]] +} + + + +--- + +declare { + key = "grow", + type = "direction", + + summary = [[" + This key specifies in which direction the neighbors of a node + ``should grow.'' For some graph drawing algorithms, especially for + those that layout trees, but also for those that produce layered + layouts, there is a natural direction in which the ``children'' of + a node should be placed. For instance, saying |grow=down| will cause + the children of a node in a tree to be placed in a left-to-right + line below the node (as always, you can replace the \meta{angle} + by direction texts). The children are requested to be placed in a + counter-clockwise fashion, the |grow'| key will place them in a + clockwise fashion. + "]], + documentation = [[" + Note that when you say |grow=down|, it is not necessarily the case + that any particular node is actually directly below the current + node; the key just requests that the direction of growth is + downward. + + In principle, you can specify the direction of growth for each node + individually, but do not count on graph drawing algorithms to + honour these wishes. + + When you give the |grow=right| key to the graph as a whole, it will + be applied to all nodes. This happens to be exactly what you want: + "]], + examples = { + [[" + \tikz \graph [layered layout, sibling distance=5mm] + { + a [grow=right] -- { b, c, d, e -- {f, g, h} }; + { h, g } -- a; + }; + "]], + [[" + \tikz \graph [layered layout, grow=right, sibling distance=5mm] + { + a -- { b, c, d, e -- {f, g, h} }; + { h, g } -- a; + }; + "]], + [[" + \tikz + \graph [layered layout, grow=-80] + { + {a,b,c} --[complete bipartite] {e,d,f} + --[complete bipartite] {g,h,i}; + }; + "]] + } +} + + +--- + +declare { + key = "grow'", + type = "direction", + + summary = "Same as |grow|, only with the children in clockwise order.", + examples = [[" + \tikz \graph [layered layout, sibling distance=5mm] + { + a [grow'=right] -- { b, c, d, e -- {f, g, h} }; + { h, g } -- a; + }; + "]] +} + + +-- Done + +return Orientation
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Sublayouts.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Sublayouts.lua new file mode 100644 index 00000000000..c10df7a0696 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Sublayouts.lua @@ -0,0 +1,536 @@ +-- 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/control/Sublayouts.lua,v 1.4 2013/09/23 20:04:26 tantau Exp $ + +local function full_print(g, pref) + local s = "" + + for _,v in ipairs(g.vertices) do + s = s .. tostring(v) .. "[" .. tostring(v.pos) .. "]\n " + end + + s = s .. "\n" + + for _,a in ipairs(g.arcs) do + for _,e in ipairs(a.syntactic_edges) do + s = s .. tostring(e) .. "(" .. tostring(e.path) .. ")\n" + end + end + + pgf.debug((pref or "") .. s) +end + + +--- +-- The |Sublayouts| module handles graphs for which multiple layouts are defined. +-- +-- Please see Section~\ref{section-gd-sublayouts} for an overview of +-- sublayouts. +-- + +local Sublayouts = {} + +-- Namespace +require("pgf.gd.control").Sublayouts = Sublayouts + + +-- Includes + +local Digraph = require "pgf.gd.model.Digraph" +local Vertex = require "pgf.gd.model.Vertex" +local Coordinate = require "pgf.gd.model.Coordinate" +local Path = require "pgf.gd.model.Path" + +local lib = require "pgf.gd.lib" + +local InterfaceCore = require "pgf.gd.interface.InterfaceCore" + +local Storage = require "pgf.gd.lib.Storage" + + + +-- Storages + +local subs = Storage.newTableStorage() +local already_nudged = Storage.new() +local positions = Storage.newTableStorage() + + + + +-- Offset a node by an offset. This will \emph{also} offset all +-- subnodes, which arise from sublayouts. +-- +-- @param vertex A vertex +-- @param pos A offset +-- +local function offset_vertex(v, delta) + v.pos:shiftByCoordinate(delta) + for _,sub in ipairs(subs[v]) do + offset_vertex(sub, delta) + end +end + + +-- Nudge positioning. You can call this function several times on the +-- same graph; nudging will be done only once. +-- +-- @param graph A graph +-- +local function nudge(graph) + for _,v in ipairs(graph.vertices) do + local nudge = v.options['nudge'] + if nudge and not already_nudged[v] then + offset_vertex(v, nudge) + already_nudged[v] = true + end + end +end + + + +-- Create subgraph nodes +-- +-- @param scope A scope +-- @param syntactic_digraph The syntactic digraph. +-- @param test Only for vertices whose subgraph collection passes this test will we create subgraph nodes +local function create_subgraph_node(scope, syntactic_digraph, vertex) + + local subgraph_collection = vertex.subgraph_collection + local binding = InterfaceCore.binding + + local cloud = {} + -- Add all points of n's collection, except for v itself, to the cloud: + for _,v in ipairs(subgraph_collection.vertices) do + if vertex ~= v then + assert(syntactic_digraph:contains(v), "the layout must contain all nodes of the subgraph") + for _,p in ipairs(v.path) do + if type(p) == "table" then + cloud[#cloud+1] = p + v.pos + end + end + end + end + for _,e in ipairs(subgraph_collection.edges) do + for _,p in ipairs(e.path) do + if type(p) == "table" then + cloud[#cloud+1] = p:clone() + end + end + end + local x_min, y_min, x_max, y_max, c_x, c_y = Coordinate.boundingBox(cloud) + + -- Shift the graph so that it is centered on the origin: + for _,p in ipairs(cloud) do + p:unshift(c_x,c_y) + end + + local o = vertex.subgraph_info.generated_options + + o[#o+1] = { key = "subgraph point cloud", value = table.concat(lib.imap(cloud, tostring)) } + o[#o+1] = { key = "subgraph bounding box height", value = tostring(y_max-y_min) .. "pt" } + o[#o+1] = { key = "subgraph bounding box width", value = tostring(x_max-x_min) .. "pt" } + + -- And now, the "grand call": + binding:createVertex(vertex.subgraph_info) + + -- Shift it were it belongs + vertex.pos:shift(c_x,c_y) + + -- Remember all the subnodes for nudging and regardless + -- positioning + local s = {} + for _,v in ipairs(subgraph_collection.vertices) do + if v ~= vertex then + s[#s+1] = v + end + end + + subs[vertex] = s +end + + +-- Tests whether two graphs have a vertex in common +local function intersection(g1, g2) + for _,v in ipairs(g1.vertices) do + if g2:contains(v) then + return v + end + end +end + +-- Tests whether a graph is a set is a subset of another +local function special_vertex_subset(vertices, graph) + for _,v in ipairs(vertices) do + if not graph:contains(v) and not (v.kind == "subgraph node") then + return false + end + end + return true +end + + + +--- +-- The layout recursion. See \ref{section-gd-sublayouts} for details. +-- +-- @param scope The graph drawing scope +-- @param layout The to-be-laid-out collection +-- @param fun The to-be-called function for laying out the graph. +-- processed. This stack is important when a new syntactic vertex is +-- added by the algorithm: In this case, this vertex is added to all +-- layouts on this stack. +-- +-- @return A laid out graph. + +function Sublayouts.layoutRecursively(scope, layout, fun) + + -- Step 1: Iterate over all sublayouts of the current layout: + local resulting_graphs = {} + local loc = Storage.new() + + -- Now, iterate over all sublayouts + for i,child in ipairs(layout:childrenOfKind(InterfaceCore.sublayout_kind)) do + resulting_graphs[i] = Sublayouts.layoutRecursively(scope, child, fun) + loc[resulting_graphs[i]] = child + end + + -- Step 2: Run the merge process: + local merged_graphs = {} + + while #resulting_graphs > 0 do + + local n = #resulting_graphs + + -- Setup marked array: + local marked = {} + for i=1,n do + marked[i] = false + end + + -- Mark first graph and copy everything from there + marked[1] = true + local touched = Storage.new() + for _,v in ipairs(resulting_graphs[1].vertices) do + v.pos = positions[v][resulting_graphs[1]] + touched[v] = true + end + + -- Repeatedly find a node that is connected to a marked node: + local i = 1 + while i <= n do + if not marked[i] then + for j=1,n do + if marked[j] then + local v = intersection(resulting_graphs[i], resulting_graphs[j]) + if v then + -- Aha, they intersect at vertex v + + -- Mark the i-th graph: + marked[i] = true + connected_some_graph = true + + -- Shift the i-th graph: + local x_offset = v.pos.x - positions[v][resulting_graphs[i]].x + local y_offset = v.pos.y - positions[v][resulting_graphs[i]].y + + for _,u in ipairs(resulting_graphs[i].vertices) do + if not touched[u] then + touched[u] = true + u.pos = positions[u][resulting_graphs[i]]:clone() + u.pos:shift(x_offset, y_offset) + + for _,a in ipairs(resulting_graphs[i]:outgoing(u)) do + for _,e in ipairs(a.syntactic_edges) do + for _,p in ipairs(e.path) do + if type(p) == "table" then + p:shift(x_offset, y_offset) + end + end + end + end + end + end + + -- Restart + i = 0 + break + end + end + end + end + i = i + 1 + end + + -- Now, we can collapse all marked graphs into one graph: + local merge = Digraph.new {} + merge.syntactic_digraph = merge + local remaining = {} + + -- Add all vertices and edges: + for i=1,n do + if marked[i] then + merge:add (resulting_graphs[i].vertices) + for _,a in ipairs(resulting_graphs[i].arcs) do + local ma = merge:connect(a.tail,a.head) + for _,e in ipairs(a.syntactic_edges) do + ma.syntactic_edges[#ma.syntactic_edges+1] = e + end + end + else + remaining[#remaining + 1] = resulting_graphs[i] + end + end + + -- Remember the first layout this came from: + loc[merge] = loc[resulting_graphs[1]] + + -- Restart with rest: + merged_graphs[#merged_graphs+1] = merge + + resulting_graphs = remaining + end + + -- Step 3: Run the algorithm on the layout: + + local class = layout.options.algorithm_phases.main + assert (type(class) == "table", "algorithm selection failed") + + local algorithm = class + local uncollapsed_subgraph_nodes = lib.imap( + scope.collections[InterfaceCore.subgraph_node_kind] or {}, + function (c) + if c.parent_layout == layout then + return c.subgraph_node + end + end) + + + -- Create a new syntactic digraph: + local syntactic_digraph = Digraph.new { + options = layout.options + } + + syntactic_digraph.syntactic_digraph = syntactic_digraph + + -- Copy all vertices and edges from the collection... + syntactic_digraph:add (layout.vertices) + for _,e in ipairs(layout.edges) do + syntactic_digraph:add {e.head, e.tail} + local arc = syntactic_digraph:connect(e.tail, e.head) + arc.syntactic_edges[#arc.syntactic_edges+1] = e + end + + -- Find out which subgraph nodes can be created now and make them part of the merged graphs + for i=#uncollapsed_subgraph_nodes,1,-1 do + local v = uncollapsed_subgraph_nodes[i] + local vertices = v.subgraph_collection.vertices + -- Test, if all vertices of the subgraph are in one of the merged graphs. + for _,g in ipairs(merged_graphs) do + if special_vertex_subset(vertices, g) then + -- Ok, we can create a subgraph now + create_subgraph_node(scope, syntactic_digraph, v) + -- Make it part of the collapse! + g:add{v} + -- Do not consider again + uncollapsed_subgraph_nodes[i] = false + break + end + end + end + + -- Collapse the nodes that are part of a merged_graph + local collapsed_vertices = {} + for _,g in ipairs(merged_graphs) do + + local intersection = {} + for _,v in ipairs(g.vertices) do + if syntactic_digraph:contains(v) then + intersection[#intersection+1] = v + end + end + if #intersection > 0 then + -- Compute bounding box of g (this should actually be the convex + -- hull) Hmm...: + local array = {} + for _,v in ipairs(g.vertices) do + local min_x, min_y, max_x, max_y = v:boundingBox() + array[#array+1] = Coordinate.new(min_x + v.pos.x, min_y + v.pos.y) + array[#array+1] = Coordinate.new(max_x + v.pos.x, max_y + v.pos.y) + end + for _,a in ipairs(g.arcs) do + for _,e in ipairs(a.syntactic_edges) do + for _,p in ipairs(e.path) do + if type(p) == "table" then + array[#array+1] = p + end + end + end + end + local x_min, y_min, x_max, y_max, c_x, c_y = Coordinate.boundingBox(array) + + -- Shift the graph so that it is centered on the origin: + for _,v in ipairs(g.vertices) do + v.pos:unshift(c_x,c_y) + end + for _,a in ipairs(g.arcs) do + for _,e in ipairs(a.syntactic_edges) do + for _,p in ipairs(e.path) do + if type(p) == "table" then + p:unshift(c_x,c_y) + end + end + end + end + + x_min = x_min - c_x + x_max = x_max - c_x + y_min = y_min - c_y + y_max = y_max - c_y + + local index = loc[g].event.index + + local v = Vertex.new { + -- Standard stuff + shape = "none", + kind = "node", + path = Path.new { + "moveto", + x_min, y_min, + x_min, y_max, + x_max, y_max, + x_max, y_min, + "closepath" + }, + options = {}, + event = scope.events[index] + } + + -- Update node_event + scope.events[index].parameters = v + + local collapse_vertex = syntactic_digraph:collapse( + intersection, + v, + nil, + function (new_arc, arc) + for _,e in ipairs(arc.syntactic_edges) do + new_arc.syntactic_edges[#new_arc.syntactic_edges+1] = e + end + end) + + syntactic_digraph:remove(intersection) + collapsed_vertices[#collapsed_vertices+1] = collapse_vertex + end + end + + -- Sort the vertices + table.sort(syntactic_digraph.vertices, function(u,v) return u.event.index < v.event.index end) + + -- Should we "hide" the subgraph nodes? + local hidden_node + if not algorithm.include_subgraph_nodes then + local subgraph_nodes = lib.imap (syntactic_digraph.vertices, + function (v) if v.kind == "subgraph node" then return v end end) + + if #subgraph_nodes > 0 then + hidden_node = Vertex.new {} + syntactic_digraph:collapse(subgraph_nodes, hidden_node) + syntactic_digraph:remove (subgraph_nodes) + syntactic_digraph:remove {hidden_node} + end + end + + -- Now, we want to call the actual algorithm. This call may modify + -- the layout's vertices and edges fields, namely when new vertices + -- and edges are created. We then need to add these to our local + -- syntactic digraph. So, we remember the length of these fields + -- prior to the call and then add everything ``behind'' these + -- positions later on. + + -- Ok, everything setup! Run the algorithm... + fun(scope, algorithm, syntactic_digraph, layout) + + if hidden_node then + syntactic_digraph:expand(hidden_node) + end + + -- Now, we need to expand the collapsed vertices once more: + for i=#collapsed_vertices,1,-1 do + syntactic_digraph:expand( + collapsed_vertices[i], + function (c, v) + v.pos:shiftByCoordinate(c.pos) + end, + function (a, v) + for _,e in ipairs(a.syntactic_edges) do + for _,p in ipairs(e.path) do + if type(p) == "table" then + p:shiftByCoordinate(v.pos) + end + end + end + end + ) + for _,a in ipairs(syntactic_digraph:outgoing(collapsed_vertices[i])) do + for _,e in ipairs(a.syntactic_edges) do + for _,p in ipairs(e.path) do + if type(p) == "table" then + p:shiftByCoordinate(a.tail.pos) + p:unshiftByCoordinate(e.tail.pos) + end + end + end + end + end + syntactic_digraph:remove(collapsed_vertices) + + -- Step 4: Create the layout node if necessary + for i=#uncollapsed_subgraph_nodes,1,-1 do + if uncollapsed_subgraph_nodes[i] then + create_subgraph_node(scope, syntactic_digraph, uncollapsed_subgraph_nodes[i]) + end + end + + -- Now seems like a good time to nudge and do regardless positioning + nudge(syntactic_digraph) + + -- Step 5: Cleanup + -- Push the computed position into the storage: + for _,v in ipairs(syntactic_digraph.vertices) do + positions[v][syntactic_digraph] = v.pos:clone() + end + + return syntactic_digraph +end + + + + + +--- +-- Regardless positioning. +-- +-- @param graph A graph +-- +function Sublayouts.regardless(graph) + for _,v in ipairs(graph.vertices) do + local regardless = v.options['regardless at'] + if regardless then + offset_vertex(v, regardless - v.pos) + end + end +end + + + +-- Done + +return Sublayouts
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/library.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/library.lua new file mode 100644 index 00000000000..fbb3a33857d --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/library.lua @@ -0,0 +1,199 @@ +-- 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/control/library.lua,v 1.9 2013/05/23 20:01:26 tantau Exp $ + + +-- Load declarations from: + +require "pgf.gd.control.FineTune" +require "pgf.gd.control.Anchoring" +require "pgf.gd.control.Sublayouts" +require "pgf.gd.control.Orientation" +require "pgf.gd.control.Distances" +require "pgf.gd.control.Components" +require "pgf.gd.control.ComponentAlign" +require "pgf.gd.control.ComponentDirection" +require "pgf.gd.control.ComponentDistance" +require "pgf.gd.control.ComponentOrder" +require "pgf.gd.control.NodeAnchors" + + +local InterfaceCore = require "pgf.gd.interface.InterfaceCore" +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare +local lib = require "pgf.gd.lib" + + + +--- + +declare { + key = "nodes behind edges", + type = "boolean", + + summary = "Specifies, that nodes should be drawn behind the edges", + documentation = [[" + Once a graph drawing algorithm has determined positions for the nodes, + they are drawn \emph{before} the edges are drawn; after + all, it is hard to draw an edge between nodes when their positions + are not yet known. However, we typically want the nodes to be + rendered \emph{after} or rather \emph{on top} of the edges. For + this reason, the default behaviour is that the nodes at their + final positions are collected in a box that is inserted into the + output stream only after the edges have been drawn -- which has + the effect that the nodes will be placed ``on top'' of the + edges. + + This behaviour can be changed using this option. When the key is + invoked, nodes are placed \emph{behind} the edges. + "]], + examples = [[" + \tikz \graph [simple necklace layout, nodes={draw,fill=white}, + nodes behind edges] + { subgraph K_n [n=7], 1 [regardless at={(0,-1)}] }; + "]] +} + + +--- + +declare { + key = "edges behind nodes", + use = { + { key = "nodes behind edges", value = "false" }, + }, + + summary = [[" + This is the default placemenet of edges: Behind the nodes. + "]], + examples = [[" + \tikz \graph [simple necklace layout, nodes={draw,fill=white}, + edges behind nodes] + { subgraph K_n [n=7], 1 [regardless at={(0,-1)}] }; + "]] +} + +--- +declare { + key = "random seed", + type = "number", + initial = "42", + + summary = [[" + To ensure that the same is always shown in the same way when the + same algorithm is applied, the random is seed is reset on each call + of the graph drawing engine. To (possibly) get different results on + different runs, change this value. + "]] +} + + +--- +declare { + key = "variation", + type = "number", + use = { + { key = "random seed", value = lib.id }, + }, + summary = "An alias for |random seed|." +} + + +--- +declare { + key = "weight", + type = "number", + initial = 1, + + summary = [[" + Sets the ``weight'' of an edge or a node. For many algorithms, this + number tells the algorithm how ``important'' the edge or node is. + For instance, in a |layered layout|, an edge with a large |weight| + will be as short as possible. + "]], + examples = { + [[" + \tikz \graph [layered layout] { + a -- {b,c,d} -- e -- a; + }; + "]], + [[" + \tikz \graph [layered layout] { + a -- {b,c,d} -- e --[weight=3] a; + }; + "]] + } +} + + + +--- +declare { + key = "length", + type = "length", + initial = 1, + + summary = [[" + Sets the ``length'' of an edge. Algorithms may take this value + into account when drawing a graph. + "]], + examples = { + [[" + \tikz \graph [phylogenetic tree layout] { + a --[length=2] b --[length=1] {c,d}; + a --[length=3] e + }; + "]], + } +} + + +--- + +declare { + key = "radius", + type = "number", + initial = "0", + + summary = [[" + The radius of a circular object used in graph drawing. + "]] +} + +--- + +declare { + key = "no layout", + algorithm = { + run = + function (self) + for _,v in ipairs(self.digraph.vertices) do + if v.options['desired at'] then + v.pos.x = v.options['desired at'].x + v.pos.y = v.options['desired at'].y + end + end + end }, + summary = "This layout does nothing.", +} + + + +-- The following collection kinds are internal + +declare { + key = InterfaceCore.sublayout_kind, + layer = 0 +} + +declare { + key = InterfaceCore.subgraph_node_kind, + layer = 0 +} + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Cluster.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Cluster.lua new file mode 100644 index 00000000000..748eee9429a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Cluster.lua @@ -0,0 +1,65 @@ +-- Copyright 2011 by Jannis Pohlmann +-- 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/deprecated/Cluster.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + + +--- The Cluser class defines a model of a cluster inside a graph. +-- +-- + +local Cluster = {} +Cluster.__index = Cluster + + +-- Namespace + + + +--- TODO Jannis: Add documentation for this class. +-- +function Cluster.new(name) + local cluster = { + name = name, + nodes = {}, + contains_node = {}, + } + setmetatable(cluster, Cluster) + return cluster +end + + + +function Cluster:getName() + return self.name +end + + + +function Cluster:addNode(node) + if not self:findNode(node) then + self.contains_node[node] = true + self.nodes[#self.nodes + 1] = node + end +end + + + +function Cluster:findNode(node) + return self.contains_node[node] +end + + + + +-- Done + +return Cluster
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Edge.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Edge.lua new file mode 100644 index 00000000000..22ba62e04af --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Edge.lua @@ -0,0 +1,358 @@ +-- Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster +-- Copyright 2011 by Jannis Pohlmann +-- 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/deprecated/Edge.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + + + +--- The Edge class +-- +-- + +local Edge = {} +Edge.__index = Edge + + +-- Namespace + +local lib = require "pgf.gd.lib" + + +-- Definitions + +Edge.UNDIRECTED = "--" +Edge.LEFT = "<-" +Edge.RIGHT = "->" +Edge.BOTH = "<->" +Edge.NONE = "-!-" + + +--- Creates an edge between nodes of a graph. +-- +-- @param values Values to override default edge settings. +-- The following parameters can be set:\par +-- |nodes|: TODO \par +-- |edge_nodes|: TODO \par +-- |options|: TODO \par +-- |tikz_options|: TODO \par +-- |direction|: TODO \par +-- |bend_points|: TODO \par +-- |bend_nodes|: TODO \par +-- |reversed|: TODO \par +-- +-- @return A newly-allocated edge. +-- +function Edge.new(values) + local defaults = { + nodes = {}, + edge_nodes = '', + options = {}, + tikz_options = {}, + direction = Edge.DIRECTED, + bend_points = {}, + bend_nodes = {}, + reversed = false, + algorithmically_generated_options = {}, + index = nil, + event_index = nil, + } + setmetatable(defaults, Edge) + if values then + for k,v in pairs(values) do + defaults[k] = v + end + end + return defaults +end + + + +--- Sets the edge option \meta{name} to \meta{value}. +-- +-- @param name Name of the option to be changed. +-- @param value New value for the edge option \meta{name}. +-- +function Edge:setOption(name, value) + self.options[name] = value +end + + + +--- Returns the value of the edge option \meta{name}. +-- +-- @param name Name of the option. +-- @param graph If this optional argument is given, +-- in case the option is not set as a node parameter, +-- we try to look it up as a graph parameter. +-- +-- @return The value of the edge option \meta{name} or |nil|. +-- +function Edge:getOption(name, graph) + return lib.lookup_option(name, self, graph) +end + + + +--- Checks whether or not the edge is a loop edge. +-- +-- An edge is a loop if it one node multiple times and no other node. +-- +-- @return |true| if the edge is a loop, |false| otherwise. +-- +function Edge:isLoop() + local nodes = self.nodes + for i=1,#nodes do + if nodes[i] ~= nodes[1] then + return false + end + end + return true +end + + + +--- Returns whether or not the edge is a hyperedge. +-- +-- A hyperedge is an edge with more than two adjacent nodes. +-- +-- @return |true| if the edge is a hyperedge. |false| otherwise. +-- +function Edge:isHyperedge() + return self:getDegree() > 2 +end + + + +--- Returns all nodes of the edge. +-- +-- Instead of calling |edge:getNodes()| the nodes can alternatively be +-- accessed directly with |edge.nodes|. +-- +-- @return All edges of the node. +-- +function Edge:getNodes() + return self.nodes +end + + + +--- Returns whether or not a node is adjacent to the edge. +-- +-- @param node The node to check. +-- +-- @return |true| if the node is adjacent to the edge. |false| otherwise. +-- +function Edge:containsNode(node) + return lib.find(self.nodes, function (other) return other == node end) ~= nil +end + + + +--- If possible, adds a node to the edge. +-- +-- @param node The node to be added to the edge. +-- +function Edge:addNode(node) + table.insert(self.nodes, node) + node:addEdge(self) +end + + + +--- Gets first neighbour of the node (disregarding hyperedges). +-- +-- @param node The node which first neighbour should be returned. +-- +-- @return The first neighbour of the node. +-- +function Edge:getNeighbour(node) + if node == self.nodes[1] then + return self.nodes[#self.nodes] + else + return self.nodes[1] + end +end + + + +--- Counts the nodes on this edge. +-- +-- @return The number of nodes on the edge. +-- +function Edge:getDegree() + return #self.nodes +end + + + +function Edge:getHead() + -- by default, the head of -> edges is the last node and the head + -- of <- edges is the first node + local head_index = (self.direction == Edge.LEFT) and 1 or #self.nodes + + -- if the edge should be assumed reversed, we simply switch head and + -- tail positions + if self.reversed then + head_index = (head_index == 1) and #self.nodes or 1 + end + + return self.nodes[head_index] +end + + + +function Edge:getTail() + -- by default, the tail of -> edges is the first node and the tail + -- of <- edges is the last node + local tail_index = (self.direction == Edge.LEFT) and #self.nodes or 1 + + -- if the edge should be assumed reversed, we simply switch head + -- and tail positions + if self.reversed then + tail_index = (tail_index == 1) and #self.nodes or 1 + end + + return self.nodes[tail_index] +end + + + +--- Checks whether a node is the head of the edge. Does not work for hyperedges. +-- +-- This method only works for edges with two adjacent nodes. +-- +-- Edges may be reversed internally, so their head and tail might be switched. +-- Whether or not this internal reversal is handled by this method +-- can be specified with the optional second \meta{ignore\_reversed} parameter +-- which is |false| by default. +-- +-- @param node The node to check. +-- +-- @return True if the node is the head of the edge. +-- +function Edge:isHead(node) + local result = false + + -- by default, the head of -> edges is the last node and the head + -- of <- edges is the first node + local head_index = (self.direction == Edge.LEFT) and 1 or #self.nodes + + -- if the edge should be assumed reversed, we simply switch head and + -- tail positions + if self.reversed then + head_index = (head_index == 1) and #self.nodes or 1 + end + + -- check if the head node equals the input node + if self.nodes[head_index].name == node.name then + result = true + end + + return result +end + + + +--- Checks whether a node is the tail of the edge. Does not work for hyperedges. +-- +-- This method only works for edges with two adjacent nodes. +-- +-- Edges may be reversed internally, so their head and tail might be switched. +-- Whether or not this internal reversal is handled by this method +-- can be specified with the optional second \meta{ignore\_reversed} parameter +-- which is |false| by default. +-- +-- @param node The node to check. +-- @param ignore_reversed Optional parameter. Set this to true if reversed edges +-- should not be considered reversed for this method call. +-- +-- @return True if the node is the tail of the edge. +-- +function Edge:isTail(node, ignore_reversed) + local result = false + + -- by default, the tail of -> edges is the first node and the tail + -- of <- edges is the last node + local tail_index = (self.direction == Edge.LEFT) and #self.nodes or 1 + + -- if the edge should be assumed reversed, we simply switch head + -- and tail positions + if self.reversed then + tail_index = (tail_index == 1) and #self.nodes or 1 + end + + -- check if the tail node equals the input node + if self.nodes[tail_index].name == node.name then + result = true + end + + return result +end + + + +--- Copies an edge (preventing accidental use). +-- +-- The nodes of the edge are not preserved and have to be added +-- to the copy manually if necessary. +-- +-- @return Shallow copy of the edge. +-- +function Edge:copy() + local result = lib.copy(self, Edge.new()) + result.nodes = {} + return result + end + + + + +local function reverse_values(source) + local copy = {} + for i = 1,#source do + copy[i] = source[#source-i+1] + end + return copy +end + + +--- Returns a readable string representation of the edge. +-- +-- @ignore This should not appear in the documentation. +-- +-- @return String representation of the edge. +-- +function Edge:__tostring() + local result = "Edge(" .. self.direction .. ", reversed = " .. tostring(self.reversed) .. ", " + if #self.nodes > 0 then + local node_strings = lib.imap(self.nodes, function (node) return node.name end) + result = result .. table.concat(node_strings, ', ') + end + --return result .. ")" + + -- Note: the following lines generate a shorter string representation + -- of the edge that is more readable and can be used for debugging. + -- So please don't remove this: + -- + local node_strings = lib.imap(self.nodes, function (node) return node.name end) + if self.reversed then + return table.concat(reverse_values(node_strings), ' ' .. self.direction .. ' ') + else + return table.concat(node_strings, ' ' .. self.direction .. ' ') + end +end + + + +-- Done + +return Edge
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Graph.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Graph.lua new file mode 100644 index 00000000000..43b886787c4 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Graph.lua @@ -0,0 +1,396 @@ +-- Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster +-- Copyright 2011 by Jannis Pohlmann +-- 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/deprecated/Graph.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + + + +--- The Graph class +-- +-- + +local Graph = {} +Graph.__index = Graph + + +-- Namespace + +-- Imports +local Edge = require "pgf.gd.deprecated.Edge" + +local lib = require "pgf.gd.lib" + + +--- Creates a new graph. +-- +-- @param values Values to override default graph settings. +-- The following parameters can be set:\par +-- |nodes|: The nodes of the graph.\par +-- |edges|: The edges of the graph.\par +-- |clusters|: The node clusters of the graph.\par +-- |options|: A table of node options passed over from \tikzname. +-- |events|: A sequence of events signaled during the graph specification. +-- +-- @return A newly-allocated graph. +-- +function Graph.new(values) + local defaults = { + nodes = {}, + edges = {}, + clusters = {}, + options = {}, + events = {}, + } + setmetatable(defaults, Graph) + if values then + for k,v in pairs(values) do + defaults[k] = v + end + end + return defaults +end + + + +--- Prepares a graph for an algorithm. +-- +-- This method causes self, all its nodes, and all its edges to get +-- a new empty table for the key algorithm. This allows an algorithm to +-- store stuff with nodes and edges without them interfering with information +-- stored by other algorithms. +-- +-- @param An algorithm object. + +function Graph:registerAlgorithm(algorithm) + self[algorithm] = self[algorithm] or {} + + -- Add an algorithm field to all nodes, all edges, and the graph: + for _,n in pairs(self.nodes) do + n[algorithm] = n[algorithm] or {} + end + for _,e in pairs(self.edges) do + e[algorithm] = e[algorithm] or {} + end +end + + +--- Sets the graph option \meta{name} to \meta{value}. +-- +-- @param name Name of the option to be changed. +-- @param value New value for the graph option \meta{name}. +-- +function Graph:setOption(name, value) + self.options[name] = value +end + + + +--- Returns the value of the graph option \meta{name}. +-- +-- @param name Name of the option. +-- +-- @return The value of the graph option \meta{name} or |nil|. +-- +function Graph:getOption(name) + return self.options[name] +end + + + + +--- Creates a shallow copy of a graph. +-- +-- The nodes and edges of the original graph are not preserved in the copy. +-- +-- @return A shallow copy of the graph. +-- +function Graph:copy () + return Graph.new({options = self.options, events = self.events}) +end + + +--- Adds a node to the graph. +-- +-- @param node The node to be added. +-- +function Graph:addNode(node) + -- only add the node if it's not included in the graph yet + if not self:findNode(node.name) then + -- Does the node have an index, yet? + if not node.index then + node.index = #self.nodes + 1 + end + + table.insert(self.nodes, node) + end +end + + + +--- If possible, removes a node from the graph and returns it. +-- +-- @param node The node to remove. +-- +-- @return The removed node or |nil| if it was not found in the graph. +-- +function Graph:removeNode(node) + local _, index = lib.find(self.nodes, function (other) + return other.name == node.name + end) + if index then + table.remove(self.nodes, index) + return node + else + return nil + end +end + + + +--- If possible, looks up the node with the given name in the graph. +-- +-- @param name Name of the node to look up. +-- +-- @return The node with the given name or |nil| if it was not found in the graph. +-- +function Graph:findNode(name) + return self:findNodeIf(function (node) return node.name == name end) +end + + + +--- Looks up the first node for which the function \meta{test} returns |true|. +-- +-- @param test A function that takes one parameter (a |Node|) and returns +-- |true| or |false|. +-- +-- @return The first node for which \meta{test} returns |true|. +-- +function Graph:findNodeIf(test) + return lib.find(self.nodes, test) +end + + + +--- Like removeNode, but also deletes all adjacent edges of the removed node. +-- +-- This function also removes the deleted adjacent edges from all neighbours +-- of the removed node. +-- +-- @param node The node to be deleted together with its adjacent edges. +-- +-- @return The removed node or |nil| if the node was not found in the graph. +-- +function Graph:deleteNode(node) + local node = self:removeNode(node) + if node then + for _,edge in ipairs(node.edges) do + self:removeEdge(edge) + for _,other_node in ipairs(edge.nodes) do + if other_node.name ~= node.name then + other_node:removeEdge(edge) + end + end + end + node.edges = {} + end + return node +end + + + +-- Checks whether the edge already exists in the graph and returns it if possible. +-- +-- @param edge Edge to search for. +-- +-- @return The edge if it was found in the graph, |nil| otherwise. +-- +function Graph:findEdge(edge) + return lib.find(self.edges, function (other) return other == edge end) +end + + + +--- Adds an edge to the graph. +-- +-- @param edge The edge to be added. +-- +function Graph:addEdge(edge) + if not edge.index then + edge.index = #self.edges + 1 + end + + table.insert(self.edges, edge) +end + + + +--- If possible, removes an edge from the graph and returns it. +-- +-- @param edge The edge to be removed. +-- +-- @return The removed edge or |nil| if it was not found in the graph. +-- +function Graph:removeEdge(edge) + local _, index = lib.find(self.edges, function (other) return other == edge end) + if index then + table.remove(self.edges, index) + return edge + else + return nil + end +end + + + +--- Like removeEdge, but also removes the edge from its adjacent nodes. +-- +-- @param edge The edge to be deleted. +-- +-- @return The removed edge or |nil| if it was not found in the graph. +-- +function Graph:deleteEdge(edge) + local edge = self:removeEdge(edge) + if edge then + for _,node in ipairs(edge.nodes) do + node:removeEdge(edge) + end + end + return edge +end + + + +--- Removes an edge between two nodes and also removes it from these nodes. +-- +-- @param from Start node of the edge. +-- @param to End node of the edge. +-- +-- @return The deleted edge. +-- +function Graph:deleteEdgeBetweenNodes(from, to) + -- try to find the edge + local edge = lib.find(self.edges, function (edge) + return edge.nodes[1] == from and edge.nodes[2] == to + end) + + -- delete and return the edge + if edge then + return self:deleteEdge(edge) + else + return nil + end +end + + + +--- Creates and adds a new edge to the graph. +-- +-- @param first_node The first node of the new edge. +-- @param second_node The second node of the new edge. +-- @param direction The direction of the new edge. Possible values are +-- \begin{itemize} +-- \item |Edge.UNDIRECTED|, +-- \item |Edge.LEFT|, +-- \item |Edge.RIGHT|, +-- \item |Edge.BOTH| and +-- \item |Edge.NONE| (for invisible edges). +-- \end{itemize} +-- @param edge_nodes A string of \tikzname\ edge nodes that needs to be passed +-- back to the \TeX layer unmodified. +-- @param options The options of the new edge. +-- @param tikz_options A table of \tikzname\ options to be used by graph drawing +-- algorithms to treat the edge in special ways. +-- +-- @return The newly created edge. +-- +function Graph:createEdge(first_node, second_node, direction, edge_nodes, options, tikz_options) + local edge = Edge.new{ + direction = direction, + edge_nodes = edge_nodes, + options = options, + tikz_options = tikz_options + } + edge:addNode(first_node) + edge:addNode(second_node) + self:addEdge(edge) + return edge +end + + + +--- Returns the cluster with the given name or |nil| if no such cluster exists. +-- +-- @param name Name of the node cluster to look up. +-- +-- @return The cluster with the given name or |nil| if no such cluster is defined. +-- +function Graph:findClusterByName(name) + return lib.find(self.clusters, function (cluster) + return cluster.name == name + end) +end + + + +--- Tries to add a cluster to the graph. Returns whether or not this was successful. +-- +-- Clusters are supposed to have unique names. This function will add the given +-- cluster only if there is no cluster with this name already. It returns |true| +-- if the cluster was added and |false| otherwise. +-- +-- @param cluster Cluster to add to the graph. +-- +-- @return |true| if the cluster was added successfully, |false| otherwise. +-- +function Graph:addCluster(cluster) + if not self:findClusterByName(cluster.name) then + table.insert(self.clusters, cluster) + end +end + + + + + +--- Returns a string representation of this graph including all nodes and edges. +-- +-- @ignore This should not appear in the documentation. +-- +-- @return Graph as string. +-- +function Graph:__tostring() + local tmp = Graph.__tostring + Graph.__tostring = nil + local result = "Graph<" .. tostring(self) .. ">((" + Graph.__tostring = tmp + + local first = true + for _,node in ipairs(self.nodes) do + if first then first = false else result = result .. ", " end + result = result .. tostring(node) + end + result = result .. "), (" + first = true + for _,edge in ipairs(self.edges) do + if first then first = false else result = result .. ", " end + result = result .. tostring(edge) + end + + return result .. "))" +end + + + +-- Done + +return Graph
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Iterators.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Iterators.lua new file mode 100644 index 00000000000..8e29d78667a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Iterators.lua @@ -0,0 +1,91 @@ +-- Copyright 2011 by Jannis Pohlmann +-- 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/deprecated/Iterators.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + + +--- The Iterators class is a singleton object. +-- +-- It provides advanced iterators. + +local Iterators = {} + +-- Namespace + +local lib = require("pgf.gd.lib") + + + +--- Iterator for traversing a \meta{dag} using a topological sorting. +-- +-- A topological sorting of a directed graph is a linear ordering of its +-- nodes such that, for every edge |(u,v)|, |u| comes before |v|. +-- +-- Important note: if performed on a graph with at least one cycle a +-- topological sorting is impossible. Thus, the nodes returned from the +-- iterator are not guaranteed to satisfy the ``|u| comes before |v|'' +-- criterion. The iterator may even terminate early or loop forever. +-- +-- @param graph A directed acyclic graph. +-- +-- @return An iterator for traversing \meta{graph} in a topological order. +-- +function Iterators.topologicallySorted(dag) + -- track visited edges + local deleted_edges = {} + + -- collect all sources (nodes with no incoming edges) of the dag + local sources = lib.imap(dag.nodes, function (node) if node:getInDegree() == 0 then return node end end) + + -- return the iterator function + return function () + while #sources > 0 do + -- fetch the next sink from the queue + local source = table.remove(sources, 1) + + -- get its outgoing edges + local out_edges = source:getOutgoingEdges() + + -- iterate over all outgoing edges we haven't visited yet + for _,edge in ipairs(out_edges) do + if not deleted_edges[edge] then + -- mark the edge as visited + deleted_edges[edge] = true + + -- get the node at the other end of the edge + local neighbour = edge:getNeighbour(source) + + -- get a list of all incoming edges of the neighbour that have + -- not been visited yet + local in_edges = lib.imap(neighbour:getIncomingEdges(), + function (edge) if not deleted_edges[edge] then return edge end end) + + -- if there are no such edges then we have a new source + if #in_edges == 0 then + sources[#sources+1] = neighbour + end + end + end + + -- return the current source + return source + end + + -- the iterator terminates if there are no sources left + return nil + end +end + + + +-- Done + +return Iterators
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Node.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Node.lua new file mode 100644 index 00000000000..89e8a2e68fa --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Node.lua @@ -0,0 +1,280 @@ +-- Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster +-- Copyright 2011 by Jannis Pohlmann +-- 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/deprecated/Node.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + + +--- The Node class +-- +-- + +local Node = {} +Node.__index = Node + + +-- Namespace + +local lib = require "pgf.gd.lib" + + +-- Imports + +local Vector = require "pgf.gd.deprecated.Vector" + + + +--- Creates a new node. +-- +-- @param values Values to override default node settings. +-- The following parameters can be set:\par +-- |name|: The name of the node. It is obligatory to define this.\par +-- |tex|: Information about the corresponding \TeX\ node.\par +-- |edges|: Edges adjacent to the node.\par +-- |pos|: Initial position of the node.\par +-- |options|: A table of node options passed over from \tikzname. +-- +-- @return A newly allocated node. +-- +function Node.new(values) + local new = { + class = Node, + name = nil, + tex = { + -- texNode = nil, + -- maxX = nil, + -- minX = nil, + -- maxY = nil, + -- minY = nil + }, + edges = {}, + -- pos = nil, + options = {}, + -- growth_direction = nil, + -- index = nil, + -- event_index = nil, + kind = "node", + } + setmetatable(new, Node) + if values then + for k,v in pairs(values) do + new [k] = v + end + end + if not new.pos then + new.pos = Vector.new(2) + end + return new +end + + + +--- Sets the node option \meta{name} to \meta{value}. +-- +-- @param name Name of the node option to be changed. +-- @param value New value for the node option \meta{name}. +-- +function Node:setOption(name, value) + self.options[name] = value +end + + + +--- Returns the value of the node option \meta{name}. +-- +-- @param name Name of the node option. +-- @param graph If this optional argument is given, +-- in case the option is not set as a node parameter, +-- we try to look it up as a graph parameter. +-- +-- @return The value of the node option \meta{name} or |nil|. +-- +function Node:getOption(name, graph) + return lib.lookup_option(name, self, graph) +end + + + +--- Computes the width of the node. +-- +-- @return Width of the node. +-- +function Node:getTexWidth() + return math.abs(self.tex.maxX - self.tex.minX) +end + + + +--- Computes the heigth of the node. +-- +-- @return Height of the node. +-- +function Node:getTexHeight() + return math.abs(self.tex.maxY - self.tex.minY) +end + + + +--- Adds new edge to the node. +-- +-- @param edge The edge to be added. +-- +function Node:addEdge(edge) + table.insert(self.edges, edge) +end + + + +--- Removes an edge from the node. +-- +-- @param edge The edge to remove. +-- +function Node:removeEdge(edge) + self.edges = lib.imap (self.edges, function(other) if other ~= edge then return other end end) +end + + + +--- Counts the adjacent edges of the node. +-- +-- @return The number of adjacent edges of the node. +-- +function Node:getDegree() + return #self.edges +end + + + +--- Returns all edges of the node. +-- +-- Instead of calling |node:getEdges()| the edges can alternatively be +-- accessed directly with |node.edges|. +-- +-- @return All edges of the node. +-- +function Node:getEdges() + return self.edges +end + + + +--- Returns the incoming edges of the node. Undefined result for hyperedges. +-- +-- @param ignore_reversed Optional parameter to consider reversed edges not +-- reversed for this method call. Defaults to |false|. +-- +-- @return Incoming edges of the node. This includes undirected edges +-- and directed edges pointing to the node. +-- +function Node:getIncomingEdges(ignore_reversed) + return lib.imap(self.edges, + function (edge) + if edge:isHead(self, ignore_reversed) then return edge end + end) +end + + + +--- Returns the outgoing edges of the node. Undefined result for hyperedges. +-- +-- @param ignore_reversed Optional parameter to consider reversed edges not +-- reversed for this method call. Defaults to |false|. +-- +-- @return Outgoing edges of the node. This includes undirected edges +-- and directed edges leaving the node. +-- +function Node:getOutgoingEdges(ignore_reversed) + return lib.imap(self.edges, + function (edge) + if edge:isTail(self, ignore_reversed) then return edge end + end) +end + + + +--- Returns the number of incoming edges of the node. +-- +-- @see Node:getIncomingEdges(reversed) +-- +-- @param ignore_reversed Optional parameter to consider reversed edges not +-- reversed for this method call. Defaults to |false|. +-- +-- @return The number of incoming edges of the node. +-- +function Node:getInDegree(ignore_reversed) + return #self:getIncomingEdges(ignore_reversed) +end + + + +--- Returns the number of edges starting at the node. +-- +-- @see Node:getOutgoingEdges() +-- +-- @param ignore_reversed Optional parameter to consider reversed edges not +-- reversed for this method call. Defaults to |false|. +-- +-- @return The number of outgoing edges of the node. +-- +function Node:getOutDegree(ignore_reversed) + return #self:getOutgoingEdges(ignore_reversed) +end + + + +--- Creates a shallow copy of the node. +-- +-- Most notably, the edges adjacent are not preserved in the copy. +-- +-- @return Copy of the node. +-- +function Node:copy() + local result = lib.copy(self, Node.new()) + result.edges = {} + return result +end + + + +--- Compares two nodes by their name. +-- +-- @ignore This should not appear in the documentation. +-- +-- @param other Another node to compare with. +-- +-- @return |true| if both nodes have the same name. |false| otherwise. +-- +function Node:__eq(object) + return self.name == object.name +end + + + +--- Returns a formated string representation of the node. +-- +-- @ignore This should not appear in the documentation. +-- +-- @return String represenation of the node. +-- +function Node:__tostring() + local tmp = Node.__tostring + Node.__tostring = nil + local result = "Node<" .. tostring(self) .. ">(" .. self.name .. ")" + Node.__tostring = tmp + return result +end + + + + +-- Done + +return Node
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Vector.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Vector.lua new file mode 100644 index 00000000000..ab94ebe9686 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Vector.lua @@ -0,0 +1,256 @@ +-- 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/deprecated/Vector.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + +--- Vector class +-- +-- This class augments a normal array so that: +-- +-- 1) Several functions like "plus" or "normalize" become available. +-- 2) You can access the ".x" and ".y" fields to get the fields [1] and [2]. + +local Vector = {} + + +-- Namespace: +local lib = require "pgf.gd.lib" +lib.Vector = Vector + + +-- Class setup +Vector.__index = + function (t, k) + if k == "x" then + return rawget(t,1) + elseif k == "y" then + return rawget(t,2) + else + return rawget(Vector,k) + end + end +Vector.__newindex = + function (t, k, v) + if k == "x" then + rawset(t,1,v) + elseif k == "y" then + rawset(t,2,v) + else + rawset(t,k,v) + end + end + + + +--- Creates a new vector with \meta{n} values using an optional \meta{fill\_function}. +-- +-- @param n The number of elements of the vector. (If omitted, then 2.) +-- @param fill_function Optional function that takes a number between 1 and \meta{n} +-- and is expected to return a value for the corresponding element +-- of the vector. If omitted, all elements of the vector will +-- be initialized with 0. +-- +-- @return A newly-allocated vector with \meta{n} elements. +-- +function Vector.new(n, fill_function) + -- create vector + local vector = { } + setmetatable(vector, Vector) + + local n = n or 2 + + if type(n) == 'table' then + for k,v in pairs(n) do + vector[k] = v + end + else + -- fill vector elements with values + if not fill_function then + for i = 1,n do + rawset(vector,i,0) + end + else + for i = 1,n do + rawset(vector,i,fill_function(i)) + end + end + end + + return vector +end + + + +--- Creates a copy of the vector that holds the same elements as the original. +-- +-- @return A newly-allocated copy of the vector holding exactly the same elements. +-- +function Vector:copy() + return Vector.new(#self, function (n) return self[n] end) +end + + + +--- Performs a vector addition and returns the result in a new vector. +-- +-- @param other The vector to add. +-- +-- @return A new vector with the result of the addition. +-- +function Vector:plus(other) + assert(#self == #other) + + return Vector.new(#self, function (n) return self[n] + other[n] end) +end + + + +--- Subtracts two vectors and returns the result in a new vector. +-- +-- @param other Vector to subtract. +-- +-- @return A new vector with the result of the subtraction. +-- +function Vector:minus(other) + assert(#self == #other) + + return Vector.new(#self, function (n) return self[n] - other[n] end) +end + + + +--- Divides a vector by a scalar value and returns the result in a new vector. +-- +-- @param scalar Scalar value to divide the vector by. +-- +-- @return A new vector with the result of the division. +-- +function Vector:dividedByScalar(scalar) + return Vector.new(#self, function (n) return self[n] / scalar end) +end + + + +--- Multiplies a vector by a scalar value and returns the result in a new vector. +-- +-- @param scalar Scalar value to multiply the vector with. +-- +-- @return A new vector with the result of the multiplication. +-- +function Vector:timesScalar(scalar) + return Vector.new(#self, function (n) return self[n] * scalar end) +end + + + +--- Performs the dot product of two vectors and returns the result in a new vector. +-- +-- @param other Vector to perform the dot product with. +-- +-- @return A new vector with the result of the dot product. +-- +function Vector:dotProduct(other) + assert(#self == #other) + + local product = 0 + for n = 1,#self do + product = product + self[n] * other[n] + end + return product +end + + + +--- Computes the Euclidean norm of the vector. +-- +-- @return The Euclidean norm of the vector. +-- +function Vector:norm() + return math.sqrt(self:dotProduct(self)) +end + + + +--- Normalizes the vector and returns the result in a new vector. +-- +-- @return Normalized version of the original vector. +-- +function Vector:normalized() + local norm = self:norm() + if norm == 0 then + return Vector.new(#self) + else + return self:dividedByScalar(self:norm()) + end +end + + + +--- Updates the values of the vector in-place. +-- +-- @param update_function A function that is called for each element of the +-- vector. The elements are replaced by the values +-- returned from this function. +-- +function Vector:update(update_function) + for i=1,#self do + self[i] = update_function(self[i]) + end +end + + + +--- Limits all elements of the vector in-place. +-- +-- @param limit_function A function that is called for each index/element +-- pair. It is supposed to return minimum and maximum +-- values for the element. The element is then clamped +-- to these values. +-- +function Vector:limit(limit_function) + for i=1,#self do + local min, max = limit_function(i, self[i]) + self[i] = math.max(min, math.min(max, value)) + end +end + + +--- Tests whether all elements of two vectors are the same +-- +-- @param other The other vector +-- +-- @return true or false +-- +function Vector:equals(other) + if #self ~= #other then + return false + end + + for n = 1, #self do + if self[n] ~= other[n] then + return false + end + end + + return true +end + + +function Vector:__tostring() + return '(' .. table.concat(self, ', ') .. ')' +end + + + + + +-- Done + +return Vector
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc.lua new file mode 100644 index 00000000000..5d02603943c --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc.lua @@ -0,0 +1,122 @@ +-- Copyright 2013 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/doc.lua,v 1.2 2013/03/20 17:16:38 tantau Exp $ + + +--- +-- The table doc is used for documentation purposes. It is used to +-- provide lazy documentation for keys, that is, to install +-- documentation for keys only when this information is requested and +-- when the documentation is kept in a separate file. +-- +-- Using the doc facility is easy: +-- +-- \begin{enumerate} +-- \item In the |declare| statement of the key, you do not provide +-- fields like |documentation| or |summary|. Rather, you provide the +-- field |documentation_in|, which gets the name of a Lua file the +-- will be read whenever one of the fields |documentation|, |summary|, +-- or |examples| is requested for the key. +-- \item When the key is requested, |require| will be applied to the +-- filename given in the |documentation_in| field. +-- \item In this file, you start with the following code: +--\begin{codeexample}[code only] +--local doc = require 'pgf.gd.doc' +--local key = doc.key +--local documentation = doc.documentation +--local summary = doc.summary +--local example = doc.example +--\end{codeexample} +-- This will setup nice shortcuts for the commands you are going to +-- use in your file. +-- \item Next, for each to-be-lazily-documented key, add a block to +-- the file like the following: +--\begin{codeexample}[code only] +-- --- +-- key "my radius" +-- summary "This key specifies a radius." +-- documentation +-- [[ +-- This key is used, whenever... +-- ]] +-- example "\tikz \graph [foo layout, my radius=5] { a--b };" +-- example "\tikz \graph [foo layout, my radius=3] { c--d };" +--\end{codeexample} +-- +-- Note that |[[| and |]]| are used in Lua for raw multi-line +-- strings. +-- +-- The effect of the above code will be that for the key |my radius| +-- the different field like |summary| or |documentation| get +-- updated. The |key| function simple ``selects'' a key and subsequent +-- commands like |summary| will update this key until a different key +-- is selected through another use of |key|. +-- \end{enumerate} + +local doc = {} + +local current_key + + +-- Namespace +require "pgf.gd".doc = doc + + +-- Imports +local keys = require "pgf.gd.interface.InterfaceCore".keys + +--- +-- Selects the key which will be subsequently updated by the other +-- functions of this class. +-- +-- @param key A key. + +function doc.key (key) + current_key = assert(keys[key], "trying to document not-yet-declared key") +end + + +--- +-- Updates (replaces) the summary field of the last key selected +-- through the |key| command. +-- +-- @param string A (new) summary string. + +function doc.summary (string) + current_key.summary = string +end + + +--- +-- Updates (replaces) the documentation field of the last key selected +-- through the |key| command. +-- +-- @param string A (new) documentation string. Typically, the |[[| +-- syntax will be used to specify this string. + +function doc.documentation (string) + current_key.documentation = string +end + + +--- +-- Adds an example to the |examples| field of the last key selected +-- through the |key| command. +-- +-- @param string An additional example string. + +function doc.example (string) + local examples = rawget(current_key, "examples") or {} + examples[#examples + 1] = string + current_key.examples = examples +end + + +return doc diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/circular/Tantau2012.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/circular/Tantau2012.lua new file mode 100644 index 00000000000..e40a0bbdb1f --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/circular/Tantau2012.lua @@ -0,0 +1,136 @@ +-- Copyright 2013 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/doc/circular/Tantau2012.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------- +key "simple necklace layout" + +summary +[[ This simple layout arranges the nodes in a circle, which is +especially useful for drawing, well, circles of nodes. ]] + +documentation +[[ +The name |simple necklace layout| is reminiscent of the more general +``necklace layout,'' a term coined by Speckmann and Verbeek in +their paper +\begin{itemize} +\item + Bettina Speckmann and Kevin Verbeek, + \newblock Necklace Maps, + \newblock \emph{IEEE Transactions on Visualization and Computer + Graphics,} 16(6):881--889, 2010. +\end{itemize} + +For a |simple necklace layout|, the centers of the nodes +are placed on a counter-clockwise circle, starting with the first +node at the |grow| direction (for |grow'|, the circle is +clockwise). The order of the nodes is the order in which they appear +in the graph, the edges are not taken into consideration, unless the +|componentwise| option is given. + +\begin{codeexample}[] +\tikz[>=spaced stealth'] + \graph [simple necklace layout, grow'=down, node sep=1em, + nodes={draw,circle}, math nodes] + { + x_1 -> x_2 -> x_3 -> x_4 -> + x_5 -> "\dots"[draw=none] -> "x_{n-1}" -> x_n -> x_1 + }; +\end{codeexample} + +When you give the |componentwise| option, the graph will be +decomposed into connected components, which are then laid out +individually and packed using the usual component packing +mechanisms: + +\begin{codeexample}[] +\tikz \graph [simple necklace layout] { + a -- b -- c -- d -- a, + 1 -- 2 -- 3 -- 1 +}; +\end{codeexample} +\begin{codeexample}[] +\tikz \graph [simple necklace layout, componentwise] { + a -- b -- c -- d -- a, + 1 -- 2 -- 3 -- 1 +}; +\end{codeexample} + +The nodes are placed in such a way that +\begin{enumerate} +\item The (angular) distance between the centers of consecutive + nodes is at least |node distance|, +\item the distance between the borders of consecutive nodes is at + least |node sep|, and +\item the radius is at least |radius|. +\end{enumerate} +The radius of the circle is chosen near-minimal such that the above +properties are satisfied. To be more precise, if all nodes are +circles, the radius is chosen optimally while for, say, rectangular +nodes there may be too much space between the nodes in order to +satisfy the second condition. +]] + +example +[[ +\tikz \graph [simple necklace layout, + node sep=0pt, node distance=0pt, + nodes={draw,circle}] +{ 1 -- 2 [minimum size=30pt] -- 3 -- + 4 [minimum size=50pt] -- 5 [minimum size=40pt] -- 6 -- 7 }; +]] + +example +[[ +\begin{tikzpicture}[radius=1.25cm] + \graph [simple necklace layout, + node sep=0pt, node distance=0pt, + nodes={draw,circle}] + { 1 -- 2 [minimum size=30pt] -- 3 -- + 4 [minimum size=50pt] -- 5 [minimum size=40pt] -- 6 -- 7 }; + + \draw [red] (0,-1.25) circle []; +\end{tikzpicture} +]] + +example +[[ +\tikz \graph [simple necklace layout, + node sep=0pt, node distance=1cm, + nodes={draw,circle}] +{ 1 -- 2 [minimum size=30pt] -- 3 -- + 4 [minimum size=50pt] -- 5 [minimum size=40pt] -- 6 -- 7 }; +]] + +example +[[ +\tikz \graph [simple necklace layout, + node sep=2pt, node distance=0pt, + nodes={draw,circle}] +{ 1 -- 2 [minimum size=30pt] -- 3 -- + 4 [minimum size=50pt] -- 5 [minimum size=40pt] -- 6 -- 7 }; +]] + +example +[[ +\tikz \graph [simple necklace layout, + node sep=0pt, node distance=0pt, + nodes={rectangle,draw}] +{ 1 -- 2 [minimum size=30pt] -- 3 -- + 4 [minimum size=50pt] -- 5 [minimum size=40pt] -- 6 -- 7 }; +]] +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/control/Anchoring.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/control/Anchoring.lua new file mode 100644 index 00000000000..0a80baf0ca5 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/control/Anchoring.lua @@ -0,0 +1,224 @@ +-- 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/doc/control/Anchoring.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------- +key "desired at" + +summary +[[ +When you add this key to a node in a graph, you ``desire'' +that the node should be placed at the \meta{coordinate} by the graph +drawing algorithm. +]] + +documentation +[[ +Now, when you set this key for a single node of a graph, +then, by shifting the graph around, this ``wish'' can obviously +always be fulfill: +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + \graph [spring layout] + { + a [desired at={(1,2)}] -- b -- c -- a; + }; +\end{tikzpicture} +\end{codeexample} +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + \graph [spring layout] + { + a -- b[desired at={(2,1)}] -- c -- a; + }; +\end{tikzpicture} +\end{codeexample} +Since the key's name is a bit long and since the many braces and +parentheses are a bit cumbersome, there is a special support for +this key inside a |graph|: The standard |/tikz/at| key is redefined +inside a |graph| so that it points to |/graph drawing/desired at| +instead. (Which is more logical anyway, since it makes no sense to +specify an |at| position for a node whose position it to be computed +by a graph drawing algorithm.) A nice side effect of this is that +you can use the |x| and |y| keys (see +Section~\ref{section-graphs-xy}) to specify desired positions: +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + \graph [spring layout] + { + a -- b[x=2,y=0] -- c -- a; + }; +\end{tikzpicture} +\end{codeexample} +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + \graph [layered layout] + { + a [x=1,y=2] -- { b, c } -- {e, f} -- a + }; +\end{tikzpicture} +\end{codeexample} + +A problem arises when two or more nodes have this key set, because +then your ``desires'' for placement and the positions computed by +the graph drawing algorithm may clash. Graph drawing algorithms are +``told'' about the desired positions. Most algorithms will simply +ignore these desired positions since they will be taken care of in +the so-called post-anchoring phase, see below. However, for some +algorithms it makes a lot of sense to fix the positions of some +nodes and only compute the positions +of the other nodes relative to these nodes. For instance, for a +|spring layout| it makes perfect sense that some nodes are +``nailed to the canvas'' while other nodes can ``move freely''. +]] + +example +[[ +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + \graph [spring layout] + { + a[x=1] -- { b, c, d, e -- {f,g,h} }; + { h, g } -- a; + }; +\end{tikzpicture} +]] + +example +[[ +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + \graph [spring layout] + { + a -- { b, c, d[x=0], e -- {f[x=2], g, h[x=1]} }; + { h, g } -- a; + }; +\end{tikzpicture} +]] + +example +[[ +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + \graph [spring layout] + { + a -- { b, c, d[x=0], e -- {f[x=2,y=1], g, h[x=1]} }; + { h, g } -- a; + }; +\end{tikzpicture} +]] +-------------------------------------------------------------------- + + + +-------------------------------------------------------------------- +key "anchor node" + +summary +[[ +This option can be used with a graph to specify a node that +should be used for anchoring the whole graph. +]] + +documentation +[[ +When this option is specified, after the layout has been computed, the +whole graph will be shifted in such a way that the \meta{node name} is +either +\begin{itemize} +\item at the current value of |anchor at| or +\item at the position that is specified in the form of a + |desired at| for the \meta{node name}. +\end{itemize} +Note how in the last example |c| is placed at |(1,1)| rather than +|b| as would happen by default. +]] + +example +[[ +\tikz \draw (0,0) + -- (1,0.5) graph [edges=red, layered layout, anchor node=a] { a -> {b,c} } + -- (1.5,0) graph [edges=blue, layered layout, + anchor node=y, anchor at={(2,0)}] { x -> {y,z} }; +]] + +example +[[ +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + + \graph [layered layout, anchor node=c, edges=rounded corners] + { a -- {b [x=1,y=1], c [x=1,y=1] } -- d -- a}; +\end{tikzpicture} +]] +-------------------------------------------------------------------- + + + + +-------------------------------------------------------------------- +key "anchor at" + +summary +[[ +The coordinate at which the graph should be anchored when no +explicit anchor is given for any node. The initial value is the origin. +]] + +example +[[ +\begin{tikzpicture} + \draw [help lines] (0,0) grid (2,2); + + \graph [layered layout, edges=rounded corners, anchor at={(1,2)}] + { a -- {b, c [anchor here] } -- d -- a}; +\end{tikzpicture} +]] +-------------------------------------------------------------------- + + + + +-------------------------------------------------------------------- +key "anchor here" + +summary +[[ +This option can be passed to a single node (rather than the +graph as a whole) in order to specify that this node should be used +for the anchoring process. +]] + +documentation +[[ +In the example, |c| is placed at the origin since this is the +default |anchor at| position. +]] + +example +[[ +\begin{tikzpicture} + \draw [help lines] (0,0) grid (2,2); + + \graph [layered layout, edges=rounded corners] + { a -- {b, c [anchor here] } -- d -- a}; +\end{tikzpicture} +]] +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased.lua new file mode 100644 index 00000000000..7dfd9179648 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased.lua @@ -0,0 +1,19 @@ +-- Copyright 2013 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/doc/ogdf/energybased.lua,v 1.1 2013/03/07 22:28:37 tantau Exp $ + + + +--- +-- @section subsection {Force-Based Algorithms} +-- +-- + +local _
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FMMMLayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FMMMLayout.lua new file mode 100644 index 00000000000..3f2b9bc2e30 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FMMMLayout.lua @@ -0,0 +1,129 @@ +-- Copyright 2013 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/doc/ogdf/energybased/FMMMLayout.lua,v 1.2 2013/10/09 19:46:59 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "FMMMLayout" +summary "The fast multipole multilevel layout algorithm." + +documentation +[[ +|FMMMLayout| implements a force-directed graph drawing +method suited also for very large graphs. It is based on a +combination of an efficient multilevel scheme and a strategy for +approximating the repulsive forces in the system by rapidly +evaluating potential fields. + +The implementation is based on the following publication: + +\begin{itemize} +\item Stefan Hachul, Michael J\"unger: Drawing Large Graphs with + a Potential-Field-Based Multilevel Algorithm. \emph{12th + International Symposium on Graph Drawing 1998 (GD '04)}, New York, LNCS 3383, + pp. 285--295, 2004. +\end{itemize} +]] + +example +[[ +\tikz \graph [FMMMLayout] { a -- {b,c,d} -- e -- a }; +]] + + +example +[[ +\tikz [nodes={text height=.7em, text depth=.2em, + draw=black!20, thick, fill=white, font=\footnotesize}, + >=spaced stealth', rounded corners, semithick] + \graph [FMMMLayout, node sep=1mm, variation=2] { + "5th Edition" -> { "6th Edition", "PWB 1.0" }; + "6th Edition" -> { "LSX", "1 BSD", "Mini Unix", "Wollongong", "Interdata" }; + "Interdata" ->[orient=down] "Unix/TS 3.0", + "Interdata" -> { "PWB 2.0", "7th Edition" }; + "7th Edition" -> { "8th Edition", "32V", "V7M", "Ultrix-11", "Xenix", "UniPlus+" }; + "V7M" -> "Ultrix-11"; + "8th Edition" -> "9th Edition"; + "1 BSD" -> "2 BSD" -> "2.8 BSD" -> { "Ultrix-11", "2.9 BSD" }; + "32V" -> "3 BSD" -> "4 BSD" -> "4.1 BSD" -> { "4.2 BSD", "2.8 BSD", "8th Edition" }; + "4.2 BSD" -> { "4.3 BSD", "Ultrix-32" }; + "PWB 1.0" -> { "PWB 1.2" -> "PWB 2.0", "USG 1.0" -> { "CB Unix 1", "USG 2.0" }}; + "CB Unix 1" -> "CB Unix 2" -> "CB Unix 3" -> { "Unix/TS++", "PDP-11 Sys V" }; + { "USG 2.0" -> "USG 3.0", "PWB 2.0", "Unix/TS 1.0" } -> "Unix/TS 3.0"; + { "Unix/TS++", "CB Unix 3", "Unix/TS 3.0" } -> + "TS 4.0" -> "System V.0" -> "System V.2" -> "System V.3"; + }; +]] +-------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------- +key "FMMMLayout.randSeed" +summary "Sets the random seed for the |FMMMLayout|." +documentation +[[ +By changing this number, you can vary the appearance of the generated +graph drawing. This key is an alias for |random seed|, which in turn +can be set by using the |variation| key. +]] + +example +[[ +\tikz \graph [FMMMLayout, variation=1] { a -- {b,c,d} -- e -- a }; +]] +example +[[ +\tikz \graph [FMMMLayout, variation=2] { a -- {b,c,d} -- e -- a }; +]] +-------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------- +key "FMMMLayout.unitEdgeLength" +summary "The ``ideal'' padding between two nodes." + +documentation +[[ +The algorithm will try to make the padding between any two vertices +this distance. Naturally, this is not always possible, so, normally, +distance will actually be different. This key is an alias for the more +natural |node sep|. +]] + +example +[[ +\tikz { + \graph [FMMMLayout, node sep=1cm] { subgraph C_n[n=6]; }; + + \draw [red, ultra thick, |-|] (1.south) -- ++(down:1cm); +} +]] +example +[[ +\tikz { + \graph [FMMMLayout, node sep=5mm] { subgraph C_n[n=6]; }; + + \draw [red, ultra thick, |-|] (1.south) -- ++(down:5mm); +} +]] +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End:
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FastMultipoleEmbedder.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FastMultipoleEmbedder.lua new file mode 100644 index 00000000000..8fe64399c91 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FastMultipoleEmbedder.lua @@ -0,0 +1,51 @@ +-- Copyright 2013 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/doc/ogdf/energybased/FastMultipoleEmbedder.lua,v 1.1 2013/03/15 15:04:41 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "FastMultipoleEmbedder" +summary "Implementation of a fast multipole embedder by Martin Gronemann." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "FastMultipoleEmbedder.numIterations" +summary "sets the maximum number of iterations" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "FastMultipoleEmbedder.multipolePrec" +summary "sets the number of coefficients for the expansions. default = 4" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "FastMultipoleEmbedder.defaultEdgeLength" +summary "" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "FastMultipoleEmbedder.defaultNodeSize" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/GEMLayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/GEMLayout.lua new file mode 100644 index 00000000000..d564af44dfa --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/GEMLayout.lua @@ -0,0 +1,103 @@ +-- Copyright 2013 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/doc/ogdf/energybased/GEMLayout.lua,v 1.2 2013/10/07 18:43:25 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "GEMLayout" +summary "The energy-based GEM layout algorithm." + +documentation [[ +The implementation used in |GEMLayout| is based on the following publication: +\begin{itemize} +\item Arne Frick, Andreas Ludwig, Heiko Mehldau: \emph{A Fast Adaptive Layout + Algorithm for Undirected Graphs.} Proc. Graph Drawing 1994, + LNCS 894, pp. 388-403, 1995. +\end{itemize} + +]] +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.numberOfRounds" +summary "Sets the maximal number of round per node." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.minimalTemperature" +summary "Sets the minimal temperature." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.initialTemperature" +summary "Sets the initial temperature; must be $\\ge$ |minimalTemperature|." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.gravitationalConstant" +summary "Sets the gravitational constant; must be $\\ge 0$." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.desiredLength" +summary "Sets the desired edge length; must be $\\ge 0$." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.maximalDisturbance" +summary "Sets the maximal disturbance; must be $\\ge 0$." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.rotationAngle" +summary "Sets the opening angle for rotations ($0 \\le x \\le \\pi / 2$)." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.oscillationAngle" +summary "Sets the opening angle for oscillations ($0 \\le x \\le \\pi / 2$)." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.rotationSensitivity" +summary "Sets the rotation sensitivity ($0 \\le x \\le 1$)." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.oscillationSensitivity" +summary "Sets the oscillation sensitivity ($0 \\le x \\le 1$)." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.attractionFormula" +summary "sets the formula for attraction (1 = Fruchterman / Reingold, 2 = GEM)." +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/MultilevelLayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/MultilevelLayout.lua new file mode 100644 index 00000000000..783ab8b4bff --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/MultilevelLayout.lua @@ -0,0 +1,33 @@ +-- Copyright 2013 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/doc/ogdf/energybased/MultilevelLayout.lua,v 1.1 2013/03/15 15:04:41 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "MultilevelLayout" +summary "A wrapper for the multilevel layout computation using the modular multi-level mixer." + +example [[ +\tikz \graph [MultilevelLayout] { + a -- b -- c -- a -- d -- e -- f -- a +}; +]] +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFR.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFR.lua new file mode 100644 index 00000000000..2c5ae1bc293 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFR.lua @@ -0,0 +1,54 @@ +-- Copyright 2013 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/doc/ogdf/energybased/SpringEmbedderFR.lua,v 1.1 2013/11/07 15:43:35 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFR" +summary "The spring-embedder layout algorithm by Fruchterman and Reingold." + +documentation [[ +The implementation used in SpringEmbedderFR is based on the following +publication: + +Thomas M. J. Fruchterman, Edward M. Reingold: \emph{Graph Drawing by Force-directed +Placement}. Software - Practice and Experience 21(11), pp. 1129-1164, 1991. + +]] +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFR.iterations" +summary "Sets the number of iterations." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFR.noise" +summary "Sets the parameter noise." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFR.scaleFunctionFactor" +summary "Sets the scale function factor." +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFRExact.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFRExact.lua new file mode 100644 index 00000000000..8d4462d0815 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFRExact.lua @@ -0,0 +1,57 @@ +-- Copyright 2013 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/doc/ogdf/energybased/SpringEmbedderFRExact.lua,v 1.1 2013/11/07 15:43:35 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFRExact" +summary "Declaration of Spring-Embedder (Fruchterman,Reingold) algorithm with exact force computations." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFRExact.iterations" +summary "Sets the number of iterations." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFRExact.noise" +summary "Sets the parameter noise." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFRExact.coolingFunction" +summary "Sets the parameter coolingFunction to |factor| or to |logarithmic|." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFRExact.idealEdgeLength" +summary "Sets the ideal edge length to a length." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFRExact.convTolerance" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderKK.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderKK.lua new file mode 100644 index 00000000000..a2882845c98 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderKK.lua @@ -0,0 +1,64 @@ +-- Copyright 2013 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/doc/ogdf/energybased/SpringEmbedderKK.lua,v 1.1 2013/11/07 15:43:35 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "SpringEmbedderKK" +summary "The spring embedder of Kamada and Kawai" + +documentation [[ + The implementation used in |SpringEmbedderKK| is based on + the following publication: + + Tomihisa Kamada, Satoru Kawai: \emph{An Algorithm for Drawing + General Undirected Graphs.} Information Processing Letters 31, pp. 7--15, 1989. + + There are some parameters that can be tuned to optimize the + algorithm's behavior regarding runtime and layout quality. + First of all note that the algorithm uses all pairs shortest path + to compute the graph theoretic distance. This can be done either + with BFS (ignoring node sizes) in quadratic time or by using + e.g. Floyd's algorithm in cubic time with given edge lengths + that may reflect the node sizes. Also |m_computeMaxIt| decides + if the computation is stopped after a fixed maximum number of + iterations. The desirable edge length can either be set or computed + from the graph and the given layout. + +]] +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderKK.stopTolerance" +summary "Sets the value for the stop tolerance." +documentation +[[ +Below this value, the system is regarded stable (balanced) and the +optimization stopped. +]] +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderKK.desLength" +summary "Sets desirable edge length directly" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/BarycenterPlacer.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/BarycenterPlacer.lua new file mode 100644 index 00000000000..20ca3ce3d12 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/BarycenterPlacer.lua @@ -0,0 +1,33 @@ +-- Copyright 2013 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/doc/ogdf/energybased/multilevelmixer/BarycenterPlacer.lua,v 1.1 2013/03/15 15:04:41 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "BarycenterPlacer" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "BarycenterPlacer.weightedPositionPriority" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/CirclePlacer.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/CirclePlacer.lua new file mode 100644 index 00000000000..0cda25ca466 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/CirclePlacer.lua @@ -0,0 +1,45 @@ +-- Copyright 2013 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/doc/ogdf/energybased/multilevelmixer/CirclePlacer.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "CirclePlacer" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "CirclePlacer.circleSize" +summary "" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "CirclePlacer.radiusFixed" +summary "" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "CirclePlacer.nodeSelection" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/EdgeCoverMerger.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/EdgeCoverMerger.lua new file mode 100644 index 00000000000..9623b70d89e --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/EdgeCoverMerger.lua @@ -0,0 +1,33 @@ +-- Copyright 2013 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/doc/ogdf/energybased/multilevelmixer/EdgeCoverMerger.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "EdgeCoverMerger" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "EdgeCoverMerger.factor" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/IndependentSetMerger.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/IndependentSetMerger.lua new file mode 100644 index 00000000000..15e11ff91c7 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/IndependentSetMerger.lua @@ -0,0 +1,33 @@ +-- Copyright 2013 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/doc/ogdf/energybased/multilevelmixer/IndependentSetMerger.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "IndependentSetMerger" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "IndependentSetMerger.searchDepthBase" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/LocalBiconnectedMerger.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/LocalBiconnectedMerger.lua new file mode 100644 index 00000000000..352a1f5400a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/LocalBiconnectedMerger.lua @@ -0,0 +1,33 @@ +-- Copyright 2013 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/doc/ogdf/energybased/multilevelmixer/LocalBiconnectedMerger.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "LocalBiconnectedMerger" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "LocalBiconnectedMerger.factor" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MatchingMerger.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MatchingMerger.lua new file mode 100644 index 00000000000..eb52badcc55 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MatchingMerger.lua @@ -0,0 +1,33 @@ +-- Copyright 2013 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/doc/ogdf/energybased/multilevelmixer/MatchingMerger.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "MatchingMerger" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "MatchingMerger.selectByNodeMass" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MedianPlacer.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MedianPlacer.lua new file mode 100644 index 00000000000..50be16489c2 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MedianPlacer.lua @@ -0,0 +1,27 @@ +-- Copyright 2013 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/doc/ogdf/energybased/multilevelmixer/MedianPlacer.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "MedianPlacer" +summary "?" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomMerger.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomMerger.lua new file mode 100644 index 00000000000..4d8bfd179de --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomMerger.lua @@ -0,0 +1,33 @@ +-- Copyright 2013 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/doc/ogdf/energybased/multilevelmixer/RandomMerger.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "RandomMerger" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "RandomMerger.factor" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomPlacer.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomPlacer.lua new file mode 100644 index 00000000000..779e992bb83 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomPlacer.lua @@ -0,0 +1,33 @@ +-- Copyright 2013 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/doc/ogdf/energybased/multilevelmixer/RandomPlacer.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "RandomPlacer" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "RandomPlacer.circleSize" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarMerger.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarMerger.lua new file mode 100644 index 00000000000..081067143da --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarMerger.lua @@ -0,0 +1,39 @@ +-- Copyright 2013 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/doc/ogdf/energybased/multilevelmixer/SolarMerger.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "SolarMerger" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SolarMerger.simple" +summary "" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SolarMerger.massAsNodeRadius" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarPlacer.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarPlacer.lua new file mode 100644 index 00000000000..21eb1f122ee --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarPlacer.lua @@ -0,0 +1,27 @@ +-- Copyright 2013 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/doc/ogdf/energybased/multilevelmixer/SolarPlacer.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "SolarPlacer" +summary "?" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/ZeroPlacer.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/ZeroPlacer.lua new file mode 100644 index 00000000000..f4dcfc632cc --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/ZeroPlacer.lua @@ -0,0 +1,33 @@ +-- Copyright 2013 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/doc/ogdf/energybased/multilevelmixer/ZeroPlacer.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "ZeroPlacer" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "ZeroPlacer.randomRange" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered.lua new file mode 100644 index 00000000000..6dfa6a46575 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered.lua @@ -0,0 +1,19 @@ +-- Copyright 2013 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/doc/ogdf/layered.lua,v 1.2 2013/03/07 18:17:14 tantau Exp $ + + + +--- +-- @section subsection {Algorithms for Drawing Layered Graphs} +-- +-- + +local _
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/BarycenterHeuristic.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/BarycenterHeuristic.lua new file mode 100644 index 00000000000..f0e20321e86 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/BarycenterHeuristic.lua @@ -0,0 +1,23 @@ +-- Copyright 2013 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/doc/ogdf/layered/BarycenterHeuristic.lua,v 1.1 2013/03/07 18:17:14 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + + +-------------------------------------------------------------------- +key "BarycenterHeuristic" +summary "The barycenter heuristic for 2-layer crossing minimization." +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/CoffmanGrahamRanking.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/CoffmanGrahamRanking.lua new file mode 100644 index 00000000000..b5fd3ba6669 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/CoffmanGrahamRanking.lua @@ -0,0 +1,35 @@ +-- Copyright 2013 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/doc/ogdf/layered/CoffmanGrahamRanking.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------- +key "CoffmanGrahamRanking" +summary "The ranking algorithm due to Coffman and Graham." +documentation +[[ +|CoffmanGrahamRanking| implements a node ranking algorithmn based on +the Coffman--Graham scheduling algorithm, which can be used as first +phase in |SugiyamaLayout|. The aim of the algorithm is to ensure that +the height of the ranking (the number of layers) is kept small. +]] +-------------------------------------------------------------------- + + +-------------------------------------------------------------------- +key "CoffmanGrahamRanking.width" +summary "A mysterious width parameter..." +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/DfsAcyclicSubgraph.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/DfsAcyclicSubgraph.lua new file mode 100644 index 00000000000..4a4935e4aea --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/DfsAcyclicSubgraph.lua @@ -0,0 +1,27 @@ +-- Copyright 2013 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/doc/ogdf/layered/DfsAcyclicSubgraph.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + + +-------------------------------------------------------------------- +key "DfsAcyclicSubgraph" +summary "DFS-based algorithm for computing a maximal acyclic subgraph." +documentation +[[ +The algorithm simply removes all DFS-backedges and works in linear-time. +]] +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastHierarchyLayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastHierarchyLayout.lua new file mode 100644 index 00000000000..af593f6d972 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastHierarchyLayout.lua @@ -0,0 +1,99 @@ +-- Copyright 2013 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/doc/ogdf/layered/FastHierarchyLayout.lua,v 1.2 2013/03/07 22:28:37 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------- +key "FastHierarchyLayout" +summary "Coordinate assignment phase for the Sugiyama algorithm by Buchheim et al." +documentation +[[ +This class implements a hierarchy layout algorithm, that is, it +layouts hierarchies with a given order of nodes on each +layer. It is used as a third phase of the Sugiyama algorithm. + +All edges of the layout will have at most two +bends. Additionally, for each edge having exactly two bends, the +segment between them is drawn vertically. This applies in +particular to the long edges arising in the first phase of the +Sugiyama algorithm. + +The implementation is based on: + +\begin{itemize} +\item + Christoph Buchheim, Michael Jünger, Sebastian Leipert: A Fast + Layout Algorithm for k-Level Graphs. \emph{Proc. Graph + Drawing 2000}, volumne 1984 of LNCS, pages 229--240, 2001. +\end{itemize} +]] + +example +[[ +\tikz \graph [SugiyamaLayout, FastHierarchyLayout] { + a -- {b,c,d} -- e -- a; +}; +]] +-------------------------------------------------------------------- + + + +-------------------------------------------------------------------- +key "FastHierarchyLayout.fixedLayerDistance" +summary "If true, the distance between neighbored layers is fixed, otherwise variable." +-------------------------------------------------------------------- + + + + +-------------------------------------------------------------------- +key "FastHierarchyLayout.layerDistance" +summary "Separation distance (padding) between two consecutive layers." + +documentation +[[ +Sets the (minimum?) padding between nodes on two consecutive +layers. It defaults to the sum of the keys +|level pre sep| and |level post sep|. +]] + +example +[[ +\tikz \graph [SugiyamaLayout, FastHierarchyLayout, + level sep=1cm] { + a -- {b,c,d} -- e -- a; +}; +]] +-------------------------------------------------------------------- + +-------------------------------------------------------------------- +key "FastHierarchyLayout.nodeDistance" +summary "Separation distance (padding) between two consecutive nodes on the same layer." + +documentation +[[ +Sets the (minimum?) padding between sibling nodes. It defaults to the +sum of the keys |sibling pre sep| and |sibling post sep|. +]] + +example +[[ +\tikz \graph [SugiyamaLayout, FastHierarchyLayout, + sibling sep=5mm] { + a -- {b,c,d} -- e -- a; +}; +]] +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastSimpleHierarchyLayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastSimpleHierarchyLayout.lua new file mode 100644 index 00000000000..1798cb7e0df --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastSimpleHierarchyLayout.lua @@ -0,0 +1,97 @@ +-- Copyright 2013 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/doc/ogdf/layered/FastSimpleHierarchyLayout.lua,v 1.1 2013/03/07 18:17:14 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------- +key "FastSimpleHierarchyLayout" +summary "Coordinate assignment phase for the Sugiyama algorithm by Ulrik Brandes and Boris Köpf." + +documentation +[[ +This class implements a hierarchy layout algorithm, that is, it +layouts hierarchies with a given order of nodes on each +layer. It is used as a third phase of the Sugiyama algorithm. + +The algorithm runs in three phases: +\begin{enumerate} +\item Alignment (4x) +\item Horizontal Compactation (4x) +\item Balancing +\end{enumerate} +The alignment and horizontal compactification phases are calculated +downward, upward, left-to-right and right-to-left. The four +resulting layouts are combined in a balancing step. + +Warning: The implementation is known to not always produce a +correct layout. Therefore this Algorithm is for testing purpose +only. + +The implementation is based on: + +\begin{itemize} +\item + Ulrik Brandes, Boris Köpf: Fast and Simple Horizontal + Coordinate Assignment. \emph{LNCS} 2002, Volume 2265/2002, + pp. 33--36 +\end{itemize} +]] + +example +[[ +\tikz \graph [SugiyamaLayout, FastSimpleHierarchyLayout] { + a -- {b,c,d} -- e -- a; +}; +]] +-------------------------------------------------------------------- + + + +-------------------------------------------------------------------- +key "FastSimpleHierarchyLayout.layerDistance" +summary "Distance between the cetners of nodes of two consecutive layers." + +documentation +[[ +Sets the (minimum?) distance between nodes on two consecutive +layers. It defaults to the key |level distance|. +]] +example +[[ +\tikz \graph [SugiyamaLayout, FastSimpleHierarchyLayout, + level distance=2cm] { + a -- {b,c,d} -- e -- a; +}; +]] +-------------------------------------------------------------------- + +-------------------------------------------------------------------- +key "FastSimpleHierarchyLayout.siblingDistance" +summary "Distance between the cetners of nodes of sibling nodes." + +documentation +[[ +Sets the (minimum?) padding between sibling nodes. It defaults to +|sibling distance|. +]] +example +[[ +\tikz \graph [SugiyamaLayout, FastSimpleHierarchyLayout, + sibling distance=5mm] { + a -- {b,c,d} -- e -- a; +}; +]] +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyCycleRemoval.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyCycleRemoval.lua new file mode 100644 index 00000000000..c0b407bb050 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyCycleRemoval.lua @@ -0,0 +1,27 @@ +-- Copyright 2013 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/doc/ogdf/layered/GreedyCycleRemoval.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------- +key "GreedyCycleRemoval" +summary "Greedy algorithm for computing a maximal acyclic subgraph." +documentation +[[ +The algorithm applies a greedy heuristic to compute a maximal +acyclic subgraph and works in linear-time. +]] +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyInsertHeuristic.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyInsertHeuristic.lua new file mode 100644 index 00000000000..f6c59ac2125 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyInsertHeuristic.lua @@ -0,0 +1,23 @@ +-- Copyright 2013 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/doc/ogdf/layered/GreedyInsertHeuristic.lua,v 1.1 2013/03/07 18:17:14 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + + +-------------------------------------------------------------------- +key "GreedyInsertHeuristic" +summary "The greedy-insert heuristic for 2-layer crossing minimization." +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/LongestPathRanking.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/LongestPathRanking.lua new file mode 100644 index 00000000000..65dd5176f8b --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/LongestPathRanking.lua @@ -0,0 +1,57 @@ +-- Copyright 2013 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/doc/ogdf/layered/LongestPathRanking.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------- +key "LongestPathRanking" +summary "The longest-path ranking algorithm." +documentation +[[ +|LongestPathRanking| implements the well-known longest-path ranking +algorithm, which can be used as first phase in |SugiyamaLayout|. The +implementation contains a special optimization for reducing edge +lengths, as well as special treatment of mixed-upward graphs (for +instance, \textsc{uml} class diagrams). +]] +-------------------------------------------------------------------- + + +-------------------------------------------------------------------- +key "LongestPathRanking.separateDeg0Layer" +summary "If set to true, isolated nodes are placed on a separate layer." +-------------------------------------------------------------------- + + +-------------------------------------------------------------------- +key "LongestPathRanking.separateMultiEdges" +summary "If set to true, multi-edges will span at least two layers." +-------------------------------------------------------------------- + + + +-------------------------------------------------------------------- +key "LongestPathRanking.optimizeEdgeLength" +summary +[[ +If set to true the ranking algorithm tries to reduce edge +length even if this might increase the height of the layout. Choose +false, if the longest-path ranking known from the literature should be +used. +]] +-------------------------------------------------------------------- + + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/MedianHeuristic.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/MedianHeuristic.lua new file mode 100644 index 00000000000..5ad07881fe1 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/MedianHeuristic.lua @@ -0,0 +1,24 @@ +-- Copyright 2013 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/doc/ogdf/layered/MedianHeuristic.lua,v 1.1 2013/03/07 18:17:14 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + + +-------------------------------------------------------------------- +key "MedianHeuristic" +summary "The median heuristic for 2-layer crossing minimization." +-------------------------------------------------------------------- + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/OptimalRanking.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/OptimalRanking.lua new file mode 100644 index 00000000000..e694de6e790 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/OptimalRanking.lua @@ -0,0 +1,35 @@ +-- Copyright 2013 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/doc/ogdf/layered/OptimalRanking.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------- +key "OptimalRanking" +summary "The optimal ranking algorithm." +documentation +[[ +The |OptimalRanking| implements the LP-based algorithm for +computing a node ranking with minimal edge lengths, which can +be used as first phase in |SugiyamaLayout|. +]] +-------------------------------------------------------------------- + + + +-------------------------------------------------------------------- +key "OptimalRanking.separateMultiEdges" +summary "If set to true, multi-edges will span at least two layers." +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SiftingHeuristic.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SiftingHeuristic.lua new file mode 100644 index 00000000000..6231ab49249 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SiftingHeuristic.lua @@ -0,0 +1,34 @@ +-- Copyright 2013 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/doc/ogdf/layered/SiftingHeuristic.lua,v 1.1 2013/03/07 18:17:14 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + + +-------------------------------------------------------------------- +key "SiftingHeuristic" +summary "The sifting heuristic for 2-layer crossing minimization." +-------------------------------------------------------------------- + + +-------------------------------------------------------------------- +key "SiftingHeuristic.strategy" +summary "Sets a so-called ``sifting strategy.''" +documentation +[[ +The following values are permissible: |left_to_right|, |desc_degree|, +and |random|. +]] +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SplitHeuristic.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SplitHeuristic.lua new file mode 100644 index 00000000000..fc897d71c51 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SplitHeuristic.lua @@ -0,0 +1,24 @@ +-- Copyright 2013 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/doc/ogdf/layered/SplitHeuristic.lua,v 1.1 2013/03/07 18:17:14 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + + +-------------------------------------------------------------------- +key "SplitHeuristic" +summary "The split heuristic for 2-layer crossing minimization." +-------------------------------------------------------------------- + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SugiyamaLayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SugiyamaLayout.lua new file mode 100644 index 00000000000..d887b6c6bad --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SugiyamaLayout.lua @@ -0,0 +1,116 @@ +-- Copyright 2013 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/doc/ogdf/layered/SugiyamaLayout.lua,v 1.4 2013/10/09 19:47:00 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "SugiyamaLayout" +summary "The OGDF implementation of the Sugiyama algorithm." + +documentation +[[ +This layout represents a customizable implementation of Sugiyama's +layout algorithm. The implementation used in |SugiyamaLayout| is based +on the following publications: + +\begin{itemize} +\item Emden R. Gansner, Eleftherios Koutsofios, Stephen + C. North, Kiem-Phong Vo: A technique for drawing directed + graphs. \emph{IEEE Trans. Software Eng.} 19(3):214--230, 1993. +\item Georg Sander: \emph{Layout of compound directed graphs.} + Technical Report, Universität des Saarlandes, 1996. +\end{itemize} +]] + +example +[[ +\tikz \graph [SugiyamaLayout] { a -- {b,c,d} -- e -- a }; +]] + +example +[[ +\tikz \graph [SugiyamaLayout, grow=right] { + a -- {b,c,d} -- e -- a +}; +]] + +example +[[ +\tikz [nodes={text height=.7em, text depth=.2em, + draw=black!20, thick, fill=white, font=\footnotesize}, + >=spaced stealth', rounded corners, semithick] + \graph [SugiyamaLayout, FastSimpleHierarchyLayout, grow=-80, + level distance=1.5cm, sibling distance=7mm] { + "5th Edition" -> { "6th Edition", "PWB 1.0" }; + "6th Edition" -> { "LSX", "1 BSD", "Mini Unix", "Wollongong", "Interdata" }; + "Interdata" -> { "Unix/TS 3.0", "PWB 2.0", "7th Edition" }; + "7th Edition" -> { "8th Edition", "32V", "V7M", "Ultrix-11", "Xenix", "UniPlus+" }; + "V7M" -> "Ultrix-11"; + "8th Edition" -> "9th Edition"; + "1 BSD" -> "2 BSD" -> "2.8 BSD" -> { "Ultrix-11", "2.9 BSD" }; + "32V" -> "3 BSD" -> "4 BSD" -> "4.1 BSD" -> { "4.2 BSD", "2.8 BSD", "8th Edition" }; + "4.2 BSD" -> { "4.3 BSD", "Ultrix-32" }; + "PWB 1.0" -> { "PWB 1.2" -> "PWB 2.0", "USG 1.0" -> { "CB Unix 1", "USG 2.0" }}; + "CB Unix 1" -> "CB Unix 2" -> "CB Unix 3" -> { "Unix/TS++", "PDP-11 Sys V" }; + { "USG 2.0" -> "USG 3.0", "PWB 2.0", "Unix/TS 1.0" } -> "Unix/TS 3.0"; + { "Unix/TS++", "CB Unix 3", "Unix/TS 3.0" } -> + "TS 4.0" -> "System V.0" -> "System V.2" -> "System V.3"; + }; +]] +-------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------- +key "SugiyamaLayout.runs" +summary "Determines, how many times the crossing minimization is repeated." +documentation +[[ +Each repetition (except for the first) starts with +randomly permuted nodes on each layer. Deterministic behaviour can +be achieved by setting |SugiyamaLayout.runs| to 1. +]] +-------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------- +key "SugiyamaLayout.transpose" +documentation +[[ +Determines whether the transpose step is performed +after each 2-layer crossing minimization; this step tries to +reduce the number of crossings by switching neighbored nodes on +a layer. +]] +-------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------- +key "SugiyamaLayout.fails" +documentation +[[ +The number of times that the number of crossings may +not decrease after a complete top-down bottom-up traversal, +before a run is terminated. +]] +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End:
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout.lua new file mode 100644 index 00000000000..e9c2c427774 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout.lua @@ -0,0 +1,19 @@ +-- Copyright 2013 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/doc/ogdf/misclayout.lua,v 1.1 2013/03/15 15:04:41 tantau Exp $ + + + +--- +-- @section subsection {Miscellaneous Algorithms for Graph Drawing} +-- +-- + +local _
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/BalloonLayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/BalloonLayout.lua new file mode 100644 index 00000000000..9a8dd45a641 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/BalloonLayout.lua @@ -0,0 +1,48 @@ +-- Copyright 2013 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/doc/ogdf/misclayout/BalloonLayout.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "BalloonLayout" +summary "A ``balloon layout''." + +documentation +[[ +This algorithm computes a radial (balloon) layout based on a +spanning tree. The algorithm is partially based on the paper +\emph{On Balloon Drawings of Rooted Trees} by Lin and Yen and on +\emph{Interacting with Huge Hierarchies: Beyond Cone Trees} by +Carriere and Kazman. +]] + +example +[[ +\tikz \graph [BalloonLayout] { a -- {b,c,d -- {e,f,h,h,i}, j -- k -- {l,m,n}} }; +]] +-------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------- +key "BalloonLayout.evenAngles" +summary "Subtrees may be assigned even angles or angles depending on their size." +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End:
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/CircularLayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/CircularLayout.lua new file mode 100644 index 00000000000..4cada7886b4 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/CircularLayout.lua @@ -0,0 +1,95 @@ +-- Copyright 2013 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/doc/ogdf/misclayout/CircularLayout.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "CircularLayout" +summary "The circular layout algorithm." + +documentation +[[ +The implementation used in CircularLayout is based on the following publication: + +\begin{itemize} +\item Ugur Dogrus\"oz, Brendan Madden, Patrick Madden: Circular + Layout in the Graph Layout Toolkit. \emph{Proc. Graph Drawing 1996,} + LNCS 1190, pp. 92--100, 1997. +\end{itemize} +]] + +example +[[ +\tikz \graph [CircularLayout] { + a -- b -- c -- a -- d -- e -- f -- g -- d; + b -- {x,y,z}; +}; +]] +-------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------- +key "CircularLayout.minDistCircle" +summary "The minimal padding between nodes on a circle." + +documentation "This is an alias for |part sep|." + +example +[[ +\tikz \graph [CircularLayout, part sep=1cm] { + a -- b -- c -- a -- d -- e -- f -- g -- d; + b -- {x,y,z}; +}; +]] +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "CircularLayout.minDistLevel" +summary "The minimal padding between nodes on different levels." + +documentation "This is an alias for |layer sep| and |level sep|." + +example +[[ +\tikz \graph [CircularLayout, layer sep=1cm] { + a -- b -- c -- a -- d -- e -- f -- g -- d; + b -- {x,y,z}; +}; +]] +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "CircularLayout.minDistSibling" +summary "The minimal padding between sibling nodes." + +documentation "This is an alias for |sibling sep|." + +example +[[ +\tikz \graph [CircularLayout, sibling sep=1cm] { + a -- b -- c -- a -- d -- e -- f -- g -- d; + b -- {x,y,z}; +}; +]] +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End:
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/AcyclicSubgraphModule.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/AcyclicSubgraphModule.lua new file mode 100644 index 00000000000..97d3a7f0191 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/AcyclicSubgraphModule.lua @@ -0,0 +1,18 @@ +-- Copyright 2013 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/doc/ogdf/module/AcyclicSubgraphModule.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + + +--- +-- @section subsubsection {Computing Acyclic Subgraphs Module} +-- + +local _ + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/HierarchyLayoutModule.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/HierarchyLayoutModule.lua new file mode 100644 index 00000000000..9ee6a534eb4 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/HierarchyLayoutModule.lua @@ -0,0 +1,17 @@ +-- Copyright 2013 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/doc/ogdf/module/HierarchyLayoutModule.lua,v 1.1 2013/03/07 22:28:37 tantau Exp $ + + +--- +-- @section subsubsection {The Hierarchy Layout Module} +-- + +local _ diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/InitialPlacer.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/InitialPlacer.lua new file mode 100644 index 00000000000..7fc5c535f2d --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/InitialPlacer.lua @@ -0,0 +1,17 @@ +-- Copyright 2013 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/doc/ogdf/module/InitialPlacer.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +--- +-- @section subsubsection {The Initial Placer Module} +-- + +local _ diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/MultilevelBuilder.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/MultilevelBuilder.lua new file mode 100644 index 00000000000..d79f1c41fc7 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/MultilevelBuilder.lua @@ -0,0 +1,17 @@ +-- Copyright 2013 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/doc/ogdf/module/MultilevelBuilder.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +--- +-- @section subsubsection {The Multilevel Builder Module} +-- + +local _ diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/RankingModule.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/RankingModule.lua new file mode 100644 index 00000000000..672a3375358 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/RankingModule.lua @@ -0,0 +1,17 @@ +-- Copyright 2013 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/doc/ogdf/module/RankingModule.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + + +--- +-- @section subsubsection {The Ranking Module} +-- + +local _ diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/TwoLayerCrossMin.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/TwoLayerCrossMin.lua new file mode 100644 index 00000000000..edc96e7b49f --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/TwoLayerCrossMin.lua @@ -0,0 +1,17 @@ +-- Copyright 2013 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/doc/ogdf/module/TwoLayerCrossMin.lua,v 1.1 2013/03/07 22:28:37 tantau Exp $ + + +--- +-- @section subsubsection {The Two Layer Crossing Minimization Module} +-- + +local _ diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/planarity.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/planarity.lua new file mode 100644 index 00000000000..66835b6f012 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/planarity.lua @@ -0,0 +1,19 @@ +-- Copyright 2013 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/doc/ogdf/planarity.lua,v 1.1 2013/05/23 20:01:26 tantau Exp $ + + + +--- +-- @section subsection {Algorithms for Drawing Planar Graphs} +-- +-- + +local _
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/planarity/PlanarizationLayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/planarity/PlanarizationLayout.lua new file mode 100644 index 00000000000..bceba167894 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/planarity/PlanarizationLayout.lua @@ -0,0 +1,66 @@ +-- Copyright 2013 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/doc/ogdf/planarity/PlanarizationLayout.lua,v 1.1 2013/05/23 20:01:26 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "PlanarizationLayout" +summary "The planarization layout algorithm." + +documentation +[[ +A |PlanarizationLayout| represents a customizable implementation +of the planarization approach for drawing graphs. The implementation +used in PlanarizationLayout is based on the following publication: + +\begin{itemize} +\item C. Gutwenger, P. Mutzel: \emph{An Experimental Study of Crossing + Minimization Heuristics.} 11th International Symposium on Graph + Drawing 2003, Perugia (GD '03), LNCS 2912, pp. 13-24, 2004. +\end{itemize} +]] + +example +[[ +\tikz \graph [PlanarizationLayout] { a -- {b,c,d,e,f} -- g -- a }; +]] +-------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------- +key "PlanarizationLayout.preprocessCliques" +summary "Configures, whether cliques are collapsed in a preprocessing step." +documentation +[[ +If set to true, a preprocessing for cliques (complete subgraphs) +is performed and cliques will be laid out in a special form (straight-line, +not orthogonal). The preprocessing may reduce running time and improve +layout quality if the input graphs contains dense subgraphs. +]] +-------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------- +key "PlanarizationLayout.minCliqueSize" +summary "The minimum size of cliques collapsed in preprocessing." +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End:
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/trees/ReingoldTilford1981.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/trees/ReingoldTilford1981.lua new file mode 100644 index 00000000000..794214c5f74 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/trees/ReingoldTilford1981.lua @@ -0,0 +1,309 @@ +-- 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/doc/trees/ReingoldTilford1981.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------- +key "tree layout" + +summary "This layout uses the Reingold--Tilform method for drawing trees." + +documentation +[[ +The Reingold--Tilford method is a standard method for drawing +trees. It is described in: +\begin{itemize} +\item + E.~M.\ Reingold and J.~S.\ Tilford, + \newblock Tidier drawings of trees, + \newblock \emph{IEEE Transactions on Software Engineering,} + 7(2), 223--228, 1981. +\end{itemize} +My implementation in |graphdrawing.trees| follows the following paper, which +introduces some nice extensions of the basic algorithm: +\begin{itemize} +\item + A.\ Br\"uggemann-Klein, D.\ Wood, + \newblock Drawing trees nicely with \TeX, + \emph{Electronic Publishing,} 2(2), 101--115, 1989. +\end{itemize} +As a historical remark, Br\"uggemann-Klein and Wood have implemented +their version of the Reingold--Tilford algorithm directly in \TeX\ +(resulting in the Tree\TeX\ style). With the power of Lua\TeX\ at +our disposal, the 2012 implementation in the |graphdrawing.tree| +library is somewhat more powerful and cleaner, but it really was an +impressive achievement to implement this algorithm back in 1989 +directly in \TeX. + +The basic idea of the Reingold--Tilford algorithm is to use the +following rules to position the nodes of a tree (the following +description assumes that the tree grows downwards, other growth +directions are handled by the automatic orientation mechanisms of +the graph drawing library): +\begin{enumerate} +\item For a node, recursively compute a layout for each of its children. +\item Place the tree rooted at the first child somewhere on the page. +\item Place the tree rooted at the second child to the right of the + first one as near as possible so that no two nodes touch (and such + that the |sibling sep| padding is not violated). +\item Repeat for all subsequent children. +\item Then place the root above the child trees at the middle + position, that is, at the half-way point between the left-most and + the right-most child of the node. +\end{enumerate} +The standard keys |level distance|, |level sep|, |sibling distance|, +and |sibling sep|, as well as the |pre| and |post| versions of these +keys, as taken into consideration when nodes are positioned. See also +Section~\ref{subsection-gd-dist-pad} for details on these keys. + +\noindent\textbf{Handling of Missing Children.} +As described in Section~\ref{section-gd-missing-children}, you can +specify that some child nodes are ``missing'' in the tree, but some +space should be reserved for them. This is exactly what happens: +When the subtrees of the children of a node are arranged, each +position with a missing child is treated as if a zero-width, +zero-height subtree were present at that positions: +\begin{codeexample}[] +\tikz [tree layout, nodes={draw,circle}] + \node {r} + child { node {a} + child [missing] + child { node {b} } + } + child[missing]; +\end{codeexample} +or in |graph| syntax: +\begin{codeexample}[] + \tikz \graph [tree layout, nodes={draw,circle}] + { + r -> { + a -> { + , %missing + b}, + % missing + } + }; +\end{codeexample} +More than one child can go missing: +\begin{codeexample}[] +\tikz \graph [tree layout, nodes={draw,circle}, sibling sep=0pt] + { r -> { a, , ,b -> {c,d}, ,e} }; +\end{codeexample} +Although missing children are taken into consideration for the +computation of the placement of the children of a root node relative +to one another and also for the computation of the position of the +root node, they are usually \emph{not} considered as part of the +``outline'' of a subtree (the \texttt{minimum number of children} +key ensures that |b|, |c|, |e|, and |f| all have a missing right +child): +\begin{codeexample}[] +\tikz \graph [tree layout, minimum number of children=2, + nodes={draw,circle}] + { a -> { b -> c -> d, e -> f -> g } }; +\end{codeexample} +This behaviour of ``ignoring'' missing children in later stages of +the recursion can be changed using the key |missing nodes get space|. + +\noindent\textbf{Significant Pairs of Siblings.} +Br\"uggemann-Klein and Wood have proposed an extension of the +Reingold--Tilford method that is intended to better highlight the +overall structure of a tree. Consider the following two trees: + +\begin{codeexample}[] +\tikz [baseline=(a.base), tree layout, minimum number of children=2, + sibling distance=5mm, level distance=5mm] + \graph [nodes={circle, inner sep=0pt, minimum size=2mm, fill, as=}]{ + a -- { b -- c -- { d -- e, f -- { g, h }}, i -- j -- k[second] } + };\quad +\tikz [baseline=(a.base), tree layout, minimum number of children=2, + sibling distance=5mm, level distance=5mm] + \graph [nodes={circle, inner sep=0pt, minimum size=2mm, fill, as=}]{ + a -- { b -- c -- d -- e, i -- j -- { f -- {g,h}, k } } + }; +\end{codeexample} +As observed by Br\"uggemann-Klein and Wood, the two trees are +structurally quite different, but the Reingold--Tilford method +places the nodes at exactly the same positions and only one edge +``switches'' positions. In order to better highlight the differences +between the trees, they propose to add a little extra separation +between siblings that form a \emph{significant pair}. They define +such a pair as follows: Consider the subtrees of two adjacent +siblings. There will be one or more levels where these subtrees have +a minimum distance. For instance, the following two trees the +subtrees of the nodes |a| and |b| have a minimum distance only at +the top level in the left example, and in all levels in the second +example. A \emph{significant pair} is a pair of siblings where the +minimum distance is encountered on any level other than the first +level. Thus, in the first example there is no significant pair, +while in the second example |a| and |b| form such a pair. +\begin{codeexample}[] +\tikz \graph [tree layout, minimum number of children=2, + level distance=5mm, nodes={circle,draw}] + { / -> { a -> / -> /, b -> /[second] -> /[second] }}; + \quad +\tikz \graph [tree layout, minimum number of children=2, + level distance=5mm, nodes={circle,draw}] + { / -> { a -> / -> /, b -> / -> / }}; +\end{codeexample} +Whenever the algorithm encounters a significant pair, it adds extra +space between the siblings as specified by the |significant sep| +key. +]] + + +example +[[ +\tikz [tree layout, sibling distance=8mm] + \graph [nodes={circle, draw, inner sep=1.5pt}]{ + 1 -- { 2 -- 3 -- { 4 -- 5, 6 -- { 7, 8, 9 }}, 10 -- 11 -- { 12, 13 } } + }; +]] + + +example +[[ +\tikz [tree layout, grow=-30, + sibling distance=0mm, level distance=0mm,] + \graph [nodes={circle, draw, inner sep=1.5pt}]{ + 1 -- { 2 -- 3 -- { 4 -- 5, 6 -- { 7, 8, 9 }}, 10 -- 11 -- { 12, 13 } } + }; +]] +-------------------------------------------------------------------- + + + +-------------------------------------------------------------------- +key "missing nodes get space" + +summary +[[ +When set to true, missing children are treated as if they +where zero-width, zero-height nodes during the whole tree layout +process. +]] + + +example +[[ +\tikz \graph [tree layout, missing nodes get space, + minimum number of children=2, nodes={draw,circle}] +{ a -> { b -> c -> d, e -> f -> g } }; +]] +-------------------------------------------------------------------- + + + + + +-------------------------------------------------------------------- +key "significant sep" + +summary +[[ This space is added to signifcant pairs by the modified +Reingold--Tilford algorithm. ]] + +example +[[ +\tikz [baseline=(a.base), tree layout, significant sep=1em, + minimum number of children=2, + sibling distance=5mm, level distance=5mm] + \graph [nodes={circle, inner sep=0pt, minimum size=2mm, fill, as=}]{ + a -- { b -- c -- { d -- e, f -- { g, h }}, i -- j -- k[second] } + };\quad +\tikz [baseline=(a.base), tree layout, significant sep=1em, + minimum number of children=2, + sibling distance=5mm, level distance=5mm] + \graph [nodes={circle, inner sep=0pt, minimum size=2mm, fill, as=}]{ + a -- { b -- c -- d -- e, i -- j -- { f -- {g,h}, k } } + }; +]] +-------------------------------------------------------------------- + + + +-------------------------------------------------------------------- +key "binary tree layout" + +summary +[[ A layout based on the Reingold--Tilford method for drawing +binary trees. ]] + +documentation +[[ +This key executes: +\begin{enumerate} +\item |tree layout|, thereby selecting the Reingold--Tilford method, +\item |minimum number of children=2|, thereby ensuring the all nodes + have (at least) two children or none at all, and +\item |significant sep=10pt| to highlight significant pairs. +\end{enumerate} +In the examples, the last one is taken from the paper of +Br\"uggemann-Klein and Wood. It demonstrates nicely the +advantages of having the full power of \tikzname's anchoring and the +graph drawing engine's orientation mechanisms at one's disposal. +]] + + +example +[[ +\tikz [grow'=up, binary tree layout, sibling distance=7mm, level distance=7mm] + \graph { + a -- { b -- c -- { d -- e, f -- { g, h }}, i -- j -- k[second] } + }; +]] + +example +[[ +\tikz \graph [binary tree layout] { + Knuth -> { + Beeton -> Kellermann [second] -> Carnes, + Tobin -> Plass -> { Lamport, Spivak } + } +};\qquad +\tikz [>=spaced stealth'] + \graph [binary tree layout, grow'=right, level sep=1.5em, + nodes={right, fill=blue!50, text=white, chamfered rectangle}, + edges={decorate,decoration={snake, post length=5pt}}] + { + Knuth -> { + Beeton -> Kellermann [second] -> Carnes, + Tobin -> Plass -> { Lamport, Spivak } + } + }; +]] +-------------------------------------------------------------------- + + + +-------------------------------------------------------------------- +key "extended binary tree layout" + +summary +[[ This algorithm is similar to |binary tree layout|, only the +option \texttt{missing nodes get space} is executed and the +\texttt{significant sep} is zero. ]] + +example +[[ +\tikz [grow'=up, extended binary tree layout, + sibling distance=7mm, level distance=7mm] + \graph { + a -- { b -- c -- { d -- e, f -- { g, h }}, i -- j -- k[second] } + }; +]] +-------------------------------------------------------------------- + + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples.lua new file mode 100644 index 00000000000..bf6907bddb1 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples.lua @@ -0,0 +1,26 @@ +-- 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/examples.lua,v 1.1 2012/11/27 17:24:23 tantau Exp $ + + + +-- Imports + +require "pgf" +require "pgf.gd" + + +-- Declare namespace +pgf.gd.examples = {} + + +-- Done + +return pgf.gd.examples
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/ASCIIDisplayer.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/ASCIIDisplayer.lua new file mode 100644 index 00000000000..ccaa91f9992 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/ASCIIDisplayer.lua @@ -0,0 +1,32 @@ +local InterfaceToDisplay = require "pgf.gd.interface.InterfaceToDisplay" + +InterfaceToDisplay.bind(require "pgf.gd.examples.BindingToASCII") +require "pgf.gd.layered.library" +require "pgf.gd.force.library" + +local algorithm = io.read():match("%s*graph%s*%[(.-)%]") + +InterfaceToDisplay.pushPhase(algorithm, "main", 1) +InterfaceToDisplay.pushOption("level distance", 6, 2) +InterfaceToDisplay.pushOption("sibling distance", 8, 3) +InterfaceToDisplay.beginGraphDrawingScope(3) +InterfaceToDisplay.pushLayout(4) + +for line in io.lines() do + if line:match("}") then + break + elseif line:find("-") then + local n1, dir, n2 = string.match(line, "^%s*(.-)%s*(-.)%s*(.-)%s*;") + InterfaceToDisplay.createEdge(n1, n2, dir, 4) + else + local n1 = string.match(line, "^%s*(.-)%s*;") + InterfaceToDisplay.createVertex(n1, "rectangle", nil, 4) + end +end + +InterfaceToDisplay.runGraphDrawingAlgorithm() +InterfaceToDisplay.renderGraph() +InterfaceToDisplay.endGraphDrawingScope() + + + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/BindingToASCII.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/BindingToASCII.lua new file mode 100644 index 00000000000..9752254907a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/BindingToASCII.lua @@ -0,0 +1,87 @@ +local lib = require "pgf.gd.lib" + +-- Create a binding to ourselves +local BindingToASCII = lib.class { base_class = require "pgf.gd.bindings.Binding" } + +local canvas + +function BindingToASCII:renderStart() + canvas = {} + -- Clear the canvas + for x=-30,30 do + canvas [x] = {} + for y=-30,30 do + canvas[x][y] = ' ' + end + end +end + +function BindingToASCII:renderStop() + for y=10,-30,-1 do + local t = {} + for x=-30,30 do + local s = canvas[x][y] + for i=1,#s do + pos = x+30+i-math.floor(#s/2) + if not t[pos] or t[pos] == " " or t[pos] == "." then + t[pos] = string.sub(s,i,i) + end + end + end + print(table.concat(t)) + end +end + +function BindingToASCII:renderVertex(v) + canvas [math.floor(v.pos.x)][math.floor(v.pos.y)] = v.name +end + +function BindingToASCII:renderEdge(e) + + local function connect (p,q) + + local x1, y1, x2, y2 = math.floor(p.x+0.5), math.floor(p.y+0.5), math.floor(q.x+0.5), math.floor(q.y+0.5) + + -- Go upward with respect to x + if x2 < x1 then + x1, y1, x2, y2 = x2, y2, x1, y1 + end + + local delta_x = x2-x1 + local delta_y = y2-y1 + + if math.abs(delta_x) > math.abs(delta_y) then + local slope = delta_y/delta_x + for i=x1,x2 do + local x,y = i, math.floor(y1 + (i-x1)*slope + 0.5) + + if canvas[x][y] == " " then + canvas[x][y] = '.' + end + end + elseif math.abs(delta_y) > 0 then + local slope = delta_x/delta_y + for i=y1,y2,(y1<y2 and 1) or -1 do + local x,y = math.floor(x1 + (i-y1)*slope + 0.5), i + + if canvas[x][y] == " " then + canvas[x][y] = '.' + end + end + end + end + + + local p = e.tail.pos + + for i=1,#e.path do + if type(e.path[i]) == "table" then + connect(p, e.path[i]) + p = e.path[i] + end + end + + connect(p, e.head.pos) +end + +return BindingToASCII diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleDemo.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleDemo.lua new file mode 100644 index 00000000000..cff5d95253a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleDemo.lua @@ -0,0 +1,82 @@ +-- Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster +-- 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/examples/SimpleDemo.lua,v 1.6 2013/12/20 14:44:46 tantau Exp $ + + +--- +-- @section subsubsection {The ``Hello World'' of Graph Drawing} +-- +-- @end + + +-- Inputs +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + +--- + +declare { + key = "simple demo layout", + algorithm = { + run = + function (self) + local g = self.digraph + local alpha = (2 * math.pi) / #g.vertices + + for i,vertex in ipairs(g.vertices) do + local radius = vertex.options['radius'] or g.options['radius'] + vertex.pos.x = radius * math.cos(i * alpha) + vertex.pos.y = radius * math.sin(i * alpha) + end + end + }, + + summary = [[" + This algorithm is the ``Hello World'' of graph drawing. + "]], + documentation = [=[" + The algorithm + arranges nodes in a circle (without paying heed to the sizes of the + nodes or to the edges). In order to ``really'' layout nodes in a + circle, use |simple necklace layout|; the present layout is only intended + to demonstrate how much (or little) is needed to implement a graph + drawing algorithm. +\begin{codeexample}[code only, tikz syntax=false] +-- File pgf.gd.examples.SimpleDemo +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + +declare { + key = "simple demo layout", + algorithm = { + run = + function (self) + local g = self.digraph + local alpha = (2 * math.pi) / #g.vertices + + for i,vertex in ipairs(g.vertices) do + local radius = vertex.options['radius'] or g.options['radius'] + vertex.pos.x = radius * math.cos(i * alpha) + vertex.pos.y = radius * math.sin(i * alpha) + end + end + }, + summary = "This algorithm is the 'Hello World' of graph drawing.", + documentation = [[" + This algorithm arranges nodes in a circle ... + "]] +} +\end{codeexample} + + On the display layer (\tikzname, that is) the algorithm can now + immediately be employed; you just need to say + |\usegdlibrary{examples.SimpleDemo}| at the beginning + somewhere. + "]=] +}
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleEdgeDemo.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleEdgeDemo.lua new file mode 100644 index 00000000000..2becd305cf1 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleEdgeDemo.lua @@ -0,0 +1,142 @@ +-- Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster +-- 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/examples/SimpleEdgeDemo.lua,v 1.3 2013/12/20 14:44:46 tantau Exp $ + + +--- +-- @section subsubsection {How To Generate Edges Inside an Algorithm} +-- +-- @end + + +-- Imports +local InterfaceToAlgorithms = require "pgf.gd.interface.InterfaceToAlgorithms" +local declare = InterfaceToAlgorithms.declare + +-- The class object +local SimpleEdgeDemo = {} + + +--- +declare { + key = "simple edge demo layout", + algorithm = SimpleEdgeDemo, + + summary = "This algorithm shows how edges can be created by an algorithm.", + documentation = [[" + For its job, the algorithm uses the function |createEdge|, which can be + called during the run of the algorithm to create edges in the + syntactic graph. The algorithm first does exactly the same as the + simple demo layout, then it creates an edge for every node where the + |new edge to| option is set. You will see in the code how this + option is declared and how we use it to look up a vertex in the + graph by its name. + +\begin{codeexample}[] +\tikz [simple edge demo layout] +\graph [radius=2cm] { + a, b, c, d, e, f; + + e -> [red] f; % normal edge + + % Edges generated by the algorithm: + a[new edge to=b]; + b[new edge to=d]; + c[new edge to=f]; +}; +\end{codeexample} + + And the algorithm: +\begin{codeexample}[code only, tikz syntax=false] + -- File pgf.gd.examples.SimpleEdgeDemo + + -- Imports + local InterfaceToAlgorithms = require "pgf.gd.interface.InterfaceToAlgorithms" + local declare = InterfaceToAlgorithms.declare + + -- The class object + local SimpleEdgeDemo = {} + +declare { + key = "simple edge demo layout", + algorithm = SimpleEdgeDemo, + summary = "This algorithm shows...", +} +\end{codeexample} + + Next comes the declaration of the new option |new edge to|: + +\begin{codeexample}[code only, tikz syntax=false] +declare { + key = "new edge to", + type = "string", + summary = "This option takes the name of a vertex..." +} +\end{codeexample} + + Finally, the algorithm's code: + +\begin{codeexample}[code only, tikz syntax=false] +function SimpleEdgeDemo:run() + -- As in a SimpleDemo: + ... + -- Now add some edges: + for _,tail in ipairs(g.vertices) do + local name = tail.options['new edge to'] + if name then + local node = InterfaceToAlgorithms.findVertexByName(name) + if node and self.digraph:contains(node) then + InterfaceToAlgorithms.createEdge (self, tail, node) + end + end + end +end +\end{codeexample} + "]] +} + +--- +declare { + key = "new edge to", + type = "string", + + summary = [[" + This option takes the name of a vertex. An edge leading to this + vertex is added to the syntactic digraph. + "]] +} + + +function SimpleEdgeDemo:run() + + -- As in a SimpleDemo: + local g = self.digraph + local alpha = (2 * math.pi) / #g.vertices + + for i,vertex in ipairs(g.vertices) do + local radius = vertex.options['radius'] or g.options['radius'] + vertex.pos.x = radius * math.cos(i * alpha) + vertex.pos.y = radius * math.sin(i * alpha) + end + + -- Now add some edges: + for _,tail in ipairs(g.vertices) do + local name = tail.options['new edge to'] + if name then + local node = InterfaceToAlgorithms.findVertexByName(name) + if node and self.digraph:contains(node) then + InterfaceToAlgorithms.createEdge (self, tail, node) + end + end + end +end + +return SimpleEdgeDemo
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleHuffman.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleHuffman.lua new file mode 100644 index 00000000000..1e3bd381e79 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleHuffman.lua @@ -0,0 +1,277 @@ +-- 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/examples/SimpleHuffman.lua,v 1.5 2013/12/20 14:44:46 tantau Exp $ + + +--- +-- @section subsubsection {How To Generate Nodes Inside an Algorithm} +-- +-- @end + + + +-- Imports +local layered = require "pgf.gd.layered" +local InterfaceToAlgorithms = require "pgf.gd.interface.InterfaceToAlgorithms" +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + +-- The class +local SimpleHuffman = {} + + +--- + +declare { + key = "simple Huffman layout", + algorithm = SimpleHuffman, + + postconditions = { + upward_oriented = true + }, + + summary = [[" + This algorithm demonstrates how an algorithm can generate new + nodes. + "]], + documentation = [[" + The input graph should just consist of some nodes (without + edges) and each node should have a |probability| key set. The nodes + will then be arranged in a line (as siblings) and a Huffman tree + will be constructed ``above'' these nodes. For the construction of + the Huffman tree, new nodes are created and connected. + + \pgfgdset{ + HuffmanLabel/.style={/tikz/edge node={node[fill=white,font=\footnotesize,inner sep=1pt]{#1}}}, + HuffmanNode/.style={/tikz/.cd,circle,inner sep=0pt,outer sep=0pt,draw,minimum size=3pt} + } + +\begin{codeexample}[] +\tikz \graph [simple Huffman layout, + level distance=7mm, sibling distance=8mm, grow'=up] +{ + a ["0.5", probability=0.5], + b ["0.12", probability=0.12], + c ["0.2", probability=0.2], + d ["0.1", probability=0.1], + e ["0.11", probability=0.11] +}; +\end{codeexample} + The file starts with some setups and declarations: +\begin{codeexample}[code only, tikz syntax=false] +-- File pgf.gd.examples.SimpleHuffman + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + +-- The class +local SimpleHuffman = {} + +declare { + key = "simple Huffman layout", + algorithm = SimpleHuffman, + postconditions = { upward_oriented = true } + summary = "..." +} + +declare { + key = "probability", + type = "number", + initial = "1", + summary = "..." +} + +-- Import +local layered = require "pgf.gd.layered" +local InterfaceToAlgorithms = require "pgf.gd.interface.InterfaceToAlgorithms" +local Storage = require "pgf.gd.lib.Storage" + +local probability = Storage.new() +local layer = Storage.new() + +function SimpleHuffman:run() + -- Construct a Huffman tree on top of the vertices... +\end{codeexample} + + Next comes a setup, where we create the working list of vertices + that changes as the Huffman coding method proceeds: +\begin{codeexample}[code only, tikz syntax=false] + -- Shorthand + local function prop (v) + return probability[v] or v.options['probability'] + end + + -- Copy the vertex table, since we are going to modify it: + local vertices = {} + for i,v in ipairs(self.ugraph.vertices) do + vertices[i] = v + end +\end{codeexample} + + The initial vertices are arranged in a line on the last layer. The + function |ideal_sibling_distance| takes care of the rather + complicated handling of the (possibly rotated) bounding boxes and + separations. The |props| and |layer| are tables used by + algorithms to ``store stuff'' at a vertex or at an arc. The + table will be accessed by |arrange_layers_by_baselines| to + determine the ideal vertical placements. +\begin{codeexample}[code only, tikz syntax=false] + -- Now, arrange the nodes in a line: + vertices [1].pos.x = 0 + layer[ vertices [1] ] = #vertices + for i=2,#vertices do + local d = layered.ideal_sibling_distance(self.adjusted_bb, self.ugraph, vertices[i-1], vertices[i]) + vertices [i].pos.x = vertices[i-1].pos.x + d + layer[ vertices [i] ] = #vertices + end +\end{codeexample} + + Now comes the actual Huffman algorithm: Always find the vertices + with a minimal probability\dots +\begin{codeexample}[code only, tikz syntax=false] + -- Now, do the Huffman thing... + while #vertices > 1 do + -- Find two minimum probabilities + local min1, min2 + + for i=1,#vertices do + if not min1 or prop(vertices[i]) < prop(vertices[min1]) then + min2 = min1 + min1 = i + elseif not min2 or prop(vertices[i]) < prop(vertices[min2]) then + min2 = i + end + end +\end{codeexample} + \dots and connect them with a new node. This new node gets the + option |HuffmanNode|. It is now the job of the higher layers to map + this option to something ``nice''. +\begin{codeexample}[code only, tikz syntax=false] + -- Create new node: + local p = prop(vertices[min1]) + prop(vertices[min2]) + local v = InterfaceToAlgorithms.createVertex(self, { generated_options = {{key="HuffmanNode"}}}) + probability[v] = p + layer[v] = #vertices-1 + v.pos.x = (vertices[min1].pos.x + vertices[min2].pos.x)/2 + vertices[#vertices + 1] = v + + InterfaceToAlgorithms.createEdge (self, v, vertices[min1], + {generated_options = {{key="HuffmanLabel", value = "0"}}}) + InterfaceToAlgorithms.createEdge (self, v, vertices[min2], + {generated_options = {{key="HuffmanLabel", value = "1"}}}) + + table.remove(vertices, math.max(min1, min2)) + table.remove(vertices, math.min(min1, min2)) + end +\end{codeexample} + Ok, we are mainly done now. Finish by computing vertical placements + and do formal cleanup. +\begin{codeexample}[code only, tikz syntax=false] + layered.arrange_layers_by_baselines(layers, self.adjusted_bb, self.ugraph) +end +\end{codeexample} + + In order to use the class, we have to make sure that, on the + display layer, the options |HuffmanLabel| and |HuffmanNode| are + defined. This is done by adding, for instance, the following to + \tikzname: +\begin{codeexample}[code only] +\pgfkeys{ + /graph drawing/HuffmanLabel/.style={ + /tikz/edge node={node[fill=white,font=\footnotesize,inner sep=1pt]{#1}} + }, + /graph drawing/HuffmanNode/.style={ + /tikz/.cd,circle,inner sep=0pt,outer sep=0pt,draw,minimum size=3pt + } +} +\end{codeexample} + "]] +} + + +--- + +declare { + key = "probability", + type = "number", + initial = "1", + + summary = [[" + The probability parameter. It is used by the Huffman algorithm to + group nodes. + "]] +} + +-- Imports + +local Storage = require 'pgf.gd.lib.Storage' + +-- Storages + +local probability = Storage.new() +local layer = Storage.new() + + +function SimpleHuffman:run() + -- Construct a Huffman tree on top of the vertices... + + -- Shorthand + local function prop (v) + return probability[v] or v.options['probability'] + end + + -- Copy the vertex table, since we are going to modify it: + local vertices = {} + for i,v in ipairs(self.ugraph.vertices) do + vertices[i] = v + end + + -- Now, arrange the nodes in a line: + vertices [1].pos.x = 0 + layer[vertices [1]] = #vertices + for i=2,#vertices do + local d = layered.ideal_sibling_distance(self.adjusted_bb, self.ugraph, vertices[i-1], vertices[i]) + vertices [i].pos.x = vertices[i-1].pos.x + d + layer[vertices [i]] = #vertices + end + + -- Now, do the Huffman thing... + while #vertices > 1 do + -- Find two minimum probabilities + local min1, min2 + + for i=1,#vertices do + if not min1 or prop(vertices[i]) < prop(vertices[min1]) then + min2 = min1 + min1 = i + elseif not min2 or prop(vertices[i]) < prop(vertices[min2]) then + min2 = i + end + end + + -- Create new node: + local p = prop(vertices[min1]) + prop(vertices[min2]) + local v = InterfaceToAlgorithms.createVertex(self, { generated_options = {{key="HuffmanNode"}}}) + probability[v] = p + layer[v] = #vertices-1 + v.pos.x = (vertices[min1].pos.x + vertices[min2].pos.x)/2 + vertices[#vertices + 1] = v + + InterfaceToAlgorithms.createEdge (self, v, vertices[min1], + {generated_options = {{key="HuffmanLabel", value = "0"}}}) + InterfaceToAlgorithms.createEdge (self, v, vertices[min2], + {generated_options = {{key="HuffmanLabel", value = "1"}}}) + + table.remove(vertices, math.max(min1, min2)) + table.remove(vertices, math.min(min1, min2)) + end + + layered.arrange_layers_by_baselines(layer, self.adjusted_bb, self.ugraph) +end + +return SimpleHuffman
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/example_graph_for_ascii_displayer.txt b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/example_graph_for_ascii_displayer.txt new file mode 100644 index 00000000000..052ebdcdb81 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/example_graph_for_ascii_displayer.txt @@ -0,0 +1,20 @@ +graph [layered layout] { + Alice; + Bob; + Charly; + Dave; + Eve; + Fritz; + George; + Alice -> Bob; + Alice -> Charly; + Charly -> Dave; + Bob -> Dave; + Dave -> Eve; + Eve -> Fritz; + Fritz -> Alice; + George -> Eve; + George -> Fritz; + Alice -> George; +} + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/library.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/library.lua new file mode 100644 index 00000000000..0c8038d3148 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/library.lua @@ -0,0 +1,30 @@ +-- 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/examples/library.lua,v 1.2 2013/04/04 20:43:45 tantau Exp $ + + + +--- +-- This package presents some examples of how different aspects of the +-- graph drawing engine can be used. In particular, the algorithms of +-- this package are not really meant to be used to layout graphs +-- (although they can be used, in principle); rather you are invited +-- to have a look at their implementation and to adapt them to your needs. +-- +-- @library + +local examples + + +-- Load algorithms from: +require "pgf.gd.examples.SimpleDemo" +require "pgf.gd.examples.SimpleEdgeDemo" +require "pgf.gd.examples.SimpleHuffman" + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force.lua new file mode 100644 index 00000000000..cb30ec17914 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force.lua @@ -0,0 +1,26 @@ +-- 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/force.lua,v 1.1 2012/11/27 17:24:23 tantau Exp $ + + + +-- Imports + +require "pgf" +require "pgf.gd" + + +-- Declare namespace +pgf.gd.force = {} + + +-- Done + +return pgf.gd.force
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/CoarseGraph.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/CoarseGraph.lua new file mode 100644 index 00000000000..c9739dcaf63 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/CoarseGraph.lua @@ -0,0 +1,435 @@ +-- Copyright 2011 by Jannis Pohlmann +-- 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/force/CoarseGraph.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + +--- A class for handling "coarse" versions of a graph. Such versions contain +-- less nodes and edges than the original graph while retaining the overall +-- structure. + +local Graph = require "pgf.gd.deprecated.Graph" -- we subclass from here +local CoarseGraph = Graph.new() +CoarseGraph.__index = CoarseGraph + + + +-- Namespace: +local force = require "pgf.gd.force" +force.CoarseGraph = CoarseGraph + + +-- Imports +local Node = require "pgf.gd.deprecated.Node" +local Edge = require "pgf.gd.deprecated.Edge" + +local lib = require "pgf.gd.lib" + + +-- Class setup + +CoarseGraph.COARSEN_INDEPENDENT_EDGES = 0 -- TT: Remark: These uppercase constants are *ugly*. Why do people do this?! +CoarseGraph.COARSEN_INDEPENDENT_NODES = 1 +CoarseGraph.COARSEN_HYBRID = 2 + + + +--- Creates a new coarse graph derived from an existing graph. +-- +-- Generates a coarse graph for the input |Graph|. +-- +-- Coarsening describes the process of reducing the amount of nodes in a graph +-- by merging nodes into supernodes. There are different strategies, called +-- schemes, that can be applied, like merging nodes that belong to edges in a +-- maximal independent edge set or by creating supernodes based on a maximal +-- independent node set. +-- +-- Coarsening is not performed automatically. The functions |CoarseGraph:coarsen| +-- and |CoarseGraph:interpolate| can be used to further coarsen the graph or +-- to restore the previous state (while interpolating the node positions from +-- the coarser version of the graph). +-- +-- Note, however, that the input \meta{graph} is always modified in-place, so +-- if the original version of \meta{graph} is needed in parallel to its +-- coarse representations, a deep copy of \meta{grpah} needs to be passed over +-- to |CoarseGraph.new|. +-- +-- @param graph An existing graph that needs to be coarsened. +-- @param scheme Coarsening scheme to use. Possible values are:\par +-- |CoarseGraph.COARSEN_INDEPENDENT_EDGES|: +-- Coarsen the input graph by computing a maximal independent edge set +-- and collapsing edges from this set. The resulting coarse graph has +-- at least 50% of the nodes of the input graph. This coarsening scheme +-- gives slightly better results than +-- |CoarseGraph.COARSEN_INDEPENDENT_NODES| because it is less aggressive. +-- However, this comes at higher computational cost.\par +-- |CoarseGraph.COARSEN_INDEPENDENT_NODES|: +-- Coarsen the input graph by computing a maximal independent node set, +-- making nodes from this set supernodes in the coarse graph, merging +-- adjacent nodes into the supernodes and connecting the supernodes +-- if their grpah distance is no greater than three. This scheme gives +-- slightly worse results than |CoarseGraph.COARSEN_INDEPENDENT_EDGES| +-- but is computationally more efficient.\par +-- |CoarseGraph.COARSEN_HYBRID|: Combines the other schemes by starting +-- with |CoarseGraph.COARSEN_INDEPENDENT_EDGES| and switching to +-- |CoarseGraph.COARSEN_INDEPENDENT_NODES| as soon as the first scheme +-- does not reduce the amount of nodes by a factor of 25%. +-- +function CoarseGraph.new(graph, scheme) + local coarse_graph = { + graph = graph, + level = 0, + scheme = scheme or CoarseGraph.COARSEN_INDEPENDENT_EDGES, + ratio = 0, + } + setmetatable(coarse_graph, CoarseGraph) + return coarse_graph +end + + + +local function custom_merge(table1, table2, first_metatable) + local result = table1 and lib.copy(table1) or {} + local first_metatable = first_metatable == true or false + + for key, value in pairs(table2) do + if not result[key] then + result[key] = value + end + end + + if not first_metatable or not getmetatable(result) then + setmetatable(result, getmetatable(table2)) + end + + return result +end + + +local function pairs_by_sorted_keys (t, f) + local a = {} + for n in pairs(t) do a[#a + 1] = n end + table.sort (a, f) + local i = 0 + return function () + i = i + 1 + return a[i], t[a[i]] + end +end + + + +function CoarseGraph:coarsen() + -- update the level + self.level = self.level + 1 + + local old_graph_size = #self.graph.nodes + + if self.scheme == CoarseGraph.COARSEN_INDEPENDENT_EDGES then + local matching, unmatched_nodes = self:findMaximalMatching() + + for _,edge in ipairs(matching) do + -- get the two nodes of the edge that we are about to collapse + local u, v = edge.nodes[1], edge.nodes[2] + + assert(u ~= v, 'the edge ' .. tostring(edge) .. ' is a loop. loops are not supported by this algorithm') + + -- create a supernode + local supernode = Node.new{ + name = '(' .. u.name .. ':' .. v.name .. ')', + weight = u.weight + v.weight, + subnodes = { u, v }, + subnode_edge = edge, + level = self.level, + } + + -- add the supernode to the graph + self.graph:addNode(supernode) + + -- collact all neighbours of the nodes to merge, create a node -> edge mapping + local u_neighbours = lib.map(u.edges, function(edge) return edge, edge:getNeighbour(u) end) + local v_neighbours = lib.map(v.edges, function(edge) return edge, edge:getNeighbour(v) end) + + -- remove the two nodes themselves from the neighbour lists + u_neighbours = lib.map(u_neighbours, function (edge,node) if node ~= v then return edge,node end end) + v_neighbours = lib.map(v_neighbours, function (edge,node) if node ~= u then return edge,node end end) + + -- compute a list of neighbours u and v have in common + local common_neighbours = lib.map(u_neighbours, + function (edge,node) + if v_neighbours[node] ~= nil then return edge,node end + end) + + -- create a node -> edges mapping for common neighbours + common_neighbours = lib.map(common_neighbours, function (edge, node) + return { edge, v_neighbours[node] }, node + end) + + -- drop common edges from the neighbour mappings + u_neighbours = lib.map(u_neighbours, function (val,node) if not common_neighbours[node] then return val,node end end) + v_neighbours = lib.map(v_neighbours, function (val,node) if not common_neighbours[node] then return val,node end end) + + -- merge neighbour lists + local disjoint_neighbours = custom_merge(u_neighbours, v_neighbours) + + -- create edges between the supernode and the neighbours of the merged nodes + for neighbour, edge in pairs_by_sorted_keys(disjoint_neighbours, function (n,m) return n.index < m.index end) do + + -- create a superedge to replace the existing one + local superedge = Edge.new{ + direction = edge.direction, + weight = edge.weight, + subedges = { edge }, + level = self.level, + } + + -- add the supernode and the neighbour to the edge + if u_neighbours[neighbour] then + superedge:addNode(neighbour) + superedge:addNode(supernode) + + else + superedge:addNode(supernode) + superedge:addNode(neighbour) + + end + + -- replace the old edge + self.graph:addEdge(superedge) + self.graph:deleteEdge(edge) + end + + -- do the same for all neighbours that the merged nodes have + -- in common, except that the weights of the new edges are the + -- sums of the of the weights of the edges to the common neighbours + for neighbour, edges in pairs_by_sorted_keys(common_neighbours, function (n,m) return n.index < m.index end) do + local weights = 0 + for _,e in ipairs(edges) do + weights = weights + edge.weight + end + + local superedge = Edge.new{ + direction = Edge.UNDIRECTED, + weight = weights, + subedges = edges, + level = self.level, + } + + -- add the supernode and the neighbour to the edge + superedge:addNode(supernode) + superedge:addNode(neighbour) + + -- replace the old edges + self.graph:addEdge(superedge) + for _,edge in ipairs(edges) do + self.graph:deleteEdge(edge) + end + end + + -- delete the nodes u and v which were replaced by the supernode + assert(#u.edges == 1, 'node ' .. u.name .. ' is part of a multiedge') -- if this fails, then there is a multiedge involving u + assert(#v.edges == 1, 'node ' .. v.name .. ' is part of a multiedge') -- same here + self.graph:deleteNode(u) + self.graph:deleteNode(v) + end + else + assert(false, 'schemes other than CoarseGraph.COARSEN_INDEPENDENT_EDGES are not implemented yet') + end + + -- calculate the number of nodes ratio compared to the previous graph + self.ratio = #self.graph.nodes / old_graph_size +end + + + +function CoarseGraph:revertSuperedge(superedge) + -- TODO we can probably skip adding edges that have one or more + -- subedges with the same level. But that needs more testing. + + -- TODO we might have to pass the corresponding supernode to + -- this method so that we can move subnodes to the same + -- position, right? Interpolating seems to work fine without + -- though... + + if #superedge.subedges == 1 then + local subedge = superedge.subedges[1] + + if not self.graph:findNode(subedge.nodes[1].name) then + self.graph:addNode(subedge.nodes[1]) + end + + if not self.graph:findNode(subedge.nodes[2].name) then + self.graph:addNode(subedge.nodes[2]) + end + + if not self.graph:findEdge(subedge) then + subedge.nodes[1]:addEdge(subedge) + subedge.nodes[2]:addEdge(subedge) + self.graph:addEdge(subedge) + end + + if subedge.level and subedge.level >= self.level then + self:revertSuperedge(subedge) + end + else + for _,subedge in ipairs(superedge.subedges) do + if not self.graph:findNode(subedge.nodes[1].name) then + self.graph:addNode(subedge.nodes[1]) + end + + if not self.graph:findNode(subedge.nodes[2].name) then + self.graph:addNode(subedge.nodes[2]) + end + + if not self.graph:findEdge(subedge) then + subedge.nodes[1]:addEdge(subedge) + subedge.nodes[2]:addEdge(subedge) + self.graph:addEdge(subedge) + end + + if subedge.level and subedge.level >= self.level then + self:revertSuperedge(subedge) + end + end + end +end + + + +function CoarseGraph:interpolate() + -- FIXME TODO Jannis: This does not work now that we allow multi-edges + -- and loops! Reverting generates the same edges multiple times which leads + -- to distorted drawings compared to the awesome results we had before! + + local nodes = lib.copy(self.graph.nodes) + + for _,supernode in ipairs(nodes) do + assert(not supernode.level or supernode.level <= self.level) + + if supernode.level and supernode.level == self.level then + -- move the subnode to the position of the supernode and add it to the graph + supernode.subnodes[1].pos.x = supernode.pos.x + supernode.subnodes[1].pos.y = supernode.pos.y + + if not self.graph:findNode(supernode.subnodes[1].name) then + self.graph:addNode(supernode.subnodes[1]) + end + + -- move the subnode to the position of the supernode and add it to the graph + supernode.subnodes[2].pos.x = supernode.pos.x + supernode.subnodes[2].pos.y = supernode.pos.y + + if not self.graph:findNode(supernode.subnodes[2].name) then + self.graph:addNode(supernode.subnodes[2]) + end + + if not self.graph:findEdge(supernode.subnode_edge) then + supernode.subnodes[1]:addEdge(supernode.subnode_edge) + supernode.subnodes[2]:addEdge(supernode.subnode_edge) + self.graph:addEdge(supernode.subnode_edge) + end + + local superedges = lib.copy(supernode.edges) + + for _,superedge in ipairs(superedges) do + self:revertSuperedge(superedge) + end + + self.graph:deleteNode(supernode) + end + end + + -- Make sure that the nodes and edges are in the correct order: + table.sort (self.graph.nodes, function (a, b) return a.index < b.index end) + table.sort (self.graph.edges, function (a, b) return a.index < b.index end) + for _, n in pairs(self.graph.nodes) do + table.sort (n.edges, function (a, b) return a.index < b.index end) + end + + -- update the level + self.level = self.level - 1 +end + + + +function CoarseGraph:getSize() + return #self.graph.nodes +end + + + +function CoarseGraph:getRatio() + return self.ratio +end + + + +function CoarseGraph:getLevel() + return self.level +end + + + +function CoarseGraph:getGraph() + return self.graph +end + + + +function CoarseGraph:findMaximalMatching() + local matching = {} + local matched_nodes = {} + local unmatched_nodes = {} + + -- iterate over nodes in random order + for _,j in ipairs(lib.random_permutation(#self.graph.nodes)) do + local node = self.graph.nodes[j] + -- ignore nodes that have already been matched + if not matched_nodes[node] then + -- mark the node as matched + matched_nodes[node] = true + + -- filter out edges adjacent to neighbours already matched + local edges = lib.imap(node.edges, + function (edge) + if not matched_nodes[edge:getNeighbour(node)] then return edge end + end) + + -- FIXME TODO We use a light-vertex matching here. This is + -- different from the algorithm proposed by Hu which collapses + -- edges based on a heavy-edge matching... + if #edges > 0 then + -- sort edges by the weights of the node's neighbours + table.sort(edges, function (a, b) + return a:getNeighbour(node).weight < b:getNeighbour(node).weight + end) + + -- match the node against the neighbour with minimum weight + matched_nodes[edges[1]:getNeighbour(node)] = true + table.insert(matching, edges[1]) + end + end + end + + -- generate a list of nodes that were not matched at all + for _,j in ipairs(lib.random_permutation(#self.graph.nodes)) do + local node = self.graph.nodes[j] + if not matched_nodes[node] then + table.insert(unmatched_nodes, node) + end + end + + return matching, unmatched_nodes +end + + +-- done + +return CoarseGraph
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/Control.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/Control.lua new file mode 100644 index 00000000000..113f54b7ace --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/Control.lua @@ -0,0 +1,28 @@ +-- 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/force/Control.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + +--- +-- @section subsection {Controlling and Configuring Force-Based Algorithms} +-- +-- All force-based algorithms are based on +-- a general pattern which we detail in the following. Numerous options +-- can be used to influence the behaviour of this general pattern; more +-- specific options that apply only to individual algorithms are +-- explained along with these algorithms. +-- +-- @end + + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlCoarsening.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlCoarsening.lua new file mode 100644 index 00000000000..330f401d5b5 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlCoarsening.lua @@ -0,0 +1,148 @@ +-- 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/force/ControlCoarsening.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + +--- +-- @section subsubsection {Coarsening} +-- +-- @end + + +--- + +declare { + key = "coarsen", + type = "boolean", + initial = "true", + + summary = [[" + Defines whether or not a multilevel approach is used that + iteratively coarsens the input graph into graphs $G_1,\dots,G_l$ + with a smaller and smaller number of nodes. The coarsening stops as + soon as a minimum number of nodes is reached, as set via the + |minimum coarsening size| option, or if, in the last iteration, the + number of nodes was not reduced by at least the ratio specified via + |downsize ratio|. + "]], + documentation = [[" + A random initial layout is computed for the coarsest graph $G_l$ first. + Afterwards, it is laid out by computing the attractive and repulsive + forces between its nodes. + + In the subsequent steps, the previous coarse graph $G_{l-1}$ is + restored and its node positions are interpolated from the nodes + in~$G_l$. The graph $G_{l-1}$ is again laid out by computing the forces + between its nodes. These steps are repeated with $G_{l-2},\dots,G_1$ until + the original input graph $G_0$ has been restored, interpolated + and laid out. + + The idea behind this approach is that, by arranging recursively + formed supernodes first and then interpolating and arranging their + subnodes step by step, the algorithm is less likely to settle in a + local energy minimum (of which there can be many, particularly for + large graphs). The quality of the drawings with coarsening enabled is + expected to be higher than graphics where this feature is not applied. + + The following example demonstrates how coarsening can improve the + quality of graph drawings generated with Walshaw's algorihtm + |spring electrical layout'|. + "]], + examples = [[" + \tikz \graph [spring electrical layout', coarsen=false, vertical=3 to 4] + { + { [clique] 1, 2 } -- 3 -- 4 -- { 5, 6, 7 } + }; + + \tikz \graph [spring electrical layout', coarsen, vertical=3 to 4] + { + { [clique] 1, 2 } -- 3 -- 4 -- { 5, 6, 7 } + }; + "]] +} + +--- + +declare { + key = "minimum coarsening size", + type = "number", + initial = 2, + + summary = [[" + Defines the minimum number of nodes down to which the graph is + coarsened iteratively. The first graph that has a smaller or equal + number of nodes becomes the coarsest graph $G_l$, where $l$ is the + number of coarsening steps. The algorithm proceeds with the steps + described in the documentation of the |coarsen| option. + "]], + documentation = [[" + In the following example the same graph is coarsened down to two + and four nodes, respectively. The layout of the original graph is + interpolated from the random initial layout and is not improved + further because the forces are not computed (0 iterations). Thus, + in the two graphs, the nodes are placed at exactly two and four + coordinates in the final drawing. + "]], + examples = [[" + \tikz \graph [spring layout, iterations=0, + minimum coarsening size=2] + { subgraph C_n [n=8] }; + + \tikz \graph [spring layout, iterations=0, + minimum coarsening size=4] + { subgraph C_n [n=8] }; + "]] +} + +--- + +declare { + key = "downsize ratio", + type = "number", + initial = "0.25", + + summary = [[" + Minimum ratio between 0 and 1 by which the number of nodes between + two coarse graphs $G_i$ and $G_{i+1}$ need to be reduced in order for + the coarsening to stop and for the algorithm to use $G_{i+1}$ as the + coarsest graph $G_l$. Aside from the input graph, the optimal value + of |downsize ratio| mostly depends on the coarsening scheme being + used. Possible schemes are |collapse independent edges| and + |connect independent nodes|. + "]], + documentation = [[" + Increasing this option possibly reduces the number of coarse + graphs computed during the coarsening phase as coarsening will stop as + soon as a coarse graph does not reduce the number of nodes + substantially. This may speed up the algorithm but if the size of the + coarsest graph $G_l$ is much larger than |minimum coarsening size|, the + multilevel approach may not produce drawings as good as with a lower + |downsize ratio|. + "]], + examples = [[" + % 1. ratio too high, coarsening stops early, benefits are lost + \tikz \graph [spring electrical layout', + downsize ratio=1.0, + node distance=7mm, vertical=3 to 4] + { { [clique] 1, 2 } -- 3 -- 4 -- { 5, 6, 7 } }; + + % 2. ratio set to default, coarsening benefits are visible + \tikz \graph [spring electrical layout', + downsize ratio=0.2, + node distance=7mm, vertical=3 to 4] + { { [clique] 1, 2 } -- 3 -- 4 -- { 5, 6, 7 } }; + "]] +} + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlElectric.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlElectric.lua new file mode 100644 index 00000000000..d708bd6d7b7 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlElectric.lua @@ -0,0 +1,100 @@ +-- 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/force/ControlElectric.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + +--- +-- @section subsubsection {Forces and Their Effects: Electrical +-- Repulsion} +-- +-- @end + + +--- + +declare { + key = "electric charge", + type = "number", + initial = 1, + + summary = [[" + Defines the electric charge of the node. The stronger the + |electric charge| of a node the stronger the repulsion between the + node and others in the graph. A negative |electric charge| means that + other nodes are further attracted to the node rather than repulsed, + although in theory this effect strongly depends on how the + |spring electrical layout| algorithm works. + Two typcal effects of increasing the |electric charge| are distortion + of symmetries and an upscaling of the drawings. + "]], + examples = { + [[" + \tikz \graph [spring electrical layout, horizontal=0 to 1] + { 0 [electric charge=1] -- subgraph C_n [n=10] }; + "]], + [[" + \tikz \graph [spring electrical layout, horizontal=0 to 1] + { 0 [electric charge=5] -- subgraph C_n [n=10] }; + "]], + [[" + \tikz \graph [spring electrical layout, horizontal=0 to 1] + { [clique] 1 [electric charge=5], 2, 3, 4 }; + "]] + } +} + + +--- + +declare { + key = "electric force order", + type = "number", + initial = "1", + + summary = [[" + Sometimes, when drawing symmetric and mesh-like graphs, the + peripheral distortion caused by long-range electric forces may be + undesired. Some electric force models allow to reduce long-range + forces and distortion effects by increasing + the order (epxonent) of electric forces. Values between 0 and 1 + increase long-range electric forces and the scaling of the + generated layouts. Value greater than 1 decrease long-range + electric forces and results in shrinking drawings. + "]] + } + + +--- + +declare { + key = "approximate remote forces", + type = "boolean", + + summary = [[" + Force based algorithms often need to compute a force for each pair + of vertices, which, for larger numbers of vertices, can lead to a + significant time overhead. This problem can be addressed by + approximating these forces: For a vertex far removed from a cluster + of vertices, instead of computing the force contribution of each + vertex of the cluster indiviually, we form a sort of + ``supervertex'' at the ``gravitational center'' of the cluster and + then compute only the force between this supervertex and the single + vertex. + + \emph{Remark:} Currently, the implementation seems to be broken, at + least the results are somewhat strange when this key is used. + "]] + } + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlIteration.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlIteration.lua new file mode 100644 index 00000000000..f07f23aeac3 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlIteration.lua @@ -0,0 +1,144 @@ +-- 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/force/ControlIteration.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + + +--- +-- @section subsubsection {The Iterative Process and Cooling} +-- +-- @end + + + +--- + +declare { + key = "iterations", + type = "number", + initial = "500", + + summary = [[" + Limits the number of iterations of algorithms for force-based + layouts to \meta{number}. + "]], + documentation = [[" + Depending on the characteristics of the input graph and the parameters + chosen for the algorithm, minimizing the system energy may require + many iterations. + + In these situations it may come in handy to limit the number of + iterations. This feature can also be useful to draw the same graph + after different iterations and thereby demonstrate how the spring or + spring-electrical algorithm improves the drawing step by step. + + The examples shows two drawings generated using two + different |iteration| limits. + "]], + examples = { + [[" + \tikz \graph [spring layout, iterations=10] { subgraph K_n [n=4] }; + "]], + [[" + \tikz \graph [spring layout, iterations=500] { subgraph K_n [n=4] }; + "]], + [[" + \tikz \graph [spring electrical layout, iterations=10] + { subgraph K_n [n=4] }; + "]], + [[" + \tikz \graph [spring electrical layout, iterations=500] + { subgraph K_n [n=4] }; + "]] + } +} + +--- + +declare { + key = "initial step length", + type = "length", + initial = "0", + + summary = [[" + This parameter specifies the amount by which nodes will be + displaced in each iteration, initially. If set to |0| (which is the + default), an appropriate value is computed automatically. + "]] + } + +--- + +declare { + key = "cooling factor", + type = "number", + initial = "0.95", + + summary = [[" + This parameter helps in controlling how layouts evolve over + time. It is used to gradually reduce the step size + between one iteration to the next. + "]], + documentation = [[" + A small positive cooling factor + $\ge 0$ means that the movement of nodes is quickly or abruptly + reduced, while a large cooling factor $\le 1$ allows for a smoother + step by step layout refinement at the cost of more iterations. The + following example demonstrates how a smaller cooling factor may + result in a less balanced drawing. By default, Hu2006 spring, + Hu2006 spring electrical, and Walshaw2000 spring electrical use a + cooling factor of |0.95|. + "]], + examples = { + [[" + \tikz \graph [spring layout, cooling factor=0.1] + { a -> b -> c -> a }; + "]], + [[" + \tikz \graph [spring layout, cooling factor=0.5] + { a -> b -> c -> a }; + "]] + } +} + +--- + +declare { + key = "convergence tolerance", + type = "number", + initial = "0.01", + + summary = [[" + All spring and spring-electrical algorithms implemented in the + thesis terminate as soon as the maximum movement of any node drops + below $k \cdot \meta{tolerance}$. This tolerance factor can be changed + with the convergence tolerance option: + "]], + examples = { + [[" + \tikz \graph [spring layout, convergence tolerance=0.001] + { { [clique] 1, 2 } -- 3 -- 4 -- { 5, 6, 7 } }; + "]], + [[" + \tikz \graph [spring layout, convergence tolerance=1.0] + { { [clique] 1, 2 } -- 3 -- 4 -- { 5, 6, 7 } }; + "]] + } +} + + + + + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlSprings.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlSprings.lua new file mode 100644 index 00000000000..2ef55169bca --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlSprings.lua @@ -0,0 +1,58 @@ +-- 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/force/ControlSprings.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + +--- +-- @section subsubsection {Forces and Their Effects: Springs} +-- +-- The most important parameter of springs is their ``natural +-- length'', which can be configured using the general-purpose +-- |node distance| parameter. It is the ``equilibrium length'' of a +-- spring between two nodes in the graph. When an edge has this +-- lenght, no forces will ``push'' or ``pull'' along the edge. +-- +-- The following examples shows how a simple graph can be scaled by +-- changing the |node distance|: +-- \begin{codeexample}[] +-- \tikz \graph [spring layout, node distance=7mm] { subgraph C_n[n=3] }; +-- \tikz \graph [spring layout] { subgraph C_n[n=3] }; +-- \tikz \graph [spring layout, node distance=15mm]{ subgraph C_n[n=3] }; +-- \end{codeexample} +-- \begin{codeexample}[] +-- \tikz \graph [spring electrical layout, node distance=0.7cm] { subgraph C_n[n=3] }; +-- \tikz \graph [spring electrical layout] { subgraph C_n[n=3] }; +-- \tikz \graph [spring electrical layout, node distance=1.5cm] { subgraph C_n[n=3] }; +-- \end{codeexample} +-- +-- @end + + + +--- + +declare { + key = "spring constant", + type = "number", + initial = "0.01", + + summary = [[" + The ``spring constant'' is a factor from Hooke's law describing the + ``stiffness'' of a spring. This factor is used inside spring-based + algorithms to determine how strongly edges ``pull'' and ``push'' at + the nodes they connect. + "]] + } + + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlStart.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlStart.lua new file mode 100644 index 00000000000..6b93f311290 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlStart.lua @@ -0,0 +1,40 @@ +-- 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/force/ControlStart.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + + +--- +-- @section subsubsection {Start Configuration} +-- +-- Currently, the start configuration for force-based algorithms is a +-- random distribution of the vertices. You can influence it by +-- changing the |random seed|: +-- +--\begin{codeexample}[] +--\tikz \graph [random seed=10, spring layout] { +-- a -- {b, c, d} -- e -- f -- {g,h} -- {a,b,e}; +--}; +--\end{codeexample} +--\begin{codeexample}[] +--\tikz \graph [random seed=11, spring layout] { +-- a -- {b, c, d} -- e -- f -- {g,h} -- {a,b,e}; +--}; +--\end{codeexample} +-- +-- Other methods, like a planar preembedding, are not implemented +-- currently. +-- +-- @end
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/QuadTree.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/QuadTree.lua new file mode 100644 index 00000000000..1a7d0abf25a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/QuadTree.lua @@ -0,0 +1,280 @@ +-- Copyright 2011 by Jannis Pohlmann +-- 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/force/QuadTree.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + +--- An implementation of a quad trees. +-- +-- The class QuadTree provides methods form handling quadtrees. +-- + +local QuadTree = { + -- Subclases + Particle = {}, + Cell = {} +} +QuadTree.__index = QuadTree + +-- Namespace: +require("pgf.gd.force").QuadTree = QuadTree + +-- Imports: +local Vector = require "pgf.gd.deprecated.Vector" +local lib = require "pgf.gd.lib" + + +--- Creates a new quad tree. +-- +-- @return A newly-allocated quad tree. +-- +function QuadTree.new(x, y, width, height, max_particles) + local tree = { + root_cell = QuadTree.Cell.new(x, y, width, height, max_particles) + } + setmetatable(tree, QuadTree) + return tree +end + + + +--- Inserts a particle +-- +-- @param param A particle of type QuadTree.Particle +-- +function QuadTree:insert(particle) + self.root_cell:insert(particle) +end + + + +--- Computes the interactions of a particle with other cells +-- +-- @param particle A particle +-- @param test_func A test function, which on input of a cubical cell and a particle should +-- decide whether the cubical cell should be inserted into the result +-- @param cells An optional array of cells, to which the found cells will be added +-- +-- @return The cells array or a new array, if it was empty. +-- +function QuadTree:findInteractionCells(particle, test_func, cells) + local test_func = test_func or function (cell, particle) return true end + cells = cells or {} + + self.root_cell:findInteractionCells(particle, test_func, cells) + + return cells +end + + + + +--- Partical subclass +QuadTree.Particle.__index = QuadTree.Particle + + + +--- Creates a new particle. +-- +-- @return A newly-allocated particle. +-- +function QuadTree.Particle.new(pos, mass) + local particle = { + pos = pos:copy(), + mass = mass or 1, + subparticles = {}, + } + setmetatable(particle, QuadTree.Particle) + return particle +end + + + +--- A cell of a quadtree +-- +-- TT: Why is it called "cubical", by the way?! + +QuadTree.Cell.__index = QuadTree.Cell + + + +--- Creates a new cubicle cell. +-- +-- @return a newly-allocated cubicle cell. +-- +function QuadTree.Cell.new(x, y, width, height, max_particles) + local cell = { + x = x, + y = y, + width = width, + height = height, + max_particles = max_particles or 1, + subcells = {}, + particles = {}, + center_of_mass = nil, + mass = 0, + } + setmetatable(cell, QuadTree.Cell) + return cell +end + + + +function QuadTree.Cell:containsParticle(particle) + return particle.pos.x >= self.x and particle.pos.x <= self.x + self.width + and particle.pos.y >= self.y and particle.pos.y <= self.y + self.height +end + + + +function QuadTree.Cell:findSubcell(particle) + return lib.find(self.subcells, function (cell) + return cell:containsParticle(particle) + end) +end + + + +function QuadTree.Cell:createSubcells() + assert(type(self.subcells) == 'table' and #self.subcells == 0) + assert(type(self.particles) == 'table' and #self.particles <= self.max_particles) + + if #self.subcells == 0 then + for _,x in ipairs({self.x, self.x + self.width/2}) do + for _,y in ipairs({self.y, self.y + self.height/2}) do + local cell = QuadTree.Cell.new(x, y, self.width/2, self.height/2, self.max_particles) + table.insert(self.subcells, cell) + end + end + end +end + + + +function QuadTree.Cell:insert(particle) + -- check if we have a particle with the exact same position already + local existing = lib.find(self.particles, function (other) + return other.pos:equals(particle.pos) + end) + + if existing then + -- we already have a particle at the same position; splitting the cell + -- up makes no sense; instead we add the new particle as a + -- subparticle of the existing one + table.insert(existing.subparticles, particle) + else + if #self.subcells == 0 and #self.particles < self.max_particles then + table.insert(self.particles, particle) + else + if #self.subcells == 0 then + self:createSubcells() + end + + -- move particles to the new subcells + for _,existing in ipairs(self.particles) do + local cell = self:findSubcell(existing) + assert(cell, 'failed to find a cell for particle ' .. tostring(existing.pos)) + cell:insert(existing) + end + + self.particles = {} + + local cell = self:findSubcell(particle) + assert(cell) + cell:insert(particle) + end + end + + self:updateMass() + self:updateCenterOfMass() + + assert(self.mass) + assert(self.center_of_mass) +end + + + +function QuadTree.Cell:updateMass() + -- reset mass to zero + self.mass = 0 + + if #self.subcells == 0 then + -- the mass is the number of particles of the cell + for _,particle in ipairs(self.particles) do + self.mass = self.mass + particle.mass + for _,subparticle in ipairs(particle.subparticles) do + self.mass = self.mass + subparticle.mass + end + end + else + -- the mass is the sum of the masses of the subcells + for _,subcell in ipairs(self.subcells) do + self.mass = self.mass + subcell.mass + end + end +end + + + +function QuadTree.Cell:updateCenterOfMass() + -- reset center of mass, assuming the cell is empty + self.center_of_mass = nil + + if #self.subcells == 0 then + -- the center of mass is the average position of the particles + -- weighted by their masses + self.center_of_mass = Vector.new (2) + for _,p in ipairs(self.particles) do + for _,sp in ipairs(p.subparticles) do + self.center_of_mass = self.center_of_mass:plus(sp.pos:timesScalar(sp.mass)) + end + self.center_of_mass = self.center_of_mass:plus(p.pos:timesScalar(p.mass)) + end + self.center_of_mass = self.center_of_mass:dividedByScalar(self.mass) + else + -- the center of mass is the average of the weighted centers of mass + -- of the subcells + self.center_of_mass = Vector.new(2) + for _,sc in ipairs(self.subcells) do + if sc.center_of_mass then + self.center_of_mass = self.center_of_mass:plus(sc.center_of_mass:timesScalar(sc.mass)) + else + assert(sc.mass == 0) + end + end + self.center_of_mass = self.center_of_mass:dividedByScalar(self.mass) + end +end + + + +function QuadTree.Cell:findInteractionCells(particle, test_func, cells) + if #self.subcells == 0 or test_func(self, particle) then + table.insert(cells, self) + else + for _,subcell in ipairs(self.subcells) do + subcell:findInteractionCells(particle, test_func, cells) + end + end +end + + +function QuadTree.Cell:__tostring() + return '((' .. self.x .. ', ' .. self.y .. ') ' + .. 'to (' .. self.x + self.width .. ', ' .. self.y + self.height .. '))' + .. (self.particle and ' => ' .. self.particle.name or '') + .. (self.center_of_mass and ' mass ' .. self.mass .. ' at ' .. tostring(self.center_of_mass) or '') +end + + + +-- done + +return QuadTree
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalHu2006.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalHu2006.lua new file mode 100644 index 00000000000..54ceddcc25a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalHu2006.lua @@ -0,0 +1,521 @@ +-- Copyright 2011 by Jannis Pohlmann +-- +-- This file may be distributed and/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/force/SpringElectricalHu2006.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + +local SpringElectricalHu2006 = {} + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + + +--- + +declare { + key = "spring electrical Hu 2006 layout", + algorithm = SpringElectricalHu2006, + + preconditions = { + connected = true, + loop_free = true, + simple = true, + }, + + old_graph_model = true, + + summary = [[" + Implementation of a spring electrical graph drawing algorithm based on + a paper by Hu. + "]], + documentation = [[" + \begin{itemize} + \item + Y. Hu. + \newblock Efficient, high-quality force-directed graph drawing. + \newblock \emph{The Mathematica Journal}, 2006. + \end{itemize} + + There are some modifications compared to the original algorithm, + see the Diploma thesis of Pohlmann for details. + "]] +} + +-- Imports + +local PathLengths = require "pgf.gd.lib.PathLengths" +local Vector = require "pgf.gd.deprecated.Vector" + +local QuadTree = require "pgf.gd.force.QuadTree" +local CoarseGraph = require "pgf.gd.force.CoarseGraph" + +local lib = require "pgf.gd.lib" + + +function SpringElectricalHu2006:run() + + -- Setup properties + local options = self.digraph.options + + self.iterations = options['iterations'] + self.cooling_factor = options['cooling factor'] + self.initial_step_length = options['initial step length'] + self.convergence_tolerance = options['convergence tolerance'] + + self.natural_spring_length = options['node distance'] + self.spring_constant = options['spring constant'] + + self.approximate_repulsive_forces = options['approximate remote forces'] + self.repulsive_force_order = options['electric force order'] + + self.coarsen = options['coarsen'] + self.downsize_ratio = options['downsize ratio'] + self.minimum_graph_size = options['minimum coarsening size'] + + -- Adjust types + self.downsize_ratio = math.max(0, math.min(1, self.downsize_ratio)) + self.graph_size = #self.graph.nodes + self.graph_density = (2 * #self.graph.edges) / (#self.graph.nodes * (#self.graph.nodes - 1)) + + -- validate input parameters + assert(self.iterations >= 0, 'iterations (value: ' .. self.iterations .. ') need to be greater than 0') + assert(self.cooling_factor >= 0 and self.cooling_factor <= 1, 'the cooling factor (value: ' .. self.cooling_factor .. ') needs to be between 0 and 1') + assert(self.initial_step_length >= 0, 'the initial step length (value: ' .. self.initial_step_length .. ') needs to be greater than or equal to 0') + assert(self.convergence_tolerance >= 0, 'the convergence tolerance (value: ' .. self.convergence_tolerance .. ') needs to be greater than or equal to 0') + assert(self.natural_spring_length >= 0, 'the natural spring dimension (value: ' .. self.natural_spring_length .. ') needs to be greater than or equal to 0') + assert(self.spring_constant >= 0, 'the spring constant (value: ' .. self.spring_constant .. ') needs to be greater or equal to 0') + assert(self.downsize_ratio >= 0 and self.downsize_ratio <= 1, 'the downsize ratio (value: ' .. self.downsize_ratio .. ') needs to be between 0 and 1') + assert(self.minimum_graph_size >= 2, 'the minimum coarsening size of coarse graphs (value: ' .. self.minimum_graph_size .. ') needs to be greater than or equal to 2') + + -- initialize node weights + for _,node in ipairs(self.graph.nodes) do + node.weight = node:getOption('electric charge') + end + + -- initialize edge weights + for _,edge in ipairs(self.graph.edges) do + edge.weight = 1 + end + + -- initialize the coarse graph data structure. note that the algorithm + -- is the same regardless whether coarsening is used, except that the + -- number of coarsening steps without coarsening is 0 + local coarse_graph = CoarseGraph.new(self.graph) + + -- check if the multilevel approach should be used + if self.coarsen then + -- coarsen the graph repeatedly until only minimum_graph_size nodes + -- are left or until the size of the coarse graph was not reduced by + -- at least the downsize ratio configured by the user + while coarse_graph:getSize() > self.minimum_graph_size + and coarse_graph:getRatio() <= (1 - self.downsize_ratio) + do + coarse_graph:coarsen() + end + end + + if self.coarsen then + -- use the natural spring length as the initial natural spring length + local spring_length = self.natural_spring_length + + -- compute a random initial layout for the coarsest graph + self:computeInitialLayout(coarse_graph.graph, spring_length) + + -- set the spring length to the average edge length of the initial layout + spring_length = 0 + for _,edge in ipairs(coarse_graph.graph.edges) do + spring_length = spring_length + edge.nodes[1].pos:minus(edge.nodes[2].pos):norm() + end + spring_length = spring_length / #coarse_graph.graph.edges + + -- additionally improve the layout with the force-based algorithm + -- if there are more than two nodes in the coarsest graph + if coarse_graph:getSize() > 2 then + self:computeForceLayout(coarse_graph.graph, spring_length, SpringElectricalHu2006.adaptive_step_update) + end + + -- undo coarsening step by step, applying the force-based sub-algorithm + -- to every intermediate coarse graph as well as the original graph + while coarse_graph:getLevel() > 0 do + + -- compute the diameter of the parent coarse graph + local parent_diameter = PathLengths.pseudoDiameter(coarse_graph.graph) + + -- interpolate the previous coarse graph from its parent + coarse_graph:interpolate() + + -- compute the diameter of the current coarse graph + local current_diameter = PathLengths.pseudoDiameter(coarse_graph.graph) + + -- scale node positions by the quotient of the pseudo diameters + for _,node in ipairs(coarse_graph.graph) do + node.pos:update(function (n, value) + return value * (current_diameter / parent_diameter) + end) + end + + -- compute forces in the graph + self:computeForceLayout(coarse_graph.graph, spring_length, SpringElectricalHu2006.conservative_step_update) + end + else + -- compute a random initial layout for the coarsest graph + self:computeInitialLayout(coarse_graph.graph, self.natural_spring_length) + + -- set the spring length to the average edge length of the initial layout + spring_length = 0 + for _,e in ipairs(coarse_graph.graph.edges) do + spring_length = spring_length + edge.nodes[1].pos:minus(edge.nodes[2].pos):norm() + end + spring_length = spring_length / #coarse_graph.graph.edges + + -- improve the layout with the force-based algorithm + self:computeForceLayout(coarse_graph.graph, spring_length, SpringElectricalHu2006.adaptive_step_update) + end +end + + + +function SpringElectricalHu2006:computeInitialLayout(graph, spring_length) + -- TODO how can supernodes and fixed nodes go hand in hand? + -- maybe fix the supernode if at least one of its subnodes is + -- fixated? + + -- fixate all nodes that have a 'desired at' option. this will set the + -- node.fixed member to true and also set node.pos.x and node.pos.y + self:fixateNodes(graph) + + if #graph.nodes == 2 then + if not (graph.nodes[1].fixed and graph.nodes[2].fixed) then + local fixed_index = graph.nodes[2].fixed and 2 or 1 + local loose_index = graph.nodes[2].fixed and 1 or 2 + + if not graph.nodes[1].fixed and not graph.nodes[2].fixed then + -- both nodes can be moved, so we assume node 1 is fixed at (0,0) + graph.nodes[1].pos.x = 0 + graph.nodes[1].pos.y = 0 + end + + -- position the loose node relative to the fixed node, with + -- the displacement (random direction) matching the spring length + local direction = Vector.new{x = math.random(1, spring_length), y = math.random(1, spring_length)} + local distance = 3 * spring_length * self.graph_density * math.sqrt(self.graph_size) / 2 + local displacement = direction:normalized():timesScalar(distance) + + graph.nodes[loose_index].pos = graph.nodes[fixed_index].pos:plus(displacement) + else + -- both nodes are fixed, initial layout may be far from optimal + end + else + + -- use a random positioning technique + local function positioning_func(n) + local radius = 3 * spring_length * self.graph_density * math.sqrt(self.graph_size) / 2 + return math.random(-radius, radius) + end + + -- compute initial layout based on the random positioning technique + for _,node in ipairs(graph.nodes) do + if not node.fixed then + node.pos.x = positioning_func(1) + node.pos.y = positioning_func(2) + end + end + end +end + + + +function SpringElectricalHu2006:computeForceLayout(graph, spring_length, step_update_func) + -- global (=repulsive) force function + function accurate_repulsive_force(distance, weight) + -- note: the weight is taken into the equation here. unlike in the original + -- algorithm different electric charges are allowed for each node in this + -- implementation + return - weight * self.spring_constant * math.pow(spring_length, self.repulsive_force_order + 1) / math.pow(distance, self.repulsive_force_order) + end + + -- global (=repulsive, approximated) force function + function approximated_repulsive_force(distance, mass) + return - mass * self.spring_constant * math.pow(spring_length, self.repulsive_force_order + 1) / math.pow(distance, self.repulsive_force_order) + end + + -- local (spring) force function + function attractive_force(distance) + return (distance * distance) / spring_length + end + + -- define the Barnes-Hut opening criterion + function barnes_hut_criterion(cell, particle) + local distance = particle.pos:minus(cell.center_of_mass):norm() + return cell.width / distance <= 1.2 + end + + -- fixate all nodes that have a 'desired at' option. this will set the + -- node.fixed member to true and also set node.pos.x and node.pos.y + self:fixateNodes(graph) + + -- adjust the initial step length automatically if desired by the user + local step_length = self.initial_step_length == 0 and spring_length or self.initial_step_length + + -- convergence criteria etc. + local converged = false + local energy = math.huge + local iteration = 0 + local progress = 0 + + while not converged and iteration < self.iterations do + -- remember old node positions + local old_positions = lib.map(graph.nodes, function (node) + return node.pos:copy(), node + end) + + -- remember the old system energy and reset it for the current iteration + local old_energy = energy + energy = 0 + + -- build the quadtree for approximating repulsive forces, if desired + local quadtree = nil + if self.approximate_repulsive_forces then + quadtree = self:buildQuadtree(graph) + end + + for _,v in ipairs(graph.nodes) do + if not v.fixed then + -- vector for the displacement of v + local d = Vector.new(2) + + -- compute repulsive forces + if self.approximate_repulsive_forces then + -- determine the cells that have a repulsive influence on v + local cells = quadtree:findInteractionCells(v, barnes_hut_criterion) + + -- compute the repulsive force between these cells and v + for _,cell in ipairs(cells) do + -- check if the cell is a leaf + if #cell.subcells == 0 then + -- compute the forces between the node and all particles in the cell + for _,particle in ipairs(cell.particles) do + local real_particles = lib.copy(particle.subparticles) + table.insert(real_particles, particle) + + for _,real_particle in ipairs(real_particles) do + local delta = real_particle.pos:minus(v.pos) + + -- enforce a small virtual distance if the node and the cell's + -- center of mass are located at (almost) the same position + if delta:norm() < 0.1 then + delta:update(function (n, value) return 0.1 + math.random() * 0.1 end) + end + + -- compute the repulsive force vector + local repulsive_force = approximated_repulsive_force(delta:norm(), real_particle.mass) + local force = delta:normalized():timesScalar(repulsive_force) + + -- move the node v accordingly + d = d:plus(force) + end + end + else + -- compute the distance between the node and the cell's center of mass + local delta = cell.center_of_mass:minus(v.pos) + + -- enforce a small virtual distance if the node and the cell's + -- center of mass are located at (almost) the same position + if delta:norm() < 0.1 then + delta:update(function (n, value) return 0.1 + math.random() * 0.1 end) + end + + -- compute the repulsive force vector + local repulsive_force = approximated_repulsive_force(delta:norm(), cell.mass) + local force = delta:normalized():timesScalar(repulsive_force) + + -- move the node v accordingly + d = d:plus(force) + end + end + else + for _,u in ipairs(graph.nodes) do + if v ~= u then + -- compute the distance between u and v + local delta = u.pos:minus(v.pos) + + -- enforce a small virtual distance if the nodes are + -- located at (almost) the same position + if delta:norm() < 0.1 then + delta:update(function (n, value) return 0.1 + math.random() * 0.1 end) + end + + -- compute the repulsive force vector + local repulsive_force = accurate_repulsive_force(delta:norm(), u.weight) + local force = delta:normalized():timesScalar(repulsive_force) + + -- move the node v accordingly + d = d:plus(force) + end + end + end + + -- compute attractive forces between v and its neighbours + for _,edge in ipairs(v.edges) do + local u = edge:getNeighbour(v) + + -- compute the distance between u and v + local delta = u.pos:minus(v.pos) + + -- enforce a small virtual distance if the nodes are + -- located at (almost) the same position + if delta:norm() < 0.1 then + delta:update(function (n, value) return 0.1 + math.random() * 0.1 end) + end + + -- compute the spring force vector between u and v + local attr_force = attractive_force(delta:norm()) + local force = delta:normalized():timesScalar(attr_force) + + -- move the node v accordingly + d = d:plus(force) + end + + -- really move the node now + -- TODO note how all nodes are moved by the same amount (step_length) + -- while Walshaw multiplies the normalized force with min(step_length, + -- d:norm()). could that improve this algorithm even further? + v.pos = v.pos:plus(d:normalized():timesScalar(step_length)) + + -- TODO Hu doesn't mention this but the energy of a particle is + -- typically considered as the product of its mass and the square of + -- its forces. This means we should probably take the weight of + -- the node v into the equation, doesn't it? + -- + -- update the energy function + energy = energy + math.pow(d:norm(), 2) + end + end + + -- update the step length and progress counter + step_length, progress = step_update_func(step_length, self.cooling_factor, energy, old_energy, progress) + + -- compute the maximum node movement in this iteration + local max_movement = 0 + for _,x in ipairs(graph.nodes) do + local delta = x.pos:minus(old_positions[x]) + max_movement = math.max(delta:norm(), max_movement) + end + + -- the algorithm will converge if the maximum movement is below a + -- threshold depending on the spring length and the convergence + -- tolerance + if max_movement < spring_length * self.convergence_tolerance then + converged = true + end + + -- increment the iteration counter + iteration = iteration + 1 + end +end + + + +-- Fixes nodes at their specified positions. +-- +function SpringElectricalHu2006:fixateNodes(graph) + local number_of_fixed_nodes = 0 + + for _,node in ipairs(graph.nodes) do + -- read the 'desired at' option of the node + local coordinate = node:getOption('desired at') + + if coordinate then + -- apply the coordinate + node.pos.x = coordinate.x + node.pos.y = coordinate.y + + -- mark the node as fixed + node.fixed = true + + number_of_fixed_nodes = number_of_fixed_nodes + 1 + end + end + if number_of_fixed_nodes > 1 then + self.growth_direction = "fixed" -- do not grow, orientation is now fixed + end +end + + + +function SpringElectricalHu2006:buildQuadtree(graph) + -- compute the minimum x and y coordinates of all nodes + local min_pos = graph.nodes[1].pos + for _,node in ipairs(graph.nodes) do + min_pos = Vector.new(2, function (n) return math.min(min_pos[n], node.pos[n]) end) + end + + -- compute maximum x and y coordinates of all nodes + local max_pos = graph.nodes[1].pos + for _,node in ipairs(graph.nodes) do + max_pos = Vector.new(2, function (n) return math.max(max_pos[n], node.pos[n]) end) + end + + -- make sure the maximum position is at least a tiny bit + -- larger than the minimum position + if min_pos:equals(max_pos) then + max_pos = max_pos:plus(Vector.new(2, function (n) + return 0.1 + math.random() * 0.1 + end)) + end + + -- make sure to make the quadtree area slightly larger than required + -- in theory; for some reason Lua will otherwise think that nodes with + -- min/max x/y coordinates are outside the box... weird? yes. + min_pos = min_pos:minus({1,1}) + max_pos = max_pos:plus({1,1}) + + -- create the quadtree + quadtree = QuadTree.new(min_pos.x, min_pos.y, + max_pos.x - min_pos.x, + max_pos.y - min_pos.y) + + -- insert nodes into the quadtree + for _,node in ipairs(graph.nodes) do + local particle = QuadTree.Particle.new(node.pos, node.weight) + particle.node = node + quadtree:insert(particle) + end + + return quadtree +end + + + +function SpringElectricalHu2006.conservative_step_update(step, cooling_factor) + return cooling_factor * step, nil +end + + + +function SpringElectricalHu2006.adaptive_step_update(step, cooling_factor, energy, old_energy, progress) + if energy < old_energy then + progress = progress + 1 + if progress >= 5 then + progress = 0 + step = step / cooling_factor + end + else + progress = 0 + step = cooling_factor * step + end + return step, progress +end + + +-- done + +return SpringElectricalHu2006
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalLayouts.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalLayouts.lua new file mode 100644 index 00000000000..f8854e71618 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalLayouts.lua @@ -0,0 +1,54 @@ +-- 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/force/SpringElectricalLayouts.lua,v 1.4 2013/05/23 20:01:27 tantau Exp $ + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + +--- +-- @section subsection {Spring Electrical Layouts} +-- +-- @end + + + +--- + +declare { + key = "spring electrical layout", + use = { + { key = "spring electrical Hu 2006 layout" }, + { key = "spring constant", value = "0.2" } + }, + + summary = [[" + This key selects Hu's 2006 spring electrical layout with + appropriate settings for some parameters. + "]] + } + + +--- + +declare { + key = "spring electrical layout'", + use = { + { key = "spring electrical Walshaw 2000 layout" }, + { key = "spring constant", value = "0.01" }, + { key = "convergence tolerance", value = "0.001" }, + }, + + summary = [[" + This key selects Walshaw's 2000 spring electrical layout with + appropriate settings for some parameters. + "]] + } diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalWalshaw2000.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalWalshaw2000.lua new file mode 100644 index 00000000000..25782bc9c3c --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalWalshaw2000.lua @@ -0,0 +1,516 @@ +-- Copyright 2011 by Jannis Pohlmann +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed and/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/force/SpringElectricalWalshaw2000.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + + + +local SpringElectricalWalshaw2000 = {} + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + + +--- + +declare { + key = "spring electrical Walshaw 2000 layout", + algorithm = SpringElectricalWalshaw2000, + + preconditions = { + connected = true, + loop_free = true, + simple = true, + }, + + old_graph_model = true, + + summary = [[" + Implementation of a spring electrical graph drawing algorithm based on + a paper by Walshaw. + "]], + documentation = [[" + \begin{itemize} + \item + C. Walshaw. + \newblock A multilevel algorithm for force-directed graph + drawing. + \newblock In J. Marks, editor, \emph{Graph Drawing}, Lecture Notes in + Computer Science, 1984:31--55, 2001. + \end{itemize} + + The following modifications compared to the original algorithm were applied: + \begin{itemize} + \item An iteration limit was added. + \item The natural spring length for all coarse graphs is computed based + on the formula presented by Walshaw, so that the natural spring + length of the original graph (coarse graph 0) is the same as + the value requested by the user. + \item Users can define custom node and edge weights. + \item Coarsening stops when $|V(G_i+1)|/|V(G_i)| < p$ where $p = 0.75$. + \item Coarsening stops when the maximal matching is empty. + \item Theruntime of the algorithm is improved by use of a quadtree + data structure like Hu does in his algorithm. + \item A limiting the number of levels of the quadtree is not implemented. + \end{itemize} + "]] +} + +-- TODO Implement the following keys (or whatever seems appropriate +-- and doable for this algorithm): +-- - /tikz/desired at +-- - /tikz/influence cutoff distance +-- - /tikz/spring stiffness (could this be the equivalent to the electric +-- charge of nodes? +-- - /tikz/natural spring dimension per edge +-- +-- TODO Implement the following features: +-- - clustering of nodes using color classes +-- - different cluster layouts (vertical line, horizontal line, +-- normal cluster, internally fixed subgraph) + + + +local Vector = require "pgf.gd.deprecated.Vector" + +local QuadTree = require "pgf.gd.force.QuadTree" +local CoarseGraph = require "pgf.gd.force.CoarseGraph" + + +local lib = require "pgf.gd.lib" + + +function SpringElectricalWalshaw2000:run() + + -- Setup parameters + local options = self.digraph.options + + self.iterations = options['iterations'] + self.cooling_factor = options['cooling factor'] + self.initial_step_length = options['initial step length'] + self.convergence_tolerance = options['convergence tolerance'] + + self.natural_spring_length = options['node distance'] + self.spring_constant = options['spring constant'] + + self.approximate_repulsive_forces = options['approximate remote forces'] + self.repulsive_force_order = options['electric force order'] + + self.coarsen = options['coarsen'] + self.downsize_ratio = options['downsize ratio'] + self.minimum_graph_size = options['minimum coarsening size'] + + -- Adjust types + self.downsize_ratio = math.max(0, math.min(1, self.downsize_ratio)) + self.graph_size = #self.graph.nodes + self.graph_density = (2 * #self.graph.edges) / (#self.graph.nodes * (#self.graph.nodes - 1)) + + -- validate input parameters + assert(self.iterations >= 0, 'iterations (value: ' .. self.iterations .. ') need to be greater than 0') + assert(self.cooling_factor >= 0 and self.cooling_factor <= 1, 'the cooling factor (value: ' .. self.cooling_factor .. ') needs to be between 0 and 1') + assert(self.initial_step_length >= 0, 'the initial step length (value: ' .. self.initial_step_length .. ') needs to be greater than or equal to 0') + assert(self.convergence_tolerance >= 0, 'the convergence tolerance (value: ' .. self.convergence_tolerance .. ') needs to be greater than or equal to 0') + assert(self.natural_spring_length >= 0, 'the natural spring dimension (value: ' .. self.natural_spring_length .. ') needs to be greater than or equal to 0') + assert(self.spring_constant >= 0, 'the spring constant (value: ' .. self.spring_constant .. ') needs to be greater or equal to 0') + assert(self.downsize_ratio >= 0 and self.downsize_ratio <= 1, 'the downsize ratio (value: ' .. self.downsize_ratio .. ') needs to be between 0 and 1') + assert(self.minimum_graph_size >= 2, 'the minimum coarsening size of coarse graphs (value: ' .. self.minimum_graph_size .. ') needs to be greater than or equal to 2') + + -- initialize node weights + for _,node in ipairs(self.graph.nodes) do + node.weight = node:getOption('electric charge') + + -- a node is charged if its weight derives from the default setting + -- of 1 (where it has no influence on the forces) + node.charged = node.weight ~= 1 + end + + -- initialize edge weights + for _,edge in ipairs(self.graph.edges) do + edge.weight = 1 + end + + + -- initialize the coarse graph data structure. note that the algorithm + -- is the same regardless whether coarsening is used, except that the + -- number of coarsening steps without coarsening is 0 + local coarse_graph = CoarseGraph.new(self.graph) + + -- check if the multilevel approach should be used + if self.coarsen then + -- coarsen the graph repeatedly until only minimum_graph_size nodes + -- are left or until the size of the coarse graph was not reduced by + -- at least the downsize ratio configured by the user + while coarse_graph:getSize() > self.minimum_graph_size + and coarse_graph:getRatio() < (1 - self.downsize_ratio) + do + coarse_graph:coarsen() + end + end + + -- compute the natural spring length for the coarsest graph in a way + -- that will result in the desired natural spring length in the + -- original graph + local spring_length = self.natural_spring_length / math.pow(math.sqrt(4/7), coarse_graph:getLevel()) + + if self.coarsen then + -- generate a random initial layout for the coarsest graph + self:computeInitialLayout(coarse_graph.graph, spring_length) + + -- undo coarsening step by step, applying the force-based sub-algorithm + -- to every intermediate coarse graph as well as the original graph + while coarse_graph:getLevel() > 0 do + -- interpolate the previous coarse graph + coarse_graph:interpolate() + + -- update the natural spring length so that, for the original graph, + -- it equals the natural spring dimension configured by the user + spring_length = spring_length * math.sqrt(4/7) + + -- apply the force-based algorithm to improve the layout + self:computeForceLayout(coarse_graph.graph, spring_length) + end + else + -- generate a random initial layout for the coarsest graph + self:computeInitialLayout(coarse_graph.graph, spring_length) + + -- apply the force-based algorithm to improve the layout + self:computeForceLayout(coarse_graph.graph, spring_length) + end +end + + + +function SpringElectricalWalshaw2000:computeInitialLayout(graph, spring_length) + -- TODO how can supernodes and fixed nodes go hand in hand? + -- maybe fix the supernode if at least one of its subnodes is + -- fixated? + + -- fixate all nodes that have a 'desired at' option. this will set the + -- node.fixed member to true and also set node.pos.x and node.pos.y + self:fixateNodes(graph) + + if #graph.nodes == 2 then + if not (graph.nodes[1].fixed and graph.nodes[2].fixed) then + local fixed_index = graph.nodes[2].fixed and 2 or 1 + local loose_index = graph.nodes[2].fixed and 1 or 2 + + if not graph.nodes[1].fixed and not graph.nodes[2].fixed then + -- both nodes can be moved, so we assume node 1 is fixed at (0,0) + graph.nodes[1].pos.x = 0 + graph.nodes[1].pos.y = 0 + end + + -- position the loose node relative to the fixed node, with + -- the displacement (random direction) matching the spring length + local direction = Vector.new{x = math.random(1, 2), y = math.random(1, 2)} + local distance = 3 * spring_length * self.graph_density * math.sqrt(self.graph_size) / 2 + local displacement = direction:normalized():timesScalar(distance) + + graph.nodes[loose_index].pos = graph.nodes[fixed_index].pos:plus(displacement) + else + -- both nodes are fixed, initial layout may be far from optimal + end + else + -- function to filter out fixed nodes + local function nodeNotFixed(node) return not node.fixed end + + -- use the random positioning technique + local function positioning_func(n) + local radius = 3 * spring_length * self.graph_density * math.sqrt(self.graph_size) / 2 + return math.random(-radius, radius) + end + + -- compute initial layout based on the random positioning technique + for _,node in ipairs(graph.nodes) do + if not node.fixed then + node.pos.x = positioning_func(1) + node.pos.y = positioning_func(2) + end + end + end +end + + + +function SpringElectricalWalshaw2000:computeForceLayout(graph, spring_length) + -- global (=repulsive) force function + local function accurate_repulsive_force(distance, weight) + return - self.spring_constant * weight * math.pow(spring_length, self.repulsive_force_order + 1) / math.pow(distance, self.repulsive_force_order) + end + + -- global (=repulsive, approximated) force function + local function approximated_repulsive_force(distance, mass) + return - mass * self.spring_constant * math.pow(spring_length, self.repulsive_force_order + 1) / math.pow(distance, self.repulsive_force_order) + end + + -- local (spring) force function + local function attractive_force(distance, d, weight, charged, repulsive_force) + -- for charged nodes, never subtract the repulsive force; we want ALL other + -- nodes to be attracted more / repulsed less (not just non-adjacent ones), + -- depending on the charge of course + if charged then + return (distance - spring_length) / d - accurate_repulsive_force(distance, weight) + else + return (distance - spring_length) / d - (repulsive_force or 0) + end + end + + -- define the Barnes-Hut opening criterion + function barnes_hut_criterion(cell, particle) + local distance = particle.pos:minus(cell.center_of_mass):norm() + return cell.width / distance <= 1.2 + end + + -- fixate all nodes that have a 'desired at' option. this will set the + -- node.fixed member to true and also set node.pos.x and node.pos.y + self:fixateNodes(graph) + + -- adjust the initial step length automatically if desired by the user + local step_length = self.initial_step_length == 0 and spring_length or self.initial_step_length + + -- convergence criteria + local converged = false + local i = 0 + + while not converged and i < self.iterations do + + -- assume that we are converging + converged = true + i = i + 1 + + -- build the quadtree for approximating repulsive forces, if desired + local quadtree = nil + if self.approximate_repulsive_forces then + quadtree = self:buildQuadtree(graph) + end + + local function nodeNotFixed(node) return not node.fixed end + + -- iterate over all nodes + for _,v in ipairs(graph.nodes) do + if not v.fixed then + -- vector for the displacement of v + local d = Vector.new(2) + + -- repulsive force induced by other nodes + local repulsive_forces = {} + + -- compute repulsive forces + if self.approximate_repulsive_forces then + -- determine the cells that have an repulsive influence on v + local cells = quadtree:findInteractionCells(v, barnes_hut_criterion) + + -- compute the repulsive force between these cells and v + for _,cell in ipairs(cells) do + -- check if the cell is a leaf + if #cell.subcells == 0 then + -- compute the forces between the node and all particles in the cell + for _,particle in ipairs(cell.particles) do + -- build a table that contains the particle plus all its subparticles + -- (particles at the same position) + local real_particles = lib.copy(particle.subparticles) + table.insert(real_particles, particle) + + for _,real_particle in ipairs(real_particles) do + local delta = real_particle.pos:minus(v.pos) + + -- enforce a small virtual distance if the node and the cell's + -- center of mass are located at (almost) the same position + if delta:norm() < 0.1 then + delta:update(function (n, value) return 0.1 + math.random() * 0.1 end) + end + + -- compute the repulsive force vector + local repulsive_force = approximated_repulsive_force(delta:norm(), real_particle.mass) + local force = delta:normalized():timesScalar(repulsive_force) + + -- remember the repulsive force for the particle so that we can + -- subtract it later when computing the attractive forces with + -- adjacent nodes + repulsive_forces[real_particle.node] = repulsive_force + + -- move the node v accordingly + d = d:plus(force) + end + end + else + -- compute the distance between the node and the cell's center of mass + local delta = cell.center_of_mass:minus(v.pos) + + -- enforce a small virtual distance if the node and the cell's + -- center of mass are located at (almost) the same position + if delta:norm() < 0.1 then + delta:update(function (n, value) return 0.1 + math.random() * 0.1 end) + end + + -- compute the repulsive force vector + local repulsive_force = approximated_repulsive_force(delta:norm(), cell.mass) + local force = delta:normalized():timesScalar(repulsive_force) + + -- TODO for each neighbour of v, check if it is in this cell. + -- if this is the case, compute the quadtree force for the mass + -- 'node.weight / cell.mass' and remember this as the repulsive + -- force of the neighbour; (it is not necessarily at + -- the center of mass of the cell, so the result is only an + -- approximation of the real repulsive force generated by the + -- neighbour) + + -- move te node v accordingly + d = d:plus(force) + end + end + else + for _,u in ipairs(graph.nodes) do + if u.name ~= v.name then + -- compute the distance between u and v + local delta = u.pos:minus(v.pos) + + -- enforce a small virtual distance if the nodes are + -- located at (almost) the same position + if delta:norm() < 0.1 then + delta:update(function (n, value) return 0.1 + math.random() * 0.1 end) + end + + -- compute the repulsive force vector + local repulsive_force = accurate_repulsive_force(delta:norm(), u.weight) + local force = delta:normalized():timesScalar(repulsive_force) + + -- remember the repulsive force so we can later subtract them + -- when computing the attractive forces + repulsive_forces[u] = repulsive_force + + -- move the node v accordingly + d = d:plus(force) + end + end + end + + -- compute attractive forces between v and its neighbours + for _,edge in ipairs(v.edges) do + local u = edge:getNeighbour(v) + + -- compute the distance between u and v + local delta = u.pos:minus(v.pos) + + -- enforce a small virtual distance if the nodes are + -- located at (almost) the same position + if delta:norm() < 0.1 then + delta:update(function (n, value) return 0.1 + math.random() * 0.1 end) + end + + -- compute the spring force between them + local attr_force = attractive_force(delta:norm(), #v.edges, u.weight, u.charged, repulsive_forces[u]) + local force = delta:normalized():timesScalar(attr_force) + + -- move the node v accordingly + d = d:plus(force) + end + + -- remember the previous position of v + old_position = v.pos:copy() + + if d:norm() > 0 then + -- reposition v according to the force vector and the current temperature + v.pos = v.pos:plus(d:normalized():timesScalar(math.min(step_length, d:norm()))) + end + + -- we need to improve the system energy as long as any of + -- the node movements is large enough to assume we're far + -- away from the minimum system energy + if v.pos:minus(old_position):norm() > spring_length * self.convergence_tolerance then + converged = false + end + end + end + + -- update the step length using the conservative cooling scheme + step_length = self.cooling_factor * step_length + end +end + + + +-- Fixes nodes at their specified positions. +-- +function SpringElectricalWalshaw2000:fixateNodes(graph) + local number_of_fixed_nodes = 0 + + for _,node in ipairs(graph.nodes) do + -- read the 'desired at' option of the node + local coordinate = node:getOption('desired at') + + if coordinate then + -- parse the coordinate + node.pos.x = coordinate.x + node.pos.y = coordinate.y + + -- mark the node as fixed + node.fixed = true + + number_of_fixed_nodes = number_of_fixed_nodes + 1 + end + end + if number_of_fixed_nodes > 1 then + self.growth_direction = "fixed" -- do not grow, orientation is now fixed + end +end + + + +function SpringElectricalWalshaw2000:buildQuadtree(graph) + -- compute the minimum x and y coordinates of all nodes + local min_pos = graph.nodes[1].pos + for _,node in ipairs(graph.nodes) do + min_pos = Vector.new(2, function (n) return math.min(min_pos[n], node.pos[n]) end) + end + + -- compute maximum x and y coordinates of all nodes + local max_pos = graph.nodes[1].pos + for _,node in ipairs(graph.nodes) do + max_pos = Vector.new(2, function (n) return math.max(max_pos[n], node.pos[n]) end) + end + + -- make sure the maximum position is at least a tiny bit + -- larger than the minimum position + if min_pos:equals(max_pos) then + max_pos = max_pos:plus(Vector.new(2, function (n) + return 0.1 + math.random() * 0.1 + end)) + end + + -- make sure to make the quadtree area slightly larger than required + -- in theory; for some reason Lua will otherwise think that nodes with + -- min/max x/y coordinates are outside the box... weird? yes. + min_pos = min_pos:minusScalar(1) + max_pos = max_pos:plusScalar(1) + + -- create the quadtree + quadtree = QuadTree.new(min_pos.x, min_pos.y, + max_pos.x - min_pos.x, + max_pos.y - min_pos.y) + + -- insert nodes into the quadtree + for _,node in ipairs(graph.nodes) do + local particle = QuadTree.Particle.new(node.pos, node.weight) + particle.node = node + quadtree:insert(particle) + end + + return quadtree +end + + + +-- done + +return SpringElectricalWalshaw2000
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringHu2006.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringHu2006.lua new file mode 100644 index 00000000000..35dc21008fb --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringHu2006.lua @@ -0,0 +1,387 @@ +-- Copyright 2011 by Jannis Pohlmann +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed and/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/force/SpringHu2006.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + + +local SpringHu2006 = {} + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + + +--- + +declare { + key = "spring Hu 2006 layout", + algorithm = SpringHu2006, + + preconditions = { + connected = true, + loop_free = true, + simple = true, + }, + + old_graph_model = true, + + summary = [[" + Implementation of a spring graph drawing algorithm based on + a paper by Hu. + "]], + documentation = [[" + \begin{itemize} + \item + Y. Hu. + \newblock Efficient, high-quality force-directed graph drawing. + \newblock \emph{The Mathematica Journal}, 2006. + \end{itemize} + + There are some modifications compared to the original algorithm, + see the Diploma thesis of Pohlmann for details. + "]] +} + + +-- Imports + +local PathLengths = require "pgf.gd.lib.PathLengths" +local Vector = require "pgf.gd.deprecated.Vector" + +local CoarseGraph = require "pgf.gd.force.CoarseGraph" + +local lib = require("pgf.gd.lib") + + + + + +function SpringHu2006:run() + + -- Setup some parameters + local options = self.digraph.options + + self.iterations = options['iterations'] + self.cooling_factor = options['cooling factor'] + self.initial_step_length = options['initial step length'] + self.convergence_tolerance = options['convergence tolerance'] + + self.natural_spring_length = options['node distance'] + + self.coarsen = options['coarsen'] + self.downsize_ratio = options['downsize ratio'] + self.minimum_graph_size = options['minimum coarsening size'] + + + -- Setup + + self.downsize_ratio = math.max(0, math.min(1, tonumber(self.downsize_ratio))) + + self.graph_size = #self.graph.nodes + self.graph_density = (2 * #self.graph.edges) / (#self.graph.nodes * (#self.graph.nodes - 1)) + + -- validate input parameters + assert(self.iterations >= 0, 'iterations (value: ' .. self.iterations .. ') need to be greater than 0') + assert(self.cooling_factor >= 0 and self.cooling_factor <= 1, 'the cooling factor (value: ' .. self.cooling_factor .. ') needs to be between 0 and 1') + assert(self.initial_step_length >= 0, 'the initial step length (value: ' .. self.initial_step_length .. ') needs to be greater than or equal to 0') + assert(self.convergence_tolerance >= 0, 'the convergence tolerance (value: ' .. self.convergence_tolerance .. ') needs to be greater than or equal to 0') + assert(self.natural_spring_length >= 0, 'the natural spring dimension (value: ' .. self.natural_spring_length .. ') needs to be greater than or equal to 0') + assert(self.downsize_ratio >= 0 and self.downsize_ratio <= 1, 'the downsize ratio (value: ' .. self.downsize_ratio .. ') needs to be between 0 and 1') + assert(self.minimum_graph_size >= 2, 'the minimum coarsening size of coarse graphs (value: ' .. self.minimum_graph_size .. ') needs to be greater than or equal to 2') + + -- initialize node weights + for _,node in ipairs(self.graph.nodes) do + node.weight = 1 + end + + -- initialize edge weights + for _,edge in ipairs(self.graph.edges) do + edge.weight = 1 + end + + + -- initialize the coarse graph data structure. note that the algorithm + -- is the same regardless whether coarsening is used, except that the + -- number of coarsening steps without coarsening is 0 + local coarse_graph = CoarseGraph.new(self.graph) + + -- check if the multilevel approach should be used + if self.coarsen then + -- coarsen the graph repeatedly until only minimum_graph_size nodes + -- are left or until the size of the coarse graph was not reduced by + -- at least the downsize ratio configured by the user + while coarse_graph:getSize() > self.minimum_graph_size + and coarse_graph:getRatio() <= (1 - self.downsize_ratio) + do + coarse_graph:coarsen() + end + end + + if self.coarsen then + -- use the natural spring length as the initial natural spring length + local spring_length = self.natural_spring_length + + -- compute a random initial layout for the coarsest graph + self:computeInitialLayout(coarse_graph.graph, spring_length) + + -- set the spring length to the average edge length of the initial layout + spring_length = 0 + for _,edge in ipairs(coarse_graph.graph.edges) do + spring_length = spring_length + edge.nodes[1].pos:minus(edge.nodes[2].pos):norm() + end + spring_length = spring_length / #coarse_graph.graph.edges + + -- additionally improve the layout with the force-based algorithm + -- if there are more than two nodes in the coarsest graph + if coarse_graph:getSize() > 2 then + self:computeForceLayout(coarse_graph.graph, spring_length, SpringHu2006.adaptive_step_update) + end + + -- undo coarsening step by step, applying the force-based sub-algorithm + -- to every intermediate coarse graph as well as the original graph + while coarse_graph:getLevel() > 0 do + -- compute the diameter of the parent coarse graph + local parent_diameter = PathLengths.pseudoDiameter(coarse_graph.graph) + + -- interpolate the previous coarse graph from its parent + coarse_graph:interpolate() + + -- compute the diameter of the current coarse graph + local current_diameter = PathLengths.pseudoDiameter(coarse_graph.graph) + + -- scale node positions by the quotient of the pseudo diameters + for _,node in ipairs(coarse_graph.graph) do + node.pos:update(function (n, value) + return value * (current_diameter / parent_diameter) + end) + end + + -- compute forces in the graph + self:computeForceLayout(coarse_graph.graph, spring_length, SpringHu2006.conservative_step_update) + end + else + -- compute a random initial layout for the coarsest graph + self:computeInitialLayout(coarse_graph.graph, self.natural_spring_length) + + -- set the spring length to the average edge length of the initial layout + spring_length = 0 + for _,edge in ipairs(coarse_graph.graph.edges) do + spring_length = spring_length + edge.nodes[1].pos:minus(edge.nodes[2].pos):norm() + end + spring_length = spring_length / #coarse_graph.graph.edges + + -- improve the layout with the force-based algorithm + self:computeForceLayout(coarse_graph.graph, spring_length, SpringHu2006.adaptive_step_update) + end + + local avg_spring_length = 0 + for _,edge in ipairs(self.graph.edges) do + avg_spring_length = avg_spring_length + edge.nodes[1].pos:minus(edge.nodes[2].pos):norm() + end + avg_spring_length = avg_spring_length / #self.graph.edges +end + + + +function SpringHu2006:computeInitialLayout(graph, spring_length) + -- TODO how can supernodes and fixed nodes go hand in hand? + -- maybe fix the supernode if at least one of its subnodes is + -- fixated? + + -- fixate all nodes that have a 'desired at' option. this will set the + -- node.fixed member to true and also set node.pos.x and node.pos.y + self:fixateNodes(graph) + + if #graph.nodes == 2 then + if not (graph.nodes[1].fixed and graph.nodes[2].fixed) then + local fixed_index = graph.nodes[2].fixed and 2 or 1 + local loose_index = graph.nodes[2].fixed and 1 or 2 + + if not graph.nodes[1].fixed and not graph.nodes[2].fixed then + -- both nodes can be moved, so we assume node 1 is fixed at (0,0) + graph.nodes[1].pos.x = 0 + graph.nodes[1].pos.y = 0 + end + + -- position the loose node relative to the fixed node, with + -- the displacement (random direction) matching the spring length + local direction = Vector.new{x = math.random(1, spring_length), y = math.random(1, spring_length)} + local distance = 1.8 * spring_length * self.graph_density * math.sqrt(self.graph_size) / 2 + local displacement = direction:normalized():timesScalar(distance) + + graph.nodes[loose_index].pos = graph.nodes[fixed_index].pos:plus(displacement) + else + -- both nodes are fixed, initial layout may be far from optimal + end + else + -- use a random positioning technique + local function positioning_func(n) + local radius = 2 * spring_length * self.graph_density * math.sqrt(self.graph_size) / 2 + return math.random(-radius, radius) + end + + -- compute initial layout based on the random positioning technique + for _,node in ipairs(graph.nodes) do + if not node.fixed then + node.pos.x = positioning_func(1) + node.pos.y = positioning_func(2) + end + end + end +end + + + +function SpringHu2006:computeForceLayout(graph, spring_length, step_update_func) + -- global (=repulsive) force function + function repulsive_force(distance, graph_distance, weight) + --return (1/4) * (1/math.pow(graph_distance, 2)) * (distance - (spring_length * graph_distance)) + return (distance - (spring_length * graph_distance)) + end + + -- fixate all nodes that have a 'desired at' option. this will set the + -- node.fixed member to true and also set node.pos.x and node.pos.y + self:fixateNodes(graph) + + -- adjust the initial step length automatically if desired by the user + local step_length = self.initial_step_length == 0 and spring_length or self.initial_step_length + + -- convergence criteria etc. + local converged = false + local energy = math.huge + local iteration = 0 + local progress = 0 + + -- compute graph distance between all pairs of nodes + local distances = PathLengths.floydWarshall(graph) + + while not converged and iteration < self.iterations do + -- remember old node positions + local old_positions = lib.map(graph.nodes, function (node) return node.pos:copy(), node end) + + -- remember the old system energy and reset it for the current iteration + local old_energy = energy + energy = 0 + + for _,v in ipairs(graph.nodes) do + if not v.fixed then + -- vector for the displacement of v + local d = Vector.new(2) + + for _,u in ipairs(graph.nodes) do + if v ~= u then + -- compute the distance between u and v + local delta = u.pos:minus(v.pos) + + -- enforce a small virtual distance if the nodes are + -- located at (almost) the same position + if delta:norm() < 0.1 then + delta:update(function (n, value) return 0.1 + math.random() * 0.1 end) + end + + local graph_distance = (distances[u] and distances[u][v]) and distances[u][v] or #graph.nodes + 1 + + -- compute the repulsive force vector + local force = repulsive_force(delta:norm(), graph_distance, v.weight) + local force = delta:normalized():timesScalar(force) + + -- move the node v accordingly + d = d:plus(force) + end + end + + -- really move the node now + -- TODO note how all nodes are moved by the same amount (step_length) + -- while Walshaw multiplies the normalized force with min(step_length, + -- d:norm()). could that improve this algorithm even further? + v.pos = v.pos:plus(d:normalized():timesScalar(step_length)) + + -- update the energy function + energy = energy + math.pow(d:norm(), 2) + end + end + + -- update the step length and progress counter + step_length, progress = step_update_func(step_length, self.cooling_factor, energy, old_energy, progress) + + -- compute the maximum node movement in this iteration + local max_movement = 0 + for _,x in ipairs(graph.nodes) do + local delta = x.pos:minus(old_positions[x]) + max_movement = math.max(delta:norm(), max_movement) + end + + -- the algorithm will converge if the maximum movement is below a + -- threshold depending on the spring length and the convergence + -- tolerance + if max_movement < spring_length * self.convergence_tolerance then + converged = true + end + + -- increment the iteration counter + iteration = iteration + 1 + end +end + + + +-- Fixes nodes at their specified positions. +-- +function SpringHu2006:fixateNodes(graph) + local number_of_fixed_nodes = 0 + + for _,node in ipairs(graph.nodes) do + -- read the 'desired at' option of the node + local coordinate = node:getOption('desired at') + + if coordinate then + -- apply the coordinate + node.pos.x = coordinate.x + node.pos.y = coordinate.y + + -- mark the node as fixed + node.fixed = true + + number_of_fixed_nodes = number_of_fixed_nodes + 1 + end + end + if number_of_fixed_nodes > 1 then + self.growth_direction = "fixed" -- do not grow, orientation is now fixed + end +end + + + +function SpringHu2006.conservative_step_update(step, cooling_factor) + return cooling_factor * step, nil +end + + + +function SpringHu2006.adaptive_step_update(step, cooling_factor, energy, old_energy, progress) + if energy < old_energy then + progress = progress + 1 + if progress >= 5 then + progress = 0 + step = step / cooling_factor + end + else + progress = 0 + step = cooling_factor * step + end + return step, progress +end + + +-- done + +return SpringHu2006
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringLayouts.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringLayouts.lua new file mode 100644 index 00000000000..ab0126d7fcd --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringLayouts.lua @@ -0,0 +1,36 @@ +-- 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/force/SpringLayouts.lua,v 1.4 2013/05/23 20:01:27 tantau Exp $ + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + +--- +-- @section subsection {Spring Layouts} +-- +-- @end + + + +--- + +declare { + key = "spring layout", + use = { + { key = "spring Hu 2006 layout" }, + }, + + summary = [[" + This key selects Hu's 2006 spring layout with appropriate settings + for some parameters. + "]] + } diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/library.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/library.lua new file mode 100644 index 00000000000..af3a1a62c27 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/library.lua @@ -0,0 +1,126 @@ +-- 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/force/library.lua,v 1.4 2013/05/23 20:01:27 tantau Exp $ + + + +--- +-- Nature creates beautiful graph layouts all the time. Consider a +-- spider's web: Nodes are connected by edges in a visually most pleasing +-- manner (if you ignore the spider in the middle). The layout of a +-- spider's web is created just by the physical forces exerted by the +-- threads. The idea behind force-based graph drawing algorithms is to +-- mimic nature: We treat edges as threads that exert forces and simulate +-- into which configuration the whole graph is ``pulled'' by these +-- forces. +-- +-- When you start thinking about for a moment, it turns out that there +-- are endless variations of the force model. All of these models have +-- the following in common, however: +-- \begin{itemize} +-- \item ``Forces'' pull and push at the nodes in different +-- directions. +-- \item The effect of these forces is simulated by iteratively moving +-- all the nodes simultaneously a little in the direction of the forces +-- and by then recalculating the forces. +-- \item The iteration is stopped either after a certain number of +-- iterations or when a \emph{global energy minimum} is reached (a very +-- scientific way of saying that nothing happens anymore). +-- \end{itemize} +-- +-- The main difference between the different force-based approaches is +-- how the forces are determined. Here are some ideas what could cause a +-- force to be exerted between two nodes (and there are more): +-- \begin{itemize} +-- \item If the nodes are connected by an edge, one can treat the edge as +-- a ``spring'' that has a ``natural spring dimension.'' If the nodes +-- are nearer than the spring dimension, they are push apart; if they +-- are farther aways than the spring dimension, they are pulled +-- together. +-- \item If two nodes are connected by a path of a certain length, the +-- nodes may ``wish to be at a distance proportional to the path +-- length''. If they are nearer, they are pushed apart; if they are +-- farther, they are pulled together. (This is obviously a +-- generalization of the previous idea.) +-- \item There may be a general force field that pushes nodes apart (an +-- electrical field), so that nodes do not tend to ``cluster''. +-- \item There may be a general force field that pulls nodes together (a +-- gravitational field), so that nodes are not too loosely scattered. +-- \item There may be highly nonlinear forces depending on the distance of +-- nodes, so that nodes very near to each get pushed apart strongly, +-- but the effect wears of rapidly at a distance. (Such forces are +-- known as strong nuclear forces.) +-- \item There rotational forces caused by the angles between the edges +-- leaving a node. Such forces try to create a \emph{perfect angular +-- resolution} (a very scientific way of saying that all angles +-- at a node are equal). +-- \end{itemize} +-- +-- Force-based algorithms combine one or more of the above ideas into a +-- single algorithm that uses ``good'' formulas for computing the +-- forces. +-- +-- Currently, three algorithms are implemented in this library, two of +-- which are from the first of the following paper, while the third is +-- from the third paper: +-- +-- \begin{itemize} +-- \item +-- Y. Hu. +-- \newblock Efficient, high-quality force-directed graph drawing. +-- \newblock \emph{The Mathematica Journal}, 2006. +-- \item +-- C. Walshaw. +-- \newblock A multilevel algorithm for force-directed graph +-- drawing. +-- \newblock In J. Marks, editor, \emph{Graph Drawing}, Lecture Notes in +-- Computer Science, 1984:31--55, 2001. +-- \end{itemize} +-- +-- Our implementation is described in detail in the following +-- diploma thesis: +-- +-- \begin{itemize} +-- \item +-- Jannis Pohlmann, +-- \newblock \emph{Configurable Graph Drawing Algorithms +-- for the \tikzname\ Graphics Description Language,} +-- \newblock Diploma Thesis, +-- \newblock Institute of Theoretical Computer Science, Univerist\"at +-- zu L\"ubeck, 2011.\\[.5em] +-- \newblock Online at +-- \url{http://www.tcs.uni-luebeck.de/downloads/papers/2011/}\\ \url{2011-configurable-graph-drawing-algorithms-jannis-pohlmann.pdf} +-- \end{itemize} +-- +-- In the future, I hope that most, if not all, of the force-based +-- algorithms become ``just configuration options'' of a general +-- force-based algorithm similar to the way the modular Sugiyama method +-- is implemented in the |layered| graph drawing library. +-- +-- @library + +local force -- Library name + +-- Load declarations from: +require "pgf.gd.force.Control" +require "pgf.gd.force.ControlStart" +require "pgf.gd.force.ControlIteration" +require "pgf.gd.force.ControlSprings" +require "pgf.gd.force.ControlElectric" +require "pgf.gd.force.ControlCoarsening" + +require "pgf.gd.force.SpringLayouts" +require "pgf.gd.force.SpringElectricalLayouts" + +-- Load algorithms from: +require "pgf.gd.force.SpringHu2006" +require "pgf.gd.force.SpringElectricalHu2006" +require "pgf.gd.force.SpringElectricalWalshaw2000" + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface.lua new file mode 100644 index 00000000000..bd53ae4376b --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface.lua @@ -0,0 +1,26 @@ +-- 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.lua,v 1.1 2012/11/27 17:24:24 tantau Exp $ + + + +-- Imports + +require "pgf" +require "pgf.gd" + + +-- Declare namespace +pgf.gd.interface = {} + + +-- Done + +return pgf.gd.interface
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceCore.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceCore.lua new file mode 100644 index 00000000000..3e5d947c736 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceCore.lua @@ -0,0 +1,174 @@ +-- 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/InterfaceCore.lua,v 1.5 2013/03/07 18:17:14 tantau Exp $ + + + +--- +-- This class provides the core functionality of the interface between +-- all the different layers (display layer, binding layer, and +-- algorithm layer). The two classes |InterfaceToAlgorithms| and +-- |InterfaceToDisplay| use, in particular, the data structures +-- provided by this class. +-- +-- @field binding This field stores the ``binding.'' The graph drawing +-- system is ``bound'' to the display layer through such a binding (a +-- subclass of |Binding|). Such a binding can be thought of as a +-- ``driver'' in operating systems terminology: It is a small set of +-- functions needed to adapt the functionality to one specific display +-- system. Note that the whole graph drawing scope is bound to exactly +-- one display layer; to use several bindings you need to setup a +-- completely new Lua instance. +-- +-- @field scopes This is a stack of graph drawing scopes. All +-- interface methods refer to the top of this stack. +-- +-- @field collection_kinds This table stores which collection kinds +-- have been defined together with their properties. +-- +-- @field algorithm_classes A table that maps algorithm keys (like +-- |tree layout| to class objects). +-- +-- @field keys A lookup table of all declared keys. Each entry of this +-- table consists of the original entry passed to the |declare| +-- method. Each of these tables is both index at a number (so you can +-- iterate over it using |ipairs|) and also via the key's name. + +local InterfaceCore = { + -- The main binding. Set by |InterfaceToDisplay.bind| method. + binding = nil, + + -- The stack of Scope objects. + scopes = {}, + + -- The collection kinds. + collection_kinds = {}, + + -- The algorithm classes + algorithm_classes = {}, + + -- The declared keys + keys = {}, + + -- Internals for handling the options stack + option_stack = {}, + option_cache_height = nil, + option_initial = { + algorithm_phases = {} + }, + option_aliases = { + [{}] = true -- dummy entry to make sure table is not empty + }, + + -- Constant strings for special collection kinds. + sublayout_kind = "INTERNAL_sublayout_kind", + subgraph_node_kind = "INTERNAL_subgraph_node_kind", +} + +-- Namespace +require("pgf.gd.interface").InterfaceCore = InterfaceCore + + +InterfaceCore.option_initial.__index = InterfaceCore.option_initial +InterfaceCore.option_initial.algorithm_phases.__index = InterfaceCore.option_initial.algorithm_phases + + +-- Imports +local Coordinate = require "pgf.gd.model.Coordinate" + + +--- Returns the top scope +-- +-- @return The current top scope, which is the scope in which +-- everything should happen right now. + +function InterfaceCore.topScope() + return assert(InterfaceCore.scopes[#InterfaceCore.scopes], "no graph drawing scope open") +end + + + +local factors = { + cm=28.45274, + mm=2.84526, + pt=1.0, + bp=1.00374, + sp=0.00002, + pc=12.0, + em=10, + ex=4.30554, + ["in"]=72.27, + dd=1.07, + cc=12.8401, + [""]=1, +} + +local directions = { + down = -90, + up = 90, + left = 180, + right = 0, + south = -90, + north = 90, + west = 180, + east = 0, + ["north east"] = 45, + ["north west"] = 135, + ["south east"] = -45, + ["south west"] = -135, + ["-"] = 0, + ["|"] = -90, +} + +--- +-- Converts parameters types. This method is used by both the +-- algorithm layer as well as the display layer to convert strings +-- into the different types of parameters. When a parameter +-- is pushed onto the option stack, you can either provide a value of +-- the parameter's type; but you can also provide a string. This +-- string can then be converted by this function to a value of the +-- correct type. +-- +-- @param s A parameter value or a string. +-- @param t The type of the parameter +-- +-- @return If |s| is not a string, it is just returned. If it is a +-- string, it is converted to the type |t|. + +function InterfaceCore.convert(s,t) + if type(s) ~= "string" then + return s + elseif t == "number" then + return tonumber(s) + elseif t == "length" then + local num, dim = string.match(s, "([%d.]+)(.*)") + return tonumber(num) * assert(factors[dim], "unknown unit") + elseif t == "string" then + return s + elseif t == "canvas coordinate" or t == "coordinate" then + local x, y = string.match(s,"%(([%d.]+)pt,([%d.]+)pt%)") + return Coordinate.new(tonumber(x),tonumber(y)) + elseif t == "boolean" then + return s == "true" + elseif t == "raw" then + return loadstring(s)() + elseif t == "direction" then + return directions[s] or tonumber(s) + elseif t == "nil" or t == nil then + return nil + else + error ("unknown parameter type") + end +end + + +-- Done + +return InterfaceCore
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToAlgorithms.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToAlgorithms.lua new file mode 100644 index 00000000000..586efa12067 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToAlgorithms.lua @@ -0,0 +1,938 @@ +-- 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/InterfaceToAlgorithms.lua,v 1.17 2013/12/20 14:44:46 tantau Exp $ + + + +--- +-- This class provides the interface between the graph drawing system +-- and algorithms. Another class, |InterfaceToDisplay|, binds the +-- display layers (like \tikzname\ or a graph drawing editor) to the +-- graph drawing system ``from the other side''. +-- +-- The functions declared here can be used by algorithms to +-- communicate with the graph drawing system, which will usually +-- forward the ``requests'' of the algorithms to the display layers in +-- some way. For instance, when you declare a new parameter, this +-- parameter will become available on the display layer. + +local InterfaceToAlgorithms = {} + +-- Namespace +require("pgf.gd.interface").InterfaceToAlgorithms = InterfaceToAlgorithms + + +-- Imports +local InterfaceCore = require "pgf.gd.interface.InterfaceCore" +local InterfaceToDisplay = require "pgf.gd.interface.InterfaceToDisplay" +local InterfaceToC = require "pgf.gd.interface.InterfaceToC" + +local LookupTable = require "pgf.gd.lib.LookupTable" +local LayoutPipeline = require "pgf.gd.control.LayoutPipeline" + +local Edge = require "pgf.gd.model.Edge" + +local lib = require "pgf.gd.lib" + +local doc = require "pgf.gd.doc" + +-- Forwards + +local declare_handlers + + + + +--- +-- Adds a handler for the |declare| function. The |declare| +-- command is just a ``dispatcher'' to one of many possible +-- declaration functions. Which function is used, depends on which +-- fields are present in the table passed to |declare|. For each +-- registered handler, we call the |test| function. If it returns +-- neither |nil| nor |false|, the |handler| field of this handler is +-- called. If it returns |true|, the handler immediately +-- finishes. Otherwise, the next handler is tried. + +function InterfaceToAlgorithms.addHandler(test, handler) + table.insert(declare_handlers, 1, { test = test, handler = handler }) +end + + + +-- Local stuff + +local key_metatable = {} + +--- +-- This function is the ``work-horse'' for declaring things. It allows +-- you to specify on the algorithmic layer that a key ``is available'' +-- for use on the display layer. There is just one function for +-- handling all declarations in order to make the declarations +-- easy-to-use since you just need to import a single function: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare +--\end{codeexample} +-- +-- You can now use |declare| it as follows: You pass it a table +-- containing information about the to-be-declared key. The table +-- \emph{must} have a field |key| whose value is unique and must be a +-- string. If the value of |key| is, say, |"foo"|, the +-- parameter can be set on the display layer such as, say, the +-- \tikzname\ layer, using |/graph drawing/foo|. Here is a typical +-- example of how a declaration is done: +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- --- +-- declare { +-- key = "electrical charge", +-- type = "number", +-- initial = "1.0", +-- +-- summary = "The ``electrical charge'' is a property...", +-- documentation = [[...]], +-- examples = [[...]] +-- } +--\end{codeexample} +-- +-- \medskip\noindent\textbf{Inlining Documentation.} +-- The three keys |summary|, |documentation| and |examples| are +-- intended for the display layer to give the users information about +-- what the key does. The |summary| should be a string that succinctly +-- describes the option. This text will typically be displayed for +-- instance as a ``tool tip'' or in an option overview. The +-- |documentation| optionally provides more information and should be +-- typeset using \TeX. The |examples| can either be a single string or +-- an array of strings. Each should be a \tikzname\ example +-- demonstrating how the key is used. +-- +-- Note that you can take advantage of the Lua syntax of enclosing +-- very long multi-line strings in |[[| and |]]|. As a bonus, if the +-- summary, documentation, or an example starts and ends with a quote, +-- these two quotes will be stripped. This allows you to enclose the +-- whole multi-line string (additionally) in quotes, leading to better +-- syntax highlighting in editors. +-- +-- \medskip\noindent\textbf{External Documentation.} +-- It is sometimes more desirable to put the documentation of a key +-- into an external file. First, this makes the code leaner and, thus, +-- faster to read (both for humans and for computers). Second, for C +-- code, it is quite inconvenient to have long strings inside a C +-- file. In such cases, you can use the |documentation_in| field: +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- --- +-- declare { +-- key = "electrical charge", +-- type = "number", +-- initial = "1.0", +-- documentation_in = "some_filename" +-- } +--\end{codeexample} +-- +-- The |some_filename| must be the name of a Lua file that will be +-- read ``on demand,'' that is, whenever someone tries to access the +-- documentation, summary, or examples field of the key, this file +-- will be loaded using |require|. The file should then use +-- |pgf.gd.doc| to install the missing information in the keys. +-- +-- \medskip\noindent\textbf{The Use Field.} +-- When you declare a key, you can provide a |use| field. If present, +-- you must set it to an array of small tables which have two fields: +-- \begin{itemize} +-- \item |key| This is the name of another key or a function. +-- \item |value| This is either a value (like a string or a number) or +-- a function or |nil|. +-- \end{itemize} +-- +-- Here is an example: +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- --- +-- declare { +-- key = "binary tree layout", +-- use = { +-- { key = "minimum number of children", value = 2 }, +-- { key = "significant sep", value = 12 }, +-- { key = "tree layout" } +-- }, +-- summary = "The |binary tree layout| places node...", +-- documentation = ..., +-- examples = ..., +-- } +--\end{codeexample} +-- +-- The effect of a |use| field is the following: Whenever the key is +-- encountered on the option stack, the key is first handled +-- normally. Then, we iterate over all elements of the |use| +-- array. For each element, we perform the action as if the |key| of +-- the array had been set explicitly to the value given by the |value| +-- field. If the |value| is a function, we pass a different value to +-- the key, namely the result of applying the function to the value +-- originally passed to the original key. Here is a typical example: +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- --- +-- declare { +-- key = "level sep", +-- type = "length", +-- use = { +-- { key = "level pre sep", value = function (v) return v/2 end }, +-- { key = "level post sep", value = function (v) return v/2 end } +-- }, +-- summary = "..." +-- } +--\end{codeexample} +-- +-- Just like the value, the key itself can also be a function. In this +-- case, the to-be-used key is also computed by applying the function +-- to the value passed to the original key. +-- +-- As mentioned at the beginning, |declare| is a work-horse that will call +-- different internal functions depending on whether you declare a +-- parameter key or a new algorithm or a collection kind. Which kind +-- of declaration is being done is detected by the presence of certain +-- fields in the table passed to |t|. The different kind of +-- possible declarations are documented in the |declare_...| +-- functions. Note that these functions are internal and cannot be +-- called from outside; you must use the |declare| function. +-- +-- @param t A table contain the field |key| and other fields as +-- described. + +function InterfaceToAlgorithms.declare (t) + local keys = InterfaceCore.keys + + -- Sanity check: + assert (type(t.key) == "string" and t.key ~= "", "parameter key may not be the empty string") + if keys[t.key] or t.keys == "algorithm_phases" then + error("parameter '" .. t.key .. "' already declared") + end + + for _,h in ipairs (declare_handlers) do + if h.test(t) then + if h.handler(t) then + break + end + end + end + + -- Attach metatable: + setmetatable (t, key_metatable) + + -- Set! + keys[t.key] = t + keys[#keys + 1] = t +end + + +function key_metatable.__index (key_table, what) + if what == "documentation" or what == "summary" or what == "examples" then + local doc = rawget(key_table,"documentation_in") + if doc then + require (doc) + return rawget(key_table, what) + end + end +end + + + +--- +-- This function is called by |declare| for ``normal parameter keys,'' +-- which are all keys for which no special field like |algorithm| or +-- |layer| is declared. You write +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- --- +-- declare { +-- key = "electrical charge", +-- type = "number", +-- initial = "1.0", +-- +-- summary = "The ``electrical charge'' is a property...", +-- documentation = [[...]], +-- examples = [[...]] +-- } +--\end{codeexample} +-- +-- When an author writes |my node[electrical charge=5-3]| in the +-- description of her graph, the object |vertex| corresponding to the +-- node |my node| will have a field |options| attached to it with +--\begin{codeexample}[code only, tikz syntax=false] +--vertex.options["electrical charge"] == 2 +--\end{codeexample} +-- +-- The |type| field does not refer to Lua types. Rather, these types are +-- sensible types for graph drawing and they are mapped by the higher +-- layers to Lua types. In detail, the following types are available: +-- +-- \begin{itemize} +-- \item |number| A dimensionless number. Will be mapped to a normal +-- Lua |number|. So, when the author writes |foo=5*2|, the |foo| key +-- of the |options| field of the corresponding object will be set to +-- |10.0|. +-- \item |length| A ``dimension'' in the sense of \TeX\ (a number with +-- a dimension like |cm| attached to it). It is the job of the display +-- layer to map this to a number in ``\TeX\ points,'' that is, to a +-- multiple of $1/72.27$th of an inch. +-- \item |string| Some text. Will be mapped to a Lua |string|. +-- \item |canvas coordinate| A position on the canvas. Will be mapped +-- to a |model.Coordinate|. +-- \item |boolean| A Boolean value. +-- \item |raw| Some to-be-executed Lua text. +-- \item |direction| Normally, an angle; however, +-- the special values of |down|, |up|, |left|, |right| as well as the +-- directions |north|, |north west|, and so on are also legal on the +-- display layer. All of them will be mapped to a number. Furthermore, +-- a vertical bar (\verb!|!) will be mapped to |-90| and a minus sign +-- (|-|) will be mapped to |0|. +-- \item |hidden| A key of this type ``cannot be set,'' that is, +-- users cannot set this key at all. However algorithms can still read +-- this key and, through the use of |alias|, can use the key as a +-- handle to another key. +-- \item |user value| The key stores a Lua user value (userdata). Such +-- keys can only be set from C since user values cannot be created in +-- Lua (let alone in \tikzname). +-- \end{itemize} +-- +-- If the |type| field is missing, it is automatically set to +-- |"string"|. +-- +-- A parameter can have an |initial| value. This value will be used +-- whenever the parameter has not been set explicitly for an object. +-- +-- A parameter can have a |default| value. This value will be used as +-- the parameter value whenever the parameter is explicitly set, but +-- no value is provided. For a key of type |"boolean"|, if no +-- |default| is provided, |"true"| will be used automatically. +-- +-- A parameter can habe an |alias| field. This field must be set to +-- the name of another key or to a function. Whenever you access the +-- current key and this key is not set, the |alias| key is tried +-- instead. If it is set, its value will be returned (if the |alias| +-- key has itself an alias set, this is tried recursively). If the +-- alias is not set either and neither does it have an initial value, +-- the |initial| value is used. Note that in case the alias has its +-- |initial| field set, the |initial| value of the current key will +-- never be used. +-- +-- The main purpose of the current key is to allow algorithms to +-- introduce their own terminology for keys while still having access +-- to the standard keys. For instance, the |OptimalHierarchyLayout| +-- class uses the name |layerDistance| for what would be called +-- |level distance| in the rest of the graph drawing system. In this +-- case, we can declare the |layerDistance| key as follows: +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- declare { +-- key = "layerDistance", +-- type = "length", +-- alias = "level distance" +-- } +--\end{codeexample} +-- +-- Inside the algorithm, we can write |...options.layerDistance| and +-- will get the current value of the |level distance| unless the +-- |layerDistance| has been set explicitly. Indeed, we might set the +-- |type| to |hidden| to ensure that \emph{only} the |level distance| +-- can and must set to set the layerDistance. +-- +-- Note that there is a difference between |alias| and the |use| +-- field: Suppose we write +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- declare { +-- key = "layerDistance", +-- type = "length", +-- use = { +-- { key = "level distance", value = lib.id } +-- } +-- } +--\end{codeexample} +-- +-- Here, when you say |layerDistance=1cm|, the |level distance| itself +-- will be modified. When the |level distance| is set, however, the +-- |layerDistance| will not be modified. +-- +-- If the alias is a function, it will be called with the option table +-- as its parameter. You can thus say things like +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- declare { +-- key = "layerDistance", +-- type = "length", +-- alias = function (option) +-- return option["layer pre dist"] + option["layer post dist"] +-- end +-- } +--\end{codeexample} +-- +-- As a special curtesy to C code, you can also set the key +-- |alias_function_string|, which allows you to put the function into +-- a string that is read using |loadstring|. +-- +-- (You cannot call this function directly, it is included for +-- documentation purposes only.) +-- +-- @param t The table originally passed to |declare|. + +local function declare_parameter (t) + + t.type = t.type or "string" + + if t.type == "boolean" and t.default == nil then + t.default = true + end + + -- Normal key + assert (type(t.type) == "string", "key type must be a string") + + -- Declare via the hub: + if t.type ~= "hidden" then + InterfaceCore.binding:declareCallback(t) + + -- Handle initials: + if t.initial then + InterfaceCore.option_initial[t.key] = InterfaceCore.convert(t.initial, t.type) + end + end + + if t.alias_function_string and not t.alias then + local count = 0 + t.alias = load ( + function () + count = count + 1 + if count == 1 then + return "return " + elseif count == 2 then + return t.alias_function_string + else + return nil + end + end)() + end + + if t.alias then + assert (type(t.alias) == "string" or type(t.alias == "function"), "alias must be a string or a function") + InterfaceCore.option_aliases[t.key] = t.alias + end + + return true +end + + + + +--- +-- This function is called by |declare| for ``algorithm +-- keys.'' They are detected by the presence of the field |algorithm| +-- in the table |t| passed to |declare|. Here is an example of how it +-- is used: +--\begin{codeexample}[code only, tikz syntax=false] +-- local ReingoldTilford1981 = {} +-- +-- --- +-- declare { +-- key = "tree layout", +-- algorithm = ReingoldTilford1981, +-- +-- preconditions = { +-- connected = true, +-- tree = true +-- }, +-- +-- postconditions = { +-- upward_oriented = true +-- }, +-- +-- summary = "The Reingold--Tilford method is...", +-- documentation = ..., +-- examples = ..., +-- } +-- +-- function ReingoldTilford1981:run() +-- ... +-- end +--\end{codeexample} +-- +-- The |algorithm| field expects either a table or a string as +-- value. If you provide a string, then |require| will be applied to +-- this string to obtain the table; however, this will happen only +-- when the key is actually used for the first time. This means that +-- you can declare (numerous) algorithms in a library without these +-- algorithms actually being loaded until they are needed. +-- +-- Independently of how the table is obtained, it will be ``upgraded'' +-- to a class by setting its |__index| field and installing a static +-- |new| function (which takes a table of initial values as +-- argument). Both these settings will only be done if they have not +-- yet been performed. +-- +-- Next, you can specify the fields |preconditions| and +-- |postconditions|. The preconditions are a table that tell the graph +-- drawing engine what kind of graphs your algorithm expects. If the +-- input graph is not of this kind, it will be automatically +-- transformed to meet this condition. Similarly, the postconditions +-- tell the engine about properties of your graph after the algorithm +-- has run. Again, additional transformations may be performed. +-- +-- You can also specify the field |phase|. This tells the graph +-- drawing engine which ``phase'' of the graph drawing process your +-- option applies to. Each time you select an algorithm later on +-- through use of the algorithm's key, the algorithm for this phase +-- will be set; algorithms of other phases will not be changed. So, +-- for instance, when an algorithm is part of the spanning tree +-- computation, its phase will be |"spanning tree computation"| and +-- using its key does not change the main algorithm, but only the +-- algorithm used during the computation of a spanning tree for the +-- current graph (in case this is needed by the main algorithm). In +-- case the |phase| field is missing, the phase |main| is used. Thus, +-- when no phase field is given, the key will change the main +-- algorithm used to draw the graph. +-- +-- Later on, the algorithm set for the current phase can be accessed +-- through the special |algorithm_phases| field of |options| +-- tables. The |algorithm_phases| table will contain a field for each +-- phase for which some algorithm has been set. +-- +-- The following example shows the declaration of an algorithm that is +-- the default for the phase |spanning tree computation|: +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- --- +-- declare { +-- key = "breadth first spanning tree", +-- algorithm = { +-- run = +-- function (self) +-- return SpanningTreeComputation.computeSpanningTree(self.ugraph, false, self.events) +-- end +-- }, +-- phase = "spanning tree computation", +-- phase_default = true, +-- summary = ... +-- } +--\end{codeexample} +-- +-- The algorithm is called as follows during a run of the main +-- algorithms: +-- +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- local graph = ... -- the graph object +-- local spanning_algorithm_class = graph.options.algorithm_phases["spanning tree computation"] +-- local spanning_algorithm = +-- spanning_algorithm_class.new{ +-- ugraph = ugraph, +-- events = scope.events +-- } +-- local spanning_tree = spanning_algorithm:run() +--\end{codeexample} +-- +-- If you set the |phase_default| field of |t| to |true|, the algorithm will +-- be installed as the default algorithm for the phase. This can be +-- done only once per phase. Furthermore, for such a default algorithm +-- the |algorithm| key must be table, it may not be a string (in other +-- words, all default algorithms are loaded immediately). +-- +-- (You cannot call this function directly, it is included for +-- documentation purposes only.) +-- +-- @param t The table originally passed to |declare|. + +local function declare_algorithm (t) + -- Algorithm declaration! + assert(type(t.algorithm) == "table" or type(t.algorithm) == "string") + + t.phase = t.phase or "main" + + local function make_class () + local class + + if type(t.algorithm) == "table" then + class = lib.class(t.algorithm) + else + class = lib.class(require(t.algorithm)) + end + + -- Now, save pre- and postconditions + class.preconditions = t.preconditions or {} + class.postconditions = t.postconditions or {} + + -- Save phase + class.phase = t.phase + + -- Compatibility + class.old_graph_model = t.old_graph_model + + return class + end + + -- Store this: + local store_me + if type(t.algorithm) == "table" then + store_me = make_class() + else + store_me = make_class + end + + -- Save in the algorithm_classes table: + InterfaceCore.algorithm_classes[t.key] = store_me + + -- Install! + InterfaceCore.binding:declareCallback(t) + + if t.phase_default then + assert (not InterfaceCore.option_initial.algorithm_phases[t.phase], + "default algorithm for phase already set") + assert (type(store_me) == "table", + "default algorithms must be loaded immediately") + InterfaceCore.option_initial.algorithm_phases[t.phase] = store_me + end + + return true +end + + + + +--- +-- This function is called by |declare| for ``collection kinds.'' They +-- are detected by the presence of the field |layer| +-- in the table |t| passed to |declare|. See the class |Collection| +-- for details on what a collection and a collection kind is. +-- +-- The |key| field of the table |t| passed to this function is both +-- the name of the to-be-declared collection kind as well as the key +-- that is used on the display layer to indicate that a node or edge +-- belongs to a collection. +-- +-- \medskip +-- \noindent\textbf{The Display Layer.} +-- Let us first have a look at what happens on the display layer: +-- A key |t.key| is setup on the display layer that, when used inside +-- a graph drawing scope, starts a new collection of the specified +-- kind. ``Starts'' means that all nodes and edges mentioned in the +-- rest of the current option scope will belong to a new collection +-- of kind |t.key|. +-- +--\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, the nodes |a|, |b|, |c| will belong to a collection of +-- kind |hyper|. The nodes |b|, |c|, and |d| will (also) belong to +-- another collection of the same kind |hyper|. You can nest +-- collections; in this case, nodes will belong to several +-- collections. +-- +-- The effect of declaring a collection kind on the algorithm layer +-- it, first of all, that |scope.collections| will have a field named +-- by the collection kind. This field will store an array that +-- contains all collections that were declared as part of the +-- graph. For instance, |collections.hyper| will contain all +-- hyperedges, each of which is a table with the following fields: The +-- |vertices| and |edges| fields each contain arrays of all objects +-- being part of the collection. The |sub| field is an array of +-- ``subcollections,'' that is, all collections that were started +-- inside another collection. (For the collection kinds |hyper| and +-- |same layer| this makes no sense, but subgraphs could, for instance, +-- be nested.) +-- +-- \medskip +-- \noindent\textbf{Rendering of Collections.} +-- For some kinds of collections, it makes sense to \emph{render} them, +-- but only after the graph drawing algorithm has run. For this +-- purpose, the binding layer will use a callback for each collection +-- kind and each collection, see the |Binding| class for details. +-- Suppose, for instance, you would +-- like hyperedges to be rendered. In this case, a graph drawing +-- algorithm should iterate over all collections of type |hyper| and +-- compute some hints on how to render the hyperedge and store this +-- information in the |generated_options| table of the hyperedge. Then, +-- the binding layer will ask the dislay layer to run some some code +-- that is able to read key--value pairs passed to +-- it (which are the key--value pairs of the |generated_options| table) +-- and use this information to nicely draw the hyperedge. +-- +-- The number |t.layer| determines in which order the different +-- collection kinds are rendered. +-- +-- The last parameter, the layer number, is used to specify the order +-- in which the different collection kinds are rendered. The higher the +-- number, the later the collection will be rendered. Thus, if there is +-- a collection kind with layer number 10 and another with layer number +-- 20, all collections of the first kind will be rendered first, +-- followed by all collections of the second kind. +-- +-- Collections whose layer kinds are non-negative get rendered +-- \emph{after} the nodes and edges have already been rendered. In +-- contrast, collections with a negative layer number get shown +-- ``below'' the nodes and edges. +-- +-- (You cannot call this function directly, it is included for +-- documentation purposes only.) +-- +-- @param t The table originally passed to |declare|. + +local function declare_collection_kind (t) + assert (type(t.layer) == "number", "layer must be a number") + + local layer = t.layer + local kind = t.key + local kinds = InterfaceCore.collection_kinds + local new_entry = { kind = kind, layer = layer } + + -- Insert into table part: + kinds[kind] = new_entry + + -- Insert into array part: + local found + for i=1,#kinds do + if kinds[i].layer > layer or (kinds[i].layer == layer and kinds[i].kind > kind) then + table.insert(kinds, i, new_entry) + return + end + end + + kinds[#kinds+1] = new_entry + + -- Bind + InterfaceCore.binding:declareCallback(t) + + return true +end + + + +-- Build in handlers: + +declare_handlers = { + { test = function (t) return t.algorithm_written_in_c end, handler = InterfaceToC.declare_algorithm_written_in_c }, + { test = function (t) return t.algorithm end, handler = declare_algorithm }, + { test = function (t) return t.layer end, handler = declare_collection_kind }, + { test = function (t) return true end, handler = declare_parameter } +} + + + + + + + + +--- +-- Finds a node by its name. This method should be used by algorithms +-- for which a node name is specified in some option and, thus, needs +-- to be converted to a vertex object during a run of the algorithm. +-- +-- @param name A node name +-- +-- @return The vertex of the given name in the syntactic digraph or +-- |nil|. + +function InterfaceToAlgorithms.findVertexByName(name) + return InterfaceCore.topScope().node_names[name] +end + + + + + +-- Helper function +local function add_to_collections(collection,where,what) + if collection then + LookupTable.addOne(collection[where],what) + add_to_collections(collection.parent,where,what) + end +end + +local unique_count = 1 + +--- +-- Generate a new vertex in the syntactic digraph. Calling this method +-- allows algorithms to create vertices that are not present in the +-- original input graph. Using the graph drawing coroutine, this +-- function will pass back control to the display layer in order to +-- render the vertex and, thereby, create precise size information +-- about it. +-- +-- Note that creating new vertices in the syntactic digraph while the +-- algorithm is already running is a bit at odds with the notion of +-- treating graph drawing as a series of graph transformations: For +-- instance, when a new vertex is created, the graph will (at least +-- temporarily) no longer be connected; even though an algorithm may +-- have requested that it should only be fed connected +-- graphs. Likewise, more complicated requirements like insisting on +-- the graph being a tree also cannot be met. +-- +-- For these reasons, the following happens, when a new vertex is +-- created using the function: +-- +-- \begin{enumerate} +-- \item The vertex is added to the syntactic digraph. +-- \item It is added to all layouts on the current layout stack. When +-- a graph drawing algorithm is run, it is not necessarily run on the +-- original syntactic digraph. Rather, a sequence / stack of nested +-- layouts may currently +-- be processed and the vertex is added to all of them. +-- \item The vertex is added to both the |digraph| and the |ugraph| of +-- the current algorithm. +-- \end{enumerate} +-- +-- @param algorithm An algorithm for whose syntactic digraph the node +-- should be added +-- @param init A table of initial values for the node that is passed +-- to |Binding:createVertex|, see that function for details. +-- +-- @return The newly created node +-- +function InterfaceToAlgorithms.createVertex(algorithm, init) + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Setup node + if not init.name then + init.name = "internal@gd@node@" .. unique_count + unique_count = unique_count + 1 + end + + -- Does vertex already exist? + assert (not scope.node_names[name], "node already created") + + if not init.shape or init.shape == "none" then + init.shape = "rectangle" + end + + -- Call binding + binding:createVertex(init) + + local v = assert(scope.node_names[init.name], "internal node creation failed") + + -- Add vertex to the algorithm's digraph and ugraph + algorithm.syntactic_component:add {v} + algorithm.digraph:add {v} + algorithm.ugraph:add {v} + + -- Compute bounding boxes: + LayoutPipeline.prepareBoundingBoxes(algorithm.rotation_info, algorithm.adjusted_bb, algorithm.digraph, {v}) + + -- Add the node to the layout stack: + add_to_collections(algorithm.layout, "vertices", v) + + algorithm.layout_graph:add { v } + + return v +end + + + +--- +-- Generate a new edge in the syntactic digraph. This method is quite +-- similar to |createVertex| and has the same effects with respect to +-- the edge: The edge is added to the syntactic digraph and also to +-- all layouts on the layout stack. Forthermore, appropriate edges are +-- added to the |digraph| and the |ugraph| of the algorithm currently +-- running. +-- +-- @param algorithm An algorithm for whose syntactic digraph the node should be added +-- @param tail A syntactic tail vertex +-- @param head A syntactic head vertex +-- @param init A table of initial values for the edge. +-- +-- The following fields are useful for |init|: +-- \begin{itemize} +-- \item |init.direction| If present, a direction for the edge. Defaults to "--". +-- \item |init.options| If present, some options for the edge. +-- \item |init.generated_options| A table that is passed back to the +-- display layer as a list of key-value pairs in the syntax of +-- |declare_parameter|. +-- \end{itemize} + +function InterfaceToAlgorithms.createEdge(algorithm, tail, head, init) + + init = init or {} + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + local syntactic_digraph = algorithm.layout_graph + local syntactic_component = algorithm.syntactic_component + + assert (syntactic_digraph:contains(tail) and + syntactic_digraph:contains(head), + "attempting to create edge between nodes that are not in the syntactic digraph") + + local arc = syntactic_digraph:connect(tail, head) + + local edge = Edge.new { + head = head, + tail = tail, + direction = init.direction or "--", + options = init.options or algorithm.layout.options, + path = init.path, + generated_options = init.generated_options + } + + -- Add to arc + arc.syntactic_edges[#arc.syntactic_edges+1] = edge + + local s_arc = syntactic_component:connect(tail, head) + s_arc.syntactic_edges = arc.syntactic_edges + + -- 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:everyEdgeCreation(edge) + + -- Add edge to digraph and ugraph + local direction = edge.direction + if direction == "->" then + algorithm.digraph:connect(tail, head) + elseif direction == "<-" then + algorithm.digraph:connect(head, tail) + elseif direction == "--" or direction == "<->" then + algorithm.digraph:connect(tail, head) + algorithm.digraph:connect(head, tail) + end + algorithm.ugraph:connect(tail, head) + algorithm.ugraph:connect(head, tail) + + -- Add edge to layouts + add_to_collections(algorithm.layout, "edges", edge) + +end + + + + + +-- Done + +return InterfaceToAlgorithms
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToC.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToC.lua new file mode 100644 index 00000000000..5b220f318bc --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToC.lua @@ -0,0 +1,77 @@ +-- 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/InterfaceToC.lua,v 1.6 2013/05/23 20:01:27 tantau Exp $ + + +--- +-- This table contains functions that are used (on the Lua side) to +-- prepare a graph for use in C and, vice versa, to translate back the +-- results of C to Lua. + +local InterfaceToC = {} + +-- Imports + +local lib = require "pgf.gd.lib" + + +--- +-- This function is called by |declare| for ``algorithm +-- keys'' where the algorithm is not written in Lua, but rather in the +-- programming language C. You do not call this function yourself; +-- |InterfaceFromC.h| will do it for you. Nevertheless, if you +-- provide a table to |declare| with the field +-- |algorithm_written_in_c| set, the following happens: The table's +-- |algorithm| field is set to an algorithm class object whose |run| +-- method calls the function passed via the +-- |algorithm_written_in_c| field. It will be called with the +-- following parameters (in that order): +-- \begin{enumerate} +-- \item The to-be-laid out digraph. This will not be the whole layout +-- graph (syntactic digraph) if preprocessing like decomposition into +-- connected components is used. +-- \item An array of the digraph's vertices, but with the table part +-- hashing vertex objects to their indices in the array part. +-- \item An array of the syntactic edges of the digraph. Like the +-- array, the table part will hash back the indices of the edge objects. +-- \item The algorithm object. +-- \end{enumerate} +-- +-- @param t The table originally passed to |declare|. + +function InterfaceToC.declare_algorithm_written_in_c (t) + t.algorithm = { + run = function (self) + local back_table = lib.icopy(self.ugraph.vertices) + for i,v in ipairs(self.ugraph.vertices) do + back_table[v] = i + end + local edges = {} + for _,a in ipairs(self.ugraph.arcs) do + local b = self.layout_graph:arc(a.tail,a.head) + if b then + lib.icopy(b.syntactic_edges, edges) + end + end + for i=1,#edges do + edges[edges[i]] = i + end + collectgarbage("stop") -- BUG! Remove this when everything is linked against a SINGLE Lua lib at runtime + t.algorithm_written_in_c (self.digraph, back_table, edges, self) + collectgarbage("restart") -- Remove also! + end + } +end + + + +-- Done + +return InterfaceToC
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua new file mode 100644 index 00000000000..cc72dc5910a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua @@ -0,0 +1,990 @@ +-- 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) + + -- 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
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/Scope.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/Scope.lua new file mode 100644 index 00000000000..7826e77e6ae --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/Scope.lua @@ -0,0 +1,92 @@ +-- 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/Scope.lua,v 1.2 2013/02/08 17:14:05 tantau Exp $ + + + +--- +-- In theory, graph drawing algorithms take graphs as input and +-- output graphs embedded into the plane as output. In practice, however, +-- the input to a graph drawing algorithm is not ``just'' the +-- graph. Rather, additional information about the graph, in particular +-- about the way the user specified the graph, is also important to many +-- graph drawing algorithms. +-- +-- The graph drawing system gathers both the original input graph as well +-- as all additional information that is provided in the graph drawing +-- scope inside a scope table. The object has a number of fields that +-- inform an algorithm about the input. +-- +-- For each graph drawing scope, a new |Scope| object is +-- created. Graph drawing scopes are kepts track of using a stack, but +-- only the top of this stack is available to the interface classes. +-- +-- @field syntactic_digraph The syntactic digraph is a digraph that +-- faithfully encodes the way the input graph is represented +-- syntactically. However, this does not mean that the syntactic +-- digraph contains the actual textual representation of the input +-- graph. Rather, when an edge is specified as, say, |a <- b|, the +-- syntactic digraph will contains an arc from |a| to |b| with an edge +-- object attached to it that is labeled as a ``backward'' +-- edge. Similarly, an edge |a -- b| is also stored as a directed arc +-- from |a| to |b| with the label |--| attached to it. Algorithms will +-- often be more interested graphs derived from the syntactic digraph +-- such as its underlying undirected graph. These derived graphs are +-- made accessible by the graph drawing engine during the preprocessing. +-- +-- @field events An array of |Event| objects. These objects, see the +-- |Event| class for details, are created during the parsing of the +-- input graph. +-- +-- @field node_names A table that maps the names of nodes to node +-- objects. Every node must have a unique name. +-- +-- @field coroutine A Lua coroutine that is used internally to allow +-- callbacks to the display layer to be issued deep down during a run +-- of an algorithm. +-- +-- @field collections The collections specified inside the scope, see +-- the |Collection| class. + +local Scope = {} +Scope.__index = Scope + +-- Namespace +require("pgf.gd.interface").Scope = Scope + +-- Imports +local lib = require "pgf.gd.lib" +local Storage = require "pgf.gd.lib.Storage" + +local Digraph = require "pgf.gd.model.Digraph" + +--- +-- Create a new |Scope| object. +-- +-- @param initial A table of initial values for the newly created +-- |Scope| object. +-- +-- @return The new scope object. + +function Scope.new(initial) + return setmetatable(lib.copy(initial, + { + syntactic_digraph = Digraph.new{}, + events = {}, + node_names = {}, + coroutine = nil, + collections = {}, + }), Scope) +end + + +-- Done + +return Scope
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered.lua new file mode 100644 index 00000000000..e5b4b5f1747 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered.lua @@ -0,0 +1,159 @@ +-- 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/layered.lua,v 1.2 2013/02/08 17:14:04 tantau Exp $ + + +local layered = {} + +-- Namespace + +require("pgf.gd").layered = layered + + +local lib = require "pgf.gd.lib" +local Storage = require "pgf.gd.lib.Storage" + +-- +-- This file defines some basic functions to compute and/or set the +-- ideal distances between nodes of any kind of layered drawing of a +-- graph. + + +--- +-- Compute the ideal distance between two siblings +-- +-- @param paddings A |Storage| object in which the computed distances +-- (paddings) are stored. +-- @param graph The graph object +-- @param n1 The first node +-- @param n2 The second node + +function layered.ideal_sibling_distance (paddings, graph, n1, n2) + local ideal_distance + local sep + + local n1_is_node = n1.kind == "node" + local n2_is_node = n2.kind == "node" + + if not n1_is_node and not n2_is_node then + ideal_distance = graph.options['sibling distance'] + sep = graph.options['sibling post sep'] + + graph.options['sibling pre sep'] + else + if n1_is_node then + ideal_distance = lib.lookup_option('sibling distance', n1, graph) + else + ideal_distance = lib.lookup_option('sibling distance', n2, graph) + end + sep = (n1_is_node and lib.lookup_option('sibling post sep', n1, graph) or 0) + + (n2_is_node and lib.lookup_option('sibling pre sep', n2, graph) or 0) + end + + return math.max(ideal_distance, sep + + ((n1_is_node and paddings[n1].sibling_post) or 0) - + ((n2_is_node and paddings[n2].sibling_pre) or 0)) +end + + + +--- +-- Compute the baseline distance between two layers +-- +-- The "baseline" distance is the distance between two layers that +-- corresponds to the distance of the two layers if the nodes where +-- "words" on two adjacent lines. In this case, the distance is +-- normally the layer_distance, but will be increased such that if we +-- draw a horizontal line below the deepest character on the first +-- line and a horizontal line above the highest character on the +-- second line, the lines will have a minimum distance of layer sep. +-- +-- Since each node on the lines might have a different layer sep and +-- layer distance specified, the maximum over all the values is taken. +-- +-- @param paddings A |Storage| object in which the distances +-- (paddings) are stored. +-- @param graph The graph in which the nodes reside +-- @param l1 An array of the nodes of the first layer +-- @param l2 An array of the nodes of the second layer + +function layered.baseline_distance (paddings, graph, l1, l2) + + if #l1 == 0 or #l2 == 0 then + return 0 + end + + local layer_distance = -math.huge + local layer_pre_sep = -math.huge + local layer_post_sep = -math.huge + + local max_post = -math.huge + local min_pre = math.huge + + for _,n in ipairs(l1) do + layer_distance = math.max(layer_distance, lib.lookup_option('level distance', n, graph)) + layer_post_sep = math.max(layer_post_sep, lib.lookup_option('level post sep', n, graph)) + if n.kind == "node" then + max_post = math.max(max_post, paddings[n].layer_post) + end + end + + for _,n in ipairs(l2) do + layer_pre_sep = math.max(layer_pre_sep, lib.lookup_option('level pre sep', n, graph)) + if n.kind == "node" then + min_pre = math.min(min_pre, paddings[n].layer_pre) + end + end + + return math.max(layer_distance, layer_post_sep + layer_pre_sep + max_post - min_pre) +end + + + +--- +-- Position nodes in layers using baselines +-- +-- @param layers A |Storage| object assigning layers to vertices. +-- @param paddings A |Storage| object storing the computed distances +-- (paddings). +-- @param graph The graph in which the nodes reside + +function layered.arrange_layers_by_baselines (layers, paddings, graph) + + local layer_vertices = Storage.newTableStorage() + + -- Decompose into layers: + for _,v in ipairs(graph.vertices) do + table.insert(layer_vertices[layers[v]], v) + end + + if #layer_vertices > 0 then -- sanity check + -- Now compute ideal distances and store + local height = 0 + + for _,v in ipairs(layer_vertices[1]) do + v.pos.y = 0 + end + + for i=2,#layer_vertices do + height = height + layered.baseline_distance(paddings, graph, layer_vertices[i-1], layer_vertices[i]) + + for _,v in ipairs(layer_vertices[i]) do + v.pos.y = height + end + end + end +end + + + + +-- Done + +return layered
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CrossingMinimizationGansnerKNV1993.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CrossingMinimizationGansnerKNV1993.lua new file mode 100644 index 00000000000..86baaf14c33 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CrossingMinimizationGansnerKNV1993.lua @@ -0,0 +1,342 @@ +-- Copyright 2011 by Jannis Pohlmann +-- +-- This file may be distributed and/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/layered/CrossingMinimizationGansnerKNV1993.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +local CrossingMinimizationGansnerKNV1993 = {} + + +-- Imports + +local lib = require "pgf.gd.lib" +local DepthFirstSearch = require "pgf.gd.lib.DepthFirstSearch" + + + +function CrossingMinimizationGansnerKNV1993:run() + + self:computeInitialRankOrdering() + + local best_ranking = self.ranking:copy() + local best_crossings = self:countRankCrossings(best_ranking) + + for iteration=1,24 do + local direction = (iteration % 2 == 0) and 'down' or 'up' + + self:orderByWeightedMedian(direction) + self:transpose(direction) + + local current_crossings = self:countRankCrossings(self.ranking) + + if current_crossings < best_crossings then + best_ranking = self.ranking:copy() + best_crossings = current_crossings + end + end + + self.ranking = best_ranking:copy() + + return self.ranking +end + + + +function CrossingMinimizationGansnerKNV1993:computeInitialRankOrdering() + + local best_ranking = self.ranking:copy() + local best_crossings = self:countRankCrossings(best_ranking) + + for _,direction in ipairs({'down', 'up'}) do + + local function init(search) + for i=#self.graph.nodes,1,-1 do + local node = self.graph.nodes[i] + if direction == 'down' then + if node:getInDegree() == 0 then + search:push(node) + search:setDiscovered(node) + end + else + if node:getOutDegree() == 0 then + search:push(node) + search:setDiscovered(node) + end + end + end + end + + local function visit(search, node) + search:setVisited(node, true) + + local rank = self.ranking:getRank(node) + local pos = self.ranking:getRankSize(rank) + self.ranking:setRankPosition(node, pos) + + if direction == 'down' then + local out = node:getOutgoingEdges() + for i=#out,1,-1 do + local neighbour = out[i]:getNeighbour(node) + if not search:getDiscovered(neighbour) then + search:push(neighbour) + search:setDiscovered(neighbour) + end + end + else + local into = node:getIncomingEdges() + for i=#into,1,-1 do + local neighbour = into[i]:getNeighbour(node) + if not search:getDiscovered(neighbour) then + search:push(neighbour) + search:setDiscovered(neighbour) + end + end + end + end + + DepthFirstSearch.new(init, visit):run() + + local crossings = self:countRankCrossings(self.ranking) + + if crossings < best_crossings then + best_ranking = self.ranking:copy() + best_crossings = crossings + end + end + + self.ranking = best_ranking:copy() + +end + + + +function CrossingMinimizationGansnerKNV1993:countRankCrossings(ranking) + + local crossings = 0 + + local ranks = ranking:getRanks() + + for rank_index = 2, #ranks do + local nodes = ranking:getNodes(ranks[rank_index]) + for i = 1, #nodes-1 do + for j = i+1, #nodes do + local v = nodes[i] + local w = nodes[j] + + -- TODO Jannis: We are REQUIRED to only check edges that lead to nodes + -- on the next or previous rank, depending on the sweep direction!!!! + local cn_vw = self:countNodeCrossings(ranking, v, w, 'down') + + crossings = crossings + cn_vw + end + end + end + + return crossings +end + + + +function CrossingMinimizationGansnerKNV1993:countNodeCrossings(ranking, left_node, right_node, sweep_direction) + + local ranks = ranking:getRanks() + local _, rank_index = lib.find(ranks, function (rank) + return rank == ranking:getRank(left_node) + end) + local other_rank_index = (sweep_direction == 'down') and rank_index-1 or rank_index+1 + + assert(ranking:getRank(left_node) == ranking:getRank(right_node)) + assert(rank_index >= 1 and rank_index <= #ranks) + + -- 0 crossings if we're at the top or bottom and are sweeping down or up + if other_rank_index < 1 or other_rank_index > #ranks then + return 0 + end + + local left_edges = {} + local right_edges = {} + + if sweep_direction == 'down' then + left_edges = left_node:getIncomingEdges() + right_edges = right_node:getIncomingEdges() + else + left_edges = left_node:getOutgoingEdges() + right_edges = right_node:getOutgoingEdges() + end + + local crossings = 0 + + local function left_neighbour_on_other_rank(edge) + local neighbour = edge:getNeighbour(left_node) + return ranking:getRank(neighbour) == ranking:getRanks()[other_rank_index] + end + + local function right_neighbour_on_other_rank(edge) + local neighbour = edge:getNeighbour(right_node) + return ranking:getRank(neighbour) == ranking:getRanks()[other_rank_index] + end + + for _,left_edge in ipairs(left_edges) do + if left_neighbour_on_other_rank(left_edge) then + local left_neighbour = left_edge:getNeighbour(left_node) + + for _,right_edge in ipairs(right_edges) do + if right_neighbour_on_other_rank(right_edge) then + local right_neighbour = right_edge:getNeighbour(right_node) + + local left_position = ranking:getRankPosition(left_neighbour) + local right_position = ranking:getRankPosition(right_neighbour) + + local neighbour_diff = right_position - left_position + + if neighbour_diff < 0 then + crossings = crossings + 1 + end + end + end + end + end + + return crossings +end + + + +function CrossingMinimizationGansnerKNV1993:orderByWeightedMedian(direction) + + local median = {} + + local function get_index(n, node) return median[node] end + local function is_fixed(n, node) return median[node] < 0 end + + if direction == 'down' then + local ranks = self.ranking:getRanks() + + for rank_index = 2, #ranks do + median = {} + local nodes = self.ranking:getNodes(ranks[rank_index]) + for _,node in ipairs(nodes) do + median[node] = self:computeMedianPosition(node, ranks[rank_index-1]) + end + + self.ranking:reorderRank(ranks[rank_index], get_index, is_fixed) + end + else + local ranks = self.ranking:getRanks() + + for rank_index = 1, #ranks-1 do + median = {} + local nodes = self.ranking:getNodes(ranks[rank_index]) + for _,node in ipairs(nodes) do + median[node] = self:computeMedianPosition(node, ranks[rank_index+1]) + end + + self.ranking:reorderRank(ranks[rank_index], get_index, is_fixed) + end + end +end + + + +function CrossingMinimizationGansnerKNV1993:computeMedianPosition(node, prev_rank) + + local positions = lib.imap( + node.edges, + function (edge) + local n = edge:getNeighbour(node) + if self.ranking:getRank(n) == prev_rank then + return self.ranking:getRankPosition(n) + end + end) + + table.sort(positions) + + local median = math.ceil(#positions / 2) + local position = -1 + + if #positions > 0 then + if #positions % 2 == 1 then + position = positions[median] + elseif #positions == 2 then + return (positions[1] + positions[2]) / 2 + else + local left = positions[median-1] - positions[1] + local right = positions[#positions] - positions[median] + position = (positions[median-1] * right + positions[median] * left) / (left + right) + end + end + + return position +end + + + +function CrossingMinimizationGansnerKNV1993:transpose(sweep_direction) + + local function transpose_rank(rank) + + local improved = false + + local nodes = self.ranking:getNodes(rank) + + for i = 1, #nodes-1 do + local v = nodes[i] + local w = nodes[i+1] + + local cn_vw = self:countNodeCrossings(self.ranking, v, w, sweep_direction) + local cn_wv = self:countNodeCrossings(self.ranking, w, v, sweep_direction) + + if cn_vw > cn_wv then + improved = true + + self:switchNodePositions(v, w) + end + end + + return improved + end + + local ranks = self.ranking:getRanks() + + local improved = false + repeat + local improved = false + + if sweep_direction == 'down' then + for rank_index = 1, #ranks-1 do + improved = transpose_rank(ranks[rank_index]) or improved + end + else + for rank_index = #ranks-1, 1, -1 do + improved = transpose_rank(ranks[rank_index]) or improved + end + end + until not improved +end + + + +function CrossingMinimizationGansnerKNV1993:switchNodePositions(left_node, right_node) + assert(self.ranking:getRank(left_node) == self.ranking:getRank(right_node)) + assert(self.ranking:getRankPosition(left_node) < self.ranking:getRankPosition(right_node)) + + local left_position = self.ranking:getRankPosition(left_node) + local right_position = self.ranking:getRankPosition(right_node) + + self.ranking:switchPositions(left_node, right_node) + + local nodes = self.ranking:getNodes(self.ranking:getRank(left_node)) +end + + + +-- done + +return CrossingMinimizationGansnerKNV1993 diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990a.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990a.lua new file mode 100644 index 00000000000..8e5111cfb72 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990a.lua @@ -0,0 +1,75 @@ +-- Copyright 2011 by Jannis Pohlmann +-- +-- This file may be distributed and/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/layered/CycleRemovalBergerS1990a.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +local CycleRemovalBergerS1990a = {} + +local lib = require("pgf.gd.lib") + + +function CycleRemovalBergerS1990a:run() + -- remember edges that were removed + local removed = {} + + -- remember edges that need to be reversed + local reverse = {} + + -- iterate over all nodes of the graph + for _,node in ipairs(self.graph.nodes) do + -- get all outgoing edges that have not been removed yet + local out_edges = lib.imap(node:getOutgoingEdges(), + function (edge) + if not removed[edge] then return edge end + end) + + -- get all incoming edges that have not been removed yet + local in_edges = lib.imap(node:getIncomingEdges(), + function (edge) + if not removed[edge] then return edge end + end) + + if #out_edges >= #in_edges then + -- we have more outgoing than incoming edges, reverse all incoming + -- edges and mark all incident edges as removed + + for _,edge in ipairs(out_edges) do + removed[edge] = true + end + for _,edge in ipairs(in_edges) do + reverse[edge] = true + removed[edge] = true + end + else + -- we have more incoming than outgoing edges, reverse all outgoing + -- edges and mark all incident edges as removed + + for _,edge in ipairs(out_edges) do + reverse[edge] = true + removed[edge] = true + end + for _,edge in ipairs(in_edges) do + removed[edge] = true + end + end + end + + -- mark edges as reversed + for edge in pairs(reverse) do + edge.reversed = true + end +end + + + +-- done + +return CycleRemovalBergerS1990a
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990b.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990b.lua new file mode 100644 index 00000000000..deaae695246 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990b.lua @@ -0,0 +1,76 @@ +-- Copyright 2011 by Jannis Pohlmann +-- +-- This file may be distributed and/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/layered/CycleRemovalBergerS1990b.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + +local CycleRemovalBergerS1990b = {} + +local lib = require("pgf.gd.lib") + + +function CycleRemovalBergerS1990b:run() + -- remember edges that were removed + local removed = {} + + -- remember edges that need to be reversed + local reverse = {} + + -- iterate over all nodes of the graph + for _,j in ipairs(lib.random_permutation(#self.graph.nodes)) do + local node = self.graph.nodes[j] + -- get all outgoing edges that have not been removed yet + -- get all outgoing edges that have not been removed yet + local out_edges = lib.imap(node:getOutgoingEdges(), + function (edge) + if not removed[edge] then return edge end + end) + + -- get all incoming edges that have not been removed yet + local in_edges = lib.imap(node:getIncomingEdges(), + function (edge) + if not removed[edge] then return edge end + end) + + if #out_edges >= #in_edges then + -- we have more outgoing than incoming edges, reverse all incoming + -- edges and mark all incident edges as removed + + for _,edge in ipairs(out_edges) do + removed[edge] = true + end + for _,edge in ipairs(in_edges) do + reverse[edge] = true + removed[edge] = true + end + else + -- we have more incoming than outgoing edges, reverse all outgoing + -- edges and mark all incident edges as removed + + for _,edge in ipairs(out_edges) do + reverse[edge] = true + removed[edge] = true + end + for _,edge in ipairs(in_edges) do + removed[edge] = true + end + end + end + + -- mark edges as reversed + for edge in pairs(reverse) do + edge.reversed = true + end +end + + + +-- done + +return CycleRemovalBergerS1990b
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalEadesLS1993.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalEadesLS1993.lua new file mode 100644 index 00000000000..6ff83ceae39 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalEadesLS1993.lua @@ -0,0 +1,124 @@ +-- Copyright 2011 by Jannis Pohlmann +-- +-- This file may be distributed and/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/layered/CycleRemovalEadesLS1993.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +-- Declare +local CycleRemovalEadesLS1993 = {} + +-- Import +local lib = require "pgf.gd.lib" + + +function CycleRemovalEadesLS1993:run() + local copied_graph = self.graph:copy() + + local copied_node = {} + local origin_node = {} + local copied_edge = {} + local origin_edge = {} + + local preserve = {} + + for _,edge in ipairs(self.graph.edges) do + copied_edge[edge] = edge:copy() + origin_edge[copied_edge[edge]] = edge + + for _,node in ipairs(edge.nodes) do + if copied_node[node] then + copied_edge[edge]:addNode(copied_node[node]) + else + copied_node[node] = node:copy() + origin_node[copied_node[node]] = node + + copied_graph:addNode(copied_node[node]) + copied_edge[edge]:addNode(copied_node[node]) + end + end + end + + local function node_is_sink(node) + return node:getOutDegree() == 0 + end + + local function node_is_source(node) + return node:getInDegree() == 0 + end + + local function node_is_isolated(node) + return node:getDegree() == 0 + end + + while #copied_graph.nodes > 0 do + local sink = lib.find(copied_graph.nodes, node_is_sink) + while sink do + for _,edge in ipairs(sink:getIncomingEdges()) do + preserve[edge] = true + end + copied_graph:deleteNode(sink) + sink = lib.find(copied_graph.nodes, node_is_sink) + end + + local isolated_node = lib.find(copied_graph.nodes, node_is_isolated) + while isolated_node do + copied_graph:deleteNode(isolated_node) + isolated_node = lib.find(copied_graph.nodes, node_is_isolated) + end + + local source = lib.find(copied_graph.nodes, node_is_source) + while source do + for _,edge in ipairs(source:getOutgoingEdges()) do + preserve[edge] = true + end + copied_graph:deleteNode(source) + source = lib.find(copied_graph.nodes, node_is_source) + end + + if #copied_graph.nodes > 0 then + local max_node = nil + local max_out_edges = nil + local max_in_edges = nil + + for _,node in ipairs(copied_graph.nodes) do + local out_edges = node:getOutgoingEdges() + local in_edges = node:getIncomingEdges() + + if max_node == nil or (#out_edges - #in_edges > #max_out_edges - #max_in_edges) then + max_node = node + max_out_edges = out_edges + max_in_edges = in_edges + end + end + + assert(max_node and max_out_edges and max_in_edges) + + for _,edge in ipairs(max_out_edges) do + preserve[edge] = true + copied_graph:deleteEdge(edge) + end + for _,edge in ipairs(max_in_edges) do + copied_graph:deleteEdge(edge) + end + + copied_graph:deleteNode(max_node) + end + end + + for _,edge in ipairs(self.graph.edges) do + if not preserve[copied_edge[edge]] then + edge.reversed = true + end + end +end + +-- done + +return CycleRemovalEadesLS1993
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalGansnerKNV1993.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalGansnerKNV1993.lua new file mode 100644 index 00000000000..a2ee9c01863 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalGansnerKNV1993.lua @@ -0,0 +1,52 @@ +-- Copyright 2011 by Jannis Pohlmann and 2012 by Till Tantau +-- +-- This file may be distributed and/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/layered/CycleRemovalGansnerKNV1993.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + +local CycleRemovalGansnerKNV1993 = {} + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare +local Simplifiers = require "pgf.gd.lib.Simplifiers" + + +function CycleRemovalGansnerKNV1993:run () + -- merge nonempty sets into supernodes + -- + -- ignore self-loops + -- + -- merge multiple edges into one edge each, whose weight is the sum of the + -- individual edge weights + -- + -- ignore leaf nodes that are not part of the user-defined sets (their ranks + -- are trivially determined) + -- + -- ensure that supernodes S_min and S_max are assigned first and last ranks + -- reverse in-edges of S_min + -- reverse out-edges of S_max + -- + -- ensure the supernodes S_min and S_max are are the only nodes in these ranks + -- for all nodes with indegree of 0, insert temporary edge (S_min, v) with delta=0 + -- for all nodes with outdegree of 0, insert temporary edge (v, S_max) with delta=0 + + -- classify edges as tree/forward, cross and back edges using a DFS traversal + local tree_or_forward_edges, cross_edges, back_edges = Simplifiers:classifyEdges(self.graph) + + -- reverse the back edges in order to make the graph acyclic + for _,edge in ipairs(back_edges) do + edge.reversed = true + end +end + + +-- done + +return CycleRemovalGansnerKNV1993
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/EdgeRoutingGansnerKNV1993.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/EdgeRoutingGansnerKNV1993.lua new file mode 100644 index 00000000000..649db1e54b6 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/EdgeRoutingGansnerKNV1993.lua @@ -0,0 +1,22 @@ +-- Copyright 2011 by Jannis Pohlmann +-- +-- This file may be distributed and/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/layered/EdgeRoutingGansnerKNV1993.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +local EdgeRoutingGansnerKNV1993 = {} + + +function EdgeRoutingGansnerKNV1993:run() +end + + +-- done +return EdgeRoutingGansnerKNV1993
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NetworkSimplex.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NetworkSimplex.lua new file mode 100644 index 00000000000..abc17477bac --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NetworkSimplex.lua @@ -0,0 +1,898 @@ +-- Copyright 2011 by Jannis Pohlmann +-- 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/layered/NetworkSimplex.lua,v 1.2 2013/05/23 20:01:27 tantau Exp $ + + + + +--- This file contains an implementation of the network simplex method +--- for node ranking and x coordinate optimization in layered drawing +--- algorithms, as proposed in +--- +--- "A Technique for Drawing Directed Graphs" +-- by Gansner, Koutsofios, North, Vo, 1993. + + +local NetworkSimplex = {} +NetworkSimplex.__index = NetworkSimplex + +-- Namespace +local layered = require "pgf.gd.layered" +layered.NetworkSimplex = NetworkSimplex + + +-- Imports +local DepthFirstSearch = require "pgf.gd.lib.DepthFirstSearch" +local Ranking = require "pgf.gd.layered.Ranking" +local Graph = require "pgf.gd.deprecated.Graph" +local lib = require "pgf.gd.lib" + + + +-- Definitions + +NetworkSimplex.BALANCE_TOP_BOTTOM = 1 +NetworkSimplex.BALANCE_LEFT_RIGHT = 2 + + +function NetworkSimplex.new(graph, balancing) + local simplex = { + graph = graph, + balancing = balancing, + } + setmetatable(simplex, NetworkSimplex) + return simplex +end + + + +function NetworkSimplex:run() + + assert (#self.graph.nodes > 0, "graph must contain at least one node") + + -- initialize the tree edge search index + self.search_index = 1 + + -- initialize internal edge parameters + self.cut_value = {} + for _,edge in ipairs(self.graph.edges) do + self.cut_value[edge] = 0 + end + + -- reset graph information needed for ranking + self.lim = {} + self.low = {} + self.parent_edge = {} + self.ranking = Ranking.new() + + if #self.graph.nodes == 1 then + self.ranking:setRank(self.graph.nodes[1], 1) + else + self:rankNodes() + end +end + + + +function NetworkSimplex:rankNodes() + -- construct feasible tree of tight edges + self:constructFeasibleTree() + + -- iteratively replace edges with negative cut values + -- with non-tree edges (chosen by minimum slack) + local leave_edge = self:findNegativeCutEdge() + while leave_edge do + local enter_edge = self:findReplacementEdge(leave_edge) + + assert(enter_edge, 'no non-tree edge to replace ' .. tostring(leave_edge) .. ' could be found') + + -- exchange leave_edge and enter_edge in the tree, updating + -- the ranks and cut values of all nodes + self:exchangeTreeEdges(leave_edge, enter_edge) + + -- find the next tree edge with a negative cut value, if + -- there are any left + leave_edge = self:findNegativeCutEdge() + end + + if self.balancing == NetworkSimplex.BALANCE_TOP_BOTTOM then + -- normalize by setting the least rank to zero + self.ranking:normalizeRanks() + + -- move nodes to feasible ranks with the least number of nodes + -- in order to avoid crowding and to improve the overall aspect + -- ratio of the drawing + self:balanceRanksTopBottom() + elseif self.balancing == NetworkSimplex.BALANCE_LEFT_RIGHT then + self:balanceRanksLeftRight() + end +end + + + +function NetworkSimplex:constructFeasibleTree() + + self:computeInitialRanking() + + -- find a maximal tree of tight edges in the graph + while self:findTightTree() < #self.graph.nodes do + + local min_slack_edge = nil + + for _,node in ipairs(self.graph.nodes) do + local out_edges = node:getOutgoingEdges() + for _,edge in ipairs(out_edges) do + if not self.tree_edge[edge] and self:isIncidentToTree(edge) then + if not min_slack_edge or self:edgeSlack(edge) < self:edgeSlack(min_slack_edge) then + min_slack_edge = edge + end + end + end + end + + if min_slack_edge then + local delta = self:edgeSlack(min_slack_edge) + + if delta > 0 then + local head = min_slack_edge:getHead() + local tail = min_slack_edge:getTail() + + if self.tree_node[head] then + delta = -delta + end + + + for _,node in ipairs(self.tree.nodes) do + local rank = self.ranking:getRank(self.orig_node[node]) + self.ranking:setRank(self.orig_node[node], rank + delta) + end + end + end + end + + self:initializeCutValues() +end + + + +function NetworkSimplex:findNegativeCutEdge() + local minimum_edge = nil + + for n=1,#self.tree.edges do + local index = self:nextSearchIndex() + + local edge = self.tree.edges[index] + + if self.cut_value[edge] < 0 then + if minimum_edge then + if self.cut_value[minimum_edge] > self.cut_value[edge] then + minimum_edge = edge + end + else + minimum_edge = edge + end + end + end + + return minimum_edge +end + + + +function NetworkSimplex:findReplacementEdge(leave_edge) + local tail = leave_edge:getTail() + local head = leave_edge:getHead() + + local v = nil + local direction = nil + + if self.lim[tail] < self.lim[head] then + v = tail + direction = 'in' + else + v = head + direction = 'out' + end + + local search_root = v + local enter_edge = nil + local slack = math.huge + + -- TODO Janns: Get rid of this recursion: + + local function find_edge(v, direction) + + if direction == 'out' then + local out_edges = self.orig_node[v]:getOutgoingEdges() + for _,edge in ipairs(out_edges) do + local head = edge:getHead() + local tree_head = self.tree_node[head] + + assert(head and tree_head) + + if not self.tree_edge[edge] then + if not self:inTailComponentOf(tree_head, search_root) then + if self:edgeSlack(edge) < slack or not enter_edge then + enter_edge = edge + slack = self:edgeSlack(edge) + end + end + else + if self.lim[tree_head] < self.lim[v] then + find_edge(tree_head, 'out') + end + end + end + + for _,edge in ipairs(v:getIncomingEdges()) do + if slack <= 0 then + break + end + + local tail = edge:getTail() + + if self.lim[tail] < self.lim[v] then + find_edge(tail, 'out') + end + end + else + local in_edges = self.orig_node[v]:getIncomingEdges() + for _,edge in ipairs(in_edges) do + local tail = edge:getTail() + local tree_tail = self.tree_node[tail] + + assert(tail and tree_tail) + + if not self.tree_edge[edge] then + if not self:inTailComponentOf(tree_tail, search_root) then + if self:edgeSlack(edge) < slack or not enter_edge then + enter_edge = edge + slack = self:edgeSlack(edge) + end + end + else + if self.lim[tree_tail] < self.lim[v] then + find_edge(tree_tail, 'in') + end + end + end + + for _,edge in ipairs(v:getOutgoingEdges()) do + if slack <= 0 then + break + end + + local head = edge:getHead() + + if self.lim[head] < self.lim[v] then + find_edge(head, 'in') + end + end + end + end + + find_edge(v, direction) + + return enter_edge +end + + + +function NetworkSimplex:exchangeTreeEdges(leave_edge, enter_edge) + + self:rerankBeforeReplacingEdge(leave_edge, enter_edge) + + local cutval = self.cut_value[leave_edge] + local head = self.tree_node[enter_edge:getHead()] + local tail = self.tree_node[enter_edge:getTail()] + + local ancestor = self:updateCutValuesUpToCommonAncestor(tail, head, cutval, true) + local other_ancestor = self:updateCutValuesUpToCommonAncestor(head, tail, cutval, false) + + assert(ancestor == other_ancestor) + + -- remove the old edge from the tree + self:removeEdgeFromTree(leave_edge) + + -- add the new edge to the tree + local tree_edge = self:addEdgeToTree(enter_edge) + + -- set its cut value + self.cut_value[tree_edge] = -cutval + + -- update DFS search tree traversal information + self:calculateDFSRange(ancestor, self.parent_edge[ancestor], self.low[ancestor]) +end + + + +function NetworkSimplex:balanceRanksTopBottom() + + -- available ranks + local ranks = self.ranking:getRanks() + + -- node to in/out weight mappings + local in_weight = {} + local out_weight = {} + + -- node to lowest/highest possible rank mapping + local min_rank = {} + local max_rank = {} + + -- compute the in and out weights of each node + for _,node in ipairs(self.graph.nodes) do + -- assume there are no restrictions on how to rank the node + min_rank[node], max_rank[node] = ranks[1], ranks[#ranks] + + for _,edge in ipairs(node:getIncomingEdges()) do + -- accumulate the weights of all incoming edges + in_weight[node] = (in_weight[node] or 0) + edge.weight + + -- update the minimum allowed rank (which is the maximum of + -- the ranks of all parent neighbours plus the minimum level + -- separation caused by the connecting edges) + local neighbour = edge:getNeighbour(node) + local neighbour_rank = self.ranking:getRank(neighbour) + min_rank[node] = math.max(min_rank[node], neighbour_rank + edge.minimum_levels) + end + + for _,edge in ipairs(node:getOutgoingEdges()) do + -- accumulate the weights of all outgoing edges + out_weight[node] = (out_weight[node] or 0) + edge.weight + + -- update the maximum allowed rank (which is the minimum of + -- the ranks of all child neighbours minus the minimum level + -- sparation caused by the connecting edges) + local neighbour = edge:getNeighbour(node) + local neighbour_rank = self.ranking:getRank(neighbour) + max_rank[node] = math.min(max_rank[node], neighbour_rank - edge.minimum_levels) + end + + -- check whether the in- and outweight is the same + if in_weight[node] == out_weight[node] then + + -- check which of the allowed ranks has the least number of nodes + local min_nodes_rank = min_rank[node] + for n = min_rank[node] + 1, max_rank[node] do + if #self.ranking:getNodes(n) < #self.ranking:getNodes(min_nodes_rank) then + min_nodes_rank = n + end + end + + -- only move the node to the rank with the least number of nodes + -- if it differs from the current rank of the node + if min_nodes_rank ~= self.ranking:getRank(node) then + self.ranking:setRank(node, min_nodes_rank) + end + + end + end +end + + + +function NetworkSimplex:balanceRanksLeftRight() + for _,edge in ipairs(self.tree.edges) do + if self.cut_value[edge] == 0 then + local other_edge = self:findReplacementEdge(edge) + if other_edge then + local delta = self:edgeSlack(other_edge) + if delta > 1 then + if self.lim[edge:getTail()] < self.lim[edge:getHead()] then + self:rerank(edge:getTail(), delta / 2) + else + self:rerank(edge:getHead(), -delta / 2) + end + end + end + end + end +end + + + +function NetworkSimplex:computeInitialRanking() + + -- queue for nodes to rank next + local queue = {} + + -- convenience functions for managing the queue + local function enqueue(node) table.insert(queue, node) end + local function dequeue() return table.remove(queue, 1) end + + -- reset the two-dimensional mapping from ranks to lists + -- of corresponding nodes + self.ranking:reset() + + -- mapping of nodes to the number of unscanned incoming edges + local remaining_edges = {} + + -- add all sinks to the queue + for _,node in ipairs(self.graph.nodes) do + local edges = node:getIncomingEdges() + + remaining_edges[node] = #edges + + if #edges == 0 then + enqueue(node) + end + end + + -- run long as there are nodes to be ranked + while #queue > 0 do + + -- fetch the next unranked node from the queue + local node = dequeue() + + -- get a list of its incoming edges + local in_edges = node:getIncomingEdges() + + -- determine the minimum possible rank for the node + local rank = 1 + for _,edge in ipairs(in_edges) do + local neighbour = edge:getNeighbour(node) + if self.ranking:getRank(neighbour) then + -- the minimum possible rank is the maximum of all neighbour ranks plus + -- the corresponding edge lengths + rank = math.max(rank, self.ranking:getRank(neighbour) + edge.minimum_levels) + end + end + + -- rank the node + self.ranking:setRank(node, rank) + + -- get a list of the node's outgoing edges + local out_edges = node:getOutgoingEdges() + + -- queue neighbours of nodes for which all incoming edges have been scanned + for _,edge in ipairs(out_edges) do + local head = edge:getHead() + remaining_edges[head] = remaining_edges[head] - 1 + if remaining_edges[head] <= 0 then + enqueue(head) + end + end + end +end + + + +function NetworkSimplex:findTightTree() + + -- TODO: Jannis: Remove the recursion below: + + local marked = {} + + local function build_tight_tree(node) + + local out_edges = node:getOutgoingEdges() + local in_edges = node:getIncomingEdges() + + local edges = lib.copy(out_edges) + for _,v in ipairs(in_edges) do + edges[#edges + 1] = v + end + + for _,edge in ipairs(edges) do + local neighbour = edge:getNeighbour(node) + if (not marked[neighbour]) and math.abs(self:edgeSlack(edge)) < 0.00001 then + self:addEdgeToTree(edge) + + for _,node in ipairs(edge.nodes) do + marked[node] = true + end + + if #self.tree.edges == #self.graph.nodes-1 then + return true + end + + if build_tight_tree(neighbour) then + return true + end + end + end + + return false + end + + for _,node in ipairs(self.graph.nodes) do + self.tree = Graph.new() + self.tree_node = {} + self.orig_node = {} + self.tree_edge = {} + self.orig_edge = {} + + build_tight_tree(node) + + if #self.tree.edges > 0 then + break + end + end + + return #self.tree.nodes +end + + + +function NetworkSimplex:edgeSlack(edge) + -- make sure this is never called with a tree edge + assert(not self.orig_edge[edge]) + + local head_rank = self.ranking:getRank(edge:getHead()) + local tail_rank = self.ranking:getRank(edge:getTail()) + local length = head_rank - tail_rank + return length - edge.minimum_levels +end + + + +function NetworkSimplex:isIncidentToTree(edge) + -- make sure this is never called with a tree edge + assert(not self.orig_edge[edge]) + + local head = edge:getHead() + local tail = edge:getTail() + + if self.tree_node[head] and not self.tree_node[tail] then + return true + elseif self.tree_node[tail] and not self.tree_node[head] then + return true + else + return false + end +end + + + +function NetworkSimplex:initializeCutValues() + self:calculateDFSRange(self.tree.nodes[1], nil, 1) + + local function init(search) + search:push({ node = self.tree.nodes[1], parent_edge = nil }) + end + + local function visit(search, data) + search:setVisited(data, true) + + local into = data.node:getIncomingEdges() + local out = data.node:getOutgoingEdges() + + for i=#into,1,-1 do + local edge = into[i] + if edge ~= data.parent_edge then + search:push({ node = edge:getTail(), parent_edge = edge }) + end + end + + for i=#out,1,-1 do + local edge = out[i] + if edge ~= data.parent_edge then + search:push({ node = edge:getHead(), parent_edge = edge }) + end + end + end + + local function complete(search, data) + if data.parent_edge then + self:updateCutValue(data.parent_edge) + end + end + + DepthFirstSearch.new(init, visit, complete):run() +end + + + +--- DFS algorithm that calculates post-order traversal indices and parent edges. +-- +-- This algorithm performs a depth-first search in a directed or undirected +-- graph. For each node it calculates the node's post-order traversal index, the +-- minimum post-order traversal index of its descendants as well as the edge by +-- which the node was reached in the depth-first traversal. +-- +function NetworkSimplex:calculateDFSRange(root, edge_from_parent, lowest) + + -- global traversal index counter + local lim = lowest + + -- start the traversal at the root node + local function init(search) + search:push({ node = root, parent_edge = edge_from_parent, low = lowest }) + end + + -- visit nodes in depth-first order + local function visit(search, data) + -- mark node as visited so we only visit it once + search:setVisited(data, true) + + -- remember the parent edge + self.parent_edge[data.node] = data.parent_edge + + -- remember the minimum traversal index for this branch of the search tree + self.low[data.node] = lim + + -- next we push all outgoing and incoming edges in reverse order + -- to simulate recursive calls + + local into = data.node:getIncomingEdges() + local out = data.node:getOutgoingEdges() + + for i=#into,1,-1 do + local edge = into[i] + if edge ~= data.parent_edge then + search:push({ node = edge:getTail(), parent_edge = edge }) + end + end + + for i=#out,1,-1 do + local edge = out[i] + if edge ~= data.parent_edge then + search:push({ node = edge:getHead(), parent_edge = edge }) + end + end + end + + -- when completing a node, store its own traversal index + local function complete(search, data) + self.lim[data.node] = lim + lim = lim + 1 + end + + -- kick off the depth-first search + DepthFirstSearch.new(init, visit, complete):run() + + local lim_lookup = {} + local min_lim = math.huge + local max_lim = -math.huge + for _,node in ipairs(self.tree.nodes) do + assert(self.lim[node]) + assert(self.low[node]) + assert(not lim_lookup[self.lim[node]]) + lim_lookup[self.lim[node]] = true + min_lim = math.min(min_lim, self.lim[node]) + max_lim = math.max(max_lim, self.lim[node]) + end + for n = min_lim, max_lim do + assert(lim_lookup[n] == true) + end +end + + + +function NetworkSimplex:updateCutValue(tree_edge) + + local v = nil + if self.parent_edge[tree_edge:getTail()] == tree_edge then + v = tree_edge:getTail() + dir = 1 + else + v = tree_edge:getHead() + dir = -1 + end + + local sum = 0 + + local out_edges = self.orig_node[v]:getOutgoingEdges() + local in_edges = self.orig_node[v]:getIncomingEdges() + local edges = lib.copy(out_edges) + for _,v in ipairs(in_edges) do + edges[#edges + 1] = v + end + + for _,edge in ipairs(edges) do + local other = edge:getNeighbour(self.orig_node[v]) + + local f = 0 + local rv = 0 + + if not self:inTailComponentOf(self.tree_node[other], v) then + f = 1 + rv = edge.weight + else + f = 0 + + if self.tree_edge[edge] then + rv = self.cut_value[self.tree_edge[edge]] + else + rv = 0 + end + + rv = rv - edge.weight + end + + local d = 0 + + if dir > 0 then + if edge:isHead(self.orig_node[v]) then + d = 1 + else + d = -1 + end + else + if edge:isTail(self.orig_node[v]) then + d = 1 + else + d = -1 + end + end + + if f > 0 then + d = -d + end + + if d < 0 then + rv = -rv + end + + sum = sum + rv + end + + self.cut_value[tree_edge] = sum +end + + + +function NetworkSimplex:inTailComponentOf(node, v) + return (self.low[v] <= self.lim[node]) and (self.lim[node] <= self.lim[v]) +end + + + +function NetworkSimplex:nextSearchIndex() + local index = 1 + + -- avoid tree edge index out of bounds by resetting the search index + -- as soon as it leaves the range of edge indices in the tree + if self.search_index > #self.tree.edges then + self.search_index = 1 + index = 1 + else + index = self.search_index + self.search_index = self.search_index + 1 + end + + return index +end + + + +function NetworkSimplex:rerank(node, delta) + local function init(search) + search:push({ node = node, delta = delta }) + end + + local function visit(search, data) + search:setVisited(data, true) + + local orig_node = self.orig_node[data.node] + self.ranking:setRank(orig_node, self.ranking:getRank(orig_node) - data.delta) + + local into = data.node:getIncomingEdges() + local out = data.node:getOutgoingEdges() + + for i=#into,1,-1 do + local edge = into[i] + if edge ~= self.parent_edge[data.node] then + search:push({ node = edge:getTail(), delta = data.delta }) + end + end + + for i=#out,1,-1 do + local edge = out[i] + if edge ~= self.parent_edge[data.node] then + search:push({ node = edge:getHead(), delta = data.delta }) + end + end + end + + DepthFirstSearch.new(init, visit):run() +end + + + +function NetworkSimplex:rerankBeforeReplacingEdge(leave_edge, enter_edge) + local delta = self:edgeSlack(enter_edge) + + if delta > 0 then + local tail = leave_edge:getTail() + + if #tail.edges == 1 then + self:rerank(tail, delta) + else + local head = leave_edge:getHead() + + if #head.edges == 1 then + self:rerank(head, -delta) + else + if self.lim[tail] < self.lim[head] then + self:rerank(tail, delta) + else + self:rerank(head, -delta) + end + end + end + end +end + + + +function NetworkSimplex:updateCutValuesUpToCommonAncestor(v, w, cutval, dir) + + while not self:inTailComponentOf(w, v) do + local edge = self.parent_edge[v] + + if edge:isTail(v) then + d = dir + else + d = not dir + end + + if d then + self.cut_value[edge] = self.cut_value[edge] + cutval + else + self.cut_value[edge] = self.cut_value[edge] - cutval + end + + if self.lim[edge:getTail()] > self.lim[edge:getHead()] then + v = edge:getTail() + else + v = edge:getHead() + end + end + + return v +end + + + +function NetworkSimplex:addEdgeToTree(edge) + assert(not self.tree_edge[edge]) + + -- create the new tree edge + local tree_edge = edge:copy() + self.orig_edge[tree_edge] = edge + self.tree_edge[edge] = tree_edge + + -- create tree nodes if necessary + for _,node in ipairs(edge.nodes) do + local tree_node + + if self.tree_node[node] then + tree_node = self.tree_node[node] + else + tree_node = node:copy() + self.orig_node[tree_node] = node + self.tree_node[node] = tree_node + end + + self.tree:addNode(tree_node) + tree_edge:addNode(tree_node) + end + + self.tree:addEdge(tree_edge) + + return tree_edge +end + + + +function NetworkSimplex:removeEdgeFromTree(edge) + self.tree:deleteEdge(edge) + self.tree_edge[self.orig_edge[edge]] = nil + self.orig_edge[edge] = nil +end + + + + +-- Done + +return NetworkSimplex
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodePositioningGansnerKNV1993.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodePositioningGansnerKNV1993.lua new file mode 100644 index 00000000000..ce0fab4efe7 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodePositioningGansnerKNV1993.lua @@ -0,0 +1,154 @@ +-- Copyright 2011 by Jannis Pohlmann +-- +-- This file may be distributed and/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/layered/NodePositioningGansnerKNV1993.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + + +local NodePositioningGansnerKNV1993 = {} + + +-- Imports + +local layered = require "pgf.gd.layered" + +local Graph = require "pgf.gd.deprecated.Graph" +local Edge = require "pgf.gd.deprecated.Edge" +local Node = require "pgf.gd.deprecated.Node" + +local NetworkSimplex = require "pgf.gd.layered.NetworkSimplex" +local Storage = require "pgf.gd.lib.Storage" + + +function NodePositioningGansnerKNV1993:run() + local auxiliary_graph = self:constructAuxiliaryGraph() + + local simplex = NetworkSimplex.new(auxiliary_graph, NetworkSimplex.BALANCE_LEFT_RIGHT) + simplex:run() + local x_ranking = simplex.ranking + + local layers = Storage.new() + + local ranks = self.ranking:getRanks() + for _,rank in ipairs(ranks) do + local nodes = self.ranking:getNodes(rank) + for _,node in ipairs(nodes) do + node.pos.x = x_ranking:getRank(node.aux_node) + layers[node.orig_vertex] = rank + end + end + + layered.arrange_layers_by_baselines(layers, self.main_algorithm.adjusted_bb, self.main_algorithm.ugraph) + + -- Copy back + for _,rank in ipairs(ranks) do + local nodes = self.ranking:getNodes(rank) + for _,node in ipairs(nodes) do + node.pos.y = node.orig_vertex.pos.y + end + end +end + + + + +function NodePositioningGansnerKNV1993:constructAuxiliaryGraph() + + local aux_graph = Graph.new() + + local edge_node = {} + + for _,node in ipairs(self.graph.nodes) do + local copy = Node.new{ + name = node.name, + orig_node = node, + } + node.aux_node = copy + aux_graph:addNode(copy) + end + + for i=#self.graph.edges,1,-1 do + local edge = self.graph.edges[i] + local node = Node.new{ + name = '{' .. tostring(edge) .. '}', + } + + aux_graph:addNode(node) + + node.orig_edge = edge + edge_node[edge] = node + + local head = edge:getHead() + local tail = edge:getTail() + + local tail_edge = Edge.new{ + direction = Edge.RIGHT, + minimum_levels = 0, + weight = edge.weight * self:getOmega(edge), + } + tail_edge:addNode(node) + tail_edge:addNode(tail.aux_node) + aux_graph:addEdge(tail_edge) + + local head_edge = Edge.new{ + direction = Edge.RIGHT, + minimum_levels = 0, + weight = edge.weight * self:getOmega(edge), + } + head_edge:addNode(node) + head_edge:addNode(head.aux_node) + aux_graph:addEdge(head_edge) + end + + local ranks = self.ranking:getRanks() + for _,rank in ipairs(ranks) do + local nodes = self.ranking:getNodes(rank) + for n = 1, #nodes-1 do + local v = nodes[n] + local w = nodes[n+1] + + local separator_edge = Edge.new{ + direction = Edge.RIGHT, + minimum_levels = self:getDesiredHorizontalDistance(v, w), + weight = 0, + } + separator_edge:addNode(v.aux_node) + separator_edge:addNode(w.aux_node) + aux_graph:addEdge(separator_edge) + end + end + + return aux_graph +end + + + +function NodePositioningGansnerKNV1993:getOmega(edge) + local node1 = edge.nodes[1] + local node2 = edge.nodes[2] + + if (node1.kind == "dummy") and (node2.kind == "dummy") then + return 8 + elseif (node1.kind == "dummy") or (node2.kind == "dummy") then + return 2 + else + return 1 + end +end + + + +function NodePositioningGansnerKNV1993:getDesiredHorizontalDistance(v, w) + return layered.ideal_sibling_distance(self.main_algorithm.adjusted_bb, self.graph.orig_digraph, v.orig_vertex, w.orig_vertex) +end + + +-- done + +return NodePositioningGansnerKNV1993
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodeRankingGansnerKNV1993.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodeRankingGansnerKNV1993.lua new file mode 100644 index 00000000000..e941029b3d3 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodeRankingGansnerKNV1993.lua @@ -0,0 +1,159 @@ +-- Copyright 2011 by Jannis Pohlmann +-- +-- This file may be distributed and/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/layered/NodeRankingGansnerKNV1993.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + +local NodeRankingGansnerKNV1993 = {} + + +-- Imports + +local Edge = require "pgf.gd.deprecated.Edge" +local Node = require "pgf.gd.deprecated.Node" + +local NetworkSimplex = require "pgf.gd.layered.NetworkSimplex" + + + +function NodeRankingGansnerKNV1993:run() + + local simplex = NetworkSimplex.new(self.graph, NetworkSimplex.BALANCE_TOP_BOTTOM) + simplex:run() + self.ranking = simplex.ranking + + return simplex.ranking +end + + + +function NodeRankingGansnerKNV1993:mergeClusters() + + self.cluster_nodes = {} + self.cluster_node = {} + self.cluster_edges = {} + + self.original_nodes = {} + self.original_edges = {} + + for _,cluster in ipairs(self.graph.clusters) do + + local cluster_node = Node.new{ + name = 'cluster@' .. cluster.name, + } + table.insert(self.cluster_nodes, cluster_node) + + for _,node in ipairs(cluster.nodes) do + self.cluster_node[node] = cluster_node + table.insert(self.original_nodes, node) + end + + self.graph:addNode(cluster_node) + end + + for _,edge in ipairs(self.graph.edges) do + local tail = edge:getTail() + local head = edge:getHead() + + if self.cluster_node[tail] or self.cluster_node[head] then + table.insert(self.original_edges, edge) + + local cluster_edge = Edge.new{ + direction = Edge.RIGHT, + weight = edge.weight, + minimum_levels = edge.minimum_levels, + } + table.insert(self.cluster_edges, cluster_edge) + + if self.cluster_node[tail] then + cluster_edge:addNode(self.cluster_node[tail]) + else + cluster_edge:addNode(tail) + end + + if self.cluster_node[head] then + cluster_edge:addNode(self.cluster_node[head]) + else + cluster_edge:addNode(head) + end + + end + end + + for _,edge in ipairs(self.cluster_edges) do + self.graph:addEdge(edge) + end + + for _,edge in ipairs(self.original_edges) do + self.graph:deleteEdge(edge) + end + + for _,node in ipairs(self.original_nodes) do + self.graph:deleteNode(node) + end +end + + + +function NodeRankingGansnerKNV1993:createClusterEdges() + for n = 1, #self.cluster_nodes-1 do + local first_cluster = self.cluster_nodes[n] + local second_cluster = self.cluster_nodes[n+1] + + local edge = Edge.new{ + direction = Edge.RIGHT, + weight = 1, + minimum_levels = 1, + } + + edge:addNode(first_cluster) + edge:addNode(second_cluster) + + self.graph:addEdge(edge) + + table.insert(self.cluster_edges, edge) + end +end + + + +function NodeRankingGansnerKNV1993:removeClusterEdges() +end + + + +function NodeRankingGansnerKNV1993:expandClusters() + + for _,node in ipairs(self.original_nodes) do + assert(self.ranking:getRank(self.cluster_node[node])) + self.ranking:setRank(node, self.ranking:getRank(self.cluster_node[node])) + self.graph:addNode(node) + end + + for _,edge in ipairs(self.original_edges) do + for _,node in ipairs(edge.nodes) do + node:addEdge(edge) + end + self.graph:addEdge(edge) + end + + for _,node in ipairs(self.cluster_nodes) do + self.ranking:setRank(node, nil) + self.graph:deleteNode(node) + end + + for _,edge in ipairs(self.cluster_edges) do + self.graph:deleteEdge(edge) + end +end + + +-- done + +return NodeRankingGansnerKNV1993
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodeRankingMinimumHeight.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodeRankingMinimumHeight.lua new file mode 100644 index 00000000000..38f52f6ba7f --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodeRankingMinimumHeight.lua @@ -0,0 +1,47 @@ +-- Copyright 2011 by Jannis Pohlmann +-- +-- This file may be distributed and/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/layered/NodeRankingMinimumHeight.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + +local NodeRankingMinimumHeight = {} + +-- Imports + +local Ranking = require "pgf.gd.layered.Ranking" +local Iterators = require "pgf.gd.deprecated.Iterators" + + +function NodeRankingMinimumHeight:run() + local ranking = Ranking.new() + + for node in Iterators.topologicallySorted(self.graph) do + local edges = node:getIncomingEdges() + + if #edges == 0 then + ranking:setRank(node, 1) + else + local max_rank = -math.huge + for _,edge in ipairs(edge) do + max_rank = math.max(max_rank, ranking:getRank(edge:getNeighbour(node))) + end + + assert(max_rank >= 1) + + ranking:setRank(node, max_rank + 1) + end + end + + return ranking +end + + +-- done + +return NodeRankingMinimumHeight
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/Ranking.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/Ranking.lua new file mode 100644 index 00000000000..8b2527edd5f --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/Ranking.lua @@ -0,0 +1,291 @@ +-- Copyright 2011 by Jannis Pohlmann +-- 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/layered/Ranking.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +--- The Ranking class is used by the Sugiyama algorithm to compute an ordering on the +-- nodes of a layer + +local Ranking = {} +Ranking.__index = Ranking + +-- Namespace +local layered = require "pgf.gd.layered" +layered.Ranking = Ranking + + +local lib = require "pgf.gd.lib" + + +-- TODO Jannis: document! + + +function Ranking.new() + local ranking = { + rank_to_nodes = {}, + node_to_rank = {}, + position_in_rank = {}, + } + setmetatable(ranking, Ranking) + return ranking +end + + + +function Ranking:copy() + local copied_ranking = Ranking.new() + + -- copy rank to nodes mapping + for rank, nodes in pairs(self.rank_to_nodes) do + copied_ranking.rank_to_nodes[rank] = lib.copy(self.rank_to_nodes[rank]) + end + + -- copy node to rank mapping + copied_ranking.node_to_rank = lib.copy(self.node_to_rank) + + -- copy node to position in rank mapping + copied_ranking.position_in_rank = lib.copy(self.position_in_rank) + + return copied_ranking +end + + + +function Ranking:reset() + self.rank_to_nodes = {} + self.node_to_rank = {} + self.position_in_rank = {} +end + + + +function Ranking:getRanks() + local ranks = {} + for rank, nodes in pairs(self.rank_to_nodes) do + table.insert(ranks, rank) + end + table.sort(ranks) + return ranks +end + + + +function Ranking:getRankSize(rank) + if self.rank_to_nodes[rank] then + return #self.rank_to_nodes[rank] + else + return 0 + end +end + + + +function Ranking:getNodeInfo(node) + return self:getRank(node), self:getRankPosition(node) +end + + + +function Ranking:getNodes(rank) + return self.rank_to_nodes[rank] or {} +end + + + +function Ranking:getRank(node) + return self.node_to_rank[node] +end + + + +function Ranking:setRank(node, new_rank) + local rank, pos = self:getNodeInfo(node) + + if rank == new_rank then + return + end + + if rank then + for n = pos+1, #self.rank_to_nodes[rank] do + local other_node = self.rank_to_nodes[rank][n] + self.position_in_rank[other_node] = self.position_in_rank[other_node]-1 + end + + table.remove(self.rank_to_nodes[rank], pos) + self.node_to_rank[node] = nil + self.position_in_rank[node] = nil + + if #self.rank_to_nodes[rank] == 0 then + self.rank_to_nodes[rank] = nil + end + end + + if new_rank then + self.rank_to_nodes[new_rank] = self.rank_to_nodes[new_rank] or {} + table.insert(self.rank_to_nodes[new_rank], node) + self.node_to_rank[node] = new_rank + self.position_in_rank[node] = #self.rank_to_nodes[new_rank] + end +end + + + +function Ranking:getRankPosition(node) + return self.position_in_rank[node] +end + + + +function Ranking:setRankPosition(node, new_pos) + local rank, pos = self:getNodeInfo(node) + + assert((rank and pos) or ((not rank) and (not pos))) + + if pos == new_pos then + return + end + + if rank and pos then + for n = pos+1, #self.rank_to_nodes[rank] do + local other_node = self.rank_to_nodes[rank][n] + self.position_in_rank[other_node] = self.position_in_rank[other_node]-1 + end + + table.remove(self.rank_to_nodes[rank], pos) + self.node_to_rank[node] = nil + self.position_in_rank[node] = nil + end + + if new_pos then + self.rank_to_nodes[rank] = self.rank_to_nodes[rank] or {} + + for n = new_pos+1, #self.rank_to_nodes[rank] do + local other_node = self.rank_to_nodes[rank][new_pos] + self.position_in_rank[other_node] = self.position_in_rank[other_node]+1 + end + + table.insert(self.rank_to_nodes[rank], node) + self.node_to_rank[node] = rank + self.position_in_rank[node] = new_pos + end +end + + + +function Ranking:normalizeRanks() + + -- get the current ranks + local ranks = self:getRanks() + + local min_rank = ranks[1] + local max_rank = ranks[#ranks] + + -- clear ranks + self.rank_to_nodes = {} + + -- iterate over all nodes and rerank them manually + for node in pairs(self.position_in_rank) do + local rank, pos = self:getNodeInfo(node) + local new_rank = rank - (min_rank - 1) + + self.rank_to_nodes[new_rank] = self.rank_to_nodes[new_rank] or {} + self.rank_to_nodes[new_rank][pos] = node + + self.node_to_rank[node] = new_rank + end +end + + + +function Ranking:switchPositions(left_node, right_node) + local left_rank = self.node_to_rank[left_node] + local right_rank = self.node_to_rank[right_node] + + assert(left_rank == right_rank, 'only positions of nodes in the same rank can be switched') + + local left_pos = self.position_in_rank[left_node] + local right_pos = self.position_in_rank[right_node] + + self.rank_to_nodes[left_rank][left_pos] = right_node + self.rank_to_nodes[left_rank][right_pos] = left_node + + self.position_in_rank[left_node] = right_pos + self.position_in_rank[right_node] = left_pos +end + + + +function Ranking:reorderRank(rank, get_index_func, is_fixed_func) + self:reorderTable(self.rank_to_nodes[rank], get_index_func, is_fixed_func) + + for n = 1, #self.rank_to_nodes[rank] do + self.position_in_rank[self.rank_to_nodes[rank][n]] = n + end +end + + + +function Ranking:reorderTable(input, get_index_func, is_fixed_func) + -- collect all allowed indices + local allowed_indices = {} + for n = 1, #input do + if not is_fixed_func(n, input[n]) then + table.insert(allowed_indices, n) + end + end + + -- collect all desired indices; for each of these desired indices, + -- remember by which element it was requested + local desired_to_real_indices = {} + local sort_indices = {} + for n = 1, #input do + if not is_fixed_func(n, input[n]) then + local index = get_index_func(n, input[n]) + if not desired_to_real_indices[index] then + desired_to_real_indices[index] = {} + table.insert(sort_indices, index) + end + table.insert(desired_to_real_indices[index], n) + end + end + + -- sort the desired indices + table.sort(sort_indices) + + -- compute the final indices by counting the final indices generated + -- prior to the current one and by mapping this number to the allowed + -- index with the same number + local final_indices = {} + local n = 1 + for _,index in ipairs(sort_indices) do + local real_indices = desired_to_real_indices[index] + for _,real_index in ipairs(real_indices) do + final_indices[real_index] = allowed_indices[n] + n = n + 1 + end + end + + -- flat-copy the input table so that we can still access the elements + -- using their real index while overwriting the input table in-place + local input_copy = lib.copy(input) + + -- move flexible elements to their final indices + for old_index, new_index in pairs(final_indices) do + input[new_index] = input_copy[old_index] + end +end + + + +-- Done + +return Ranking
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/Sugiyama.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/Sugiyama.lua new file mode 100644 index 00000000000..4d1e0ae47ed --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/Sugiyama.lua @@ -0,0 +1,478 @@ +-- Copyright 2011 by Jannis Pohlmann, 2012 by Till Tantau +-- +-- This file may be distributed and/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/layered/Sugiyama.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + + +--- +-- @section subsection {The Modular Sugiyama Method} +-- +-- @end + +local Sugiyama = {} + +-- Namespace +require("pgf.gd.layered").Sugiyama = Sugiyama + +-- Imports +local layered = require "pgf.gd.layered" +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + +local Ranking = require "pgf.gd.layered.Ranking" +local Simplifiers = require "pgf.gd.lib.Simplifiers" + +-- Deprecated stuff. Need to get rid of it! +local Edge = require "pgf.gd.deprecated.Edge" +local Node = require "pgf.gd.deprecated.Node" + +local Iterators = require "pgf.gd.deprecated.Iterators" +local Vector = require "pgf.gd.deprecated.Vector" + + + +--- + +declare { + key = "layered layout", + algorithm = Sugiyama, + + preconditions = { + connected = true, + loop_free = true, + }, + + postconditions = { + upward_oriented = true + }, + + old_graph_model = true, + + summary = [[" + The |layered layout| is the key used to select the modular Sugiyama + layout algorithm. + "]], + documentation = [[" + This algorithm consists of five consecutive steps, each of which can be + configured independently of the other ones (how this is done is + explained later in this section). Naturally, the ``best'' heuristics + are selected by default, so there is typically no need to change the + settings, but what is the ``best'' method for one graph need not be + the best one for another graph. + + As can be seen in the first example, the algorithm will not only + position the nodes of a graph, but will also perform an edge + routing. This will look visually quite pleasing if you add the + |rounded corners| option: + "]], + examples = { + [[" + \tikz \graph [layered layout, sibling distance=7mm] + { + a -> { + b, + c -> { d, e, f } + } -> + h -> + a + }; + "]], + [[" + \tikz [rounded corners] \graph [layered layout, sibling distance=7mm] + { + a -> { + b, + c -> { d, e, f } + } -> + h -> + a + }; + "]] + } +} + +--- + +declare { + key = "minimum layers", + type = "number", + initial = "1", + + summary = [[" + The minimum number of levels that an edge must span. It is a bit of + the opposite of the |weight| parameter: While a large |weight| + causes an edge to become shorter, a larger |minimum layers| value + causes an edge to be longer. + "]], + examples = [[" + \tikz \graph [layered layout] { + a -- {b [> minimum layers=3], c, d} -- e -- a; + }; + "]] +} + + +--- + +declare { + key = "same layer", + layer = 0, + + summary = [[" + The |same layer| collection allows you to enforce that several nodes + a on the same layer of a layered layout (this option is also known + as |same rank|). You use it like this: + "]], + examples = {[[" + \tikz \graph [layered layout] { + a -- b -- c -- d -- e; + + { [same layer] a, b }; + { [same layer] d, e }; + }; + "]],[[" + \tikz [rounded corners] \graph [layered layout] { + 1972 -> 1976 -> 1978 -> 1980 -> 1982 -> 1984 -> 1986 -> 1988 -> 1990 -> future; + + { [same layer] 1972, Thompson }; + { [same layer] 1976, Mashey, Bourne }, + { [same layer] 1978, Formshell, csh }, + { [same layer] 1980, esh, vsh }, + { [same layer] 1982, ksh, "System-V" }, + { [same layer] 1984, v9sh, tcsh }, + { [same layer] 1986, "ksh-i" }, + { [same layer] 1988, KornShell ,Perl, rc }, + { [same layer] 1990, tcl, Bash }, + { [same layer] "future", POSIX, "ksh-POSIX" }, + + Thompson -> { Mashey, Bourne, csh -> tcsh}, + Bourne -> { ksh, esh, vsh, "System-V", v9sh -> rc, Bash}, + { "ksh-i", KornShell } -> Bash, + { esh, vsh, Formshell, csh } -> ksh, + { KornShell, "System-V" } -> POSIX, + ksh -> "ksh-i" -> KornShell -> "ksh-POSIX", + Bourne -> Formshell, + + { [edge={draw=none}] + Bash -> tcl, + KornShell -> Perl + } + }; + "]] + } +} + + + +-- Implementation + +function Sugiyama:run() + if #self.graph.nodes <= 1 then + return + end + + local options = self.digraph.options + + local cycle_removal_algorithm_class = options.algorithm_phases['cycle removal'] + local node_ranking_algorithm_class = options.algorithm_phases['node ranking'] + local crossing_minimization_algorithm_class = options.algorithm_phases['crossing minimization'] + local node_positioning_algorithm_class = options.algorithm_phases['node positioning'] + local edge_routing_algorithm_class = options.algorithm_phases['layer edge routing'] + + self:preprocess() + + -- Helper function for collapsing multiedges + local function collapse (m,e) + m.weight = (m.weight or 0) + e.weight + m.minimum_levels = math.max((m.minimum_levels or 0), e.minimum_levels) + end + + -- Rank using cluster + + -- Create a subalgorithm object. Needed so that removed loops + -- are not stored on top of removed loops from main call. + local cluster_subalgorithm = { graph = self.graph } + self.graph:registerAlgorithm(cluster_subalgorithm) + + self:mergeClusters() + + Simplifiers:removeLoopsOldModel(cluster_subalgorithm) + Simplifiers:collapseMultiedgesOldModel(cluster_subalgorithm, collapse) + + cycle_removal_algorithm_class.new { main_algorithm = self, graph = self.graph }:run() + self.ranking = node_ranking_algorithm_class.new{ main_algorithm = self, graph = self.graph }:run() + self:restoreCycles() + + Simplifiers:expandMultiedgesOldModel(cluster_subalgorithm) + Simplifiers:restoreLoopsOldModel(cluster_subalgorithm) + + self:expandClusters() + + -- Now do actual computation + Simplifiers:collapseMultiedgesOldModel(cluster_subalgorithm, collapse) + cycle_removal_algorithm_class.new{ main_algorithm = self, graph = self.graph }:run() + self:insertDummyNodes() + + -- Main algorithm + crossing_minimization_algorithm_class.new{ + main_algorithm = self, + graph = self.graph, + ranking = self.ranking + }:run() + node_positioning_algorithm_class.new{ + main_algorithm = self, + graph = self.graph, + ranking = self.ranking + }:run() + + -- Cleanup + self:removeDummyNodes() + Simplifiers:expandMultiedgesOldModel(cluster_subalgorithm) + edge_routing_algorithm_class.new{ main_algorithm = self, graph = self.graph }:run() + self:restoreCycles() + +end + + + +function Sugiyama:preprocess() + -- initialize edge parameters + for _,edge in ipairs(self.graph.edges) do + -- read edge parameters + edge.weight = edge:getOption('weight') + edge.minimum_levels = edge:getOption('minimum layers') + + -- validate edge parameters + assert(edge.minimum_levels >= 0, 'the edge ' .. tostring(edge) .. ' needs to have a minimum layers value greater than or equal to 0') + end +end + + + +function Sugiyama:insertDummyNodes() + -- enumerate dummy nodes using a globally unique numeric ID + local dummy_id = 1 + + -- keep track of the original edges removed + self.original_edges = {} + + -- keep track of dummy nodes introduced + self.dummy_nodes = {} + + for node in Iterators.topologicallySorted(self.graph) do + local in_edges = node:getIncomingEdges() + + for _,edge in ipairs (in_edges) do + local neighbour = edge:getNeighbour(node) + local dist = self.ranking:getRank(node) - self.ranking:getRank(neighbour) + + if dist > 1 then + local dummies = {} + + for i=1,dist-1 do + local rank = self.ranking:getRank(neighbour) + i + + local dummy = Node.new{ + pos = Vector.new(), + name = 'dummy@' .. neighbour.name .. '@to@' .. node.name .. '@at@' .. rank, + kind = "dummy", + orig_vertex = pgf.gd.model.Vertex.new{} + } + + dummy_id = dummy_id + 1 + + self.graph:addNode(dummy) + self.ugraph:add {dummy.orig_vertex} + + self.ranking:setRank(dummy, rank) + + table.insert(self.dummy_nodes, dummy) + table.insert(edge.bend_nodes, dummy) + + table.insert(dummies, dummy) + end + + table.insert(dummies, 1, neighbour) + table.insert(dummies, #dummies+1, node) + + for i = 2, #dummies do + local source = dummies[i-1] + local target = dummies[i] + + local dummy_edge = Edge.new{ + direction = Edge.RIGHT, + reversed = false, + weight = edge.weight, -- TODO or should we divide the weight of the original edge by the number of virtual edges? + } + + dummy_edge:addNode(source) + dummy_edge:addNode(target) + + self.graph:addEdge(dummy_edge) + end + + table.insert(self.original_edges, edge) + end + end + end + + for _,edge in ipairs(self.original_edges) do + self.graph:deleteEdge(edge) + end +end + + + +function Sugiyama:removeDummyNodes() + -- delete dummy nodes + for _,node in ipairs(self.dummy_nodes) do + self.graph:deleteNode(node) + end + + -- add original edge again + for _,edge in ipairs(self.original_edges) do + -- add edge to the graph + self.graph:addEdge(edge) + + -- add edge to the nodes + for _,node in ipairs(edge.nodes) do + node:addEdge(edge) + end + + -- convert bend nodes to bend points for TikZ + for _,bend_node in ipairs(edge.bend_nodes) do + local point = bend_node.pos:copy() + table.insert(edge.bend_points, point) + end + + if edge.reversed then + local bp = edge.bend_points + for i=1,#bp/2 do + local j = #bp + 1 - i + bp[i], bp[j] = bp[j], bp[i] + end + end + + -- clear the list of bend nodes + edge.bend_nodes = {} + end +end + + + +function Sugiyama:mergeClusters() + + self.cluster_nodes = {} + self.cluster_node = {} + self.cluster_edges = {} + self.cluster_original_edges = {} + self.original_nodes = {} + + for _,cluster in ipairs(self.graph.clusters) do + + local cluster_node = cluster.nodes[1] + table.insert(self.cluster_nodes, cluster_node) + + for n = 2, #cluster.nodes do + local other_node = cluster.nodes[n] + self.cluster_node[other_node] = cluster_node + table.insert(self.original_nodes, other_node) + end + end + + for _,edge in ipairs(self.graph.edges) do + local tail = edge:getTail() + local head = edge:getHead() + + if self.cluster_node[tail] or self.cluster_node[head] then + local cluster_edge = Edge.new{ + direction = Edge.RIGHT, + weight = edge.weight, + minimum_levels = edge.minimum_levels, + } + + if self.cluster_node[tail] then + cluster_edge:addNode(self.cluster_node[tail]) + else + cluster_edge:addNode(tail) + end + + if self.cluster_node[head] then + cluster_edge:addNode(self.cluster_node[head]) + else + cluster_edge:addNode(head) + end + + table.insert(self.cluster_edges, cluster_edge) + table.insert(self.cluster_original_edges, edge) + end + end + + for n = 1, #self.cluster_nodes-1 do + local first_node = self.cluster_nodes[n] + local second_node = self.cluster_nodes[n+1] + + local edge = Edge.new{ + direction = Edge.RIGHT, + weight = 1, + minimum_levels = 1, + } + + edge:addNode(first_node) + edge:addNode(second_node) + + table.insert(self.cluster_edges, edge) + end + + for _,node in ipairs(self.original_nodes) do + self.graph:deleteNode(node) + end + for _,edge in ipairs(self.cluster_edges) do + self.graph:addEdge(edge) + end + for _,edge in ipairs(self.cluster_original_edges) do + self.graph:deleteEdge(edge) + end +end + + + +function Sugiyama:expandClusters() + + for _,node in ipairs(self.original_nodes) do + self.ranking:setRank(node, self.ranking:getRank(self.cluster_node[node])) + self.graph:addNode(node) + end + + for _,edge in ipairs(self.cluster_original_edges) do + for _,node in ipairs(edge.nodes) do + node:addEdge(edge) + end + self.graph:addEdge(edge) + end + + for _,edge in ipairs(self.cluster_edges) do + self.graph:deleteEdge(edge) + end +end + + +function Sugiyama:restoreCycles() + for _,edge in ipairs(self.graph.edges) do + edge.reversed = false + end +end + + + + + +-- done + +return Sugiyama
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/crossing_minimization.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/crossing_minimization.lua new file mode 100644 index 00000000000..16e3b1653de --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/crossing_minimization.lua @@ -0,0 +1,81 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed and/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/layered/crossing_minimization.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + +--- +-- @section subsection {Crossing Minimization (Node Ordering)} +-- +-- The number of edge crossings in a layered drawing is determined by +-- the ordering of nodes at each of its layers. Therefore, crossing +-- minimization is the problem of reordering the nodes at each layer +-- so that the overall number of edge crossings is minimized. The +-- crossing minimization step takes a proper layering where every edge +-- connects nodes in neighbored layers, allowing algorithms to +-- minimize crossings layer by layer rather than all at once. While +-- this does not reduce the complexity of the problem, it does make it +-- considerably easier to understand and implement. Techniques based +-- on such an iterative approach are also known as layer-by-layer +-- sweep methods. They are used in many popular heuristics due to +-- their simplicity and the good results they produce. +-- +-- Sweeping refers to moving up and down from one layer to the next, +-- reducing crossings along the way. In layer-by-layer sweep methods, +-- an initial node ordering for one of the layers is computed +-- first. Depending on the sweep direction this can either be the +-- first layer or the last; in rare occasions the layer in the middle +-- is used instead. Followed by this, the actual layer-by-layer sweep +-- is performed. Given an initial ordering for the first layer $L_1$, a +-- downward sweep first holds the nodes in $L_1$ fixed while reordering +-- the nodes in the second layer $L_2$ to reduce the number of +-- crossings between $L_1$ and $L_2$. It then goes on to reorder the +-- third layer while holding the second layer fixed. This is continued +-- until all layers except for the first one have been +-- examined. Upward sweeping and sweeping from the middle work +-- analogous. +-- +-- Obviously, the central aspect of the layer-by-layer sweep is how +-- the nodes of a specific layer are reordered using a neighbored +-- layer as a fixed reference. This problem is known as one-sided +-- crossing minimization, which unfortunately is NP-hard. In the +-- following various heuristics to solve this problem are +-- presented. +-- +-- For more details, please see Section 4.1.4 of Pohlmann's Diploma +-- thesis. +-- +-- @end + + + +--- + +declare { + key = "sweep crossing minimization", + algorithm = require "pgf.gd.layered.CrossingMinimizationGansnerKNV1993", + phase = "crossing minimization", + phase_default = true, + + summary = [[" + Gansner et al. combine an initial ordering based on a depth-first + search with the median and greedy switch heuristics applied in the + form of an alternating layer-by-layer sweep based on a weighted + median. + "]], + documentation = [[" + For more details, please see Section 4.1.4 of Pohlmann's Diploma + thesis. + + This is the default algorithm for crossing minimization. + "]] + } diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/cycle_removal.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/cycle_removal.lua new file mode 100644 index 00000000000..e201de6da4a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/cycle_removal.lua @@ -0,0 +1,139 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed and/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/layered/cycle_removal.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + +--- +-- @section subsection {Cycle Removal} +-- +-- The Sugiyama method works only on directed \emph{acyclic} +-- graphs. For this reason, if the input graph is not (yet) acyclic, a +-- number of edges need to be redirected so that acyclicity arises. In +-- the following, the different options that allow you to fine-tune +-- this process are documented. +-- +-- @end + + + +--- + +declare { + key = "depth first cycle removal", + algorithm = require "pgf.gd.layered.CycleRemovalGansnerKNV1993", + phase = "cycle removal", + phase_default = true, + + summary = [[" + Selects a cycle removal algorithm that is especially + appropriate for graphs specified ``by hand''. + "]], + documentation = [[" + When graphs are created by humans manually, one can + make assumptions about the input graph that would otherwise not + be possible. For instance, it seems reasonable to assume that the + order in which nodes and edges are entered by the user somehow + reflects the natural flow the user has had in mind for the graph. + + In order to preserve the natural flow of the input graph, Gansner + et al.\ propose to remove cycles by performing a series of + depth-first searches starting at individual nodes in the order they + appear in the graph. This algorithm + implicitly constructs a spanning tree of the nodes reached during + the searches. It thereby partitions the edges of the graph into + tree edges and non-tree edges. The non-tree edges are further + subdivided into forward edges, cross edges, and back edges. Forward + edges point from a tree nodes to one of their descendants. Cross + edges connect unrelated branches in + the search tree. Back edges connect descendants to one of their + ancestors. It is not hard to see that reversing back edges will not + only introduce no new cycles but will also make any directed graph + acyclic. Gansner et al.\ argue that this approach is more stable + than others in that fewer inappropriate edges are reversed compared + to other methods, despite the lack of a provable upper bound + for the number of reversed edges. + + See section 4.1.1 of Pohlmann's Diplom thesis for more details. + + This is the default algorithm for cycle removals. + "]] + } + +--- + +declare { + key = "prioritized greedy cycle removal", + algorithm = "pgf.gd.layered.CycleRemovalEadesLS1993", + phase = "cycle removal", + + summary = [[" + This algorithm implements a greedy heuristic of Eades et al.\ for + cycle removal that prioritizes sources and sinks. + "]], + documentation = [[" + See section 4.1.1 of Pohlmann's Diploma theses for details. + "]] +} + + +--- + +declare { + key = "greedy cycle removal", + algorithm = "pgf.gd.layered.CycleRemovalEadesLS1993", + phase = "cycle removal", + + summary = [[" + This algorithm implements a greedy heuristic of Eades et al.\ for + cycle removal that prioritizes sources and sinks. + "]], + documentation = [[" + See section 4.1.1 of Pohlmann's Diploma theses for details. + "]] + } + +--- + +declare { + key = "naive greedy cycle removal", + algorithm = "pgf.gd.layered.CycleRemovalBergerS1990a", + phase = "cycle removal", + + summary = [[" + This algorithm implements a greedy heuristic of Berger and Shor for + cycle removal. It + is not really compared to the other heuristics and only included + for demonstration purposes. + "]], + documentation = [[" + See section 4.1.1 of Pohlmann's Diploma theses for details. + "]] + } + +--- + +declare { + key = "random greedy cycle removal", + algorithm = "pgf.gd.layered.CycleRemovalBergerS1990b", + phase = "cycle removal", + + summary = [[" + This algorithm implements a randomized greedy heuristic of Berger + and Shor for cycle removal. It, too, is not really compared to + the other heuristics and only included for demonstration purposes. + "]], + documentation = [[" + See section 4.1.1 of Pohlmann's Diploma theses for details. + "]] + } + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/edge_routing.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/edge_routing.lua new file mode 100644 index 00000000000..e2cb40f68b3 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/edge_routing.lua @@ -0,0 +1,50 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed and/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/layered/edge_routing.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + +--- +-- @section subsection {Edge Routing} +-- +-- The original layered drawing method described by Eades and Sugiyama +-- in does not include the routing or shaping of edges as a main +-- step. This makes sense if all nodes have the same size and +-- shape. In practical scenarios, however, this assumption often does +-- not hold. In these cases, advanced techniques may have to be +-- applied in order to avoid overlaps of nodes and edges. +-- +-- For more details, please see Section 4.1.5 of Pohlmann's Diploma +-- thesis. +-- +-- @end + + + +--- + +declare { + key = "polyline layer edge routing", + algorithm = require "pgf.gd.layered.EdgeRoutingGansnerKNV1993", + phase = "layer edge routing", + phase_default = true, + + summary = [[" + This edge routing algorithm uses polygonal lines to connect nodes. + "]], + documentation = [[" + For more details, please see Section 4.1.5 of Pohlmann's Diploma + thesis. + + This is the default algorithm for edge routing. + "]] + } diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/library.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/library.lua new file mode 100644 index 00000000000..a3c03b7283e --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/library.lua @@ -0,0 +1,91 @@ +-- 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/layered/library.lua,v 1.3 2013/04/04 20:43:45 tantau Exp $ + + + +--- +-- A ``layered'' layout of a graph tries to arrange the nodes in +-- consecutive horizontal layers (naturally, by rotating the graph, this +-- can be changed in to vertical layers) such that edges tend to be only +-- between nodes on adjacent layers. Trees, for instance, can always be +-- laid out in this way. This method of laying out a graph is especially +-- useful for hierarchical graphs. +-- +-- The method implemented in this library is often called the +-- \emph{Sugiyama method}, which is a rather advanced method of +-- assigning nodes to layers and positions on these layers. The same +-- method is also used in the popular GraphViz program, indeed, the +-- implementation in \tikzname\ is based on the same pseudo-code from the +-- same paper as the implementation used in GraphViz and both programs +-- will often generate the same layout (but not always, as explained +-- below). The current implementation is due to Jannis Pohlmann, who +-- implemented it as part of his Diploma thesis. Please consult this +-- thesis for a detailed explanation of the Sugiyama method and its +-- history: +-- +-- \begin{itemize} +-- \item +-- Jannis Pohlmann, +-- \newblock \emph{Configurable Graph Drawing Algorithms +-- for the \tikzname\ Graphics Description Language,} +-- \newblock Diploma Thesis, +-- \newblock Institute of Theoretical Computer Science, Univerist\"at +-- zu L\"ubeck, 2011.\\[.5em] +-- \newblock Available online via +-- \url{http://www.tcs.uni-luebeck.de/downloads/papers/2011/}\\ \url{2011-configurable-graph-drawing-algorithms-jannis-pohlmann.pdf} +-- \\[.5em] +-- (Note that since the publication of this thesis some option names +-- have been changed. Most noticeably, the option name +-- |layered drawing| was changed to |layered layout|, which is somewhat +-- more consistent with other names used in the graph drawing +-- libraries. Furthermore, the keys for choosing individual +-- algorithms for the different algorithm phases, have all changed.) +-- \end{itemize} +-- +-- The Sugiyama methods lays out a graph in five steps: +-- \begin{enumerate} +-- \item Cycle removal. +-- \item Layer assignment (sometimes called node ranking). +-- \item Crossing minimization (also referred to as node ordering). +-- \item Node positioning (or coordinate assignment). +-- \item Edge routing. +-- \end{enumerate} +-- It turns out that behind each of these steps there lurks an +-- NP-complete problem, which means, in practice, that each step is +-- impossible to perform optimally for larger graphs. For this reason, +-- heuristics and approximation algorithms are used to find a ``good'' +-- way of performing the steps. +-- +-- A distinctive feature of Pohlmann's implementation of the Sugiyama +-- method for \tikzname\ is that the algorithms used for each of the +-- steps can easily be exchanged, just specify a different option. For +-- the user, this means that by specifying a different +-- option and thereby using a different heuristic for one of the steps, a +-- better layout can often be found. For the researcher, this means that +-- one can very easily test new approaches and new heuristics without +-- having to implement all of the other steps anew. +-- +-- @library + +local layered + + +-- Load declarations from: +require "pgf.gd.layered" + +-- Load algorithms from: +require "pgf.gd.layered.Sugiyama" +require "pgf.gd.layered.cycle_removal" +require "pgf.gd.layered.node_ranking" +require "pgf.gd.layered.crossing_minimization" +require "pgf.gd.layered.node_positioning" +require "pgf.gd.layered.edge_routing" + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/node_positioning.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/node_positioning.lua new file mode 100644 index 00000000000..d53b0873a3f --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/node_positioning.lua @@ -0,0 +1,57 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed and/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/layered/node_positioning.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + +--- +-- @section subsection {Node Positioning (Coordinate Assignment)} +-- +-- The second last step of the Sugiyama method decides about the final +-- $x$- and $y$-coordinates of the nodes. The main objectives of this +-- step are to position nodes so that the number of edge bends is kept +-- small and edges are drawn as vertically as possible. Another goal +-- is to avoid node and edge overlaps which is crucial in particular +-- if the nodes are allowed to have non-uniform sizes. The +-- y-coordinates of the nodes have no influence on the number of +-- bends. Obviously, nodes need to be separated enough geometrically +-- so that they do not overlap. It feels natural to aim at separating +-- all layers in the drawing by the same amount. Large nodes, however, +-- may force node positioning algorithms to override this uniform +-- level distance in order to avoid overlaps. +-- +-- For more details, please see Section 4.1.2 of Pohlmann's Diploma +-- thesis. +-- +-- @end + + + +--- + +declare { + key = "linear optimization node positioning", + algorithm = require "pgf.gd.layered.NodePositioningGansnerKNV1993", + phase = "node positioning", + phase_default = true, + + summary = [[" + This node positioning method, due to Gasner et al., is based on a + linear optimization problem. + "]], + documentation = [[" + For more details, please see Section 4.1.3 of Pohlmann's Diploma + thesis. + + This is the default algorithm for layer assignments. + "]] + } diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/node_ranking.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/node_ranking.lua new file mode 100644 index 00000000000..3a1098d6c03 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/node_ranking.lua @@ -0,0 +1,74 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed and/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/layered/node_ranking.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + +--- +-- @section subsection {Layer Assignment (Node Ranking)} +-- +-- Algorithms for producing layered drawings place nodes on discrete +-- layers from top to bottom. Layer assignment is the problem of +-- finding a partition so that for all edges $e = (u,v) \in E(G)$ the +-- equation $\mathit{layer}(u) < \mathit{layer}(v)$ holds. Such a +-- partition is called a \emph{layering}. This definition can be extended by +-- introducing edge weights or priorities and minimum length +-- constraints which has practical applications and allows users to +-- fine-tune the results. +-- +-- For more details, please see Section 4.1.2 of Pohlmann's Diploma +-- thesis. +-- +-- @end + + + +--- + +declare { + key = "linear optimization layer assignment", + algorithm = require "pgf.gd.layered.NodeRankingGansnerKNV1993", + phase = "node ranking", + phase_default = true, + + summary = [[" + This layer assigment method, due to Gasner et al., is based on a + linear optimization problem. + "]], + documentation = [[" + For more details, please see Section 4.1.2 of Pohlmann's Diploma + thesis. + + This is the default algorithm for layer assignments. + "]] + } + + + +--- + +declare { + key = "minimum height layer assignment", + algorithm = "pgf.gd.layered.NodeRankingMinimumHeight", + phase = "node ranking", + + summary = [[" + This layer assigment method minimizes the height of the resulting + graph. + "]], + documentation = [[" + For more details, please see Section 4.1.3 of Pohlmann's Diploma + thesis. + "]] + } + + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib.lua new file mode 100644 index 00000000000..dcfb468d063 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib.lua @@ -0,0 +1,356 @@ +-- 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/lib.lua,v 1.5 2013/04/04 20:43:45 tantau Exp $ + + + +--- +-- Basic library functions + +local lib = {} + +-- Declare namespace + +require("pgf.gd").lib = lib + + +-- General lib functions: + + +--- +-- Finds the first value in the |array| for which |test| is true. +-- +-- @param array An array to search in. +-- @param test A function that is applied to each element of the +-- array together with the index of the element and the +-- whole table. +-- +-- @return The value of the first value where the test is true. +-- @return The index of the first value where the test is true. +-- @return The function value of the first value where the test is +-- true (only returned if test is a function). +-- +function lib.find(array, test) + for i=1,#array do + local t = array[i] + local result = test(t,i,array) + if result then + return t,i,result + end + end +end + + +--- +-- Finds the first value in the |array| for which a function +-- returns a minimal value +-- +-- @param array An array to search in. +-- @param f A function that is applied to each element of the +-- array together with the index of the element and the +-- whole table. It should return an integer and, possibly, a value. +-- +-- Among all elements for which a non-nil integer is returned, let |i| +-- by the index of the element where this integer is minimal. +-- +-- @return |array[i]| +-- @return |i| +-- @return The return value(s) of the function at |array[i]|. +-- +function lib.find_min(array, f) + local best = math.huge + local best_result + local best_index + for i=1,#array do + local t = array[i] + local result, p = f(t,i,array) + if result and p < best then + best = p + best_result = result + best_index = i + end + end + if best_index then + return array[best_index],best_index,best_result,best + end +end + + + + +--- +-- Copies a table while preserving its metatable. +-- +-- @param source The table to copy. +-- @param target The table to which values are to be copied or |nil| if a new +-- table is to be allocated. +-- +-- @return The |target| table or a newly allocated table containing all +-- keys and values of the |source| table. +-- +function lib.copy(source, target) + if not target then + target = {} + end + for key, val in pairs(source) do + target[key] = val + end + return setmetatable(target, getmetatable(source)) +end + + +--- +-- Copies an array while preserving its metatable. +-- +-- @param source The array to copy. +-- @param target The array to which values are to be copied or |nil| if a new +-- table is to be allocated. The elements of the +-- |source| array will be added at the end. +-- +-- @return The |target| table or a newly allocated table containing all +-- keys and values of the |source| table. +-- +function lib.icopy(source, target) + target = target or {} + for _, val in ipairs(source) do + target[#target+1] = val + end + return setmetatable(target, getmetatable(source)) +end + + + + +--- +-- Apply a function to all pairs of a table, resulting in a new table. +-- +-- @param source The table. +-- @param fun A function taking two arguments (|val| and |key|, in +-- that order). Should return two values (a |new_val| and a +-- |new_key|). This pair will be inserted into the new table. If, +-- however, |new_key| is |nil|, the |new_value| will be inserted at +-- the position |key|. This means, in particular, that if the |fun| +-- takes only a single argument and returns only a single argument, +-- you have a ``classical'' value mapper. Also note that if +-- |new_value| is |nil|, the value is removed from the table. +-- +-- @return The new table. +-- +function lib.map(source, fun) + local target = {} + for key, val in pairs(source) do + local new_val, new_key = fun(val, key) + if new_key == nil then + new_key = key + end + target[new_key] = new_val + end + return target +end + + + +--- +-- Apply a function to all elements of an array, resulting in a new +-- array. +-- +-- @param source The array. +-- @param fun A function taking two arguments (|val| and |i|, the +-- current index). This function is applied to all elements of the +-- array. The result of this function is placed at the end of a new +-- array, expect when the function returns |nil|, in which case the +-- element is skipped. If this function is not provided (is |nil|), +-- the identity function is used. +-- @param new The target array (if |nil|, a new array is create). +-- +--\begin{codeexample}[code only] +-- local a = lib.imap(array, function(v) if some_test(v) then return v end end) +--\end{codeexample} +-- +-- The above code is a filter that will remove all elements from the +-- array that do not pass |some_test|. +-- +--\begin{codeexample}[code only] +-- lib.imap(a, lib.id, b) +--\end{codeexample} +-- +-- The above code has the same effect as |lib.icopy(a,b)|. +-- +-- @return The new array +-- +function lib.imap(source, fun, new) + if not new then + new = { } + end + for i, v in ipairs(source) do + new[#new+1] = fun(v, i) + end + return new +end + + +--- +-- Generate a random permutation of the numbers $1$ to $n$ in time +-- $O(n)$. Knuth's shuffle is used for this. +-- +-- @param n The desired size of the table +-- @return A random permutation + +function lib.random_permutation(n) + local p = {} + for i=1,n do + p[i] = i + end + for i=1,n-1 do + local j = math.random(i,n) + p[i], p[j] = p[i], p[j] + end + return p +end + + +--- +-- The identity function, so you can write |lib.id| instead of +-- |function (x) return x end|. +-- + +function lib.id(...) + return ... +end + + + +--- +-- Tries to find an option in different objects that have an +-- options field. +-- +-- This function iterates over all objects given as parameters. In +-- each, it tries to find out whether the options field of the object +-- contains the option |name| and, if so, +-- returns the value. The important point is that checking whether the +-- option table of an object contains the name field is done using +-- |rawget| for all but the last parameter. This means that when you +-- write +--\begin{codeexample}[code only] +--lib.lookup_option("foo", vertex, graph) +--\end{codeexample} +-- and if |/graph drawin/foo| has an inital value set, if the +-- parameter is not explicitly set in a vertex, you will get the value +-- set for the graph or, if it is not set there either, the initial +-- value. In contrast, if you write +--\begin{codeexample}[code only] +-- vertex.options["foo"] or graph.options["foo"] +--\end{codeexample} +-- what happens is that the first access to |.options| will +-- \emph{always} return something when an initial parameter has been +-- set for the option |foo|. +-- +-- @param name The name of the options +-- @param ... Any number of objects. Each must have an options +-- field. +-- +-- @return The found option + +function lib.lookup_option(name, ...) + local list = {...} + for i=1,#list-1 do + local o = list[i].options + if o then + local v = rawget(o, name) + if v then + return v + end + end + end + return list[#list].options[name] +end + + + +--- +-- Turns a table |t| into a class in the sense of object oriented +-- programming. In detail, this means that |t| is augmented by +-- a |new| function, which takes an optional table of |initial| values +-- and which outputs a new table whose metatable is the +-- class. The |new| function will call the function |constructor| if +-- it exsist. Furthermore, the class object's |__index| is set to itself +-- and its meta table is set to the |base_class| field of the +-- table. If |t| is |nil|, a new table is created. +-- +-- Here is a typical usage of this function: +-- +--\begin{codeexample}[code only] +--local Point = lib.class {} +-- +--function Point:length() +-- return math.sqrt(self.x*self.x + self.y*self.y) +--end +-- +--local p = Point.new { x = 5, y = 6 } +-- +--print(p:length()) +--\end{codeexample} +-- We can subclass this as follows: +-- +--\begin{codeexample}[code only] +--local Point3D = lib.class { base_class = Point } +-- +--function Point3D:length() +-- local l = Point.length(self) -- Call base class's function +-- return math.sqrt(l*l + self.z*self.zdy) +--end +-- +--local p = Point3D.new { x = 5, y = 6, z = 6 } +-- +--print(p:length()) +--\end{codeexample} +-- +-- @param t A table that gets augmented to a class. If |nil|, a new +-- table is created. +-- @return The augmented table. + +function lib.class(t) + t = t or {} + + -- First, setup indexing, if necessary + if not t.__index then + t.__index = t + end + + -- Second, setup new method, if necessary + t.new = t.new or + function (initial) + + -- Create new object + local obj = {} + for k,v in pairs(initial or {}) do + obj[k] = v + end + setmetatable(obj, t) + + if obj.constructor then + obj:constructor() + end + + return obj + end + + -- Third, setup inheritence, if necessary + if not getmetatable(t) then + setmetatable(t, t.base_class) + end + + return t +end + + +-- Done + +return lib
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Bezier.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Bezier.lua new file mode 100644 index 00000000000..aa149c3e4f9 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Bezier.lua @@ -0,0 +1,160 @@ +-- Copyright 2013 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/lib/Bezier.lua,v 1.1 2013/05/23 20:01:27 tantau Exp $ + + + +--- +-- This library offers a number of methods for working with Bezi\'er +-- curves. + +local Bezier = {} + +-- Namespace +require("pgf.gd.lib").Bezier = Bezier + + +-- Imports + +local Coordinate = require 'pgf.gd.model.Coordinate' + + +--- +-- Compute a point ``along a curve at a time''. You provide the four +-- coordinates of the curve and a time. You get a point on the curve +-- as return value as well as the two suport vector for curve +-- before this point and two support vectors for the curve after the +-- point. +-- +-- For speed reasons and in order to avoid superfluous creation of +-- lots of tables, all values are provided and returned as pairs of +-- values rather than as |Coordinate| objects. +-- +-- @param ax The coordinate where the curve starts. +-- @param ay +-- @param bx The first support point. +-- @param by +-- @param cx The second support point. +-- @param cy +-- @param dx The coordinate where the curve ends. +-- @param dy +-- @param t A time (a number). +-- +-- @return The point |p| on the curve at time |t| ($x$-part). +-- @return The point |p| on the curve at time |t| ($y$-part). +-- @return The first support point of the curve between |a| and |p| ($x$-part). +-- @return The first support point of the curve between |a| and |p| ($y$-part). +-- @return The second support point of the curve between |a| and |p| ($x$-part). +-- @return The second support point of the curve between |a| and |p| ($y$-part). +-- @return The first support point of the curve between |p| and |d| ($x$-part). +-- @return The first support point of the curve between |p| and |d| ($y$-part). +-- @return The second support point of the curve between |p| and |d| ($x$-part). +-- @return The second support point of the curve between |p| and |d| ($y$-part). + +function Bezier.atTime(ax,ay,bx,by,cx,cy,dx,dy,t) + + local s = 1-t + + local ex, ey = ax*s + bx*t, ay*s + by*t + local fx, fy = bx*s + cx*t, by*s + cy*t + local gx, gy = cx*s + dx*t, cy*s + dy*t + + local hx, hy = ex*s + fx*t, ey*s + fy*t + local ix, iy = fx*s + gx*t, fy*s + gy*t + + local jx, jy = hx*s + ix*t, hy*s + iy*t + + return jx, jy, ex, ey, hx, hy, ix, iy, gx, gy +end + + +--- +-- The ``coordinate version'' of the |atTime| function, where both the +-- parameters and the return values are coordinate objects. + +function Bezier.atTimeCoordinates(a,b,c,d,t) + local jx, jy, ex, ey, hx, hy, ix, iy, gx, gy = + Bezier.atTime(a.x,a.y,b.x,b.y,c.x,c.y,d.x,d.y,t) + + return + Coordinate.new(jx, jy), + Coordinate.new(ex, ey), + Coordinate.new(hx, hy), + Coordinate.new(ix, iy), + Coordinate.new(gx, gy) +end + + +--- +-- Computes the support points of a Bezier curve based on two points +-- on the curves at certain times. +-- +-- @param from The start point of the curve +-- @param p1 A first point on the curve +-- @param t1 A time when this point should be reached +-- @param p2 A second point of the curve +-- @param t2 A time when this second point should be reached +-- @param to The end of the curve +-- +-- @return sup1 A first support point of the curve +-- @return sup2 A second support point of the curve + +function Bezier.supportsForPointsAtTime(from, p1, t1, p2, t2, to) + + local s1 = 1 - t1 + local s2 = 1 - t2 + + local f1a = s1^3 + local f1b = t1 * s1^2 * 3 + local f1c = t1^2 * s1 * 3 + local f1d = t1^3 + + local f2a = s2^3 + local f2b = t2 * s2^2 * 3 + local f2c = t2^2 * s2 * 3 + local f2d = t2^3 + + -- The system: + -- p1.x - from.x * f1a - to.x * f1d = sup1.x * f1b + sup2.x * f1c + -- p2.x - from.x * f2a - to.x * f2d = sup1.x * f2b + sup2.x * f2c + -- + -- p1.y - from.y * f1a - to.y * f1d = sup1.y * f1b + sup2.y * f1c + -- p2.y - from.y * f2a - to.y * f2d = sup1.y * f2b + sup2.y * f2c + + local a = f1b + local b = f1c + local c = p1.x - from.x * f1a - to.x * f1d + local d = f2b + local e = f2c + local f = p2.x - from.x * f2a - to.x * f2d + + local det = a*e - b*d + local x1 = -(b*f - e*c)/det + local x2 = -(c*d - a*f)/det + + local c = p1.y - from.y * f1a - to.y * f1d + local f = p2.y - from.y * f2a - to.y * f2d + + local det = a*e - b*d + local y1 = -(b*f - e*c)/det + local y2 = -(c*d - a*f)/det + + return Coordinate.new(x1,y1), Coordinate.new(x2,y2) + +end + + + + + + +-- Done + +return Bezier
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/DepthFirstSearch.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/DepthFirstSearch.lua new file mode 100644 index 00000000000..768a5da0ffe --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/DepthFirstSearch.lua @@ -0,0 +1,125 @@ +-- Copyright 2011 by Jannis Pohlmann +-- 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/lib/DepthFirstSearch.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +--- The DepthFirstSearch class implements a generic depth first function. It does not +-- require that it is run on graphs, but can be used for anything where a visit function and +-- a complete function is available. + +local DepthFirstSearch = {} +DepthFirstSearch.__index = DepthFirstSearch + +-- Namespace +require("pgf.gd.lib").DepthFirstSearch = DepthFirstSearch + +-- Imports +local Stack = require "pgf.gd.lib.Stack" + + + +-- TT: TODO Jannis: Please document... + +function DepthFirstSearch.new(init_func, visit_func, complete_func) + local dfs = { + init_func = init_func, + visit_func = visit_func, + complete_func = complete_func, + + stack = Stack.new(), + discovered = {}, + visited = {}, + completed = {}, + } + setmetatable(dfs, DepthFirstSearch) + return dfs +end + + + +function DepthFirstSearch:run() + self:reset() + self.init_func(self) + + while self.stack:getSize() > 0 do + local data = self.stack:peek() + + if not self:getVisited(data) then + if self.visit_func then + self.visit_func(self, data) + end + else + if self.complete_func then + self.complete_func(self, data) + end + self:setCompleted(data, true) + self.stack:pop() + end + end +end + + + +function DepthFirstSearch:reset() + self.discovered = {} + self.visited = {} + self.completed = {} + self.stack = Stack.new() +end + + + +function DepthFirstSearch:setDiscovered(data, discovered) + self.discovered[data] = discovered +end + + + +function DepthFirstSearch:getDiscovered(data) + return self.discovered[data] +end + + + +function DepthFirstSearch:setVisited(data, visited) + self.visited[data] = visited +end + + + +function DepthFirstSearch:getVisited(data) + return self.visited[data] +end + + + +function DepthFirstSearch:setCompleted(data, completed) + self.completed[data] = completed +end + + + +function DepthFirstSearch:getCompleted(data) + return self.completed[data] +end + + + +function DepthFirstSearch:push(data) + self.stack:push(data) +end + + + +-- Done + +return DepthFirstSearch
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Direct.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Direct.lua new file mode 100644 index 00000000000..dd5dde22e1c --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Direct.lua @@ -0,0 +1,95 @@ +-- 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/lib/Direct.lua,v 1.2 2013/04/04 20:43:45 tantau Exp $ + + + +--- Direct is a class that collects algorithms for computing new +-- versions of a graph where arcs point in certain directions. + +local Direct = {} + +-- Namespace +require("pgf.gd.lib").Direct = Direct + +-- Imports +local Digraph = require "pgf.gd.model.Digraph" + + +--- Compute a digraph from a syntactic digraph. +-- +-- This function takes a syntactic digraph and compute a new digraph +-- where all arrow point in the "semantic direction" of the syntactic +-- arrows. For instance, while "a <- b" will cause an arc from a to be +-- to be added to the syntactic digraph, calling this function will +-- return a digraph in which there is an arc from b to a rather than +-- the other way round. In detail, "a <- b" is tranlated as just +-- described, "a -> b" yields an arc from a to b as expected, "a <-> b" +-- and "a -- b" yield arcs in both directions and, finally, "a -!- b" +-- yields no arc at all. +-- +-- @param syntactic_digraph A syntacitic digraph, usually the "input" +-- graph as specified syntactically be the user. +-- +-- @return A new "semantic" digraph object. + +function Direct.digraphFromSyntacticDigraph(syntactic_digraph) + local digraph = Digraph.new(syntactic_digraph) -- copy + + -- Now go over all arcs of the syntactic_digraph and turn them into + -- arcs with the correct direction in the digraph: + for _,a in ipairs(syntactic_digraph.arcs) do + for _,m in ipairs(a.syntactic_edges) do + local direction = m.direction + if direction == "->" then + digraph:connect(a.tail, a.head) + elseif direction == "<-" then + digraph:connect(a.head, a.tail) + elseif direction == "--" or direction == "<->" then + digraph:connect(a.tail, a.head) + digraph:connect(a.head, a.tail) + end + -- Case -!-: No edges... + end + end + + return digraph +end + + +--- Turn an arbitrary graph into a directed graph +-- +-- Takes a digraph as input and returns its underlying undirected +-- graph, coded as a digraph. This means that between any two vertices +-- if there is an arc in one direction, there is also one in the other. +-- +-- @param digraph A directed graph +-- +-- @return The underlying undirected graph of digraph. + +function Direct.ugraphFromDigraph(digraph) + local ugraph = Digraph.new(digraph) + + -- Now go over all arcs of the syntactic_digraph and turn them into + -- arcs with the correct direction in the digraph: + for _,a in ipairs(digraph.arcs) do + ugraph:connect(a.head,a.tail) + ugraph:connect(a.tail,a.head) + end + + return ugraph +end + + + + +-- Done + +return Direct
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Event.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Event.lua new file mode 100644 index 00000000000..918c118f4b2 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Event.lua @@ -0,0 +1,98 @@ +-- 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/lib/Event.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +--- +-- Events are used to communicate ``interesting'' events from the +-- parser to the graph drawing algorithms. +-- +-- As a syntactic description of some graph is being parsed, vertices, +-- arcs, and a digraph object representing this graph get +-- constructed. However, even though syntactic annotations such as +-- options for the vertices and arcs are attached to them and can be +-- accessed through the graph objects, some syntactic inforamtion is +-- neither represented in the digraph object nor in the vertices and +-- the arcs. A typical example is a ``missing'' node in a tree: Since +-- it is missing, there is neither a vertex object nor arc objects +-- representing it. It is also not a global option of the graph. +-- +-- For these reasons, in addition to the digraph object itself, +-- additional information can be passed by a parser to graph drawing +-- algorithms through the means of events. Each |Event| consists of a +-- |kind| field, which is just some string, and a |parameters| field, +-- which stores additional, kind-specific information. As a graph is +-- being parsed, a string of events is accumulated and is later on +-- available through the |events| field of the graph drawing scope. +-- +-- The following events are created during the parsing process by the +-- standard parsers of \tikzname: +-- +-- \begin{itemize} +-- \item[|node|] When a node of the input graph has been parsed and +-- a |Vertex| object has been created for it, an event with kind +-- |node| is created. The |parameter| of this event is the +-- just-created vertex. +-- +-- The same kind of event is used to indicate ``missing'' nodes. In +-- this case, the |parameters| field is |nil|. +-- \item[|edge|] When an edge of the input graph has been parsed, an +-- event is created of kind |edge|. The |parameters| field will store +-- an array with two entries: The first is the |Arc| object whose +-- |syntactic_edges| field stores the |edge|. The second is the index +-- of the edge inside the |syntactic_edges| field. +-- \item[|begin|] +-- Signals the beginning of a group, which will be ended with a +-- corresponding |end| event later on. The |parameters| field will +-- indicate the kind of group. Currently, only the string +-- |"descendants"| is used as |parameters|, indicating the start of +-- several nodes that are descendants of a given node. This +-- information can be used by algorithms for reconstructing the +-- input structure of trees. +-- \item[|end|] Signals the end of a group begun by a |begin| event +-- earlier on. +-- \end{itemize} +-- +-- @field kind A string representing the kind of the events. +-- @field parameters Kind-specific parameters. +-- @field index A number that stores the events logical position in +-- the sequence of events. The number need not be an integer array +-- index. +-- +local Event = {} +Event.__index = Event + + +-- Namespace +require("pgf.gd.lib").Event = Event + + + +--- +-- Create a new event object +-- +-- @param initial Initial fields of the new event. +-- +-- @return The new object + +function Event.new(values) + local new = {} + for k,v in pairs(values) do + new[k] = v + end + return setmetatable(new, Event) +end + + + +-- done + +return Event
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/LookupTable.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/LookupTable.lua new file mode 100644 index 00000000000..a3c04ca54df --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/LookupTable.lua @@ -0,0 +1,111 @@ +-- 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/lib/LookupTable.lua,v 1.2 2013/04/04 20:43:45 tantau Exp $ + + + +--- +-- This table provides two utility functions for managing ``lookup +-- tables.'' Such a table is a mixture of an array and a hashtable: +-- It stores (only) tables. Each table is stored once in a normal +-- array position. Additionally, the lookup table is also indexed at +-- the position of the table (used as a key) and this position is set +-- to |true|. This means that you can test whether a table |t| is in the +-- lookup table |l| simply by testing whether |l[t]| is true. +-- +local LookupTable = {} + +-- Namespace +require("pgf.gd.lib").LookupTable = LookupTable + + + +--- +-- Add all elements in the |array| to a lookup table. If an element of +-- the array is already present in the table, it will not be added +-- again. +-- +-- This operation takes time $O(|\verb!array!|)$. +-- +-- @param l Lookup table +-- @param array An array of to-be-added tables. + +function LookupTable.add(l, array) + for i=1,#array do + local t = array[i] + if not l[t] then + l[t] = true + l[#l + 1] = t + end + end +end + + +--- +-- Add one element to a lookup table. If it is already present in the +-- table, it will not be added again. +-- +-- This operation takes time $O(1)$. +-- +-- @param l Lookup table +-- @param e The to-be-added element. + +function LookupTable.addOne(l, e) + if not l[e] then + l[e] = true + l[#l + 1] = e + end +end + + +--- +-- Remove tables from a lookup table. +-- +-- Note that this operation is pretty expensive insofar as it will +-- always cost a traversal of the whole lookup table. However, this is +-- also the maximum cost, even when a lot of entries need to be +-- deleted. Thus, it is much better to ``pool'' multiple remove +-- operations in a single one. +-- +-- This operation takes time $O(\max\{|\verb!array!|, |\verb!l!|\})$. +-- +-- @param l Lookup table +-- @param t An array of to-be-removed tables. + +function LookupTable.remove(l, array) + -- Step 1: Mark all to-be-deleted entries + for i=1,#array do + local t = array[i] + if l[t] then + l[t] = false + end + end + + -- Step 2: Collect garbage... + local target = 1 + for i=1,#l do + local t = l[i] + if l[t] == false then + l[t] = nil + else + l[target] = t + target = target + 1 + end + end + for i=#l,target,-1 do + l[i] = nil + end +end + + + +-- Done + +return LookupTable
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/PathLengths.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/PathLengths.lua new file mode 100644 index 00000000000..c617cf80d8b --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/PathLengths.lua @@ -0,0 +1,209 @@ +-- Copyright 2011 by Jannis Pohlmann +-- 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/lib/PathLengths.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +--- +-- This table provides algorithms for computing distances between +-- nodes of a graph (in the sense of path lengths). + +local PathLengths = {} + +-- Namespace +require("pgf.gd.lib").PathLengths = PathLengths + +-- Import +local PriorityQueue = require "pgf.gd.lib.PriorityQueue" + + + +--- +-- Performs the Dijkstra algorithm to solve the single-source shortes path problem. +-- +-- The algorithm computes the shortest paths from |source| to all nodes +-- in the graph. It also generates a table with distance level sets, each of +-- which contain all nodes that have the same corresponding distance to +-- |source|. Finally, a mapping of nodes to their parents along the +-- shortest paths is generated to allow the reconstruction of the paths +-- that were chosen by the Dijkstra algorithm. +-- +-- @param graph The graph to compute the shortest paths for. +-- @param source The node to compute the distances to. +-- +-- @return A mapping of nodes to their distance to |source|. +-- @return An array of distance level sets. The set at index |i| contains +-- all nodes that have a distance of |i| to |source|. +-- @return A mapping of nodes to their parents to allow the reconstruction +-- of the shortest paths chosen by the Dijkstra algorithm. +-- +function PathLengths.dijkstra(graph, source) + local distance = {} + local levels = {} + local parent = {} + + local queue = PriorityQueue.new() + + -- reset the distance of all nodes and insert them into the priority queue + for _,node in ipairs(graph.nodes) do + if node == source then + distance[node] = 0 + parent[node] = nil + queue:enqueue(node, distance[node]) + else + distance[node] = #graph.nodes + 1 -- this is about infinity ;) + queue:enqueue(node, distance[node]) + end + end + + while not queue:isEmpty() do + local u = queue:dequeue() + + assert(distance[u] < #graph.nodes + 1, 'the graph is not connected, Dijkstra will not work') + + if distance[u] > 0 then + levels[distance[u]] = levels[distance[u]] or {} + table.insert(levels[distance[u]], u) + end + + for _,edge in ipairs(u.edges) do + local v = edge:getNeighbour(u) + local alternative = distance[u] + 1 + if alternative < distance[v] then + distance[v] = alternative + + parent[v] = u + + -- update the priority of v + queue:updatePriority(v, distance[v]) + end + end + end + + return distance, levels, parent +end + + + + +--- +-- Performs the Floyd-Warshall algorithm to solve the all-source shortes path problem. +-- +-- @param graph The graph to compute the shortest paths for. +-- +-- @return A distance matrix +-- +function PathLengths.floydWarshall(graph) + local distance = {} + local infinity = math.huge + + for _,i in ipairs(graph.nodes) do + distance[i] = {} + for _,j in ipairs(graph.nodes) do + distance[i][j] = infinity + end + end + + for _,i in ipairs(graph.nodes) do + for _,edge in ipairs(i.edges) do + local j = edge:getNeighbour(i) + distance[i][j] = edge.weight or 1 + end + end + + for _,k in ipairs(graph.nodes) do + for _,i in ipairs(graph.nodes) do + for _,j in ipairs(graph.nodes) do + distance[i][j] = math.min(distance[i][j], distance[i][k] + distance[k][j]) + end + end + end + + return distance +end + + + + +--- +-- Computes the pseudo diameter of a graph. +-- +-- The diameter of a graph is the maximum of the shortest paths between +-- any pair of nodes in the graph. A pseudo diameter is an approximation +-- of the diameter that is computed by picking a starting node |u| and +-- finding a node |v| that is farthest away from |u| and has the smallest +-- degree of all nodes that have the same distance to |u|. The algorithm +-- continues with |v| as the new starting node and iteratively tries +-- to find an end node that is generates a larger pseudo diameter. +-- It terminates as soon as no such end node can be found. +-- +-- @param graph The graph. +-- +-- @return The pseudo diameter of the graph. +-- @return The start node of the corresponding approximation of a maximum +-- shortest path. +-- @return The end node of that path. +-- +function PathLengths.pseudoDiameter(graph) + + -- find a node with minimum degree + local start_node = graph.nodes[1] + for _,node in ipairs(graph.nodes) do + if node:getDegree() < start_node:getDegree() then + start_node = node + end + end + + assert(start_node) + + local old_diameter = 0 + local diameter = 0 + local end_node = nil + + while true do + local distance, levels = PathLengths.dijkstra(graph, start_node) + + -- the number of levels is the same as the distance of the nodes + -- in the last level to the start node + old_diameter = diameter + diameter = #levels + + -- abort if the diameter could not be improved + if diameter == old_diameter then + end_node = levels[#levels][1] + break + end + + -- select the node with the smallest degree from the last level as + -- the start node for the next iteration + start_node = levels[#levels][1] + for _,node in ipairs(levels[#levels]) do + if node:getDegree() < start_node:getDegree() then + start_node = node + end + end + + assert(start_node) + end + + assert(start_node) + assert(end_node) + + return diameter, start_node, end_node +end + + + + + +-- Done + +return PathLengths
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/PriorityQueue.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/PriorityQueue.lua new file mode 100644 index 00000000000..7b93c755c56 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/PriorityQueue.lua @@ -0,0 +1,342 @@ +-- Copyright 2011 by Jannis Pohlmann +-- 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/lib/PriorityQueue.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +--- +-- A PriorityQueue supports operations for quickly finding the minimum from a set of elements +-- +-- Its implementation is based on (simplified) Fibonacci heaps. +local PriorityQueue = {} +PriorityQueue.__index = PriorityQueue + + +-- Namespace +local lib = require "pgf.gd.lib" +lib.PriorityQueue = PriorityQueue + + + +-- Local declarations +local FibonacciHeap = {} +local FibonacciHeapNode = {} + + + + +--- Creates a new priority queue +-- +-- @return The newly created queue + +function PriorityQueue.new() + local queue = { + heap = FibonacciHeap.new(), + nodes = {}, + values = {}, + } + setmetatable(queue, PriorityQueue) + return queue +end + + + +--- Add an element with a certain priority to the queue +-- +-- @param value An object +-- @param priority Its priority + +function PriorityQueue:enqueue(value, priority) + local node = self.heap:insert(priority) + self.nodes[value] = node + self.values[node] = value +end + + + +--- Removes the element with the minimum priority from the queue +-- +-- @return The element with the minimum priority + +function PriorityQueue:dequeue() + local node = self.heap:extractMinimum() + + if node then + local value = self.values[node] + self.nodes[value] = nil + self.values[node] = nil + return value + else + return nil + end +end + + + +--- Lower the priority of an element of a queue +-- +-- @param value An object +-- @param priority A new priority, which must be lower than the old priority + +function PriorityQueue:updatePriority(value, priority) + local node = self.nodes[value] + assert(node, 'updating the priority of ' .. tostring(value) .. ' failed because it is not in the priority queue') + self.heap:updateValue(node, priority) +end + + + +--- Tests, whether the queue is empty +-- +-- @return True, if the queue is empty + +function PriorityQueue:isEmpty() + return #self.heap.trees == 0 +end + + + + + + +-- Internals: An implementation of fibonacci heaps. +FibonacciHeap.__index = FibonacciHeap + + +function FibonacciHeap.new() + local heap = { + trees = trees or {}, + minimum = nil, + } + setmetatable(heap, FibonacciHeap) + return heap +end + + + +function FibonacciHeap:insert(value) + local node = FibonacciHeapNode.new(value) + local heap = FibonacciHeap.new() + table.insert(heap.trees, node) + self:merge(heap) + return node +end + + + +function FibonacciHeap:merge(other) + for _, tree in ipairs(other.trees) do + table.insert(self.trees, tree) + end + self:updateMinimum() +end + + + +function FibonacciHeap:extractMinimum() + if self.minimum then + local minimum = self:removeTableElement(self.trees, self.minimum) + + for _, child in ipairs(minimum.children) do + child.root = child + table.insert(self.trees, child) + end + + local same_degrees_found = true + while same_degrees_found do + same_degrees_found = false + + local degrees = {} + + for _, root in ipairs(self.trees) do + local degree = root:getDegree() + + if degrees[degree] then + if root.value < degrees[degree].value then + self:linkRoots(root, degrees[degree]) + else + self:linkRoots(degrees[degree], root) + end + + degrees[degree] = nil + same_degrees_found = true + break + else + degrees[degree] = root + end + end + end + + self:updateMinimum() + + return minimum + end +end + + + +function FibonacciHeap:updateValue(node, value) + local old_value = node.value + local new_value = value + + if new_value <= old_value then + self:decreaseValue(node, value) + else + assert(false, 'FibonacciHeap:increaseValue is not implemented yet') + end +end + + + +function FibonacciHeap:decreaseValue(node, value) + assert(value <= node.value) + + node.value = value + + if node.value < node.parent.value then + local parent = node.parent + self:cutFromParent(node) + + if not parent:isRoot() then + if parent.marked then + self:cutFromParent(parent) + else + parent.marked = true + end + end + end + + if node.value < self.minimum.value then + self.minimum = node + end +end + + + +function FibonacciHeap:delete(node) + self:decreaseValue(node, -math.huge) + self:extractMinimum() +end + + + +function FibonacciHeap:linkRoots(root, child) + child.root = root + child.parent = root + + child = self:removeTableElement(self.trees, child) + table.insert(root.children, child) + + return root +end + + + +function FibonacciHeap:cutFromParent(node) + local parent = node.parent + + node.root = node + node.parent = node + node.marked = false + + node = self:removeTableElement(parent.children, node) + table.insert(self.trees, node) +end + + + +function FibonacciHeap:updateMinimum() + self.minimum = self.trees[1] + + for _, root in ipairs(self.trees) do + if root.value < self.minimum.value then + self.minimum = root + end + end +end + + + +function FibonacciHeap:removeTableElement(input_table, element) + for i = 1, #input_table do + if input_table[i] == element then + return table.remove(input_table, i) + end + end +end + + + + +-- Now come the nodes + +FibonacciHeapNode.__index = FibonacciHeapNode + +function FibonacciHeapNode.new(value, root, parent) + local node = { + value = value, + children = {}, + marked = false, + root = nil, + parent = nil, + } + setmetatable(node, FibonacciHeapNode) + + if root then + node.root = root + node.parent = parent + else + node.root = node + node.parent = node + end + + return node +end + +function FibonacciHeapNode:addChild(value) + local child = FibonacciHeapNode.new(value, self.root, self) + table.insert(self.children, child) +end + +function FibonacciHeapNode:getDegree() + return #self.children +end + + + +function FibonacciHeapNode:setRoot(root) + self.root = root + + if root == self then + self.parent = root + end + + if #self.children > 0 then + for _, child in ipairs(self.children) do + child.root = root + end + end +end + + + +function FibonacciHeapNode:isRoot() + return self.root == self +end + + + + + + +-- done + +return PriorityQueue
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Simplifiers.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Simplifiers.lua new file mode 100644 index 00000000000..b935305893a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Simplifiers.lua @@ -0,0 +1,279 @@ +-- 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/lib/Simplifiers.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +--- The Simplifiers class is a singleton object. +-- Its methods allow implement methods for simplifing graphs, for instance +-- for removing loops or multiedges or computing spanning trees. + +local Simplifiers = {} + +-- Namespace +local lib = require "pgf.gd.lib" +lib.Simplifiers = Simplifiers + + + + +-- Imports + +local Edge = require "pgf.gd.deprecated.Edge" +local Node = require "pgf.gd.deprecated.Node" + + + + + +--- Algorithm to classify edges of a DFS search tree. +-- +-- TODO Jannis: document this algorithm as soon as it is completed and bug-free. +-- TT: Replace this algorithm by something else, perhaps? +-- +function Simplifiers:classifyEdges(graph) + local discovered = {} + local visited = {} + local recursed = {} + local completed = {} + + local tree_and_forward_edges = {} + local cross_edges = {} + local back_edges = {} + + local stack = {} + + local function push(node) + table.insert(stack, node) + end + + local function peek() + return stack[#stack] + end + + local function pop() + return table.remove(stack) + end + + local initial_nodes = graph.nodes + + for i=#initial_nodes,1,-1 do + local node = initial_nodes[i] + push(node) + discovered[node] = true + end + + while #stack > 0 do + local node = peek() + local edges_to_traverse = {} + + visited[node] = true + + if not recursed[node] then + recursed[node] = true + + local out_edges = node:getOutgoingEdges() + for _,edge in ipairs(out_edges) do + local neighbour = edge:getNeighbour(node) + + if not discovered[neighbour] then + table.insert(tree_and_forward_edges, edge) + table.insert(edges_to_traverse, edge) + else + if not completed[neighbour] then + if not visited[neighbour] then + table.insert(tree_and_forward_edges, edge) + table.insert(edges_to_traverse, edge) + else + table.insert(back_edges, edge) + end + else + table.insert(cross_edges, edge) + end + end + end + + if #edges_to_traverse == 0 then + completed[node] = true + pop() + else + for i=#edges_to_traverse,1,-1 do + local neighbour = edges_to_traverse[i]:getNeighbour(node) + discovered[neighbour] = true + push(neighbour) + end + end + else + completed[node] = true + pop() + end + end + + return tree_and_forward_edges, cross_edges, back_edges +end + + + + + +-- +-- +-- Loops and Multiedges +-- +-- + + +--- Remove all loops from a graph +-- +-- This method will remove all loops from a graph. +-- +-- @param algorithm An algorithm object + +function Simplifiers:removeLoopsOldModel(algorithm) + local graph = algorithm.graph + local loops = {} + + for _,edge in ipairs(graph.edges) do + if edge:getHead() == edge:getTail() then + loops[#loops+1] = edge + end + end + + for i=1,#loops do + graph:deleteEdge(loops[i]) + end + + graph[algorithm].loops = loops +end + + + +--- Restore loops that were previously removed. +-- +-- @param algorithm An algorithm object + +function Simplifiers:restoreLoopsOldModel(algorithm) + local graph = algorithm.graph + + for _,edge in ipairs(graph[algorithm].loops) do + graph:addEdge(edge) + edge:getTail():addEdge(edge) + end + + graph[algorithm].loops = nil +end + + + + +--- Remove all multiedges. +-- +-- Every multiedge of the graph will be replaced by a single edge. +-- +-- @param algorithm An algorithm object + +function Simplifiers:collapseMultiedgesOldModel(algorithm, collapse_action) + local graph = algorithm.graph + local collapsed_edges = {} + local node_processed = {} + + for _,node in ipairs(graph.nodes) do + node_processed[node] = true + + local multiedge = {} + + local function handle_edge (edge) + + local neighbour = edge:getNeighbour(node) + + if not node_processed[neighbour] then + if not multiedge[neighbour] then + multiedge[neighbour] = Edge.new{ direction = Edge.RIGHT } + collapsed_edges[multiedge[neighbour]] = {} + end + + if collapse_action then + collapse_action(multiedge[neighbour], edge, graph) + end + + table.insert(collapsed_edges[multiedge[neighbour]], edge) + end + end + + for _,edge in ipairs(node:getIncomingEdges()) do + handle_edge(edge) + end + + for _,edge in ipairs(node:getOutgoingEdges()) do + handle_edge(edge) + end + + for neighbour, multiedge in pairs(multiedge) do + + if #collapsed_edges[multiedge] <= 1 then + collapsed_edges[multiedge] = nil + else + for _,subedge in ipairs(collapsed_edges[multiedge]) do + graph:deleteEdge(subedge) + end + + multiedge:addNode(node) + multiedge:addNode(neighbour) + + graph:addEdge(multiedge) + end + end + end + + graph[algorithm].collapsed_edges = collapsed_edges +end + + +--- Expand multiedges that were previously collapsed +-- +-- @param algorithm An algorithm object + +function Simplifiers:expandMultiedgesOldModel(algorithm) + local graph = algorithm.graph + for multiedge, subedges in pairs(graph[algorithm].collapsed_edges) do + assert(#subedges >= 2) + + graph:deleteEdge(multiedge) + + for _,edge in ipairs(subedges) do + + -- Copy bend points + for _,p in ipairs(multiedge.bend_points) do + edge.bend_points[#edge.bend_points+1] = p:copy() + end + + -- Copy options + for k,v in pairs(multiedge.algorithmically_generated_options) do + edge.algorithmically_generated_options[k] = v + end + + for _,node in ipairs(edge.nodes) do + node:addEdge(edge) + end + + graph:addEdge(edge) + end + end + + graph[algorithm].collapsed_edges = nil +end + + + + + +-- Done + +return Simplifiers
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Stack.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Stack.lua new file mode 100644 index 00000000000..11466c04961 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Stack.lua @@ -0,0 +1,61 @@ +-- Copyright 2011 by Jannis Pohlmann +-- 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/lib/Stack.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + +--- A Stack is a very simple wrapper around an array +-- +-- + +local Stack = {} +Stack.__index = Stack + + +-- Namespace +require("pgf.gd.lib").Stack = Stack + + +--- Create a new stack +function Stack.new() + local stack = {} + setmetatable(stack, Stack) + return stack +end + + +--- Push an element on top of the stack +function Stack:push(data) + self[#self+1] = data +end + + +--- Inspect (but not pop) the top element of a stack +function Stack:peek() + return self[#self] +end + + +--- Pop an element from the top of the stack +function Stack:pop() + return table.remove(self, #self) +end + + +--- Get the height of the stack +function Stack:getSize() + return #self +end + + + +-- done + +return Stack
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Storage.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Storage.lua new file mode 100644 index 00000000000..525fcb4f8fc --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Storage.lua @@ -0,0 +1,110 @@ +-- 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/lib/Storage.lua,v 1.4 2013/12/20 14:44:46 tantau Exp $ + + + +--- +-- A storage is an object that, as the name suggests, allows you to +-- ``store stuff concerning objects.'' Basically, it behaves like +-- table having weak keys, which means that once the objects for which +-- you ``store stuff'' go out of scope, they are also removed from the +-- storage. Also, you can specify that for each object of the storage +-- you store a table. In this case, there is no need to initialize +-- this table for each object; rather, when you write into such a +-- table and it does not yet exist, it is created ``on the fly''. +-- +-- The typical way you use storages is best explained with the +-- following example: Suppose you want to write a depth-first search +-- algorithm for a graph. This algorithm might wish to mark all nodes +-- it has visisted. It could just say |v.marked = true|, but this might +-- clash with someone else also using the |marked| key. The solution is +-- to create a |marked| storage. The algorithm can first say +--\begin{codeexample}[code only, tikz syntax=false] +--local marked = Storage.new() +--\end{codeexample} +-- and then say +--\begin{codeexample}[code only, tikz syntax=false] +--marked[v] = true +--\end{codeexample} +-- to mark its objects. The |marked| storage object does not need to +-- be created locally inside a function, you can declare it as a local +-- variable of the whole file; nevertheless, the entries for vertices +-- no longer in use get removed automatically. You can also make it a +-- member variable of the algorithm class, which allows you make the +-- information about which objects are marked globally +-- accessible. +-- +-- Now suppose the algorithm would like to store even more stuff in +-- the storage. For this, we might use a table and can use the fact +-- that a storage will automatically create a table when necessary: +--\begin{codeexample}[code only, tikz syntax=false] +--local info = Storage.newTableStorage() +-- +--info[v].marked = true -- the "info[v]" table is +-- -- created automatically here +-- +--info[v].foo = "bar" +--\end{codeexample} +-- Again, once |v| goes out of scope, both it and the info table will +-- removed. + +local Storage = {} + +-- Namespace +require("pgf.gd.lib").Storage = Storage + + +-- The simple metatable + +local SimpleStorageMetaTable = { __mode = "k" } + +-- The adcanved metatable for table storages: + +local TableStorageMetaTable = { + __mode = "k", + __index = + function(t, k) + local new = {} + rawset(t, k, new) + return new + end +} + + +--- +-- Create a new storage object. +-- +-- @return A new |Storage| instance. + +function Storage.new() + return setmetatable({}, SimpleStorageMetaTable) +end + + +--- +-- Create a new storage object which will install a table for every +-- entry automatilly. +-- +-- @return A new |Storage| instance. + +function Storage.newTableStorage() + return setmetatable({}, TableStorageMetaTable) +end + + + + + + + +-- Done + +return Storage
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Transform.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Transform.lua new file mode 100644 index 00000000000..88ffd6446a4 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Transform.lua @@ -0,0 +1,104 @@ +-- 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/lib/Transform.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + +--- +-- The |Transform| table provides a set of static methods for +-- creating and handling canvas transformation matrices. Such a matrix +-- is actually just an array of six numbers. The idea is that +-- ``applying'' an array { a, b, c, d, e, f } a vector $(x,y)$ will +-- yield the new vector $(ax+by+e,cx+dy+f)$. For details on how such +-- matrices work, see Section~\ref{section-transform-cm} +-- +local Transform = {} + + +-- Namespace + +require("pgf.gd.model").Transform = Transform + + +--- Creates a new transformation array. +-- +-- @param a First component +-- @param b Second component +-- @param c Third component +-- @param d Fourth component +-- @param x The x shift +-- @param y The y shift +-- +-- @return A transformation object. +-- +function Transform.new(a,b,c,d,x,y) + return { a, b, c, d, x, y } +end + + +--- Creates a new transformation object that represents a shift. +-- +-- @param x An x-shift +-- @param y A y-shift +-- +-- @return A transformation object +-- +function Transform.new_shift(x,y) + return { 1, 0, 0, 1, x, y } +end + + +--- Creates a new transformation object that represents a rotation. +-- +-- @param angle An angle +-- +-- @return A transformation object +-- +function Transform.new_rotation(angle) + local c = math.cos(angle) + local s = math.sin(angle) + return { c, -s, s, c, 0, 0 } +end + + +--- Creates a new transformation object that represents a scaling. +-- +-- @param x The horizontal scaling +-- @param y The vertical scaling (if missing, the horizontal scaling is used) +-- +-- @return A transformation object +-- +function Transform.new_scaling(x_scale, y_scale) + return { x_scale, 0, 0, y_scale or x_scale, 0, 0 } +end + + + + +--- +-- Concatenate two transformation matrices, returning the new one. +-- +-- @param a The first transformation +-- @param b The second transformation +-- +-- @return The transformation representing first applying |b| and then +-- applying |a|. +-- +function Transform.concat(a,b) + local a1, a2, a3, a4, a5, a6, b1, b2, b3, b4, b5, b6 = + a[1], a[2], a[3], a[4], a[5], a[6], b[1], b[2], b[3], b[4], b[5], b[6] + return { a1*b1 + a2*b3, a1*b2 + a2*b4, + a3*b1 + a4*b3, a3*b2 + a4*b4, + a1*b5 + a2*b6 + a5, a3*b5 + a4*b6 + a6 } +end + + +-- Done + +return Transform
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model.lua new file mode 100644 index 00000000000..badde1bbd58 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model.lua @@ -0,0 +1,26 @@ +-- 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/model.lua,v 1.1 2012/11/27 17:24:24 tantau Exp $ + + + +-- Imports + +require "pgf" +require "pgf.gd" + + +-- Declare namespace +pgf.gd.model = {} + + +-- Done + +return pgf.gd.model
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Arc.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Arc.lua new file mode 100644 index 00000000000..ff08573cbbd --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Arc.lua @@ -0,0 +1,592 @@ +-- 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/model/Arc.lua,v 1.6 2013/12/20 14:44:46 tantau Exp $ + + +--- +-- An arc is a light-weight object representing an arc from a vertex +-- in a graph to another vertex. You may not create an |Arc| by +-- yourself, which is why there is no |new| method, arc creation is +-- done by the Digraph class. +-- +-- Every arc belongs to exactly one graph. If you want the same arc in +-- another graph, you need to newly connect two vertices in the other graph. +-- +-- You may read the |head| and |tail| fields, but you may not write +-- them. In order to store data for an arc, use |Storage| objects. +-- +-- Between any two vertices of a graph there can be only one arc, so +-- all digraphs are always simple graphs. However, in the +-- specification of a graph (the syntactic digraph), there might +-- be multiple edges between two vertices. This means, in particular, +-- that an arc has no |options| field. Rather, it has several +-- |optionsXxxx| functions, that will search for options in all of the +-- synactic edges that ``belong'' to an edge. +-- +-- Similarly, even though an arc has a |path| field, setting this +-- field does not immediately set the paths of the syntactic +-- edges. Indeed, you will normally want to setup and modify the +-- |path| field of an arc during your algorithm and only at the very +-- end, ``write it back'' to the multiple syntactic edges underlying +-- the graph. For this purpose, the method |sync| is used, which is +-- called automatically for the |ugraph| and |digraph| of a scope as +-- well as for spanning trees. +-- +-- The bottom line concerning the |path| field is the following: If +-- you just want a straight line along an arc, just leave the field as +-- it is (namely, |nil|). If you want to have all edges along a path +-- to follow a certain path, set the |path| field of the arc to the +-- path you desire (typically, using the |setPolylinePath| or a +-- similar method). This will cause all syntactic edges underlying the +-- arc to be set to the specified path. In the event that you want to +-- set different paths for the edges underlying a single arc +-- differently, set the |path| fields of these edges and set the +-- |path| field of the arc to |nil|. This will disable the syncing for +-- the arc and will cause the edge |paths| to remain untouched. +-- +-- @field tail The tail vertex of the arc. +-- @field head The head vertex of the arc. May be the same as the tail +-- in case of a loop. +-- @field path If non-nil, the path of the arc. See the description +-- above. +-- @field syntactic_edges This field is an array containing syntactic +-- edges (``real'' edges in the syntactic digraph) that underly this +-- arc. +-- +local Arc = {} +Arc.__index = Arc + + +-- Namespace + +require("pgf.gd.model").Arc = Arc + + +-- Imports + +local Path = require 'pgf.gd.model.Path' +local lib = require 'pgf.gd.lib' + + +--- +-- Get an array of options of the syntactic edges corresponding to an arc. +-- +-- An arc in a digraph is typically (but not always) present because +-- there are one or more edges in the syntactic digraph between the +-- tail and the head of the arc or between the head and the tail. +-- +-- Since for every arc there can be several edges present in the +-- syntactic digraph, an option like |length| may have +-- been given multiple times for the edges corresponding to the arc. +-- +-- If your algorithm gets confused by multiple edges, try saying +-- |a:options(your_option)|. This will always give the ``most +-- sensible'' choice of the option if there are multiple edges +-- corresponding to the same arc. +-- +-- @param option A string option like |"length"|. +-- +-- @return A table with the following contents: +-- \begin{enumerate} +-- \item It is an array of all values the option has for edges +-- corresponding to |self| in the syntactic digraph. Suppose, for +-- instance, you write the following: +--\begin{codeexample}[code only] +--graph { +-- tail -- [length=1] head, % multi edge 1 +-- tail -- [length=3] head, % mulit edge 2 +-- head -- [length=8] tail, % multi edge 3 +-- tail -- head, % multi edge 4 +-- head -- [length=7] tail, % multi edge 5 +-- tail -- [length=2] head, % multi edge 6 +--} +--\end{codeexample} +-- Suppose, furthermore, that |length| has been setup as an edge +-- option. Now suppose that |a| is the arc from the vertex |tail| to +-- the vertex |head|. Calling |a:optionsArray('length')| will +-- yield the array part |{1,3,2,8,7}|. The reason for the ordering is +-- as follows: First come all values |length| had for syntactic edges +-- going from |self.tail| to |self.head| in the order they appear in the graph +-- description. Then come all values the options has for syntactic +-- edges going from |self.head| to |self.tail|. The reason for this +-- slightly strange behaviour is that many algorithms do not really +-- care whether someone writes |a --[length=1] b| or +-- |b --[length=1] a|; in both cases they would ``just'' like to know +-- that the length is~|1|. +-- +-- \item There is field called |aligned|, which is an array storing +-- the actual syntactic edge objects whose values can be found in the +-- array part of the returned table. However, |aligned| contains only +-- the syntactic edges pointing ``in the same direction'' as the arc, +-- that is, the tail and head of the syntactic edge are the same as +-- those of the arc. In the above example, this array would contain +-- the edges with the comment numbers |1|, |2|, and |6|. +-- +-- Using the length of this array and the fact that the ``aligned'' +-- values come first in the table, you can easily iterate over the +-- |option|'s values of only those edges that are aligned with the arc: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local a = g:arc(tail.head) -- some arc +--local opt = a:optionsArray('length') +--local sum = 0 +--for i=1,#opt.aligned do +-- sum = sum + opt[i] +--end +--\end{codeexample} +-- +--\item There is a field called |anti_aligned|, which is an array +-- containing exactly the edges in the array part of the table not +-- aligned with the arc. The numbering start at |1| as usual, so the +-- $i$th entry of this table corresponds to the entry at position $i + +-- \verb!#opt.aligned!$ of the table. +-- +--\end{enumerate} +-- +function Arc:optionsArray(option) + + local cache = self.option_cache + local t = cache[option] + if t then + return t + end + + -- Accumulate the edges for which the option is set: + local tail = self.tail + local head = self.head + local s_graph = self.syntactic_digraph + + local arc = s_graph:arc(tail, head) + local aligned = {} + if arc then + for _,m in ipairs(arc.syntactic_edges) do + if m.options[option] ~= nil then + aligned[#aligned + 1] = m + end + end + table.sort(aligned, function (a,b) return a.event.index < b.event.index end) + end + + local arc = head ~= tail and s_graph:arc(head, tail) + local anti_aligned = {} + if arc then + for _,m in ipairs(arc.syntactic_edges) do + if m.options[option] ~= nil then + anti_aligned[#anti_aligned + 1] = m + end + end + table.sort(anti_aligned, function (a,b) return a.event.index < b.event.index end) + end + + -- Now merge them together + local t = { aligned = aligned, anti_aligned = anti_aligned } + for i=1,#aligned do + t[i] = aligned[i].options[option] + end + for i=1,#anti_aligned do + t[#t+1] = anti_aligned[i].options[option] + end + cache[option] = t + + return t +end + + + +--- +-- Returns the first option, that is, the first entry of +-- |Arc:optionsArray(option)|. However, if the |only_aligned| +-- parameter is set to true and there is no option with any aligned +-- synactic edge, |nil| is returned. +-- +-- @param option An option +-- @param only_aligned If true, only aligned syntactic edges will be +-- considered. +-- @return The first entry of the |optionsArray| +function Arc:options(option, only_aligned) + if only_aligned then + local opt = self:optionsArray(option) + if #opt.aligned > 0 then + return opt[1] + end + else + return self:optionsArray(option)[1] + end +end + + + + +--- +-- Get an accumulated value of an option of the syntactic edges +-- corresponding to an arc. +-- +-- @param option The option of interest +-- @param accumulator A function taking two values. When there are +-- more than one syntactic edges corresponding to |self| for which the +-- |option| is set, this function will be called repeatedly for the +-- different values. The first time it will be called for the first +-- two values. Next, it will be called for the result of this call and +-- the third value, and so on. +-- @param only_aligned A boolean. If true, only the aligned syntactic +-- edges will be considered. +-- +-- @return If the option is not set for any (aligned) syntactic edges +-- corresponding to |self|, |nil| is returned. If there is exectly one +-- edge, the value of this edge is returned. Otherwise, the result of +-- repeatedly applying the |accumulator| function as described +-- above. +-- +-- The result is cached, repeated calls will not invoke the +-- |accumulator| function again. +-- +-- @usage Here is typical usage: +--\begin{codeexample}[code only, tikz syntax=false] +--local total_length = a:optionsAccumulated('length', function (a,b) return a+b end) or 0 +--\end{codeexample} +-- +function Arc:optionsAccumulated(option, accumulator, only_aligned) + local opt = self:options(option) + if only_aligned then + local aligned = opt.aligned + local v = aligned[accumulator] + if v == nil then + v = opt[1] + for i=2,#aligned do + v = accumulator(v, opt[i]) + end + align[accumulator] = v + end + return v + else + local v = opt[accumulator] + if v == nil then + v = opt[1] + for i=2,#opt do + v = accumulator(v, opt[i]) + end + opt[accumulator] = v + end + return v + end +end + + + +--- +-- Compute the syntactic head and tail of an arc. For this, we have a +-- look at the syntactic digraph underlying the arc. If there is at +-- least once syntactic edge going from the arc's tail to the arc's +-- head, the arc's tail and head are returned. Otherweise, we test +-- whether there is a syntactic edge in the other direction and, if +-- so, return head and tail in reverse order. Finally, if there is no +-- syntactic edge at all corresponding to the arc in either direction, +-- |nil| is returned. +-- +-- @return The syntactic tail +-- @return The syntactic head + +function Arc:syntacticTailAndHead () + local s_graph = self.syntactic_digraph + local tail = self.tail + local head = self.head + if s_graph:arc(tail, head) then + return tail, head + elseif s_graph:arc(head, tail) then + return head, tail + end +end + + +--- +-- Compute the point cloud. +-- +-- @return This method will return the ``point cloud'' of an arc, +-- which is an array of all points that must be rotated and shifted +-- along with the endpoints of an edge. +-- +function Arc:pointCloud () + if self.cached_point_cloud then + return self.cached_point_cloud -- cached + end + local cloud = {} + local a = self.syntactic_digraph:arc(self.tail,self.head) + if a then + for _,e in ipairs(a.syntactic_edges) do + for _,p in ipairs(e.path) do + if type(p) == "table" then + cloud[#cloud + 1] = p + end + end + end + end + self.cached_point_cloud = cloud + return cloud +end + + + +--- +-- Compute an event index for the arc. +-- +-- @return The lowest event index of any edge involved +-- in the arc (or nil, if there is no syntactic edge). +-- +function Arc:eventIndex () + if self.cached_event_index then + return self.cached_event_index + end + local head = self.head + local tail = self.tail + local e = math.huge + local a = self.syntactic_digraph:arc(tail,head) + if a then + for _,m in ipairs(a.syntactic_edges) do + e = math.min(e, m.event.index) + end + end + local a = head ~= tail and self.syntactic_digraph:arc(head,tail) + if a then + for _,m in ipairs(a.syntactic_edges) do + e = math.min(e, m.event.index) + end + end + self.cached_event_index = e + return e +end + + + + +--- +-- The span collector +-- +-- This method returns the top (that is, smallest) priority of any +-- edge involved in the arc. +-- +-- The priority of an edge is computed as follows: +-- +-- \begin{enumerate} +-- \item If the option |"span priority"| is set, this number +-- will be used. +-- +-- \item If the edge has the same head as the arc, we lookup the key\\ +-- |"span priority " .. edge.direction|. If set, we use +-- this value. +-- +-- \item If the edge has a different head from the arc (the arc is +-- ``reversed'' with respect to the syntactic edge), we lookup the key +-- |"span priority reversed " .. edge.direction|. If set, +-- we use this value. +-- +-- \item Otherwise, we use priority 5. +-- \end{enumerate} +-- +-- @return The priority of the arc, as described above. +-- +function Arc:spanPriority() + if self.cached_span_priority then + return self.cached_span_priority + end + + local head = self.head + local tail = self.tail + local min + local g = self.syntactic_digraph + + local a = g:arc(tail,head) + if a then + for _,m in ipairs(a.syntactic_edges) do + local p = + m.options["span priority"] or + lib.lookup_option("span priority " .. m.direction, m, g) + + min = math.min(p or 5, min or math.huge) + end + end + + local a = head ~= tail and g:arc(head,tail) + if a then + for _,m in ipairs(a.syntactic_edges) do + local p = + m.options["span priority"] or + lib.lookup_option("span priority reversed " .. m.direction, m, g) + + min = math.min(p or 5, min or math.huge) + end + end + + self.cached_span_priority = min or 5 + + return min or 5 +end + + + + + + +--- +-- Sync an |Arc| with its syntactic edges. This causes the following: +-- If the |path| field of the arc is |nil|, nothing +-- happens. Otherwise, a copy of the |path| is created. However, for +-- every path element that is a function, this function is invoked +-- with the syntactic edge as its parameter. The result of this call +-- should now be a |Coordinate|, which will replace the function in +-- the |Path|. +-- +-- You use this method like this: +--\begin{codeexample}[code only, tikz syntax=false] +--... +--local arc = g:connect(s,t) +--arc:setPolylinePath { Coordinate.new(x,y), Coordinate.new(x1,y1) } +--... +--arc:sync() +--\end{codeexample} +-- +-- Note that this function will automatically be called for all arcs +-- of the |ugraph|, the |digraph|, and the |spanning_tree| of an +-- algorithm by the rendering pipeline. +-- +function Arc:sync() + if self.path then + local path = self.path + local head = self.head + local tail = self.tail + local a = self.syntactic_digraph:arc(tail,head) + if a and #a.syntactic_edges>0 then + for _,e in ipairs(a.syntactic_edges) do + local clone = path:clone() + for i=1,#clone do + local p = clone[i] + if type(p) == "function" then + clone[i] = p(e) + if type(clone[i]) == "table" then + clone[i] = clone[i]:clone() + end + end + end + e.path = clone + end + end + local a = head ~= tail and self.syntactic_digraph:arc(head,tail) + if a and #a.syntactic_edges>0 then + for _,e in ipairs(a.syntactic_edges) do + local clone = path:reversed() + for i=1,#clone do + local p = clone[i] + if type(p) == "function" then + clone[i] = p(e) + if type(clone[i]) == "table" then + clone[i] = clone[i]:clone() + end + end + end + e.path = clone + end + end + end +end + + +--- +-- This method returns a ``coordinate factory'' that can be used as +-- the coordinate of a |moveto| at the beginning of a path starting at +-- the |tail| of the arc. Suppose you want to create a path starting +-- at the tail vertex, going to the coordinate $(10,10)$ and ending at +-- the head vertex. The trouble is that when you create the path +-- corresponding to this route, you typically do not know where the +-- tail vertex is going to be. Even if that \emph{has} already been +-- settled, you will still have the problem that different edges +-- underlying the arc may wish to start their paths at different +-- anchors inside the tail vertex. In such cases, you use this +-- method to get a function that will, later on, compute the correct +-- position of the anchor as needed. +-- +-- Here is the code you would use to create the abovementioned path: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local a = g:connect(tail,head) +--... +--arc.path = Path.new() +--arc.path:appendMoveto(arc:tailAnchorForArcPath()) +--arc.path:appendLineto(10, 10) +--arc.path:appendLineto(arc:headAnchorForArcPath()) +--\end{codeexample} +-- +-- Normally, however, you will not write code as detailed as the above +-- and you would just write instead of the last three lines: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--arc:setPolylinePath { Coordinate.new (10, 10) } +--\end{codeexample} + +function Arc:tailAnchorForArcPath() + return function (edge) + local a = edge.options['tail anchor'] + if a == "" then + a = "center" + end + return self.tail:anchor(a) + self.tail.pos + end +end + +--- +-- See |Arc:tailAnchorForArcPath|. + +function Arc:headAnchorForArcPath() + return function (edge) + local a = edge.options['head anchor'] + if a == "" then + a = "center" + end + return self.head:anchor(a) + self.head.pos + end +end + + + +--- +-- Setup the |path| field of an arc in such a way that it corresponds +-- to a sequence of straight line segments starting at the tail's +-- anchor and ending at the head's anchor. +-- +-- @param coordinates An array of |Coordinates| through which the line +-- will go through. + +function Arc:setPolylinePath(coordinates) + local p = Path.new () + + p:appendMoveto(self:tailAnchorForArcPath()) + + for _,c in ipairs(coordinates) do + p:appendLineto(c) + end + + p:appendLineto(self:headAnchorForArcPath()) + + self.path = p +end + + + + +-- Returns a string representation of an arc. This is mainly for debugging +-- +-- @return The Arc as string. +-- +function Arc:__tostring() + return tostring(self.tail) .. "->" .. tostring(self.head) +end + + +-- Done + +return Arc diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Collection.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Collection.lua new file mode 100644 index 00000000000..a460e83505d --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Collection.lua @@ -0,0 +1,208 @@ +-- 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/model/Collection.lua,v 1.2 2013/02/08 17:14:05 tantau Exp $ + + +--- +-- A collection is essentially a subgraph of a graph, that is, a +-- ``collection'' of some nodes and some edges of the graph. The name +-- ``collection'' was chosen over ``subgraph'' since the latter are +-- often thought of as parts of a graph that are rendered in a special +-- way (such as being surrounded by a rectangle), while collections +-- are used to model such diverse things as hyperedges, sets of +-- vertices that should be on the same level in a layered algorithm, +-- or, indeed, subgraphs that are rendered in a special way. +-- +-- Collections are grouped into ``kinds.'' All collections of a given +-- kind can be accessed by algorithms through an array whose elements +-- are the collections. On the displya layer, for each kind a separate +-- key is available to indicate that a node or an edge belongs to a +-- collection. +-- +-- Collections serve two purposes: First, they can be seen as ``hints'' +-- to graph drawing algorithms that certain nodes and/or edges ``belong +-- together''. For instance, collections of kind |same layer| are used +-- by the Sugiyama algorithm to group together nodes that should appear +-- at the same height of the output. Second, since collections are also +-- passed back to the display layer in a postprocessing step, they can be +-- used to render complicated concepts such as hyperedges (which are +-- just collections of nodes, after all) or subgraphs. +-- +-- @field kind The ``kind'' of the collection. +-- +-- @field vertices A lookup table of vertices (that is, both an array +-- with the vertices in the order in which they appear as well as a +-- table such that |vertices[vertex] == true| whenever |vertex| is +-- present in the table. +-- +-- @field edges A lookup table of edges (not arcs!). +-- +-- @field options An options table. This is the table of options that +-- was in force when the collection was created. +-- +-- @field child_collections An array of all collections that are +-- direct children of this collection (that is, +-- they were defined while the current collection was the most +-- recently defined collection on the options stack). However, you +-- should use the methods |children|, |descendants|, and so to access +-- this field. +-- +-- @field parent_collection The parent collection of the current +-- colleciton. This field may be |nil| in case a collection has no parent. +-- +-- @field event An |Event| object that was create for this +-- collection. Its |kind| will be |"collection"| while its |parameter| +-- will be the collection kind. + +local Collection = {} +Collection.__index = Collection + + +-- Namespace + +require("pgf.gd.model").Collection = Collection + + +-- Imports +local Storage = require "pgf.gd.lib.Storage" + + + +--- +-- Creates a new collection. You should not call this function +-- directly, it is called by the interface classes. +-- +-- @param t A table of initial values. The field |t.kind| must be a +-- nonempty string. +-- +-- @return The new collection +-- +function Collection.new(t) + assert (type(t.kind) == "string" and t.kind ~= "", "collection kind not set") + + return setmetatable( + { + vertices = t.vertices or {}, + edges = t.edges or {}, + options = t.options or {}, + generated_options = t.generated_options or {}, + kind = t.kind, + event = t.event, + child_collections = t.child_collections or {}, + }, Collection) +end + + + + +-- +-- An internal function for registering a collection as child of +-- another collection. The collection |self| will be made a child +-- collection of |parent|. +-- +-- @param parent A collection. + +function Collection:registerAsChildOf(parent) + self.parent = parent + if parent then + assert (getmetatable(parent) == Collection, "parent must be a collection") + parent.child_collections[#parent.child_collections+1] = self + end +end + + + +--- +-- A collection can have any number of \emph{child collections}, which +-- are collections nested inside the collection. You can access the +-- array of these children through this method. You may not modify +-- the array returned by this function. +-- +-- @return The array of children of |self|. +-- +function Collection:children() + return self.child_collections +end + + +--- +-- This method works like the |children| method. However, the tree of +-- collections is, conceptually, contracted by considering only these +-- collections that have the |kind| given as parameter. For instance, +-- if |self| has a child collection of a kind different from |kind|, +-- but this child collection has, in turn, a child collection of kind +-- |kind|, this latter child collection will be included in the array +-- -- but not any of its child collections. +-- +-- @param kind The collection kind to which the tree of collections +-- should be restricted. +-- +-- @return The array of children of |self| in this contracted tree. +-- +function Collection:childrenOfKind(kind) + local function rec (c, a) + for _,d in ipairs(c.child_collections) do + if d.kind == kind then + a[#a + 1] = d + else + rec (d, a) + end + end + return a + end + return rec(self, {}) +end + + +--- +-- The descendants of a collection are its children, plus their +-- children, plus their children, and so on. +-- +-- @return An array of all descendants of |self|. It will be in +-- preorder. + +function Collection:descendants() + local function rec (c, a) + for _,d in ipairs(c.child_collections) do + a[#a + 1] = d + rec (d, a) + end + return a + end + return rec(self, {}) +end + + + +--- +-- The descendants of a collection of the given |kind|. +-- +-- @param kind A colleciton kind. +-- +-- @return An array of all descendants of |self| of the given |kind|. + +function Collection:descendantsOfKind(kind) + local function rec (c, a) + for _,d in ipairs(c.child_collections) do + if d.kind == kind then + a[#a + 1] = d + end + rec (d, a) + end + return a + end + return rec(self, {}) +end + + + +-- Done + +return Collection
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Coordinate.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Coordinate.lua new file mode 100644 index 00000000000..a3b0a7c20bf --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Coordinate.lua @@ -0,0 +1,301 @@ +-- 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/model/Coordinate.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +--- +-- A Coordinate models a position on the drawing canvas. +-- +-- It has an |x| field and a |y| field, which are numbers that will be +-- interpreted as \TeX\ points (1/72.27th of an inch). The $x$-axis goes +-- right and the $y$-axis goes up. +-- +-- @field x +-- @field y + +local Coordinate = {} +Coordinate.__index = Coordinate + + +-- Namespace + +require("pgf.gd.model").Coordinate = Coordinate + + + + +--- Creates a new coordinate. +-- +-- @param x The $x$ value +-- @param y The $y$ value +-- +-- @return A coordinate +-- +function Coordinate.new(x,y) + return setmetatable( {x=x, y=y}, Coordinate) +end + + +--- Creates a new coordinate that is a copy of an existing one. +-- +-- @return A new coordinate at the same location as |self| +-- +function Coordinate:clone() + return setmetatable( { x = self.x, y = self.y }, Coordinate) +end + + + +--- Apply a transformation matrix to a coordinate, +-- see |pgf.gd.lib.Transform| for details. +-- +-- @param t A tansformation + +function Coordinate:apply(t) + local x = self.x + local y = self.y + self.x = t[1]*x + t[2]*y + t[5] + self.y = t[3]*x + t[4]*y + t[6] +end + + +--- Shift a coordinate +-- +-- @param a An $x$ offset +-- @param b A $y$ offset + +function Coordinate:shift(a,b) + self.x = self.x + a + self.y = self.y + b +end + + +--- +-- ``Unshift'' a coordinate (which is the same as shifting by the +-- inversed coordinate; only faster). +-- +-- @param a An $x$ offset +-- @param b A $y$ offset + +function Coordinate:unshift(a,b) + self.x = self.x - a + self.y = self.y - b +end + + +--- +-- Like |shift|, only for coordinate parameters. +-- +-- @param c Another coordinate. The $x$- and $y$-values of |self| are +-- increased by the $x$- and $y$-values of this coordinate. + +function Coordinate:shiftByCoordinate(c) + self.x = self.x + c.x + self.y = self.y + c.y +end + + +--- +-- Like |unshift|, only for coordinate parameters. +-- +-- @param c Another coordinate. + +function Coordinate:unshiftByCoordinate(c) + self.x = self.x - c.x + self.y = self.y - c.y +end + + +--- +-- Moves the coordinate a fraction of |f| along a straight line to |c|. +-- +-- @param c Another coordinate +-- @param f A fraction + +function Coordinate:moveTowards(c,f) + self.x = self.x + f*(c.x-self.x) + self.y = self.y + f*(c.y-self.y) +end + + + +--- Scale a coordinate by a factor +-- +-- @param s A factor. + +function Coordinate:scale(s) + self.x = s*self.x + self.y = s*self.y +end + + + + +--- +-- Add two coordinates, yielding a new coordinate. Note that it will +-- be a lot faster to call shift, whenever this is possible. +-- +-- @param a A coordinate +-- @param b A coordinate + +function Coordinate.__add(a,b) + return setmetatable({ x = a.x + b.x, y = a.y + b.y }, Coordinate) +end + + +--- +-- Subtract two coordinates, yielding a new coordinate. Note that it will +-- be a lot faster to call unshift, whenever this is possible. +-- +-- @param a A coordinate +-- @param b A coordinate + +function Coordinate.__sub(a,b) + return setmetatable({ x = a.x - b.x, y = a.y - b.y }, Coordinate) +end + + +--- +-- The unary minus (mirror the coordinate against the origin). +-- +-- @param a A coordinate + +function Coordinate.__unm(a) + return setmetatable({ x = - a.x, y = - a.y }, Coordinate) +end + + +--- +-- The multiplication operator. Its effect depends on the parameters: +-- If both are coordinates, their dot-product is returned. If exactly +-- one of them is a coordinate and the other is a number, the scalar +-- multiple of this coordinate is returned. +-- +-- @param a A coordinate or a scalar +-- @param b A coordinate or a scalar +-- @return The dot product or scalar product. + +function Coordinate.__mul(a,b) + if getmetatable(a) == Coordinate then + if getmetatable(b) == Coordinate then + return a.x * b.x + a.y * b.y + else + return setmetatable({ x = a.x * b, y = a.y *b }, Coordinate) + end + else + return setmetatable({ x = a * b.x, y = a * b.y }, Coordinate) + end +end + +--- +-- The division operator. Returns the scalar division of a coordinate +-- by a scalar. +-- +-- @param a A coordinate +-- @param b A scalar (not equal to zero). +-- @return The scalar product or a * (1/b). + +function Coordinate.__div(a,b) + return setmetatable({ x = a.x / b, y = a.y / b }, Coordinate) +end + + +--- +-- The norm function. Returns the norm of a coordinate. +-- +-- @param a A coordinate +-- @return The norm of the coordinate + +function Coordinate:norm() + return math.sqrt(self.x * self.x + self.y * self.y) +end + + +--- +-- Normalize a vector: Ensure that it has length 1. If the vector used +-- to be the 0-vector, it gets replaced by (1,0). +-- + +function Coordinate:normalize() + local x, y = self.x, self.y + if x == 0 and y == 0 then + self.x = 1 + else + local norm = math.sqrt(x*x+y*y) + self.x = x / norm + self.y = y / norm + end +end + + +--- +-- Normalized version of a vector: Like |normalize|, only the result is +-- returned in a new vector. +-- +-- @return Normalized version of |self| + +function Coordinate:normalized() + local x, y = self.x, self.y + if x == 0 and y == 0 then + return setmetatable({ x = 1, y = 0 }, Coordinate) + else + local norm = math.sqrt(x*x+y*y) + return setmetatable({ x = x/norm, y = y/norm }, Coordinate) + end +end + + + +--- +-- Compute a bounding box around an array of coordinates +-- +-- @param array An array of coordinates +-- +-- @return |min_x| The minimum $x$ value of the bounding box of the array +-- @return |min_y| The minimum $y$ value +-- @return |max_x| +-- @return |max_y| +-- @return |center_x| The center of the bounding box +-- @return |center_y| + +function Coordinate.boundingBox(array) + if #array > 0 then + local min_x, min_y = math.huge, math.huge + local max_x, max_y = -math.huge, -math.huge + + for i=1,#array do + local c = array[i] + local x = c.x + local y = c.y + if x < min_x then min_x = x end + if y < min_y then min_y = y end + if x > max_x then max_x = x end + if y > max_y then max_y = y end + end + + return min_x, min_y, max_x, max_y, (min_x+max_x) / 2, (min_y+max_y) / 2 + end +end + + + + +-- Returns a string representation of an arc. This is mainly for debugging +-- +-- @return The Arc as string. +-- +function Coordinate:__tostring() + return "(" .. self.x .. "pt," .. self.y .. "pt)" +end + + +-- Done + +return Coordinate
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Digraph.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Digraph.lua new file mode 100644 index 00000000000..f0568d13ad9 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Digraph.lua @@ -0,0 +1,843 @@ +-- 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/model/Digraph.lua,v 1.7 2013/12/20 14:44:47 tantau Exp $ + + + + +--- +-- Each |Digraph| instance models a \emph{directed, simple} +-- graph. ``Directed'' means that all edges ``point'' from a head node +-- to a tail node. ``Simple'' means that between any nodes there can be +-- (at most) one edge. Since these properties are a bit at odds with +-- the normal behaviour of ``nodes'' and ``edges'' in \tikzname, +-- different names are used for them inside the |model| namespace: +-- The class modeling ``edges'' is actually called |Arc| to stress +-- that an arc has a specific ``start'' (the tail) and a specific +-- ``end'' (the head). The class modeling ``nodes'' is actually called +-- |Vertex|, just to stress that this is not a direct model of a +-- \tikzname\ |node|, but can represent a arbitrary vertex of a graph, +-- independently of whether it is an actual |node| in \tikzname. +-- +-- \medskip +-- \noindent\emph{Time Bounds.} +-- Since digraphs are constantly created and modified inside the graph +-- drawing engine, some care was taken to ensure that all operations +-- work as quickly as possible. In particular: +-- \begin{itemize} +-- \item Adding an array of $k$ vertices using the |add| method needs +-- time $O(k)$. +-- \item Adding an arc between two vertices needs time $O(1)$. +-- \item Accessing both the |vertices| and the |arcs| fields takes time +-- $O(1)$, provided only the above operations are used. +-- \end{itemize} +-- Deleting vertices and arcs takes more time: +-- \begin{itemize} +-- \item Deleting the vertices given in an array of $k$ vertices from a +-- graph with $n$ vertices takes time $O(\max\{n,c\})$ where $c$ is the +-- number of arcs between the to-be-deleted nodes and the remaining +-- nodes. Note that this time bound in independent of~$k$. In +-- particular, it will be much faster to delete many vertices by once +-- calling the |remove| function instead of calling it repeatedly. +-- \item Deleting an arc takes time $O(t_o+h_i)$ where $t_o$ is the +-- number of outgoing arcs at the arc's tail and $h_i$ is the number +-- of incoming arcs at the arc's head. After a call to |disconnect|, +-- the next use of the |arcs| field will take time $O(|V| + |E|)$, +-- while subsequent accesses take time $O(1)$ -- till the +-- next use of |disconnect|. This means that once you start deleting +-- arcs using |disconnect|, you should perform as many additional +-- |disconnect|s as possible before accessing |arcs| one more. +-- \end{itemize} +-- +-- \medskip +-- \noindent\emph{Stability.} The |vertices| field and the array +-- returned by |Digraph:incoming| and |Digraph:outgoing| are +-- \emph{stable} in the following sense: The ordering of the elements +-- when you use |ipairs| on the will be the ordering in which the +-- vertices or arcs were added to the graph. Even when you remove a +-- vertex or an arc, the ordering of the remaining elements stays the +-- same. +-- +-- @field vertices This array contains the vertices that are part of +-- the digraph. Internally, this array +-- is an object of type |LookupTable|, but you can mostly treat it as +-- if it were an array. In particular, you can iterate over its +-- elements using |ipairs|, but you may not modify the array; use the +-- |add| and |remove| methods, instead. +-- +-- \begin{codeexample}[code only, tikz syntax=false] +-- local g = Digraph.new {} +-- +-- g:add { v1, v2 } -- Add vertices v1 and v2 +-- g:remove { v2 } -- Get rid of v2. +-- +-- assert (g:contains(v1)) +-- assert (not g:contains(v2)) +-- \end{codeexample} +-- +-- It is important to note that although each digraph stores a +-- |vertices| array, the elements in this array are not exclusive to +-- the digraph: A vertex can be an element of any number of +-- digraphs. Whether or not a vertex is an element of digraph is not +-- stored in the vertex, only in the |vertices| array of the +-- digraph. To test whether a digraph contains a specific node, use the +-- |contains| method, which takes time $O(1)$ to perform the test (this +-- is because, as mentioned earlier, the |vertices| array is actually a +-- |LookupTable| and for each vertex |v| the field |vertices[v]| will +-- be true if, and only if, |v| is an element of the |vertices| array). +-- +-- Do not use |pairs(g.vertices)| because this may cause your graph +-- drawing algorithm to produce different outputs on different runs. +-- +-- A slightly annoying effect of vertices being able to belong to +-- several graphs at the same time is that the set of arcs incident to +-- a vertex is not a property of the vertex, but rather of the +-- graph. In other words, to get a list of all arcs whose tail is a +-- given vertex |v|, you cannot say something like |v.outgoings| or +-- perhaps |v:getOutgoings()|. Rather, you have to say |g:outgoing(v)| +-- to get this list: +--\begin{codeexample}[code only, tikz syntax=false] +--for _,a in ipairs(g:outgoing(v)) do -- g is a Digraph object. +-- pgf.debug ("There is an arc leaving " .. tostring(v) .. +-- " heading to " .. tostring(a.head)) +--end +--\end{codeexample} +-- Naturally, there is also a method |g:incoming()|. +-- +-- To iterate over all arcs of a graph you can say: +--\begin{codeexample}[code only, tikz syntax=false] +--for _,v in ipairs(g.vertices) do +-- for _,a in ipairs(g:outgoing(v)) do +-- ... +-- end +--end +--\end{codeexample} +-- +-- However, it will often be more convenient and, in case the there +-- are far less arcs than vertices, also faster to write +-- +--\begin{codeexample}[code only, tikz syntax=false] +--for _,a in ipairs(g.arcs) do +-- ... +--end +--\end{codeexample} +-- +-- @field arcs For any two vertices |t| and |h| of a graph, there may +-- or may not be +-- an arc from |t| to |h|. If this is the case, there is an |Arc| +-- object that represents this arc. Note that, since |Digraph|s are +-- always simple graphs, there can be at most one such object for every +-- pair of vertices. However, you can store any information you like for +-- an |Arc| through a |Storage|, see the |Storage| class for +-- details. Each |Arc| for an edge of the syntactic digraph stores +-- an array called |syntactic_edges| of all the multiple edges that +-- are present in the user's input. +-- +-- Unlike vertices, the arc objects of a graph are always local to a +-- graph; an |Arc| object can never be part of two digraphs at the same +-- time. For this reason, while for vertices it makes sense to create +-- |Vertex| objects independently of any |Digraph| objects, it is not +-- possible to instantiate an |Arc| directly: only the |Digraph| method +-- |connect| is allowed to create new |Arc| objects and it will return +-- any existing arcs instead of creating new ones, if there is already +-- an arc present between two nodes. +-- +-- The |arcs| field of a digraph contains a |LookupTable| of all arc +-- objects present in the |Digraph|. Although you can access this field +-- normally and use it in |ipairs| to iterate over all arcs of a graph, +-- note that this array is actually ``reconstructed lazily'' whenever +-- an arc is deleted from the graph. What happens is the following: As +-- long as you just add arcs to a graph, the |arcs| array gets updated +-- normally. However, when you remove an arc from a graph, the arc does +-- not get removed from the |arcs| array (which would be an expensive +-- operation). Instead, the |arcs| array is invalidated (internally set +-- to |nil|), allowing us to perform a |disconnect| in time +-- $O(1)$. The |arcs| array is then ignored until the next time it is +-- accessed, for instance when a user says |ipairs(g.arcs)|. At this +-- point, the |arcs| array is reconstructed by adding all arcs of all +-- nodes to it. +-- +-- The bottom line of the behaviour of the |arcs| field is that (a) the +-- ordering of the elements may change abruptly whenever you remove an +-- arc from a graph and (b) performing $k$ |disconnect| operations in +-- sequence takes time $O(k)$, provided you do not access the |arcs| +-- field between calls. +-- +-- @field syntactic_digraph is a reference to the syntactic digraph +-- from which this graph stems ultimately. This may be a cyclic +-- reference to the graph itself. +-- @field options If present, it will be a table storing +-- the options set for the syntactic digraph. +-- +local Digraph = {} + +local function recalc_arcs (digraph) + local arcs = {} + local vertices = digraph.vertices + for i=1,#vertices do + local out = vertices[i].outgoings[digraph] + for j=1,#out do + arcs[#arcs + 1] = out[j] + end + end + digraph.arcs = arcs + return arcs +end + +Digraph.__index = + function (t, k) + if k == "arcs" then + return recalc_arcs(t) + else + return rawget(Digraph,k) + end + end + + + +-- Namespace +require("pgf.gd.model").Digraph = Digraph + +-- Imports +local Arc = require "pgf.gd.model.Arc" +local LookupTable = require "pgf.gd.lib.LookupTable" +local Vertex = require "pgf.gd.model.Vertex" + + + + + +--- +-- Graphs are created using the |new| method, which takes a table of +-- |initial| values as input (like most |new| methods in the graph +-- drawing system). It is permissible that this table of initial values +-- has a |vertices| field, in which case this array will be copied. In +-- contrast, an |arcs| field in the table will be ignored -- newly +-- created graphs always have an empty arcs set. This means that +-- writing |Digraph.new(g)| where |g| is a graph creates a new graph +-- whose vertex set is the same as |g|'s, but where there are no edges: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local g = Digraph.new {} +--g:add { v1, v2, v3 } +--g:connect (v1, v2) +-- +--local h = Digraph.new (g) +--assert (h:contains(v1)) +--assert (not h:arc(v1, v2)) +--\end{codeexample} +-- +-- To completely copy a graph, including all arcs, you have to write: +--\begin{codeexample}[code only, tikz syntax=false] +--local h = Digraph.new (g) +--for _,a in ipairs(g.arcs) do h:connect(a.tail, a.head) end +--\end{codeexample} +-- +-- This operation takes time $O(1)$. +-- +-- @param initial A table of initial values. It is permissible that +-- this array contains a |vertices| field. In this +-- case, this field must be an array and its entries +-- must be nodes, which will be inserted. If initial +-- has an |arcs| field, this field will be ignored. +-- The table must contain a field |syntactic_digraph|, +-- which should normally be the syntactic digraph of +-- the graph, but may also be the string |"self"|, in +-- which case it will be set to the newly created +-- (syntactic) digraph. +-- @return A newly-allocated digraph. +-- +function Digraph.new(initial) + local digraph = {} + setmetatable(digraph, Digraph) + + if initial then + for k,v in pairs(initial or {}) do + digraph [k] = v + end + end + + local vertices = digraph.vertices + digraph.vertices = {} + digraph.arcs = {} + + if vertices then + digraph:add(vertices) + end + return digraph +end + + +--- Add vertices to a digraph. +-- +-- This operation takes time $O(|\verb!array!|)$. +-- +-- @param array An array of to-be-added vertices. +-- +function Digraph:add(array) + local vertices = self.vertices + for i=1,#array do + local v = array[i] + if not vertices[v] then + vertices[v] = true + vertices[#vertices + 1] = v + v.incomings[self] = {} + v.outgoings[self] = {} + end + end +end + + +--- Remove vertices from a digraph. +-- +-- This operation removes an array of vertices from a graph. The +-- operation takes time linear in the number of vertices, regardless of +-- how many vertices are to be removed. Thus, it will be (much) faster +-- to delete many vertices by first compiling them in an array and to +-- then delete them using one call to this method. +-- +-- This operation takes time $O(\max\{|\verb!array!|, |\verb!self.vertices!|\})$. +-- +-- @param array The to-be-removed vertices. +-- +function Digraph:remove(array) + local vertices = self.vertices + + -- Mark all to-be-deleted nodes + for i=1,#array do + local v = array[i] + assert(vertices[v], "to-be-deleted node is not in graph") + vertices[v] = false + end + + -- Disconnect them + for i=1,#array do + self:disconnect(array[i]) + end + + LookupTable.remove(self.vertices, array) +end + + + +--- Test, whether a graph contains a given vertex. +-- +-- This operation takes time $O(1)$. +-- +-- @param v The vertex to be tested. +-- +function Digraph:contains(v) + return v and self.vertices[v] == true +end + + + + +--- +-- Returns the arc between two nodes, provided it exists. Otherwise, +-- |nil| is retured. +-- +-- This operation takes time $O(1)$. +-- +-- @param tail The tail vertex +-- @param head The head vertex +-- +-- @return The arc object connecting them +-- +function Digraph:arc(tail, head) + local out = tail.outgoings[self] + if out then + return out[head] + end +end + + + +--- +-- Returns an array containing the outgoing arcs of a vertex. You may +-- only iterate over his array using ipairs, not using pairs. +-- +-- This operation takes time $O(1)$. +-- +-- @param v The vertex +-- +-- @return An array of all outgoing arcs of this vertex (all arcs +-- whose tail is the vertex) +-- +function Digraph:outgoing(v) + return assert(v.outgoings[self], "vertex not in graph") +end + + + +--- +-- Sorts the array of outgoing arcs of a vertex. This allows you to +-- later iterate over the outgoing arcs in a specific order. +-- +-- This operation takes time $O(|\verb!outgoing!| \log |\verb!outgoings!|)$. +-- +-- @param v The vertex +-- @param f A comparison function that is passed to |table.sort| +-- +function Digraph:sortOutgoing(v, f) + table.sort(assert(v.outgoings[self], "vertex not in graph"), f) +end + + +--- +-- Reorders the array of outgoing arcs of a vertex. The parameter array +-- \emph{must} contain the same set of vertices as the outgoing array, +-- but possibly in a different order. +-- +-- This operation takes time $O(|\verb!outgoing!|)$, where |outgoing| +-- is the array of |v|'s outgoing arcs in |self|. +-- +-- @param v The vertex +-- @param vertices An array containing the outgoing vertices in some order. +-- +function Digraph:orderOutgoing(v, vertices) + local outgoing = assert (v.outgoings[self], "vertex not in graph") + assert (#outgoing == #vertices) + + -- Create back hash + local lookup = {} + for i=1,#vertices do + lookup[vertices[i]] = i + end + + -- Compute ordering of the arcs + local reordered = {} + for _,arc in ipairs(outgoing) do + reordered [lookup[arc.head]] = arc + end + + -- Copy back + for i=1,#outgoing do + outgoing[i] = assert(reordered[i], "illegal vertex order") + end +end + + + +--- See |outgoing|. +-- +function Digraph:incoming(v) + return assert(v.incomings[self], "vertex not in graph") +end + + +--- +-- See |sortOutgoing|. +-- +function Digraph:sortIncoming(v, f) + table.sort(assert(v.incomings[self], "vertex not in graph"), f) +end + + +--- +-- See |orderOutgoing|. +-- +function Digraph:orderIncoming(v, vertices) + local incoming = assert (v.incomings[self], "vertex not in graph") + assert (#incoming == #vertices) + + -- Create back hash + local lookup = {} + for i=1,#vertices do + lookup[vertices[i]] = i + end + + -- Compute ordering of the arcs + local reordered = {} + for _,arc in ipairs(incoming) do + reordered [lookup[arc.head]] = arc + end + + -- Copy back + for i=1,#incoming do + incoming[i] = assert(reordered[i], "illegal vertex order") + end +end + + + + + +--- +-- Connects two nodes by an arc and returns the newly created arc +-- object. If they are already connected, the existing arc is returned. +-- +-- This operation takes time $O(1)$. +-- +-- @param s The tail vertex +-- @param t The head vertex (may be identical to |tail| in case of a +-- loop) +-- +-- @return The arc object connecting them (either newly created or +-- already existing) +-- +function Digraph:connect(s, t) + assert (s and t and self.vertices[s] and self.vertices[t], "trying connect nodes not in graph") + + local s_outgoings = s.outgoings[self] + local arc = s_outgoings[t] + + if not arc then + -- Ok, create and insert new arc object + arc = { + tail = s, + head = t, + option_cache = {}, + syntactic_digraph = self.syntactic_digraph, + syntactic_edges = {} + } + setmetatable(arc, Arc) + + -- Insert into outgoings: + s_outgoings [#s_outgoings + 1] = arc + s_outgoings [t] = arc + + local t_incomings = t.incomings[self] + -- Insert into incomings: + t_incomings [#t_incomings + 1] = arc + t_incomings [s] = arc + + -- Insert into arcs field, if it exists: + local arcs = rawget(self, "arcs") + if arcs then + arcs[#arcs + 1] = arc + end + end + + return arc +end + + + + +--- +-- Disconnect either a single vertex |v| from all its neighbors (remove all +-- incoming and outgoing arcs of this vertex) or, in case two nodes +-- are given as parameter, remove the arc between them, if it exsits. +-- +-- This operation takes time $O(|I_v| + |I_t|)$, where $I_x$ is the set +-- of vertices incident to $x$, to remove the single arc between $v$ and +-- $v$. For a single vertex $v$, it takes time $O(\sum_{y: \text{there is some +-- arc between $v$ and $y$ or $y$ and $v$}} |I_y|)$. +-- +-- @param v The single vertex or the tail vertex +-- @param t The head vertex +-- +function Digraph:disconnect(v, t) + if t then + -- Case 2: Remove a single arc. + local s_outgoings = assert(v.outgoings[self], "tail node not in graph") + local t_incomings = assert(t.incomings[self], "head node not in graph") + + if s_outgoings[t] then + -- Remove: + s_outgoings[t] = nil + for i=1,#s_outgoings do + if s_outgoings[i].head == t then + table.remove (s_outgoings, i) + break + end + end + t_incomings[v] = nil + for i=1,#t_incomings do + if t_incomings[i].tail == v then + table.remove (t_incomings, i) + break + end + end + self.arcs = nil -- invalidate arcs field + end + else + -- Case 1: Remove all arcs incident to v: + + -- Step 1: Delete all incomings arcs: + local incomings = assert(v.incomings[self], "node not in graph") + local vertices = self.vertices + + for i=1,#incomings do + local s = incomings[i].tail + if s ~= v and vertices[s] then -- skip self-loop and to-be-deleted nodes + -- Remove this arc from s: + local s_outgoings = s.outgoings[self] + s_outgoings[v] = nil + for i=1,#s_outgoings do + if s_outgoings[i].head == v then + table.remove (s_outgoings, i) + break + end + end + end + end + + -- Step 2: Delete all outgoings arcs: + local outgoings = v.outgoings[self] + for i=1,#outgoings do + local t = outgoings[i].head + if t ~= v and vertices[t] then + local t_incomings = t.incomings[self] + t_incomings[v] = nil + for i=1,#t_incomings do + if t_incomings[i].tail == v then + table.remove (t_incomings, i) + break + end + end + end + end + + if #incomings > 0 or #outgoings > 0 then + self.arcs = nil -- invalidate arcs field + end + + -- Step 3: Reset incomings and outgoings fields + v.incomings[self] = {} + v.outgoings[self] = {} + end +end + + + + +--- +-- An arc is changed so that instead of connecting |self.tail| +-- and |self.head|, it now connects a new |head| and |tail|. The +-- difference to first disconnecting and then reconnecting is that all +-- fields of the arc (other than |head| and |tail|, of course), will +-- be ``moved along.'' Reconnecting an arc in the same way as before has no +-- effect. +-- +-- If there is already an arc at the new position, fields of the +-- to-be-reconnected arc overwrite fields of the original arc. This is +-- especially dangerous with a syntactic digraph, so do not reconnect +-- arcs of the syntactic digraph (which you should not do anyway). +-- +-- The |arc| object may no longer be valid after a reconnect, but the +-- operation returns the new arc object. +-- +-- This operation needs the time of a disconnect (if necessary). +-- +-- @param arc The original arc object +-- @param tail The new tail vertex +-- @param head The new head vertex +-- +-- @return The new arc object connecting them (either newly created or +-- already existing) +-- +function Digraph:reconnect(arc, tail, head) + assert (arc and tail and head, "connect with nil parameters") + + if arc.head == head and arc.tail == tail then + -- Nothing to be done + return arc + else + local new_arc = self:connect(tail, head) + + for k,v in pairs(arc) do + if k ~= "head" and k ~= "tail" then + new_arc[k] = v + end + end + + -- Remove old arc: + self:disconnect(arc.tail, arc.head) + + return new_arc + end +end + + + +--- +-- Collapse a set of vertices into a single vertex +-- +-- Often, algorithms will wish to treat a whole set of vertices ``as a +-- single vertex''. The idea is that a new vertex is then inserted +-- into the graph, and this vertex is connected to all vertices to +-- which any of the original vertices used to be connected. +-- +-- The |collapse| method takes an array of to-be-collapsed vertices as +-- well as a vertex. First, it will store references to the +-- to-be-collapsed vertices inside the vertex. Second, we iterate over +-- all arcs of the to-be-collapsed vertices. If this arc connects a +-- to-be-collapsed vertex with a not-to-be-collapsed vertex, the +-- not-to-be-collapsed vertex is connected to the collapse +-- vertex. Additionally, the arc is stored at the vertex. +-- +-- Note that the collapse vertex will be added to the graph if it is +-- not already an element. The collapsed vertices will not be removed +-- from the graph, so you must remove them yourself, if necessary. +-- +-- A collapse vertex will store the collapsed vertices so that you can +-- call |expand| later on to ``restore'' the vertices and arcs that +-- were saved during a collapse. This storage is \emph{not} local to +-- the graph in which the collapse occured. +-- +-- @param collapse_vertices An array of to-be-collapsed vertices +-- @param collapse_vertex The vertex that represents the collapse. If +-- missing, a vertex will be created automatically and added to the graph. +-- @param vertex_fun This function is called for each to-be-collapsed +-- vertex. The parameters are the collapse vertex and the +-- to-be-collapsed vertex. May be |nil|. +-- @param arc_fun This function is called whenever a new arc is added +-- between |rep| and some other vertex. The arguments are the new arc +-- and the original arc. May be |nil|. +-- +-- @return The new vertex that represents the collapsed vertices. + +function Digraph:collapse(collapse_vertices, collapse_vertex, vertex_fun, arc_fun) + + + -- Create and add node, if necessary. + if not collapse_vertex then + collapse_vertex = Vertex.new {} + end + self:add {collapse_vertex} + + -- Copy the collapse_vertices and create lookup + local cvs = {} + for i=1,#collapse_vertices do + local v = collapse_vertices[i] + cvs[i] = v + cvs[v] = true + end + assert (cvs[collapse_vertex] ~= true, "collapse_vertex is in collapse_vertices") + + -- Connected collapse_vertex appropriately + local collapsed_arcs = {} + + if not arc_fun then + arc_fun = function () end + end + + for _,v in ipairs(cvs) do + if vertex_fun then + vertex_fun (collapse_vertex, v) + end + for _,a in ipairs(v.outgoings[self]) do + if cvs[a.head] ~= true then + arc_fun (self:connect(collapse_vertex, a.head), a) + collapsed_arcs[#collapsed_arcs + 1] = a + end + end + for _,a in ipairs(v.incomings[self]) do + if cvs[a.tail] ~= true then + arc_fun (self:connect(a.tail, collapse_vertex), a) + end + collapsed_arcs[#collapsed_arcs + 1] = a + end + end + + -- Remember the old vertices. + collapse_vertex.collapsed_vertices = cvs + collapse_vertex.collapsed_arcs = collapsed_arcs + + return collapse_vertex +end + + + +--- +-- Expand a previously collapsed vertex. +-- +-- If you have collapsed a set of vertices in a graph using +-- |collapse|, you can expand this set once more using this method. It +-- will add all vertices that were previously removed from the graph +-- and will also reinstall the deleted arcs. The collapse vertex is +-- not removed. +-- +-- @param vertex A to-be-expanded vertex that was previously returned +-- by |collapse|. +-- @param vertex_fun A function that is called once for each +-- reinserted vertex. The parameters are the collapse vertex and the +-- reinstalled vertex. May be |nil|. +-- @param arc_fun A function that is called once for each +-- reinserted arc. The parameter is the arc and the |vertex|. May be |nil|. +-- +function Digraph:expand(vertex, vertex_fun, arc_fun) + local cvs = assert(vertex.collapsed_vertices, "no expand information stored") + + -- Add all vertices: + self:add(cvs) + if vertex_fun then + for _,v in ipairs(cvs) do + vertex_fun(vertex, v) + end + end + + -- Add all arcs: + for _,arc in ipairs(vertex.collapsed_arcs) do + local new_arc = self:connect(arc.tail, arc.head) + + for k,v in pairs(arc) do + if k ~= "head" and k ~= "tail" then + new_arc[k] = v + end + end + + if arc_fun then + arc_fun(new_arc, vertex) + end + end +end + + + + + +--- +-- Invokes the |sync| method for all arcs of the graph. +-- +-- @see Arc:sync() +-- +function Digraph:sync() + for _,a in ipairs(self.arcs) do + a:sync() + end +end + + + +--- +-- Computes a string representation of this graph including all nodes +-- and edges. The syntax of this representation is such that it can be +-- used directly in \tikzname's |graph| syntax. +-- +-- @return |self| as string. +-- +function Digraph:__tostring() + local vstrings = {} + local astrings = {} + for i,v in ipairs(self.vertices) do + vstrings[i] = " " .. tostring(v) .. "[x=" .. math.floor(v.pos.x) .. "pt,y=" .. math.floor(v.pos.y) .. "pt]" + local out_arcs = v.outgoings[self] + if #out_arcs > 0 then + local t = {} + for j,a in ipairs(out_arcs) do + t[j] = tostring(a.head) + end + astrings[#astrings + 1] = " " .. tostring(v) .. " -> { " .. table.concat(t,", ") .. " }" + end + end + return "graph [id=" .. tostring(self.vertices) .. "] {\n {\n" .. + table.concat(vstrings, ",\n") .. "\n }; \n" .. + table.concat(astrings, ";\n") .. "\n}"; +end + + + + +-- Done + +return Digraph
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Edge.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Edge.lua new file mode 100644 index 00000000000..a91979d0ad5 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Edge.lua @@ -0,0 +1,205 @@ +-- 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/model/Edge.lua,v 1.6 2013/12/20 14:44:47 tantau Exp $ + + +--- +-- An |Edge| is a ``syntactic'' connection between two +-- vertices that represents a connection present in the syntactic +-- digraph. Unlike an |Arc|, |Edge| objects are not controlled by the +-- |Digraph| class. Also unlike |Arc| objects, there can be several +-- edges betwen the same vertices, namely whenever several such edges +-- are present in the syntactic digraph. +-- +-- In detail, the relationship between arcs and edges is as follows: +-- If there is an |Edge| between two vertices $u$ and $v$ in the +-- syntactic digraph, there will be an |Arc| from $u$ to $v$ and the +-- array |syntactic_edges| of this |Arc| object will contain the +-- |Edge| object. In particular, if there are several edges between +-- the same vertices, all of these edges will be part of the array in +-- a single |Arc| object. +-- +-- Edges, like arcs, are always directed from a |tail| vertex to a +-- |head| vertex; this is true even for undirected vertices. The +-- |tail| vertex will always be the vertex that came first in the +-- syntactic specification of the edge, the |head| vertex is the +-- second one. Whether +-- an edge is directed or not depends on the |direction| of the edge, which +-- may be one of the following: +-- +-- \begin{enumerate} +-- \item |"->"| +-- \item |"--"| +-- \item |"<-"| +-- \item |"<->"| +-- \item |"-!-"| +-- \end{enumerate} +-- +-- +-- @field head The head vertex of this edge. +-- +-- @field tail The tail vertex of this edge. +-- +-- @field event The creation |Event| of this edge. +-- +-- @field options A table of options that contains user-defined options. +-- +-- @field direction One of the directions named above. +-- +-- @field path A |Path| object that describes the path of the +-- edge. The path's coordinates are interpreted \emph{absolutely}. +-- +-- @field generated_options This is an options array that is generated +-- by the algorithm. When the edge is rendered later on, this array +-- will be passed back to the display layer. The syntax is the same as +-- for the |declare_parameter_sequence| function, see +-- |InterfaceToAlgorithms|. + +local Edge = {} +Edge.__index = Edge + + +-- Namespace + +require("pgf.gd.model").Edge = Edge + + +-- Imports + +local Path = require "pgf.gd.model.Path" + + +--- +-- Create a new edge. The |initial| parameter allows you to setup +-- some initial values. +-- +-- @usage +--\begin{codeexample}[code only, tikz syntax=false] +--local v = Edge.new { tail = v1, head = v2 } +--\end{codeexample} +-- +-- @param initial Values to override defaults. -- +-- @return A new edge object. +-- +function Edge.new(values) + local new = {} + for k,v in pairs(values) do + new[k] = v + end + new.generated_options = new.generated_options or {} + if not new.path then + local p = Path.new () + p:appendMoveto(Edge.tailAnchorForEdgePath(new)) + p:appendLineto(Edge.headAnchorForEdgePath(new)) + new.path = p + end + + return setmetatable(new, Edge) +end + + + + +--- +-- This method returns a ``coordinate factory'' that can be used as +-- the coordinate of a |moveto| at the beginning of a path starting at +-- the |tail| of the arc. Suppose you want to create a path starting +-- at the tail vertex, going to the coordinate $(10,10)$ and ending at +-- the head vertex. The trouble is that when you create the path +-- corresponding to this route, you typically do not know where the +-- tail vertex is going to be. In this case, you use this +-- method to get a function that will, later on, compute the correct +-- position of the anchor as needed. +-- +-- Note that you typically do not use this function, but use the +-- corresponding function of the |Arc| class. Use this function only +-- if there are multiple edges between two vertices that need to be +-- routed differently. +-- +-- Here is the code you would use to create the abovementioned path: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local a = g:connect(tail,head) +--local e = a.syntactic_edges[1] +--... +--e.path = Path.new() +--e.path:appendMoveto(e:tailAnchorForEdgePath()) +--e.path:appendLineto(10, 10) +--e.path:appendLineto(e:headAnchorForEdgePath()) +--\end{codeexample} +-- +-- As for the |Arc| class, you can also setup a polyline more easily: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--e:setPolylinePath { Coordinate.new (10, 10) } +--\end{codeexample} + +function Edge:tailAnchorForEdgePath() + return function () + local a = self.options['tail anchor'] + if a == "" then + a = "center" + end + return self.tail:anchor(a) + self.tail.pos + end +end + +--- +-- See |Arc:tailAnchorForArcPath|. + +function Edge:headAnchorForEdgePath() + return function () + local a = self.options['head anchor'] + if a == "" then + a = "center" + end + return self.head:anchor(a) + self.head.pos + end +end + + + +--- +-- Setup the |path| field of an edge in such a way that it corresponds +-- to a sequence of straight line segments starting at the tail's +-- anchor and ending at the head's anchor. +-- +-- @param coordinates An array of |Coordinates| through which the line +-- will go through. + +function Edge:setPolylinePath(coordinates) + local p = Path.new () + + p:appendMoveto(self:tailAnchorForEdgePath()) + + for _,c in ipairs(coordinates) do + p:appendLineto(c) + end + + p:appendLineto(self:headAnchorForEdgePath()) + + self.path = p +end + + + +-- +-- Returns a string representation of an edge. This is mainly for debugging. +-- +-- @return The Edge as a string. +-- +function Edge:__tostring() + return tostring(self.tail) .. self.direction .. tostring(self.head) +end + + +-- Done + +return Edge
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Hyperedge.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Hyperedge.lua new file mode 100644 index 00000000000..54a373bf83f --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Hyperedge.lua @@ -0,0 +1,56 @@ +-- 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/model/Hyperedge.lua,v 1.2 2013/05/23 20:01:27 tantau Exp $ + + + +--- +-- @section subsection {Hyperedges} +-- +-- @end + + +-- Includes + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + + +--- + +declare { + key = "hyper", + layer = -10, + + summary = [[" + A \emph{hyperedge} of a graph does not connect just two nodes, but + is any subset of the node set (although a normal edge is also a + hyperedge that happens to contain just two nodes). Internally, a + collection of kind |hyper| is created. Currently, there is + no default renderer for hyper edges. + "]], + documentation = [[" +\begin{codeexample}[code only] +\graph { + % The nodes: + a, b, c, d; + + % The edges: + {[hyper] a,b,c}; + {[hyper] b,c,d}; + {[hyper] a,c}; + {[hyper] d} +}; +\end{codeexample} + "]] +} + +-- Done + +return Hyperedge
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Path.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Path.lua new file mode 100644 index 00000000000..03a7e7c695c --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Path.lua @@ -0,0 +1,1220 @@ +-- Copyright 2014 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/model/Path.lua,v 1.2 2013/09/23 20:04:26 tantau Exp $ + + +--- +-- A Path models a path in the plane. +-- +-- Following the PostScript/\textsc{pdf}/\textsc{svg} convention, a +-- path consists of a series of path segments, each of which can be +-- closed or not. Each path segement, in turn, consists of a series of +-- Bézier curvers and straight line segments; see +-- Section~\ref{section-paths} for an introduction to paths in +-- general. +-- +-- A |Path| object is a table whose array part stores +-- |Coordinate| objects, |strings|, and |function|s that +-- describe the path of the edge. The following strings are allowed in +-- this array: +-- +-- \begin{itemize} +-- \item |"moveto"| The line's path should stop at the current +-- position and then start anew at the next coordinate in the array. +-- \item |"lineto"| The line should continue from the current position +-- to the next coordinate in the array. +-- \item |"curveto"| The line should continue form the current +-- position with a Bézier curve that is specified bz the next three +-- |Coordinate| objects (in the usual manner). +-- \item |"closepath"| The line's path should be ``closed'' in the sense +-- that the current subpath that was started with the most recent +-- moveto operation should now form a closed curve. +-- \end{itemize} +-- +-- Instead of a |Coordinate|, a |Path| may also contain a function. In +-- this case, the function, when called, must return the |Coordinate| +-- that is ``meant'' by the position. This allows algorithms to +-- add coordinates to a path that are still not fixed at the moment +-- they are added to the path. + +local Path = {} +Path.__index = Path + + +-- Namespace + +require("pgf.gd.model").Path = Path + + +-- Imports + +local Coordinate = require "pgf.gd.model.Coordinate" +local Bezier = require "pgf.gd.lib.Bezier" + + + + +local function rigid (x) + if type(x) == "function" then + return x() + else + return x + end +end + + + +--- +-- Creates an empty path. +-- +-- @param initial A table containing an array of strings and +-- coordinates that constitute the path. Coordinates may be given as +-- tables or as a pair of numbers. In this case, each pair of numbers +-- is converted into one coordinate. If omitted, a new empty path +-- is created. +-- +-- @return A empty Path +-- +function Path.new(initial) + if initial then + local new = {} + local i = 1 + local count = 0 + while i <= #initial do + local e = initial[i] + if type(e) == "string" then + assert (count == 0, "illformed path") + if e == "moveto" then + count = 1 + elseif e == "lineto" then + count = 1 + elseif e == "closepath" then + count = 0 + elseif e == "curveto" then + count = 3 + else + error ("unknown path command " .. e) + end + new[#new+1] = e + elseif type(e) == "number" then + if count == 0 then + new[#new+1] = "lineto" + else + count = count - 1 + end + new[#new+1] = Coordinate.new(e,initial[i+1]) + i = i + 1 + elseif type(e) == "table" or type(e) == "function" then + if count == 0 then + new[#new+1] = "lineto" + else + count = count - 1 + end + new[#new+1] = e + else + error ("invalid object on path") + end + i = i + 1 + end + return setmetatable(new, Path) + else + return setmetatable({}, Path) + end +end + + +--- +-- Creates a copy of a path. +-- +-- @return A copy of the path + +function Path:clone() + local new = {} + for _,x in ipairs(self) do + if type(x) == "table" then + new[#new+1] = x:clone() + else + new[#new+1] = x + end + end + return setmetatable(new, Path) +end + + + +--- +-- Returns the path in reverse order. +-- +-- @return A copy of the reversed path + +function Path:reversed() + + -- First, build segments + local subpaths = {} + local subpath = {} + + local function closepath () + if subpath.start then + subpaths [#subpaths + 1] = subpath + subpath = {} + end + end + + local prev + local start + + local i = 1 + while i <= #self do + local x = self[i] + if x == "lineto" then + subpath[#subpath+1] = { + action = 'lineto', + from = prev, + to = self[i+1] + } + prev = self[i+1] + i = i + 2 + elseif x == "moveto" then + closepath() + prev = self[i+1] + start = prev + subpath.start = prev + i = i + 2 + elseif x == "closepath" then + subpath [#subpath + 1] = { + action = "closepath", + from = prev, + to = start, + } + prev = nil + start = nil + closepath() + i = i + 1 + elseif x == "curveto" then + local s1, s2, to = self[i+1], self[i+2], self[i+3] + subpath [#subpath + 1] = { + action = "curveto", + from = prev, + to = to, + support_1 = s1, + support_2 = s2, + } + prev = self[i+3] + i = i + 4 + else + error ("illegal path command '" .. x .. "'") + end + end + closepath () + + local new = Path.new () + + for _,subpath in ipairs(subpaths) do + if #subpath == 0 then + -- A subpath that consists only of a moveto: + new:appendMoveto(subpath.start) + else + -- We start with a moveto to the end point: + new:appendMoveto(subpath[#subpath].to) + + -- Now walk backwards: + for i=#subpath,1,-1 do + if subpath[i].action == "lineto" then + new:appendLineto(subpath[i].from) + elseif subpath[i].action == "closepath" then + new:appendLineto(subpath[i].from) + elseif subpath[i].action == "curveto" then + new:appendCurveto(subpath[i].support_2, + subpath[i].support_1, + subpath[i].from) + else + error("illegal path command") + end + end + + -- Append a closepath, if necessary + if subpath[#subpath].action == "closepath" then + new:appendClosepath() + end + end + end + + return new +end + + +--- +-- Transform all points on a path. +-- +-- @param t A transformation, see |pgf.gd.lib.Transform|. It is +-- applied to all |Coordinate| objects on the path. + +function Path:transform(t) + for _,c in ipairs(self) do + if type(c) == "table" then + c:apply(t) + end + end +end + + +--- +-- Shift all points on a path. +-- +-- @param x An $x$-shift +-- @param y A $y$-shift + +function Path:shift(x,y) + for _,c in ipairs(self) do + if type(c) == "table" then + c.x = c.x + x + c.y = c.y + y + end + end +end + + +--- +-- Shift by all points on a path. +-- +-- @param x A coordinate + +function Path:shiftByCoordinate(x) + for _,c in ipairs(self) do + if type(c) == "table" then + c.x = c.x + x.x + c.y = c.y + x.y + end + end +end + + +--- +-- Makes the path empty. +-- + +function Path:clear() + for i=1,#self do + self[i] = nil + end +end + + +--- +-- Appends a |moveto| to the path. +-- +-- @param x A |Coordinate| or |function| or, if the |y| parameter is +-- not |nil|, a number that is the $x$-part of a coordiante . +-- @param y The $y$-part of the coordinate. + +function Path:appendMoveto(x,y) + self[#self + 1] = "moveto" + self[#self + 1] = y and Coordinate.new(x,y) or x +end + + +--- +-- Appends a |lineto| to the path. +-- +-- @param x A |Coordinate| or |function|, if the |y| parameter is not +-- |nil|, a number that is the $x$-part of a coordiante . +-- @param y The $y$-part of the coordinate. + +function Path:appendLineto(x,y) + self[#self + 1] = "lineto" + self[#self + 1] = y and Coordinate.new(x,y) or x +end + + + +--- +-- Appends a |closepath| to the path. + +function Path:appendClosepath() + self[#self + 1] = "closepath" +end + + +--- +-- Appends a |curveto| to the path. There can be either three +-- coordinates (or functions) as parameters (the two support points +-- and the target) or six numbers, where two consecutive numbers form a +-- Coordinate. Which case is meant is detected by the presence of a +-- sixth non-nil parameter. + +function Path:appendCurveto(a,b,c,d,e,f) + self[#self + 1] = "curveto" + if f then + self[#self + 1] = Coordinate.new(a,b) + self[#self + 1] = Coordinate.new(c,d) + self[#self + 1] = Coordinate.new(e,f) + else + self[#self + 1] = a + self[#self + 1] = b + self[#self + 1] = c + end +end + + +--- +-- Makes a path ``rigid,'' meaning that all coordinates that are only +-- given as functions are replaced by the values these functions +-- yield. + +function Path:makeRigid() + for i=1,#self do + self[i] = rigid(self[i]) + end +end + + +--- +-- Returns an array of all coordinates that are present in a +-- path. This means, essentially, that all strings are filtered out. +-- +-- @return An array of all coordinate objects on the path. + +function Path:coordinates() + local cloud = {} + for i=1,#self do + local p = self[i] + if type(p) == "table" then + cloud[#cloud + 1] = p + elseif type(p) == "function" then + cloud[#cloud + 1] = p() + end + end + return cloud +end + + +--- +-- Returns a bounding box of the path. This will not necessarily be +-- the minimal bounding box in case the path contains curves because, +-- then, the support points of the curve are used for the computation +-- rather than the actual boinding box of the path. +-- +-- If the path contains no coordinates, all return values are 0. +-- +-- @return |min_x| The minimum $x$ value of the bounding box of the path +-- @return |min_y| The minimum $y$ value +-- @return |max_x| +-- @return |max_y| +-- @return |center_x| The center of the bounding box +-- @return |center_y| + +function Path:boundingBox() + if #self > 0 then + local min_x, min_y = math.huge, math.huge + local max_x, max_y = -math.huge, -math.huge + + for i=1,#self do + local c = rigid(self[i]) + if type(c) == "table" then + local x = c.x + local y = c.y + if x < min_x then min_x = x end + if y < min_y then min_y = y end + if x > max_x then max_x = x end + if y > max_y then max_y = y end + end + end + + if min_x ~= math.huge then + return min_x, min_y, max_x, max_y, (min_x+max_x) / 2, (min_y+max_y) / 2 + end + end + return 0, 0, 0, 0, 0, 0 +end + + +-- Forwards + +local segmentize, bb, boxes_intersect, intersect_curves + +local eps = 0.0001 + + + +--- +-- Computes all intersections of a path with another path and returns +-- them as an array of coordinates. The intersections will be sorted +-- ``along the path |self|.'' The implementation uses a +-- divide-and-conquer approach that should be reasonably fast in +-- practice. +-- +-- @param path Another path +-- +-- @return Array of all intersections of |path| with |self| in the +-- order they appear on |self|. Each entry of this array is a table +-- with the following fields: +-- \begin{itemize} +-- \item |index| The index of the segment in |self| where +-- the intersection occurs. +-- \item |time| The ``time'' at which a point travelling along the +-- segment from its start point to its end point. +-- \item |point| The point itself. +-- \end{itemize} + +function Path:intersectionsWith(path) + + local p1 = segmentize(self) + local memo1 = prepare_memo(p1) + local p2 = segmentize(path) + local memo2 = prepare_memo(p2) + + local intersections = {} + + local function intersect_segments(i1, i2) + + local s1 = p1[i1] + local s2 = p2[i2] + local r = {} + + if s1.action == 'lineto' and s2.action == 'lineto' then + local a = s2.to.x - s2.from.x + local b = s1.from.x - s1.to.x + local c = s2.from.x - s1.from.x + local d = s2.to.y - s2.from.y + local e = s1.from.y - s1.to.y + local f = s2.from.y - s1.from.y + + local det = a*e - b*d + + if math.abs(det) > eps*eps then + local t, s = (c*d - a*f)/det, (b*f - e*c)/det + + if t >= 0 and t<=1 and s>=0 and s <= 1 then + local p = s1.from:clone() + p:moveTowards(s1.to, t) + return { { time = t, point = p } } + end + end + elseif s1.action == 'lineto' and s2.action == 'curveto' then + intersect_curves (0, 1, + s1.from.x, s1.from.y, + s1.from.x*2/3+s1.to.x*1/3, s1.from.y*2/3+s1.to.y*1/3, + s1.from.x*1/3+s1.to.x*2/3, s1.from.y*1/3+s1.to.y*2/3, + s1.to.x, s1.to.y, + s2.from.x, s2.from.y, + s2.support_1.x, s2.support_1.y, + s2.support_2.x, s2.support_2.y, + s2.to.x, s2.to.y, + r) + elseif s1.action == 'curveto' and s2.action == 'lineto' then + intersect_curves (0, 1, + s1.from.x, s1.from.y, + s1.support_1.x, s1.support_1.y, + s1.support_2.x, s1.support_2.y, + s1.to.x, s1.to.y, + s2.from.x, s2.from.y, + s2.from.x*2/3+s2.to.x*1/3, s2.from.y*2/3+s2.to.y*1/3, + s2.from.x*1/3+s2.to.x*2/3, s2.from.y*1/3+s2.to.y*2/3, + s2.to.x, s2.to.y, + r) + else + intersect_curves (0, 1, + s1.from.x, s1.from.y, + s1.support_1.x, s1.support_1.y, + s1.support_2.x, s1.support_2.y, + s1.to.x, s1.to.y, + s2.from.x, s2.from.y, + s2.support_1.x, s2.support_1.y, + s2.support_2.x, s2.support_2.y, + s2.to.x, s2.to.y, + r) + end + return r + end + + local function intersect (i1, j1, i2, j2) + + local bb1 = bb(i1, j1, memo1) + local bb2 = bb(i2, j2, memo2) + + if boxes_intersect(bb1, bb2) then + -- Ok, need to do something + if i1 == j1 and i2 == j2 then + local intersects = intersect_segments (i1, i2) + for _,t in ipairs(intersects) do + intersections[#intersections+1] = { + time = t.time, + index = p1[i1].path_pos, + point = t.point + } + end + elseif i1 == j1 then + local m2 = math.floor((i2 + j2) / 2) + intersect(i1, j1, i2, m2) + intersect(i1, j1, m2+1, j2) + elseif i2 == j2 then + local m1 = math.floor((i1 + j1) / 2) + intersect(i1, m1, i2, j2) + intersect(m1+1, j1, i2, j2) + else + local m1 = math.floor((i1 + j1) / 2) + local m2 = math.floor((i2 + j2) / 2) + intersect(i1, m1, i2, m2) + intersect(m1+1, j1, i2, m2) + intersect(i1, m1, m2+1, j2) + intersect(m1+1, j1, m2+1, j2) + end + end + end + + -- Run the recursion + intersect(1, #p1, 1, #p2) + + -- Sort + table.sort(intersections, function(a,b) + return a.index < b.index or + a.index == b.index and a.time < b.time + end) + + -- Remove duplicates + local remains = {} + remains[1] = intersections[1] + for i=2,#intersections do + local next = intersections[i] + local prev = remains[#remains] + if math.abs(next.point.x - prev.point.x) + math.abs(next.point.y - prev.point.y) > eps then + remains[#remains+1] = next + end + end + + return remains +end + + +-- Returns true if two bounding boxes intersection + +function boxes_intersect (bb1, bb2) + return (bb1.max_x >= bb2.min_x - eps*eps and + bb1.min_x <= bb2.max_x + eps*eps and + bb1.max_y >= bb2.min_y - eps*eps and + bb1.min_y <= bb2.max_y + eps*eps) +end + + +-- Turns a path into a sequence of segments, each being either a +-- lineto or a curveto from some point to another point. It also sets +-- up a memoization array for the bounding boxes. + +function segmentize (path) + + local prev + local start + local s = {} + + local i = 1 + while i <= #path do + local x = path[i] + + if x == "lineto" then + x = rigid(path[i+1]) + s [#s + 1] = { + path_pos = i, + action = "lineto", + from = prev, + to = x, + bb = { + min_x = math.min(prev.x, x.x), + max_x = math.max(prev.x, x.x), + min_y = math.min(prev.y, x.y), + max_y = math.max(prev.y, x.y), + } + } + prev = x + i = i + 2 + elseif x == "moveto" then + prev = rigid(path[i+1]) + start = prev + i = i + 2 + elseif x == "closepath" then + s [#s + 1] = { + path_pos = i, + action = "lineto", + from = prev, + to = start, + bb = { + min_x = math.min(prev.x, start.x), + max_x = math.max(prev.x, start.x), + min_y = math.min(prev.y, start.y), + max_y = math.max(prev.y, start.y), + } + } + prev = nil + start = nil + i = i + 1 + elseif x == "curveto" then + local s1, s2, to = rigid(path[i+1]), rigid(path[i+2]), rigid(path[i+3]) + s [#s + 1] = { + action = "curveto", + path_pos = i, + from = prev, + to = to, + support_1 = s1, + support_2 = s2, + bb = { + min_x = math.min(prev.x, s1.x, s2.x, to.x), + max_x = math.max(prev.x, s1.x, s2.x, to.x), + min_y = math.min(prev.y, s1.y, s2.y, to.y), + max_y = math.max(prev.y, s1.y, s2.y, to.y), + } + } + prev = path[i+3] + i = i + 4 + else + error ("illegal path command '" .. x .. "'") + end + end + + return s +end + + +function prepare_memo (s) + + local memo = {} + + memo.base = #s + + -- Fill memo table + for i,e in ipairs (s) do + memo[i*#s + i] = e.bb + end + + return memo +end + + +-- This function computes the bounding box of all segments between i +-- and j (inclusively) + +function bb (i, j, memo) + local b = memo[memo.base*i + j] + if not b then + assert (i < j, "memoization table filled incorrectly") + + local mid = math.floor((i+j)/2) + local bb1 = bb (i, mid, memo) + local bb2 = bb (mid+1, j, memo) + b = { + min_x = math.min(bb1.min_x, bb2.min_x), + max_x = math.max(bb1.max_x, bb2.max_x), + min_y = math.min(bb1.min_y, bb2.min_y), + max_y = math.max(bb1.max_y, bb2.max_y) + } + memo[memo.base*i + j] = b + end + + return b +end + + + +-- Intersect two Bezier curves. + +function intersect_curves(t0, t1, + c1_ax, c1_ay, c1_bx, c1_by, + c1_cx, c1_cy, c1_dx, c1_dy, + c2_ax, c2_ay, c2_bx, c2_by, + c2_cx, c2_cy, c2_dx, c2_dy, + intersections) + + -- Only do something, if the bounding boxes intersect: + local c1_min_x = math.min(c1_ax, c1_bx, c1_cx, c1_dx) + local c1_max_x = math.max(c1_ax, c1_bx, c1_cx, c1_dx) + local c1_min_y = math.min(c1_ay, c1_by, c1_cy, c1_dy) + local c1_max_y = math.max(c1_ay, c1_by, c1_cy, c1_dy) + local c2_min_x = math.min(c2_ax, c2_bx, c2_cx, c2_dx) + local c2_max_x = math.max(c2_ax, c2_bx, c2_cx, c2_dx) + local c2_min_y = math.min(c2_ay, c2_by, c2_cy, c2_dy) + local c2_max_y = math.max(c2_ay, c2_by, c2_cy, c2_dy) + + if c1_max_x >= c2_min_x and + c1_min_x <= c2_max_x and + c1_max_y >= c2_min_y and + c1_min_y <= c2_max_y then + + -- Everything "near together"? + if c1_max_x - c1_min_x < eps and c1_max_y - c1_min_y < eps then + + -- Compute intersection of lines c1_a to c1_d and c2_a to c2_d + local a = c2_dx - c2_ax + local b = c1_ax - c1_dx + local c = c2_ax - c1_ax + local d = c2_dy - c2_ay + local e = c1_ay - c1_dy + local f = c2_ay - c1_ay + + local det = a*e - b*d + local t + + t = (c*d - a*f)/det + if t<0 then + t=0 + elseif t>1 then + t=1 + end + + intersections [#intersections + 1] = { + time = t0 + t*(t1-t0), + point = Coordinate.new(c1_ax + t*(c1_dx-c1_ax), c1_ay+t*(c1_dy-c1_ay)) + } + else + -- Cut 'em in half! + local c1_ex, c1_ey = (c1_ax + c1_bx)/2, (c1_ay + c1_by)/2 + local c1_fx, c1_fy = (c1_bx + c1_cx)/2, (c1_by + c1_cy)/2 + local c1_gx, c1_gy = (c1_cx + c1_dx)/2, (c1_cy + c1_dy)/2 + + local c1_hx, c1_hy = (c1_ex + c1_fx)/2, (c1_ey + c1_fy)/2 + local c1_ix, c1_iy = (c1_fx + c1_gx)/2, (c1_fy + c1_gy)/2 + + local c1_jx, c1_jy = (c1_hx + c1_ix)/2, (c1_hy + c1_iy)/2 + + local c2_ex, c2_ey = (c2_ax + c2_bx)/2, (c2_ay + c2_by)/2 + local c2_fx, c2_fy = (c2_bx + c2_cx)/2, (c2_by + c2_cy)/2 + local c2_gx, c2_gy = (c2_cx + c2_dx)/2, (c2_cy + c2_dy)/2 + + local c2_hx, c2_hy = (c2_ex + c2_fx)/2, (c2_ey + c2_fy)/2 + local c2_ix, c2_iy = (c2_fx + c2_gx)/2, (c2_fy + c2_gy)/2 + + local c2_jx, c2_jy = (c2_hx + c2_ix)/2, (c2_hy + c2_iy)/2 + + intersect_curves (t0, (t0+t1)/2, + c1_ax, c1_ay, c1_ex, c1_ey, c1_hx, c1_hy, c1_jx, c1_jy, + c2_ax, c2_ay, c2_ex, c2_ey, c2_hx, c2_hy, c2_jx, c2_jy, + intersections) + intersect_curves (t0, (t0+t1)/2, + c1_ax, c1_ay, c1_ex, c1_ey, c1_hx, c1_hy, c1_jx, c1_jy, + c2_jx, c2_jy, c2_ix, c2_iy, c2_gx, c2_gy, c2_dx, c2_dy, + intersections) + intersect_curves ((t0+t1)/2, t1, + c1_jx, c1_jy, c1_ix, c1_iy, c1_gx, c1_gy, c1_dx, c1_dy, + c2_ax, c2_ay, c2_ex, c2_ey, c2_hx, c2_hy, c2_jx, c2_jy, + intersections) + intersect_curves ((t0+t1)/2, t1, + c1_jx, c1_jy, c1_ix, c1_iy, c1_gx, c1_gy, c1_dx, c1_dy, + c2_jx, c2_jy, c2_ix, c2_iy, c2_gx, c2_gy, c2_dx, c2_dy, + intersections) + end + end +end + + +--- +-- Shorten a path at the beginning. We are given the index of a +-- segment inside the path as well as a point in time along this +-- segment. The path is now shortened so that everything before this +-- segment and everything in the segment before the given time is +-- removed from the path. +-- +-- @param index The index of a path segment. +-- @param time A time along the specified path segment. + +function Path:cutAtBeginning(index, time) + + local cut_path = Path:new () + + -- Ok, first, we need to find the segment *before* the current + -- one. Usually, this will be a moveto or a lineto, but things could + -- be different. + assert (type(self[index-1]) == "table" or type(self[index-1]) == "function", + "segment before intersection does not end with a coordinate") + + local from = rigid(self[index-1]) + local action = self[index] + + -- Now, depending on the type of segment, we do different things: + if action == "lineto" then + + -- Ok, compute point: + local to = rigid(self[index+1]) + + from:moveTowards(to, time) + + -- Ok, this is easy: We start with a fresh moveto ... + cut_path[1] = "moveto" + cut_path[2] = from + + -- ... and copy the rest + for i=index,#self do + cut_path[#cut_path+1] = self[i] + end + elseif action == "curveto" then + + local to = rigid(self[index+3]) + local s1 = rigid(self[index+1]) + local s2 = rigid(self[index+2]) + + -- Now, compute the support vectors and the point at time: + from:moveTowards(s1, time) + s1:moveTowards(s2, time) + s2:moveTowards(to, time) + + from:moveTowards(s1, time) + s1:moveTowards(s2, time) + + from:moveTowards(s1, time) + + -- Ok, this is easy: We start with a fresh moveto ... + cut_path[1] = "moveto" + cut_path[2] = from + cut_path[3] = "curveto" + cut_path[4] = s1 + cut_path[5] = s2 + cut_path[6] = to + + -- ... and copy the rest + for i=index+4,#self do + cut_path[#cut_path+1] = self[i] + end + + elseif action == "closepath" then + -- Let us find the start point: + local found + for i=index,1,-1 do + if self[i] == "moveto" then + -- Bingo: + found = i + break + end + end + + assert(found, "no moveto found in path") + + local to = rigid(self[found+1]) + from:moveTowards(to,time) + + cut_path[1] = "moveto" + cut_path[2] = from + cut_path[3] = "lineto" + cut_path[4] = to + + -- ... and copy the rest + for i=index+1,#self do + cut_path[#cut_path+1] = self[i] + end + else + error ("wrong path operation") + end + + -- Move cut_path back: + for i=1,#cut_path do + self[i] = cut_path[i] + end + for i=#cut_path+1,#self do + self[i] = nil + end +end + + + + +--- +-- Shorten a path at the end. This method works like |cutAtBeginning|, +-- only the path is cut at the end. +-- +-- @param index The index of a path segment. +-- @param time A time along the specified path segment. + +function Path:cutAtEnd(index, time) + + local cut_path = Path:new () + + -- Ok, first, we need to find the segment *before* the current + -- one. Usually, this will be a moveto or a lineto, but things could + -- be different. + assert (type(self[index-1]) == "table" or type(self[index-1]) == "function", + "segment before intersection does not end with a coordinate") + + local from = rigid(self[index-1]) + local action = self[index] + + -- Now, depending on the type of segment, we do different things: + if action == "lineto" then + + -- Ok, compute point: + local to = rigid(self[index+1]) + to:moveTowards(from, 1-time) + + for i=1,index do + cut_path[i] = self[i] + end + cut_path[index+1] = to + + elseif action == "curveto" then + + local s1 = rigid(self[index+1]) + local s2 = rigid(self[index+2]) + local to = rigid(self[index+3]) + + -- Now, compute the support vectors and the point at time: + to:moveTowards(s2, 1-time) + s2:moveTowards(s1, 1-time) + s1:moveTowards(from, 1-time) + + to:moveTowards(s2, 1-time) + s2:moveTowards(s1, 1-time) + + to:moveTowards(s2, 1-time) + + -- ... and copy the rest + for i=1,index do + cut_path[i] = self[i] + end + + cut_path[index+1] = s1 + cut_path[index+2] = s2 + cut_path[index+3] = to + + elseif action == "closepath" then + -- Let us find the start point: + local found + for i=index,1,-1 do + if self[i] == "moveto" then + -- Bingo: + found = i + break + end + end + + assert(found, "no moveto found in path") + + local to = rigid(self[found+1]:clone()) + to:moveTowards(from,1-time) + + for i=1,index-1 do + cut_path[i] = self[i] + end + cut_path[index] = 'lineto' + cut_path[index+1] = to + else + error ("wrong path operation") + end + + -- Move cut_path back: + for i=1,#cut_path do + self[i] = cut_path[i] + end + for i=#cut_path+1,#self do + self[i] = nil + end +end + + + + +--- +-- ``Pads'' the path. The idea is the following: Suppose we stroke the +-- path with a pen whose width is twice the value |padding|. The outer +-- edge of this stroked drawing is now a path by itself. The path will +-- be a bit longer and ``larger.'' The present function tries to +-- compute an approximation to this resulting path. +-- +-- The algorithm used to compute the enlarged part does not necessarily +-- compute the precise new path. It should work correctly for polyline +-- paths, but not for curved paths. +-- +-- @param padding A padding distance. +-- @return The padded path. +-- + +function Path:pad(padding) + + local padded = self:clone() + padded:makeRigid() + + if padding == 0 then + return padded + end + + -- First, decompose the path into subpaths: + local subpaths = {} + local subpath = {} + local start_index = 1 + + local function closepath(end_index) + if #subpath >= 1 then + subpath.start_index = start_index + subpath.end_index = end_index + start_index = end_index + 1 + + local start = 1 + if (subpath[#subpath] - subpath[1]):norm() < 0.01 and subpath[2] then + start = 2 + subpath.skipped = subpath[1] + end + subpath[#subpath + 1] = subpath[start] + subpath[#subpath + 1] = subpath[start+1] + subpaths[#subpaths + 1] = subpath + subpath = {} + end + end + + for i,p in ipairs(padded) do + if p ~= "closepath" then + if type(p) == "table" then + subpath[#subpath + 1] = p + end + else + closepath (i) + end + end + closepath(#padded) + + -- Second, iterate over the subpaths: + for _,subpath in ipairs(subpaths) do + local new_coordinates = {} + local _,_,_,_,c_x,c_y = Coordinate.boundingBox(subpath) + local c = Coordinate.new(c_x,c_y) + + -- Find out the orientation of the path + local count = 0 + for i=1,#subpath-2 do + local d2 = subpath[i+1] - subpath[i] + local d1 = subpath[i+2] - subpath[i+1] + + local diff = math.atan2(d2.y,d2.x) - math.atan2(d1.y,d1.x) + + if diff < -math.pi then + count = count + 1 + elseif diff > math.pi then + count = count - 1 + end + end + + for i=2,#subpath-1 do + local p = subpath[i] + local d1 = subpath[i] - subpath[i-1] + local d2 = subpath[i+1] - subpath[i] + + local orth1 = Coordinate.new(-d1.y, d1.x) + local orth2 = Coordinate.new(-d2.y, d2.x) + + orth1:normalize() + orth2:normalize() + + if count < 0 then + orth1:scale(-1) + orth2:scale(-1) + end + + -- Ok, now we want to compute the intersection of the lines + -- perpendicular to p + padding*orth1 and p + padding*orth2: + + local det = orth1.x * orth2.y - orth1.y * orth2.x + + local c + if math.abs(det) < 0.1 then + c = orth1 + orth2 + c:scale(padding/2) + else + c = Coordinate.new (padding*(orth2.y-orth1.y)/det, padding*(orth1.x-orth2.x)/det) + end + + new_coordinates[i] = c+p + end + + for i=2,#subpath-1 do + local p = subpath[i] + local new_p = new_coordinates[i] + p.x = new_p.x + p.y = new_p.y + end + + if subpath.skipped then + local p = subpath[1] + local new_p = new_coordinates[#subpath-2] + p.x = new_p.x + p.y = new_p.y + end + + -- Now, we need to correct the curveto fields: + for i=subpath.start_index,subpath.end_index do + if self[i] == 'curveto' then + local from = rigid(self[i-1]) + local s1 = rigid(self[i+1]) + local s2 = rigid(self[i+2]) + local to = rigid(self[i+3]) + + local p1x, p1y, _, _, h1x, h1y = + Bezier.atTime(from.x, from.y, s1.x, s1.y, s2.x, s2.y, + to.x, to.y, 1/3) + + local p2x, p2y, _, _, _, _, h2x, h2y = + Bezier.atTime(from.x, from.y, s1.x, s1.y, s2.x, s2.y, + to.x, to.y, 2/3) + + local orth1 = Coordinate.new (p1y - h1y, -(p1x - h1x)) + orth1:normalize() + orth1:scale(-padding) + + local orth2 = Coordinate.new (p2y - h2y, -(p2x - h2x)) + orth2:normalize() + orth2:scale(padding) + + if count < 0 then + orth1:scale(-1) + orth2:scale(-1) + end + + local new_s1, new_s2 = + Bezier.supportsForPointsAtTime(padded[i-1], + Coordinate.new(p1x+orth1.x,p1y+orth1.y), 1/3, + Coordinate.new(p2x+orth2.x,p2y+orth2.y), 2/3, + padded[i+3]) + + padded[i+1] = new_s1 + padded[i+2] = new_s2 + end + end + end + + return padded +end + + + +-- +-- @return The Path as string. +-- +function Path:__tostring() + local r = {} + local i = 1 + while i <= #self do + local p = self[i] + + if p == "lineto" then + r [#r+1] = " -- " .. tostring(rigid(self[i+1])) + i = i + 1 + elseif p == "moveto" then + r [#r+1] = " " .. tostring(rigid(self[i+1]) ) + i = i + 1 + elseif p == "curveto" then + r [#r+1] = " .. controls " .. tostring(rigid(self[i+1])) .. " and " .. + tostring(rigid(self[i+2])) .. " .. " .. tostring(rigid(self[i+3])) + i = i + 3 + elseif p == "closepath" then + r [#r+1] = " -- cycle" + else + error("illegal path command") + end + i = i + 1 + end + return table.concat(r) +end + + + +-- Done + +return Path
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Vertex.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Vertex.lua new file mode 100644 index 00000000000..f18aa43f450 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Vertex.lua @@ -0,0 +1,277 @@ +-- 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/model/Vertex.lua,v 1.6 2013/12/20 14:44:47 tantau Exp $ + + +--- +-- A |Vertex| instance models a node of graphs. Each |Vertex| object can be an +-- element of any number of graphs (whereas an |Arc| object can only be an +-- element of a single graph). +-- +-- When a vertex is added to a digraph |g|, two tables are created in +-- the vertex' storage: An array of incoming arcs (with respect to +-- |g|) and an array of outgoing arcs (again, with respect to +-- |g|). The fields are managed by the |Digraph| class and should not +-- be modified directly. +-- +-- Note that a |Vertex| is an abstraction of \tikzname\ nodes; indeed +-- that objective is to ensure that, in principle, we can use them +-- independently of \TeX. For this reason, you will not find any +-- references to |tex| inside a |Vertex|; this information is only +-- available in the syntactic digraph. +-- +-- One important aspect of vertices are its anchors -- a concept well +-- familiar for users of \tikzname, but since we need to abstract from +-- \tikzname, a separate anchor management is available inside the +-- graph drawing system. It works as follows: +-- +-- First of all, every vertex has a path, which is a (typically +-- closed) line around the vertex. The display system will pass down +-- the vertex' path to the graph drawing system and this path will be +-- stored as a |Path| object in the |path| field of the vertex. This +-- path lives in a special ``local'' coordinate system, that is, all +-- coordinates of this path should actually be considered relative to +-- the vertex' |pos| field. Note that the path is typically, but not +-- alwyas, ``centered'' on the origin. A graph drawing algorithm +-- should arrange the vertices in such a way that the origins in the +-- path coordinate systems are aligned. +-- +-- To illustrate the difference between the origin and the vertex +-- center, conside a tree drawing algorithm in which a node |root| has +-- three children |a|, |b|, and |g|. Now, if we were to simply center +-- these three letters vertically and arrange them in a line, the +-- letters would appear to ``jump up and down'' since the height of +-- the three letters are quite different. A solution is to shift the +-- letters (and, thus, the paths of the vertices) in such a way that +-- in all three letters the baseline of the letters is exactly at the +-- origin. Now, when a graph drawing algorithm aligns these vertices +-- along the origins, the letters will all have the same baseline. +-- +-- Apart from the origin, there may be other positions in the path +-- coordinate system that are of interest -- such as the center of +-- the vertex. As mentioned above, this need not be the origin and +-- although a graph drawing algorithm should align the origins, +-- \emph{edges} between vertices should head toward these vertex +-- centers rather that toward the origins. Other points of interest +-- might be the ``top'' of the node. +-- +-- All points of special interest are called ``anchors''. The |anchor| +-- method allows you to retrieve them. By default, you always have +-- access to the |center| anchor, but other anchors may or may not be +-- available also, see the |anchor| method for details. +-- +-- @field pos A coordinate object that stores the position where the +-- vertex should be placed on the canvas. The main objective of graph drawing +-- algorithms is to update this coordinate. +-- +-- @field name An optional string that is used as a textual representation +-- of the node. +-- +-- @field path The path of the vertex's shape. This is a path along +-- the outer line resulting from stroking the vertex's original +-- shape. For instance, if you have a quadratic shape of size 1cm and +-- you stroke the path with a pen of 2mm thickness, this |path| field +-- would store a path of a square of edge length 12mm. +-- +-- @field anchors A table of anchors (in the TikZ sense). The table is +-- indexed by the anchor names (strings) and the values are +-- |Coordinate|s. Currently, it is only guaranteed that the |center| +-- anchor is present. Note that the |center| anchor need not lie at +-- the origin: A graph drawing system should align nodes relative to +-- the origin of the path's coordinate system. However, lines going to +-- and from the node will head towards the |center| anchor. See +-- Section~\ref{section-gd-anchors} for details. +-- +-- @field options A table of options that contains user-defined options. +-- +-- @field shape A string describing the shape of the node (like |rectangle| +-- or |circle|). Note, however, that this is more ``informative''; the +-- actual information that is used by the graph drawing system for +-- determining the extent of a node, its bounding box, convex hull, +-- and line intersections is the |path| field. +-- +-- @field kind A string describing the kind of the node. For instance, a +-- node of type |"dummy"| does not correspond to any real node in +-- the graph but is used by the graph drawing algorithm. +-- +-- @field event The |Event| when this vertex was created (may be |nil| +-- if the vertex is not part of the syntactic digraph). +-- +local Vertex = {} +Vertex.__index = Vertex + + +-- Namespace + +require("pgf.gd.model").Vertex = Vertex + + +-- Imports + +local Coordinate = require "pgf.gd.model.Coordinate" +local Path = require "pgf.gd.model.Path" +local Storage = require "pgf.gd.lib.Storage" + + +--- +-- Create a new vertex. The |initial| parameter allows you to setup +-- some initial values. +-- +-- @usage +--\begin{codeexample}[code only, tikz syntax=false] +--local v = Vertex.new { name = "hello", pos = Coordinate.new(1,1) } +--\end{codeexample} +-- +-- @param initial Values to override default node settings. The +-- following are permissible: +-- \begin{description} +-- \item[|pos|] Initial position of the node. +-- \item[|name|] The name of the node. It is optional to define this. +-- \item[|path|] A |Path| object representing the vertex's hull. +-- \item[|anchors|] A table of anchors. +-- \item[|options|] An options table for the vertex. +-- \item[|shape|] A string describing the shape. If not given, |"none"| is used. +-- \item[|kind|] A kind like |"node"| or |"dummy"|. If not given, |"dummy"| is used. +-- \end{description} +-- +-- @field incomings A table indexed by |Digraph| objects. For each +-- digraph, the table entry is an array of all vertices from which +-- there is an |Arc| to this vertex. This field is internal and may +-- not only be accessed by the |Digraph| class. +-- @field outgoings Like |incomings|, but for outgoing arcs. +-- +-- @return A newly allocated node. +-- +function Vertex.new(values) + local new = { + incomings = Storage.new(), + outgoings = Storage.new() + } + for k,v in pairs(values) do + new[k] = v + end + new.path = new.path or Path.new { 0, 0 } + new.shape = new.shape or "none" + new.kind = new.kind or "dummy" + new.pos = new.pos or Coordinate.new(0,0) + new.anchors = new.anchors or { center = Coordinate.new(0,0) } + return setmetatable (new, Vertex) +end + + + + +--- +-- Returns a bounding box of a vertex. +-- +-- @return |min_x| The minimum $x$ value of the bounding box of the path +-- @return |min_y| The minimum $y$ value +-- @return |max_x| +-- @return |max_y| +-- @return |center_x| The center of the bounding box +-- @return |center_y| + +function Vertex:boundingBox() + return self.path:boundingBox() +end + + + +local anchor_cache = Storage.new () + +local directions = { + north = function(min_x, min_y, max_x, max_y) + return (min_x+max_x)/2, max_y + end, + south = function(min_x, min_y, max_x, max_y) + return (min_x+max_x)/2, min_y + end, + east = function(min_x, min_y, max_x, max_y) + return max_x, (min_y+max_y)/2 + end, + west = function(min_x, min_y, max_x, max_y) + return min_x, (min_y+max_y)/2 + end, + ["north west"] = function(min_x, min_y, max_x, max_y) + return min_x, max_y + end, + ["north east"] = function(min_x, min_y, max_x, max_y) + return max_x, max_y + end, + ["south west"] = function(min_x, min_y, max_x, max_y) + return min_x, min_y + end, + ["south east"] = function(min_x, min_y, max_x, max_y) + return max_x, min_y + end, +} + +--- +-- Returns an anchor position in a vertex. First, we try to look +-- the anchor up in the vertex's |anchors| table. If it is not found +-- there, we test whether it is one of the direction strings |north|, +-- |south east|, and so on. If so, we consider a line from the center +-- of the node to the position on the bounding box that corresponds to +-- the given direction (so |south east| would be the lower right +-- corner). We intersect this line with the vertex's path and return +-- the result. Finally, if the above fails, we try to consider the +-- anchor as a number and return the intersection of a line starting +-- at the vertex's center with the number as its angle and the path of +-- the vertex. +-- +-- @param anchor An anchor as detailed above +-- @return A coordinate in the vertex's local coordinate system (so +-- add the |pos| field to arrive at the actual position). If the +-- anchor was not found, |nil| is returned + +function Vertex:anchor(anchor) + local c = self.anchors[anchor] + if not c then + local b + local d = directions [anchor] + if d then + b = Coordinate.new(d(self:boundingBox())) + else + local n = tonumber(anchor) + if n then + local x1, y1, x2, y2 = self:boundingBox() + local r = math.max(x2-x1, y2-y1) + b = Coordinate.new(r*math.cos(n/180*math.pi),r*math.sin(n/180*math.pi)) + b:shiftByCoordinate(self.anchors.center) + end + end + if not b then + return + end + local p = Path.new {'moveto', self.anchors.center, 'lineto', b} + local intersections = p:intersectionsWith(self.path) + if #intersections > 0 then + c = intersections[1].point + end + end + self.anchors[anchor] = c + return c +end + + + +-- +-- Returns a string representation of a vertex. This is mainly for debugging +-- +-- @return The Arc as string. +-- +function Vertex:__tostring() + return self.name or tostring(self.anchors) +end + + +-- Done + +return Vertex
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/library.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/library.lua new file mode 100644 index 00000000000..3bc491ec093 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/library.lua @@ -0,0 +1,15 @@ +-- 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/model/library.lua,v 1.2 2013/04/04 20:43:45 tantau Exp $ + + + +-- Load declarations from: +require "pgf.gd.model.Hyperedge" diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/ogdf.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/ogdf.lua new file mode 100644 index 00000000000..aad6eb0a440 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/ogdf.lua @@ -0,0 +1,26 @@ +-- 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/ogdf.lua,v 1.1 2012/12/17 23:53:11 tantau Exp $ + + + +-- Imports + +require "pgf" +require "pgf.gd" + + +-- Declare namespace +pgf.gd.ogdf = {} + + +-- Done + +return pgf.gd.ogdf
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/ogdf/library.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/ogdf/library.lua new file mode 100644 index 00000000000..a06c732ed1d --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/ogdf/library.lua @@ -0,0 +1,33 @@ +-- 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/ogdf/library.lua,v 1.12 2013/10/09 19:47:00 tantau Exp $ + + +--- +-- The Open Graph Drawing Framework (\textsc{ogdf}) is a large, +-- powerful graph drawing system written in C++. This library enables +-- its use inside \tikzname's graph drawing system by translating +-- back-and-forth between Lua and C++. +-- +-- Since C++ code is compiled and not interpreted (like Lua), in order +-- to use the present library, you need a compiled version of the +-- \pgfname\ interface code for the \textsc{ogdf} library +-- (|pgf/gd/ogdf/c/ogdf_script.so|) installed correctly for your particular +-- architecture. This is by no means trivial\dots +-- +-- @library + +local ogdf + + +-- Load the C++ code: + +require "pgf_gd_ogdf_c_ogdf_script" + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics.lua new file mode 100644 index 00000000000..75a78f4f478 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics.lua @@ -0,0 +1,21 @@ +-- 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/phylogenetics.lua,v 1.1 2013/02/08 17:14:04 tantau Exp $ + + +local phylogenetics = {} + +-- Declare namespace +require("pgf.gd").phylogenetics = tree + + +-- Done + +return phylogenetics
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/AuthorDefinedPhylogeny.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/AuthorDefinedPhylogeny.lua new file mode 100644 index 00000000000..dc5dea45b0f --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/AuthorDefinedPhylogeny.lua @@ -0,0 +1,77 @@ +-- Copyright 2013 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/phylogenetics/AuthorDefinedPhylogeny.lua,v 1.2 2013/03/20 17:16:38 tantau Exp $ + + + + +local AuthorDefinedPhylogeny = {} + + +-- Namespace +require("pgf.gd.phylogenetics").AuthorDefinedPhylogeny = AuthorDefinedPhylogeny + +-- Imports +local InterfaceToAlgorithms = require "pgf.gd.interface.InterfaceToAlgorithms" +local Direct = require "pgf.gd.lib.Direct" + +-- Shorthand: +local declare = InterfaceToAlgorithms.declare + + +--- +declare { + key = "phylogenetic tree by author", + algorithm = AuthorDefinedPhylogeny, + phase = "phylogenetic tree generation", + phase_default = true, + + summary = [[" + When this key is used, the phylogenetic tree must be specified + by the author (rather than being generated algorithmically). + "]], + documentation = [[" + A spanning tree of the input graph will be computed first (it + must be connected, otherwise errors will result). + The evolutionary length of the edges must be specified through + the use of the |length| key for each edge. + "]], + examples = [[" + \tikz \graph [phylogenetic tree layout] { + a -- { + b [>length=2] --[length=1] { c, d }, + e [>length=3] + } + }; + "]] +} + + + +function AuthorDefinedPhylogeny:run() + + local spanning_tree = self.main_algorithm.digraph.options.algorithm_phases["spanning tree computation"].new { + ugraph = self.main_algorithm.ugraph, + events = {} -- no events + }:run() + + local phylogenetic_tree = Direct.ugraphFromDigraph(spanning_tree) + local lengths = self.lengths + + for _,a in ipairs(phylogenetic_tree.arcs) do + lengths[a.tail][a.head] = a:options('length') + end + + return phylogenetic_tree +end + + + +return AuthorDefinedPhylogeny diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/BalancedMinimumEvolution.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/BalancedMinimumEvolution.lua new file mode 100644 index 00000000000..fd0fb62b3ad --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/BalancedMinimumEvolution.lua @@ -0,0 +1,593 @@ +-- Copyright 2013 by Sarah Mäusle and 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/phylogenetics/BalancedMinimumEvolution.lua,v 1.1 2013/02/08 17:14:05 tantau Exp $ + + + +local BalancedMinimumEvolution = {} + + +-- Namespace +require("pgf.gd.phylogenetics").BalancedMinimumEvolution = BalancedMinimumEvolution + +-- Imports +local InterfaceToAlgorithms = require("pgf.gd.interface.InterfaceToAlgorithms") +local DistanceMatrix = require("pgf.gd.phylogenetics.DistanceMatrix") +local Storage = require("pgf.gd.lib.Storage") +local Digraph = require("pgf.gd.model.Digraph") +local lib = require("pgf.gd.lib") + +-- Shorthand: +local declare = InterfaceToAlgorithms.declare + + +--- +declare { + key = "balanced minimum evolution", + algorithm = BalancedMinimumEvolution, + phase = "phylogenetic tree generation", + + summary = [[" + The BME (Balanced Minimum Evolution) algorithm tries to minimize + the total tree length. + "]], + documentation = [[" + This algorithm is from Desper and Gascuel, \emph{Fast and + Accurate Phylogeny Reconstruction Algorithms Based on the + Minimum-Evolution Principle}, 2002. The tree is built in a way + that minimizes the total tree length. The leaves are inserted + into the tree one after another, creating new edges and new + nodes. After every insertion the distance matrix has to be + updated. + "]], + examples = [[" + \tikz \graph [phylogenetic tree layout, + balanced minimum evolution, + grow'=right, sibling distance=0pt, + distance matrix={ + 0 4 9 9 9 9 9 + 4 0 9 9 9 9 9 + 9 9 0 2 7 7 7 + 9 9 2 0 7 7 7 + 9 9 7 7 0 3 5 + 9 9 7 7 3 0 5 + 9 9 7 7 5 5 0}] + { a, b, c, d, e, f, g }; + "]] +} + + + + +function BalancedMinimumEvolution:run() + + self.tree = Digraph.new(self.main_algorithm.digraph) + + self.distances = Storage.newTableStorage() + + local vertices = self.tree.vertices + + -- Sanity checks: + if #vertices == 2 then + self.tree:connect(vertices[1],vertices[2]) + return self.tree + elseif #vertices > 2 then + + -- Setup storages: + self.is_leaf = Storage.new() + + -- First, build the initial distance matrix: + local matrix = DistanceMatrix.graphDistanceMatrix(self.tree) + + -- Store distance information in the distance fields of the storages: + for _,u in ipairs(vertices) do + for _,v in ipairs(vertices) do + self.distances[u][v] = matrix[u][v] + end + end + + -- Run BME + self:runBME() + + -- Run postoptimizations + local optimization_class = self.tree.options.algorithm_phases['phylogenetic tree optimization'] + optimization_class.new { + main_algorithm = self.main_algorithm, + tree = self.tree, + matrix = self.matrix, + distances = self.distances, + is_leaf = self.is_leaf, + }:run() + end + + -- Finish + self:computeFinalLengths() + self:createFinalEdges() + + return self.tree +end + + + + +-- the BME (Balanced Minimum Evolution) algorithm +-- [DESPER and GASCUEL: Fast and Accurate Phylogeny Reconstruction +-- Algorithms Based on the Minimum-Evolution Principle, 2002] +-- +-- The tree is built in a way that minimizes the total tree length. +-- The leaves are inserted into the tree one after another, creating new edges and new nodes. +-- After every insertion the distance matrix has to be updated. +function BalancedMinimumEvolution:runBME() + local g = self.tree + local leaves = {} + local is_leaf = self.is_leaf + local distances = self.distances + + -- get user input + for i, vertex in ipairs (g.vertices) do + leaves[i] = vertex + is_leaf[vertex] = true + end + + -- create the new node which will be connected to the first three leaves + local new_node = InterfaceToAlgorithms.createVertex( + self.main_algorithm, + { + name = "BMEnode"..#g.vertices+1, + generated_options = { { key = "phylogenetic inner node" } } + } + ) + g:add {new_node} + -- set the distances of new_node to subtrees + local distance_1_2 = self:distance(leaves[1],leaves[2]) + local distance_1_3 = self:distance(leaves[1],leaves[3]) + local distance_2_3 = self:distance(leaves[2],leaves[3]) + distances[new_node][leaves[1]] = 0.5*(distance_1_2 + distance_1_3) + distances[new_node][leaves[2]] = 0.5*(distance_1_2 + distance_2_3) + distances[new_node][leaves[3]] = 0.5*(distance_1_3 + distance_2_3) + + --connect the first three leaves to the new node + for i = 1,3 do + g:connect(new_node, leaves[i]) + g:connect(leaves[i], new_node) + end + + for k = 4,#leaves do + -- compute distance from k to any subtree + local k_dists = Storage.newTableStorage() + for i = 1,k-1 do + -- note that the function called stores the k_dists before they are overwritten + self:computeAverageDistancesToAllSubtreesForK(g.vertices[i], { }, k,k_dists) + end + + -- find the best insertion point + local best_arc = self:findBestEdge(g.vertices[1],nil,k_dists) + local head = best_arc.head + local tail = best_arc.tail + + -- remove the old arc + g:disconnect(tail, head) + g:disconnect(head, tail) + + -- create the new node + local new_node = InterfaceToAlgorithms.createVertex( + self.main_algorithm, + { + name = "BMEnode"..#g.vertices+1, + generated_options = { + { key = "phylogenetic inner node" } + } + } + ) + g:add{new_node} + + -- gather the vertices that will be connected to the new node... + local vertices_to_connect = { head, tail, leaves[k] } + + -- ...and connect them + for _, vertex in pairs (vertices_to_connect) do + g:connect(new_node, vertex) + g:connect(vertex, new_node) + end + + if not is_leaf[tail] then + distances[leaves[k]][tail] = k_dists[head][tail] + end + if not is_leaf[head] then + distances[leaves[k]][head] = k_dists[tail][head] + end + -- insert distances from k to subtrees into actual matrix... + self:setAccurateDistancesForK(new_node,nil,k,k_dists,leaves) + + -- set the distance from k to the new node, which was created by inserting k into the graph + distances[leaves[k]][new_node] = 0.5*( self:distance(leaves[k], head) + self:distance(leaves[k],tail)) + + -- update the average distances + local values = {} + values.s = head -- s--u is the arc into which k has been inserted + values.u = tail + values.new_node = new_node -- the new node created by inserting k + self:updateAverageDistances(new_node, values,k,leaves) + end +end + +-- +-- Updates the average distances from k to all subtrees +-- +-- @param vertex The starting point of the recursion +-- @param values The values needed for the recursion +-- - s, u The nodes which span the edge into which k has been +-- inserted +-- - new_node The new_node which has been created to insert k +-- - l (l-1) is the number of edges between the +-- new_node and the current subtree Y +-- +-- values.new_node, values.u and values.s must be set +-- the depth first search must begin at the new node, thus vertex +-- must be set to the newly created node +function BalancedMinimumEvolution:updateAverageDistances(vertex, values, k, leaves) + local g = self.tree + local leaf_k = leaves[k] + local y, z, x + if not values.visited then + values.visited = {} + values.visited[leaf_k] = leaf_k -- we don't want to visit k! + end + -- there are (l-1) edges between new_node and y + if not values.l then values.l = 1 end + if not values.new_node then values.new_node = g:outgoing(leaf_k)[1].head end + --values.s and values.u must be set + + -- the two nodes which connect the edge on which k was inserted: s,u + + local new_node = values.new_node + local l = values.l + local visited = values.visited + + visited[vertex] = vertex + + -- computes the distances to Y{k} for all subtrees X of Z + function loop_over_x( x, y, values ) + local l = values.l + local y1= values.y1 + + -- calculate distance between Y{k} and X + local old_distance -- the distance between Y{/k} and X needed for calculating the new distance + if y == new_node then -- this y didn't exist in the former tree; so use y1 (see below) + old_distance = self:distance(x,y1) + else + old_distance = self:distance(x,y) + end + + local new_distance = old_distance + math.pow(2,-l) * ( self:distance(leaf_k,x) - self:distance(x,y1) ) + self.distances[x][y] = new_distance + self.distances[y][x] = new_distance -- symmetric matrix + + values.x_visited[x] = x + --go deeper to next x + for _, x_arc in ipairs (self.tree:outgoing(x)) do + if not values.x_visited[x_arc.head] then + local new_x = x_arc.head + loop_over_x( new_x, y, values ) + end + end + end + + --loop over Z's + for _, arc in ipairs (self.tree:outgoing(vertex)) do + if not visited[arc.head] then + -- set y1, which is the node which was pushed further away from + -- subtree Z by inserting k + if arc.head == values.s then + values.y1 = values.u + elseif arc.head == values.u then + values.y1 = values.s + else + assert(values.y1,"no y1 set!") + end + + z = arc.head -- root of the subtree we're looking at + y = arc.tail -- the root of the subtree-complement of Z + + x = z -- the first subtree of Z is Z itself + values.x_visited = {} + values.x_visited[y] = y -- we don't want to go there, as we want to stay within Z + loop_over_x( z,y, values ) -- visit all possible subtrees of Z + + -- go to next Z + values.l = values.l+1 -- moving further away from the new_node + self:updateAverageDistances(z,values,k,leaves) + values.l = values.l-1 -- moving back to the new_node + end + end +end + + +-- +-- Computes the average distances of a node, which does not yet belong +-- to the graph, to all subtrees. This is done using a depth first +-- search +-- +-- @param vertex The starting point of the depth first search +-- @param values The values for the recursion +-- - distances The table in which the distances are to be +-- stored +-- - outgoing_arcs The table containing the outgoing arcs +-- of the current vertex +-- +-- @return The average distance of the new node #k to any subtree +-- The distances are stored as follows: +-- example: distances[center][a] +-- center is any vertex, thus if center is an inner vertex +-- it has 3 neighbours a,b and c, which can all be seen as the +-- roots of subtrees A,B,C. +-- distances[center][a] gives us the distance of the new +-- node k to the subtree A. +-- if center is a leaf, it has only one neighbour, which +-- can also be seen as the root of the subtree T\{center} +-- +function BalancedMinimumEvolution:computeAverageDistancesToAllSubtreesForK(vertex, values, k, k_dists) + local is_leaf = self.is_leaf + local arcs = self.tree.arcs + local vertices = self.tree.vertices + local center_vertex = vertex + -- for every vertex a table is created, in which the distances to all + -- its subtrees will be stored + + values.outgoing_arcs = values.outgoing_arcs or self.tree:outgoing(center_vertex) + for _, arc in ipairs (values.outgoing_arcs) do + local root = arc.head -- this vertex can be seen as the root of a subtree + if is_leaf[root] then -- we know the distance of k to the leaf! + k_dists[center_vertex][root] = self:distance(vertices[k], root) + else -- to compute the distance we need the root's neighbouring vertices, which we can access by its outgoing arcs + local arc1, arc2 + local arc_back -- the arc we came from + for _, next_arc in ipairs (self.tree:outgoing(root)) do + if next_arc.head ~= center_vertex then + arc1 = arc1 or next_arc + arc2 = next_arc + else + arc_back = next_arc + end + end + + values.outgoing_arcs = { arc1, arc2, arc_back } + + -- go deeper, if the distances for the next center node haven't been set yet + if not (k_dists[root][arc1.head] and k_dists[root][arc2.head]) then + self:computeAverageDistancesToAllSubtreesForK(root, values, k,k_dists) + end + + -- set the distance between k and subtree + k_dists[center_vertex][root] = 1/2 * (k_dists[root][arc1.head] + k_dists[root][arc2.head]) + end + end +end + + +-- +-- Sets the distances from k to subtrees +-- In computeAverageDistancesToAllSubtreesForK the distances to ALL possbile +-- subtrees are computed. Once k is inserted many of those subtrees don't +-- exist for k, as k is now part of them. In this function all +-- still accurate subtrees and their distances to k are +-- extracted. +-- +-- @param center The vertex serving as the starting point of the depth-first search; +-- should be the new_node + +function BalancedMinimumEvolution:setAccurateDistancesForK(center,visited,k,k_dists,leaves) + local visited = visited or {} + local distances = self.distances + + visited[center] = center + local outgoings = self.tree:outgoing(center) + for _,arc in ipairs (outgoings) do + local vertex = arc.head + if vertex ~= leaves[k] then + local distance + -- set the distance + if not distances[leaves[k]][vertex] and k_dists[center] then + distance = k_dists[center][vertex] -- use previously calculated distance + distances[leaves[k]][vertex] = distance + distances[vertex][leaves[k]] = distance + end + -- go deeper + if not visited[vertex] then + self:setAccurateDistancesForK(vertex,visited,k,k_dists,leaves) + end + end + end +end + + +-- +-- Find the best edge for the insertion of leaf #k, such that the +-- total tree length is minimized. This function uses a depth first +-- search. +-- +-- @param vertex The vertex where the depth first search is +-- started; must be a leaf +-- @param values The values needed for the recursion +-- - visited: The vertices that already have been visited +-- - tree_length: The current tree_length +-- - best_arc: The current best_arc, such that the tree +-- length is minimzed +-- - min_length: The smallest tree_length found so far +function BalancedMinimumEvolution:findBestEdge(vertex, values, k_dists) + local arcs = self.tree.arcs + local vertices = self.tree.vertices + values = values or { visited = {} } + values.visited[vertex] = vertex + + local c -- the arc we came from + local unvisited_arcs = {} --unvisited arcs + --identify arcs + for _, arc in ipairs (self.tree:outgoing(vertex)) do + if not values.visited[arc.head] then + unvisited_arcs[#unvisited_arcs+1] = arc + else + c = arc.head --last visited arc + end + end + + for i, arc in ipairs (unvisited_arcs) do + local change_in_tree_length = 0 + -- set tree length to 0 for first insertion arc + if not values.tree_length then + values.tree_length = 0 + values.best_arc = arc + values.min_length = 0 + else -- compute new tree length for the case that k is inserted into this arc + local b = arc.head --current arc + local a = unvisited_arcs[i%2+1].head -- the remaining arc + local k_v = vertices[k] -- the leaf to be inserted + change_in_tree_length = 1/4 * ( ( self:distance(a,c) + + k_dists[vertex][b]) + - (self:distance(a,b) + + k_dists[vertex][c]) ) + values.tree_length = values.tree_length + change_in_tree_length + end + -- if the tree length becomes shorter, this is the new best arc + -- for the insertion of leaf k + if values.tree_length < values.min_length then + values.best_arc = arc + values.min_length = values.tree_length + end + + -- go deeper + self:findBestEdge(arc.head, values, k_dists) + + values.tree_length = values.tree_length - change_in_tree_length + end + return values.best_arc +end + +-- Calculates the total tree length +-- This is done by adding up all the edge lengths +-- +-- @return the tree length +function BalancedMinimumEvolution:calculateTreeLength() + local vertices = self.tree.vertices + local sum = 0 + + for index, v1 in ipairs(vertices) do + for i = index+1,#vertices do + local v2 = vertices[i] + local dist = self.lengths[v1][v2] + if dist then + sum = sum + dist + end + end + end + return sum +end + +-- generates edges for the final graph +-- +-- throughout the process of creating the tree, arcs have been +-- disconnected and connected, without truly creating edges. this is +-- done in this function +function BalancedMinimumEvolution:createFinalEdges() + local g = self.tree + local o_arcs = {} -- copy arcs since createEdge is going to modify the arcs array... + for _,arc in ipairs(g.arcs) do + if arc.tail.event.index < arc.head.event.index then + o_arcs[#o_arcs+1] = arc + end + end + for _,arc in ipairs(o_arcs) do + InterfaceToAlgorithms.createEdge( + self.main_algorithm, arc.tail, arc.head, + { generated_options = { + { key = "phylogenetic edge", value = tostring(self.lengths[arc.tail][arc.head]) } + }}) + end +end + + +-- Gets the distance between two nodes as specified in their options +-- or storage fields. +-- Note: this function implies that the distance from a to b is the +-- same as the distance from b to a. +-- +-- @param a,b The nodes +-- @return The distance between the two nodes + +function BalancedMinimumEvolution:distance(a, b) + if a == b then + return 0 + else + local distances = self.distances + return distances[a][b] or distances[b][a] + end +end + + +-- +-- computes the final branch lengths +-- +-- goes over all arcs and computes the final branch lengths, +-- as neither the BME nor the BNNI main_algorithm does so. +function BalancedMinimumEvolution:computeFinalLengths() + local is_leaf = self.is_leaf + local lengths = self.lengths + local g = self.tree + for _, arc in ipairs(g.arcs) do + local head = arc.head + local tail = arc.tail + local distance + local a,b,c,d + -- assert, that the length hasn't already been computed for this arc + if not lengths[head][tail] then + if not is_leaf[head] then + -- define subtrees a and b + for _, arc in ipairs (g:outgoing(head)) do + local subtree = arc.head + if subtree ~= tail then + a = a or subtree + b = subtree + end + end + end + if not is_leaf[tail] then + -- define subtrees c and d + for _, arc in ipairs (g:outgoing(tail)) do + local subtree = arc.head + if subtree ~= head then + c = c or subtree + d = subtree + end + end + end + -- compute the distance using the formula for outer or inner edges, respectively + if is_leaf[head] then + distance = 1/2 * ( self:distance(head,c) + + self:distance(head,d) + - self:distance(c,d) ) + elseif is_leaf[tail] then + distance = 1/2 * ( self:distance(tail,a) + + self:distance(tail,b) + - self:distance(a,b) ) + else --inner edge + distance = self:distance(head, tail) + -1/2 * ( self:distance(a,b) + + self:distance(c,d) ) + end + lengths[head][tail] = distance + lengths[tail][head] = distance + end + end + +end + + + +return BalancedMinimumEvolution diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/BalancedNearestNeighbourInterchange.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/BalancedNearestNeighbourInterchange.lua new file mode 100644 index 00000000000..a4fbc0cc3b9 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/BalancedNearestNeighbourInterchange.lua @@ -0,0 +1,372 @@ +-- Copyright 2013 by Sarah Mäusle and 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/phylogenetics/BalancedNearestNeighbourInterchange.lua,v 1.2 2013/03/20 17:16:38 tantau Exp $ + + + +local BalancedNearestNeighbourInterchange = {} + + +-- Namespace +require("pgf.gd.phylogenetics").BalancedNearestNeighbourInterchange = BalancedNearestNeighbourInterchange + +-- Imports +local InterfaceToAlgorithms = require("pgf.gd.interface.InterfaceToAlgorithms") +local DistanceMatrix = require("pgf.gd.phylogenetics.DistanceMatrix") +local lib = require("pgf.gd.lib") + +-- Shorthand: +local declare = InterfaceToAlgorithms.declare + + +--- +declare { + key = "balanced nearest neighbour interchange", + algorithm = BalancedNearestNeighbourInterchange, + phase = "phylogenetic tree optimization", + phase_default = true, + + summary = [[" + The BNNI (Balanced Nearest Neighbour Interchange) is a + postprocessing algorithm for phylogenetic trees. It swaps two + distant 3-subtrees if the total tree length is reduced by doing + so, until no such swaps are left. + "]], + documentation = [[" + This algorithm is from Desper and Gascuel, \emph{Fast and + Accurate Phylogeny Reconstruction Algorithms Based on the + Minimum-Evolution Principle}, 2002. + "]] +} + + +--- +declare { + key = "no phylogenetic tree optimization", + algorithm = { run = function(self) end }, + phase = "phylogenetic tree optimization", + + summary = [[" + Switches off any phylogenetic tree optimization. + "]], +} + + + +-- creates a binary heap, implementation as an array as described in +-- the respective wikipedia article +local function new_heap() + local heap = {} + + function heap:insert(element, value) + local object = { element = element, value = value } + heap[#heap+1]= object + + local i = #heap + local parent = math.floor(i/2) + + -- sort the new object into its correct place + while heap[parent] and heap[parent].value < heap[i].value do + heap[i] = heap[parent] + heap[parent] = object + i = parent + parent = math.floor(i/2) + end + end + + -- deletes the top element from the heap + function heap:remove_top_element() + -- replace first element with last and delete the last element + local element = heap[1].element + heap[1] = heap[#heap] + heap[#heap] = nil + + local i = 1 + local left_child = 2*i + local right_child = 2*i +1 + + -- sort the new top element into its correct place by swapping it + -- against its largest child + while heap[left_child] do + local largest_child = left_child + if heap[right_child] and heap[left_child].value < heap[right_child].value then + largest_child = right_child + end + + if heap[largest_child].value > heap[i].value then + heap[largest_child], heap[i] = heap[i], heap[largest_child] + i = largest_child + left_child = 2*i + right_child = 2*i +1 + else + return element + end + end + return element + end + + return heap +end + + +-- BNNI (Balanced Nearest Neighbour Interchange) +-- [DESPER and GASCUEL: Fast and Accurate Phylogeny Reconstruction Algorithms Based on the Minimum-Evolution Principle, 2002] +-- swaps two distant-3 subtrees if the total tree length is reduced by doing so, until no such swaps are left +-- +-- step 1: precomputation of all average distances between non-intersecting subtrees (already done by BME) +-- step 2: create heap of possible swaps +-- step 3: ( current tree with subtrees a,b,c,d: a--v-- {b, w -- {c, d}} ) +-- (a): edge (v,w) is the best swap on the heap. Remove (v,c) and (w,b) +-- (b), (c), (d) : update the distance matrix +-- (e): remove the edge (v,w) from the heap; check the four edges adjacent to it for new possible swaps +-- (d): if the heap is non-empty, return to (a) + +function BalancedNearestNeighbourInterchange:run() + local g = self.tree + -- create a heap of possible swaps + local possible_swaps = new_heap() + -- go over all arcs, look for possible swaps and add them to the heap [step 2] + for _, arc in ipairs (g.arcs) do + self:getBestSwap(arc, possible_swaps) + end + + -- achieve best swap and update the distance matrix, until there is + -- no more swap to perform + + while #possible_swaps > 0 do + -- get the best swap and delete it from the heap + local swap = possible_swaps:remove_top_element() --[part of step 3 (a)] + + -- Check if the indicated swap is still possible. Another swap may + -- have interfered. + if g:arc(swap.v, swap.subtree1) and g:arc(swap.w, swap.subtree2) and g:arc(swap.v, swap.w) and g:arc(swap.a, swap.v) and g:arc(swap.d, swap.w) then + -- insert new arcs and delete the old ones to perform the swap [part of step 3 (a)] + + -- disconnect old arcs + g:disconnect(swap.v, swap.subtree1) + g:disconnect(swap.subtree1, swap.v) + g:disconnect(swap.w, swap.subtree2) + g:disconnect(swap.subtree2, swap.w) + + -- connect new arcs + g:connect(swap.v, swap.subtree2) + g:connect(swap.subtree2, swap.v) + g:connect(swap.w, swap.subtree1) + g:connect(swap.subtree1, swap.w) + + --update distance matrix + self:updateBNNI(swap) + + -- update heap: check neighbouring arcs for new possible swaps + -- [step 3 (e)] + self:getBestSwap(g:arc(swap.a,swap.v), possible_swaps) + self:getBestSwap(g:arc(swap.subtree2, swap.v), possible_swaps) + self:getBestSwap(g:arc(swap.d,swap.w), possible_swaps) + self:getBestSwap(g:arc(swap.subtree1, swap.w), possible_swaps) + end + end + +end + + +-- +-- Gets the distance between two nodes as specified in the distances +-- fields. Note: this function assumes that the distance from a to b +-- is the +-- same as the distance from b to a. +-- +-- @param a,b The nodes +-- @return The distance between the two nodes +function BalancedNearestNeighbourInterchange:distance(a, b) + if a == b then + return 0 + else + local distances = self.distances + return distances[a][b] or distances[b][a] + end +end + +-- updates the distance matrix after a swap has been performed [step3(b),(c),(d)] +-- +-- @param swap A table containing the information on the performed swap +-- subtree1, subtree2: the two subtrees, which +-- were swapped +-- a, d: The other two subtrees bordering the +-- swapping edge +-- v, w : the two nodes connecting the swapping edge + +function BalancedNearestNeighbourInterchange:updateBNNI(swap) + local g = self.tree + local b = swap.subtree1 + local c = swap.subtree2 + local a = swap.a + local d = swap.d + local v = swap.v + local w = swap.w + local distances = self.distances + + -- updates the distances in one of the four subtrees adjacent to the + -- swapping edge + function update_BNNI_subtree(swap, values) + local g = self.tree + local b = swap.farther + local c = swap.nearer + local a = swap.subtree + local v = swap.v + local d = swap.same + local w = swap.w + + if not values then + values = { + visited = {[v] = v}, + possible_ys = {v}, + x = a, + y = v + } + -- if we're looking at subtrees in one of the swapped subtrees, + -- then need the old root (w) for the calculations + if swap.swapped_branch then values.possible_ys = {w} end + end + local visited = values.visited + local x = values.x + local y = values.y + local ys = values.possible_ys + local l = 0 -- number of edges between y and v + + local dist_x_b = self:distance(x,b) + local dist_x_c = self:distance(x,c) + visited[x] = x --mark current x as visited + + -- loop over possible y's: + for _, y in ipairs (ys) do + -- update distance [step 3(b)] + local distance = self:distance(x,y) - 2^(-l-2)*dist_x_b + 2^(-l-2)*dist_x_c + + if y == w then y = v end -- the old distance w,x was used for the new distance calculation, but it needs to be + -- saved under its appropriate new name according to its new root. this case only arises when looking at x's + -- in one of the swapped subtrees (b or c) + + distances[x][y] = distance + distances[y][x] = distance + l = l+1 -- length + 1, as the next y will be further away from v + end + + -- update the distance between x and w (root of subtree c and d) + -- [step 3(c)] + local distance = 1/2 * (self:distance(x,b) + self:distance(x,d)) + distances[x][w] = distance + distances[w][x] = distance + + -- go to next possible x's + table.insert(ys, x) -- when we're at the next possible x, y can also be the current x + for _,arc in ipairs (g:outgoing(x)) do + if not visited[arc.head] then + values.x = arc.head + --go deeper + update_BNNI_subtree(swap, values) + end + end + end + + -- name the nodes/subtrees in a general way that allows the use of the function update_BNNI_subtree + local update_a = {subtree = a, farther = b, nearer = c, v = v, same = d, w = w} + local update_b = {subtree = b, farther = a, nearer = d, v = w, same = c, w = v, swapped_branch = true} + local update_c = {subtree = c, farther = d, nearer = a, v = v, same = b, w = w, swapped_branch = true} + local update_d = {subtree = d, farther = c, nearer = b, v = w, same = a, w = v} + + -- update the distances within the subtrees a,b,c,d respectively + update_BNNI_subtree(update_a) + update_BNNI_subtree(update_b) + update_BNNI_subtree(update_c) + update_BNNI_subtree(update_d) + + -- update the distance between subtrees v and w [step 3 (d)]: + local distance = 1/4*( self:distance(a,b) + self:distance(a,d) + self:distance(c,b) + self:distance(c,d) ) + distances[v][w] = distance + distances[w][v] = distance +end + + + +-- finds the best swap across an arc and inserts it into the heap of +-- possible swaps +-- +-- @param arc The arc, which is to be checked for possible swaps +-- @param heap_of_swaps The heap, containing all swaps, which +-- improve the total tree length +-- +-- the following data of the swap are saved: +-- v,w = the nodes connecting the arc, across which the swap is +-- performed +-- subtree1,2 = the roots of the subtrees that are to be swapped +-- a,d = the roots of the two remaining subtrees adjacent to the arc + +function BalancedNearestNeighbourInterchange:getBestSwap(arc, heap_of_swaps) + local g = self.tree + local possible_swaps = heap_of_swaps + local v = arc.tail + local w = arc.head + local is_leaf = self.is_leaf + + -- only look at inner edges: + if not is_leaf[v] and not is_leaf[w] then + -- get the roots of the adjacent subtrees + local a, b, c, d + for _,outgoing in ipairs (g:outgoing(v)) do + local head = outgoing.head + if head ~= w then + a = a or head + b = head + end + end + + for _,outgoing in ipairs (g:outgoing(w)) do + local head = outgoing.head + if head ~= v then + c = c or head + d = head + end + end + + -- get the distances between the four subtrees + local a_b = self:distance(a,b) + local a_c = self:distance(a,c) + local a_d = self:distance(a,d) + local b_c = self:distance(b,c) + local b_d = self:distance(b,d) + local c_d = self:distance(c,d) + + -- difference in total tree length between old tree (T) and new tree (T') + -- when nodes b and c are swapped + local swap1 = 1/4*(a_b + c_d - a_c - b_d ) + + -- difference in total tree length between old tree and new tree when nodes b and d are swapped + local swap2 = 1/4*(a_b + c_d - a_d - b_c) + + -- choose the best swap that reduces the total tree length most (T-T' > 0) + if swap1 > swap2 and swap1 > 0 then + -- v,w = the nodes connecting the edge across which the swap is performed + -- subtree1 = one of the nodes to be swapped; connected to v + -- subtree2 = the other node to be swapped; connected to w + -- a = other node connected to v + -- d = other node connected to w + local swap = { v = v, w = w, subtree1 = b, subtree2 = c, a = a, d = d } + -- insert the swap into the heap + possible_swaps:insert(swap, swap1) + elseif swap2 > 0 then + local swap = { v = v, w = w, subtree1 = b, subtree2 = d, d = c, a = a } + possible_swaps:insert(swap, swap2) + end + end +end + + + +return BalancedNearestNeighbourInterchange diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/DistanceMatrix.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/DistanceMatrix.lua new file mode 100644 index 00000000000..0bca7773212 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/DistanceMatrix.lua @@ -0,0 +1,440 @@ +-- Copyright 2013 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/phylogenetics/DistanceMatrix.lua,v 1.2 2013/12/20 14:44:47 tantau Exp $ + + + + +local DistanceMatrix = {} + + +-- Imports +local InterfaceToAlgorithms = require("pgf.gd.interface.InterfaceToAlgorithms") +local declare = InterfaceToAlgorithms.declare + + +--- + +declare { + key = "distance matrix vertices", + type = "string", + + summary = [[" + A list of vertices that are used in the parsing of the + |distance matrix| key. If this key is not used at all, all + vertices of the graph will be used for the computation of a + distance matrix. + "]], + + documentation = [[" + The vertices must be separated by spaces and/or + commas. For vertices containing spaces or commas, the vertex + names may be surrounded by single or double quotes (as in + Lua). Typical examples are |a, b, c| or |"hello world", 'foo'|. + "]] +} + + + +--- + +declare { + key = "distance matrix", + type = "string", + + summary = [[" + A distance matrix specifies ``desired distances'' between + vertices in a graph. These distances are used, in particular, in + algorithms for computing phylogenetic trees. + "]], + + documentation = [[" + When this key is parsed, the key |distance matrix vertices| is + considered first. It is used to determine a list of vertices + for which a distance matrix is computed, see that key for + details. Let $n$ be the number of vertices derived from that + key. + + The string passed to the |distance matrix| key is basically + a sequence of numbers that are used to fill an $n \times n$ + matrix. This works as follows: We keep track of a \emph{current + position $p$} in the matrix, starting at the upper left corner + of the matrix. We read the numbers in the string + one by one, write it to the current position of the matrix, and + advance the current position by going right one step; if we go + past the right end of the matrix, we ``wrap around'' by going + back to the left border of the matrix, but one line down. If we + go past the bottom of the matrix, we start at the beginning once + more. + + This basic behaviour can be modified in different ways. First, + when a number is followed by a semicolon instead of a comma or a + space (which are the ``usual'' ways of indicating the end of a + number), we immediately go down to the next line. Second, + instead of a number you can directly provide a \emph{position} + in the matrix and the current position will be set to this + position. Such a position information is detected by a + greater-than sign (|>|). It must be followed by + \begin{itemize} + \item a number or a vertex name or + \item a number or a vertex name, a comma, and another number or + vertex name or + \item a comma and a number and a vertex name. + \end{itemize} + Examples of the respective cases are |>1|, |>a,b|, and + |>,5|. The semantics is as follows: In all cases, if a vertex + name rather than a number is given, it is converted into a + number (namely the index of the vertex inside the matrix). Then, + in the first case, the column of the current position is set to + the given number; in the second case, the columns is set to the + first number and the column is set to the second number; and in + the third case only the row is set to the given number. (This + idea is that following the |>|-sign comes a ``coordinate pair'' + whose components are separated by a comma, but part of that pair + may be missing.) If a vertex name contains special symbols like + a space or a comma, you must surround it by single or double + quotation marks (as in Lua). + + Once the string has been parsed completely, the matrix may be + filled only partially. In this case, for each missing entry + $(x,y)$, we try to set it to the value of the entry $(y,x)$, + provided that entry is set. If neither are set, the entry is set + to $0$. + + Let us now have a look at several examples that all produce the + same matrix. The vertices are |a|, |b|, |c|. +\begin{codeexample}[code only, tikz syntax=false] +0, 1, 2 +1, 0, 3 +2, 3, 0 +\end{codeexample} +\begin{codeexample}[code only, tikz syntax=false] +0 1 2 1 0 3 2 3 0 +\end{codeexample} +\begin{codeexample}[code only, tikz syntax=false] +; +1; +2 3 +\end{codeexample} +\begin{codeexample}[code only, tikz syntax=false] +>,b 1; 2 3 +\end{codeexample} +\begin{codeexample}[code only, tikz syntax=false] +>b 1 2 >c 3 +\end{codeexample} + "]] +} + + +--- + +declare { + key = "distances", + type = "string", + + summary = [[" + This key is used to specify the ``desired distances'' between + a vertex and the other vertices in a graph. + "]], + + documentation = [[" + This key works similar to the |distance matrix| key, only it is + passed to a vertex instead of to a whole graph. The syntax is + the same, only the notion of different ``rows'' is not + used. Here are some examples that all have the same effect, + provided the nodes are |a|, |b|, and |c|. +\begin{codeexample}[code only, tikz syntax=false] +0, 1, 2 +\end{codeexample} +\begin{codeexample}[code only, tikz syntax=false] +0 1 2 +\end{codeexample} +\begin{codeexample}[code only, tikz syntax=false] +>b 1 2 +\end{codeexample} +\begin{codeexample}[code only, tikz syntax=false] +>c 2, >b 1 +\end{codeexample} + "]] +} + + + +local function to_index(s, indices) + if s and s ~= "" then + if s:sub(1,1) == '"' then + local _, _, m = s:find('"(.*)"') + return indices[InterfaceToAlgorithms.findVertexByName(m)] + elseif s:sub(1,1) == "'" then + local _, _, m = s:find("'(.*)'") + return indices[InterfaceToAlgorithms.findVertexByName(m)] + else + local num = tonumber(s) + if not num then + return indices[InterfaceToAlgorithms.findVertexByName(s)] + else + return num + end + end + end +end + +local function compute_indices(vertex_string, vertices) + local indices = {} + + if not vertex_string then + for i,v in ipairs(vertices) do + indices[i] = v + indices[v] = i + end + else + -- Ok, need to parse the vertex_string. Sigh. + local pos = 1 + while pos <= #vertex_string do + local start = vertex_string:sub(pos,pos) + if not start:find("[%s,]") then + local _, vertex + if start == '"' then + _, pos, vertex = vertex_string:find('"(.-)"', pos) + elseif start == "'" then + _, pos, vertex = vertex_string:find("'(.-)'", pos) + else + _, pos, vertex = vertex_string:find("([^,%s'\"]*)", pos) + end + local v = assert(InterfaceToAlgorithms.findVertexByName(vertex), "unknown vertex name '" .. vertex .. "'") + indices [#indices + 1] = v + indices [v] = #indices + end + pos = pos + 1 + end + end + + return indices +end + + +--- +-- Compute a distance matrix based on the values of a +-- |distance matrix| and a |distance matrix vertices|. +-- +-- @param matrix_string A distance matrix string +-- @param vertex_string A distance matrix vertex string +-- @param vertices An array of all vertices in the graph. +-- +-- @return A distance matrix. This matrix will contain both a +-- two-dimensional array (accessed through numbers) and also a +-- two-dimensional hash table (accessed through vertex indices). Thus, +-- you can write both |m[1][1]| and also |m[v][v]| to access the first +-- entry of this matrix, provided |v == vertices[1]|. +-- @return An index vector. This is an array of the vertices +-- identified for the |vertex_string| parameter. + +function DistanceMatrix.computeDistanceMatrix(matrix_string, vertex_string, vertices) + -- First, we create a table of the vertices we need to consider: + local indices = compute_indices(vertex_string, vertices) + + -- Second, build matrix. + local n = #indices + local m = {} + for i=1,n do + m[i] = {} + end + + local x = 1 + local y = 1 + local pos = 1 + -- Start scanning the matrix_string + while pos <= #matrix_string do + local start = matrix_string:sub(pos,pos) + if not start:find("[%s,]") then + if start == '>' then + local _, parse + _, pos, parse = matrix_string:find(">([^%s>;]*)", pos) + local a, b + if parse:find(",") then + _,_,a,b = parse:find("(.*),(.*)") + else + a = parse + end + x = to_index(a, indices) or x + y = to_index(b, indices) or y + elseif start == ';' then + x = 1 + y = y + 1 + elseif start == ',' then + x = x + 1 + else + local _, n + _, pos, n = matrix_string:find("([^,;%s>]*)", pos) + local num = assert(tonumber(n), "number expected in distance matrix") + m[x][y] = num + x = x + 1 + -- Skip everything up to first comma: + _, pos = matrix_string:find("(%s*,?)", pos+1) + end + end + pos = pos + 1 + if x > n then + x = 1 + y = y + 1 + end + if y > n then + y = 1 + end + end + + -- Fill up + for x=1,n do + for y=1,n do + if not m[x][y] then + m[x][y] = m[y][x] or 0 + end + end + end + + -- Copy to index version + for x=1,n do + local v = indices[x] + m[v] = {} + for y=1,n do + local u = indices[y] + m[v][u] = m[x][y] + end + end + + return m, indices +end + + + + +--- +-- Compute a distance vector. See the key |distances| for details. +-- +-- @param vector_string A distance vector string +-- @param vertex_string A distance matrix vertex string +-- @param vertices An array of all vertices in the graph. +-- +-- @return A distance vector. Like a distance matrix, this vector will +-- double indexed, once by numbers and once be vertex objects. +-- @return An index vector. This is an array of the vertices +-- identified for the |vertex_string| parameter. + +function DistanceMatrix.computeDistanceVector(vector_string, vertex_string, vertices) + -- First, we create a table of the vertices we need to consider: + local indices = compute_indices(vertex_string, vertices) + + -- Second, build matrix. + local n = #indices + local m = {} + local x = 1 + local pos = 1 + -- Start scanning the vector_string + while pos <= #vector_string do + local start = vector_string:sub(pos,pos) + if not start:find("[%s,]") then + if start == '>' then + local _, parse + _, pos, parse = vector_string:find(">([^%s>;]*)", pos) + x = to_index(parse, indices) or x + elseif start == ',' then + x = x + 1 + else + local _, n + _, pos, n = vector_string:find("([^,;%s>]*)", pos) + local num = assert(tonumber(n), "number expected in distance matrix") + m[x] = num + x = x + 1 + -- Skip everything up to first comma: + _, pos = vector_string:find("(%s*,?)", pos+1) + end + end + pos = pos + 1 + if x > n then + x = 1 + end + end + + -- Fill up + for x=1,n do + m[x] = m[x] or 0 + m[indices[x]] = m[x] + end + + return m, indices +end + + + +--- +-- Compute a distance matrix for a graph that incorporates all +-- information stored in the different options of the graph and the +-- vertices. +-- +-- @param graph A digraph object. +-- +-- @return A distance matrix for all vertices of the graph. + +function DistanceMatrix.graphDistanceMatrix(digraph) + local vertices = digraph.vertices + local n = #vertices + local m = {} + for i,v in ipairs(vertices) do + m[i] = {} + m[v] = {} + end + + local indices = {} + for i,v in ipairs(vertices) do + indices[i] = v + indices[v] = i + end + + if digraph.options['distance matrix'] then + local sub, vers = DistanceMatrix.computeDistanceMatrix( + digraph.options['distance matrix'], + digraph.options['distance matrix vertices'], + vertices + ) + + for x=1,#vers do + for y=1,#vers do + m[vers[x]][vers[y]] = sub[x][y] + end + end + end + + for i,v in ipairs(vertices) do + if v.options['distances'] then + local sub, vers = DistanceMatrix.computeDistanceVector( + v.options['distances'], + v.options['distance matrix vertices'], + vertices + ) + + for x=1,#vers do + m[vers[x]][v] = sub[x] + end + end + end + + -- Fill up number versions: + for x,vx in ipairs(vertices) do + for y,vy in ipairs(vertices) do + m[x][y] = m[vx][vy] + end + end + + return m +end + + + +return DistanceMatrix diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/Maeusle2012.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/Maeusle2012.lua new file mode 100644 index 00000000000..ef0909a6d00 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/Maeusle2012.lua @@ -0,0 +1,778 @@ +-- Copyright 2013 by Sarah Mäusle and 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/phylogenetics/Maeusle2012.lua,v 1.4 2013/05/23 20:01:29 tantau Exp $ + + +-- Imports +local Digraph = require 'pgf.gd.model.Digraph' +local Coordinate = require 'pgf.gd.model.Coordinate' +local Path = require 'pgf.gd.model.Path' + +local layered = require 'pgf.gd.layered' + +local lib = require 'pgf.gd.lib' + +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + +-- Main class of this file: + +local Maeusle2012 = lib.class {} + +-- Namespace +require("pgf.gd.phylogenetics").Maeusle2012 = Maeusle2012 + + + + +--- +declare { + key = "rooted rectangular phylogram", + algorithm = { + base_class = Maeusle2012, + run = function (self) + local root = self:getRoot() + self:setPosForRectangularLayout(root) + end + }, + phase = "phylogenetic tree layout", + phase_default = true, + + summary = [[" + A rooted rectangular phylogram is... + "]], + documentation = [[" + ... + "]], + examples = [[" + \tikz \graph [phylogenetic tree layout, + rooted rectangular phylogram, + balanced minimum evolution, + distance matrix={ + 0 4 9 9 9 9 9 + 4 0 9 9 9 9 9 + 9 9 0 2 7 7 7 + 9 9 2 0 7 7 7 + 9 9 7 7 0 3 5 + 9 9 7 7 3 0 5 + 9 9 7 7 5 5 0}] + { a, b, c, d, e, f, g }; + "]] +} + +--- +declare { + key = "rectangular phylogram", + use = { { key = "rooted rectangular phylogram" } }, + summary = "An alias for |rooted rectangular phylogram|" +} + +--- +declare { + key = "rooted straight phylogram", + algorithm = { + base_class = Maeusle2012, + run = function (self) + local root = self:getRoot() + self:setXPos(root) + self:setYPosForStraightLayout(root) + end + }, + phase = "phylogenetic tree layout", + + summary = [[" + A rooted straight phylogram is... + "]], + documentation = [[" + ... + "]], + examples = [[" + \tikz \graph [phylogenetic tree layout, + rooted straight phylogram, + balanced minimum evolution, grow=right, + distance matrix={ + 0 4 9 9 9 9 9 + 4 0 9 9 9 9 9 + 9 9 0 2 7 7 7 + 9 9 2 0 7 7 7 + 9 9 7 7 0 3 5 + 9 9 7 7 3 0 5 + 9 9 7 7 5 5 0}] + { a, b, c, d, e, f, g }; + "]]} + +--- +declare { + key = "straight phylogram", + use = { { key = "rooted straight phylogram" } }, + summary = "An alias for |rooted straight phylogram|" +} + +--- +declare { + key = "unrooted rectangular phylogram", + algorithm = { + base_class = Maeusle2012, + run = function (self) + local root1, root2 = self:getRoot() + self:setPosForUnrootedRectangular(root2, root1) + end + }, + phase = "phylogenetic tree layout", + + summary = [[" + A unrooted rectangular phylogram is... + "]], + documentation = [[" + ... + "]], + examples = [[" + \tikz \graph [phylogenetic tree layout, + unrooted rectangular phylogram, + balanced minimum evolution, grow=right, + distance matrix={ + 0 4 9 9 9 9 9 + 4 0 9 9 9 9 9 + 9 9 0 2 7 7 7 + 9 9 2 0 7 7 7 + 9 9 7 7 0 3 5 + 9 9 7 7 3 0 5 + 9 9 7 7 5 5 0}] + { a, b, c, d, e, f, g }; + "]] +} + +--- +declare { + key = "unrooted straight phylogram", + algorithm = { + base_class = Maeusle2012, + run = function (self) + local root1, root2 = self:getRoot() + self:setPosForUnrootedStraight(root2, root1) + end + }, + phase = "phylogenetic tree layout", + + summary = [[" + A unrooted straight phylogram is... + "]], + documentation = [[" + ... + "]], + examples = [[" + \tikz \graph [phylogenetic tree layout, + unrooted straight phylogram, + balanced minimum evolution, grow=right, + distance matrix={ + 0 4 9 9 9 9 9 + 4 0 9 9 9 9 9 + 9 9 0 2 7 7 7 + 9 9 2 0 7 7 7 + 9 9 7 7 0 3 5 + 9 9 7 7 3 0 5 + 9 9 7 7 5 5 0}] + { a, b, c, d, e, f, g }; + "]] +} + + +--- +declare { + key = "evolutionary unit length", + type = "length", + initial = "1cm", + + summary = [[" + Specifies how long a ``unit'' of evolutionary time should be on + paper. For instance, if two nodes in a phylogenetic tree have an + evolutionary distance of 3 and this length is set to |1cm|, then + they will be |3cm| apart in a straight-line phylogram. + "]], + documentation = [[" + (This key used to be called |distance scaling factor|.) + "]], +} + + + +-- +-- Gets the edge length between two nodes +-- +-- @param vertex1, vertex2 The two nodes +-- +-- @return The length of the edge between the two nodes +function Maeusle2012:edgeLength(vertex1, vertex2) + return self.lengths[vertex1][vertex2] +end + + +-- Sets the x and y coordinates for all nodes, using a depth first +-- search +-- +-- @param vertex The starting point; should usually be the root +-- @param values Values needed for the recursion +-- @param vertex2 A node that will not be visited; this parameter should only be set +-- for an unrooted layout to ensure that only the half of the tree is set. +function Maeusle2012:setPosForRectangularLayout(vertex, values, vertex2) + local arcs = self.tree.arcs + local vertices = self.tree.vertices + local adjusted_bb = self.main_algorithm.adjusted_bb + + values = values or { + length = 0, -- current path length + visited = {}, -- all nodes that have already been visited + leaves = {}, -- all leaves from left to right + } + + local vertex_is_leaf = true + values.visited[vertex] = true + + local children = {} -- a table containing all children of the + --current vertex (for the later determination of inner vertices + --x-positions) + + + for _, arc in ipairs (self.tree:outgoing(vertex)) do + if not values.visited[arc.head] and arc.head ~= vertex2 then + -- if arc.head hasn't been visited, the current vertex cannot be a leaf + vertex_is_leaf = false + local arc_length = self:edgeLength(vertex, arc.head) + + values.length = values.length + arc_length + + -- go deeper + self:setPosForRectangularLayout(arc.head, values, vertex2) + + -- get the children of the current vertex + children[#children+1] = arc.head + + values.length = values.length - arc_length + end + end + + if vertex_is_leaf then + -- subtract layer_pre, thus the leaf itself is NOT part of the + -- edge length + vertex.pos.y = - adjusted_bb[vertex].layer_pre + + values.leaves[#values.leaves+1] = vertex + + -- x coordinate: + -- the x coordinates of the leaves are the first to be set; the + -- first leave stays at x = 0, the x coordinates for the other + -- leaves is computed with help of the ideal_sibling_distance + -- function + if #values.leaves > 1 then + local left_sibling = values.leaves[#values.leaves-1] + local ideal_distance = layered.ideal_sibling_distance(adjusted_bb, self.tree, vertex, left_sibling ) + vertex.pos.x = left_sibling.pos.x + ideal_distance + end + + else -- the vertex is an inner node + -- the x position of an inner vertex is at the center of its children. + + -- determine the outer children + local left_child = children[1] + local right_child = left_child + for _, child in ipairs(children) do + if child.pos.x < left_child.pos.x then left_child = child end + if child.pos.x > right_child.pos.x then right_child = child end + end + + -- position between child with highest and child with lowest x-value, + -- if number of children is even + local index_of_middle_child = math.ceil(#children/2) + local even = #children/2 == index_of_middle_child + + if even then + vertex.pos.x = (left_child.pos.x + right_child.pos.x) / 2 + index_of_middle_child = 0 + else -- if number of children is odd, position above the middle child + vertex.pos.x = children[index_of_middle_child].pos.x + table.remove(children, index_of_middle_child) -- don't bend the edge to this node, as it it above it anyway + end + end + + -- set the node's y-coordinate, using the calculated length + -- and a scaling factor + vertex.pos.y = vertex.pos.y + (values.length * self.tree.options['evolutionary unit length']) + + -- if this is the second subtree to be set of an unrooted tree, have + -- it grow in the other direction + if values.second_subtree then + vertex.pos.y = -vertex.pos.y + end + + -- bend the edges for the rectangular layout + for i,child in ipairs(children) do + self:bendEdge90Degree(child, vertex) + end + + return values +end + + +-- Sets only the x-positions of all nodes using a depth-first search. +-- This is necessary for straight-edge layouts. +-- +-- @param vertex The starting point of the depth-first search; should usually be the root +-- @param values Values needed for the recursion +-- @param vertex2 A node that will not be visited; this parameter should only be set +-- for an unrooted layout to ensure that only the half of the tree is set. +function Maeusle2012:setXPos(vertex, values, vertex2) + local arcs = self.tree.arcs + local vertices = self.tree.vertices + if not values then + values = { + visited = {}, -- all nodes that have already been visited + leaves = {}, -- all leaves from left to right + } + end + + local vertex_is_leaf = true + values.visited[vertex] = true + local children = {} -- a table containing all children of the current vertex (for the later determination of inner vertices x-positions) + + for _, arc in ipairs (self.tree:outgoing(vertex)) do + if not values.visited[arc.head] and arc.head ~= vertex2 then + -- if arc.head hasn't been visited, the current vertex cannot be a leaf + vertex_is_leaf = false + + -- go deeper + self:setXPos(arc.head, values, vertex2) + + -- get the children of the current vertex + table.insert(children, arc.head) + end + end + + -- set the x-position of a leaf + if vertex_is_leaf then + + table.insert(values.leaves, vertex) + + if #values.leaves > 1 then + local left_sibling = values.leaves[#values.leaves-1] + local ideal_distance = layered.ideal_sibling_distance(self.main_algorithm.adjusted_bb, self.tree, vertex, left_sibling ) + vertex.pos.x = left_sibling.pos.x + ideal_distance + end + + -- set x position of an inner node, which is at the center of its + -- children + else + -- determine the outer children + local left_child = children[1] + local right_child = left_child + for _, child in ipairs(children) do + if child.pos.x < left_child.pos.x then left_child = child end + if child.pos.x > right_child.pos.x then right_child = child end + end + + -- position between child with highest and child with lowest x-value, + -- if number of children is even + local index_of_middle_child = math.ceil(#children/2) + local even = #children/2 == index_of_middle_child + + if even then + vertex.pos.x = (left_child.pos.x + right_child.pos.x) / 2 + else -- if number of children is odd, position above the middle child + vertex.pos.x = children[index_of_middle_child].pos.x + end + end + return values +end + + +-- +-- Sets only the y-positions of all nodes using a depth-first search. +-- This is needed for a straight-edge layout, as the x-positions have +-- to bet first so that the y-coordinates can be calculated correctly +-- here. +-- +-- @param vertex1 The starting point of the depth-first search +-- @param values Values needed for the recursion +-- @param vertex2 For unrooted layout only: The root of the second subtree. +-- This node and all its children will not be visited. +function Maeusle2012:setYPosForStraightLayout(vertex, values, vertex2) + local arcs = self.tree.arcs + local vertices = self.tree.vertices + local adjusted_bb = self.main_algorithm.adjusted_bb + + values = values or { + length = 0, -- current path length + visited = {}, -- all nodes that have already been visited + leaves = {}, -- all leaves from left to right + } + + local vertex_is_leaf = true + values.visited[vertex] = true + local children = {} -- a table containing all children of the current vertex (for the later determination of inner vertices x-positions) + + for _, arc in ipairs (self.tree:outgoing(vertex)) do + if not values.visited[arc.head] and arc.head ~= vertex2 then + -- if arc.head hasn't been visited, the current vertex cannot be a leaf + vertex_is_leaf = false + + -- calculate the arc length with the help of the Pythagorean + -- theorem + local a + local l = self:edgeLength(vertex, arc.head) * self.tree.options['evolutionary unit length'] + local b = math.abs(vertex.pos.x - arc.head.pos.x) + if b > l then + a = 0 + else + a = math.sqrt(l^2-b^2) + end + local arc_length = a + + + values.length = values.length + arc_length + + -- go deeper + self:setYPosForStraightLayout(arc.head, values, vertex2) + + -- get the children of the current vertex + table.insert(children, arc.head) + + values.length = values.length - arc_length + end + end + + if vertex_is_leaf then + -- subtract layer_pre, thus the leaf itself is NOT part of the + -- edge length + vertex.pos.y = - adjusted_bb[vertex].layer_pre + + table.insert(values.leaves, vertex) + end + + -- set the node's y-coordinate, using the calculated length + vertex.pos.y = vertex.pos.y + values.length + + -- if this is the second subtree to be set of an unrooted tree, have + -- it grow in the other direction + if values.second_subtree then vertex.pos.y = -vertex.pos.y end +end + +-- +-- Correct the x-positions in the unrooted layout for a more aesthetic result +-- +-- If the roots of the two subtrees have different x-positions, this is corrected +-- by shifting the x-positions of all nodes in one subtree by that difference. +-- +-- @param vertex1 The root of the first subtree +-- @param vertex2 The root of the second subtree. +function Maeusle2012:correctXPos(vertex1, vertex2, straight) + + -- correct the x-positions + -- + -- @param vertex Starting point of the depth-first search + -- @param values Values needed for the recursion + -- @param vertex2 The root of the subtree that will not be visited + local function x_correction(vertex, values, vertex2) + values.visited[vertex] = true + local children = {} + + for _, arc in ipairs (self.tree:outgoing(vertex)) do + if not values.visited[arc.head] and arc.head ~= vertex2 then + + table.insert(children, arc.head) + x_correction(arc.head, values, vertex2) + end + end + + vertex.pos.x = vertex.pos.x + values.diff + if not straight then + for i,child in ipairs(children) do + self:bendEdge90Degree(child, vertex) + end + end + + return values + end + + -- compute the difference of the x-positions of the two subtrees' + -- roots + local diff = vertex1.pos.x - vertex2.pos.x + local values = { visited = {} } + if diff < 0 then + values.diff = - diff + x_correction(vertex1, values, vertex2) + elseif diff > 0 then + values.diff = diff + x_correction(vertex2, values, vertex1) + end +end + + +-- +-- Sets the x- and y-positions of the vertices in an unrooted layout +-- +-- This is done using the function for setting the positions for a rooted layout: +-- Two neighboring vertices are chosen as roots; one half of the tree +-- is drawn in one direction, the other half 180° to the other +-- direction. +-- +-- @param vertex1, vertex2: The vertices functioning as roots +function Maeusle2012:setPosForUnrootedRectangular(vertex1, vertex2) + -- set positions for first half of the tree... + self:setPosForRectangularLayout(vertex2,false,vertex1) + local vals={ + length = self:edgeLength(vertex1, vertex2), -- the length between the two roots + visited={}, + leaves={}, + path={}, + second_subtree = true + } + -- ... and for the second half. + self:setPosForRectangularLayout(vertex1,vals,vertex2) + -- if the two roots have different x-values, correct the x-positions for nicer layout + self:correctXPos(vertex1, vertex2, false) +end + + +-- +-- Sets the x- and y-positions of the vertices in an unrooted straight layout +-- +-- This is done using the function for setting the positions for a rooted straight layout: +-- Two neighboring vertices are chosen as roots; one half of the tree +-- is drawn in one direction, the other half 180° to the other +-- direction. +-- +-- @param vertex1, vertex2: The vertices functioning as roots +function Maeusle2012:setPosForUnrootedStraight(vertex1, vertex2) + -- first set the x-positions of the two subtrees... + local vals = {visited = {}, leaves = {} } + self:setXPos(vertex2, vals, vertex1) + self:setXPos(vertex1, vals, vertex2) + + -- ... and then the y-positions + self:setYPosForStraightLayout(vertex2, false, vertex1) + local vals={ + length = self:edgeLength(vertex1, vertex2) * self.tree.options['evolutionary unit length'], + visited={}, + leaves={}, + path={}, + second_subtree = true + } + self:setYPosForStraightLayout(vertex1, vals, vertex2) + + -- if the two roots have different x-values, correct the x-positions for nicer layout + -- as the length between the roots of the two subtrees is set to the calculated value, + -- this step is mandatory for the unrooted, straight layout + self:correctXPos(vertex1, vertex2, true) +end + + + +-- Bends the arc between two nodes by 90 degree by updating the arc's +-- path +-- +-- @param head The head of the arc +-- @param tail The tail of the arc +function Maeusle2012:bendEdge90Degree(head, tail) + local arc = self.tree:arc(tail,head) + local syntactic_tail = arc:syntacticTailAndHead() + arc:setPolylinePath { Coordinate.new(head.pos.x, tail.pos.y) } +end + + + +-- Finds the longest path in a graph +-- +-- @ return A table containing the path (an array of nodes) and the +-- path length +function Maeusle2012:findLongestPath() + local starting_point = self.tree.vertices[1] -- begin at any vertex + -- get the path lengths from the starting point to all leaves: + local paths_to_leaves = self:getPathLengthsToLeaves(starting_point) + local path_lengths = paths_to_leaves.path_lengths + local paths = paths_to_leaves.paths + + -- looks for the longest path and identifies its end-point + local function find_head_of_longest_path(path_lengths, paths) + local longest_path + local node + -- to make sure that the same path is chosen every time, we go over all vertices with "ipairs"; if we would go over path_lengths directly, we could only use "pairs" + for _, vertex in ipairs(self.tree.vertices) do + local path_length = path_lengths[vertex] + if path_length then + -- choose longest path. if two paths have the same length, take the path with more nodes + if not longest_path or path_length > longest_path or (path_length == longest_path and #paths[vertex]>#paths[node]) then + longest_path = path_length + node = vertex + end + end + end + return node + end + + -- find the longest path leading away from the starting point and identify + -- the leaf it leads to. Use that leaf as the tail for the next path + -- search + local tail = find_head_of_longest_path(path_lengths, paths) + paths_to_leaves = self:getPathLengthsToLeaves(tail) -- gets new path information + -- paths_to leaves now has all paths starting at vertex "tail"; one of these paths is the + -- longest (globally) + path_lengths = paths_to_leaves.path_lengths + paths = paths_to_leaves.paths + local head = find_head_of_longest_path(path_lengths, paths) + + local path_information = + { path = paths_to_leaves.paths[head], -- longest path + length = path_lengths[head] } -- length of that path + + return path_information +end + + +-- a depth first search for getting all path lengths from a +-- starting point to all leaves +-- +-- @param vertex The vertex where the search is to start +-- @param values Table of values needed for the recursive computation +-- +-- @return A table containing: +-- a table of the leaves with corresponding path lengths +-- and a table containing the path to each leaf (an array of +-- nodes) +function Maeusle2012:getPathLengthsToLeaves(vertex, values) + local arcs = self.tree.arcs + local vertices = self.tree.vertices + if not values then + values = { + paths = {}, -- all paths we've found so far + path_lengths = {}, -- all path lengths that have so far been computed + length = 0, -- current path length + visited = {}, -- all nodes that have already been visited + path = {}, -- the current path we're on + leaves = {} -- all leaves from left to right + } + table.insert(values.path,vertex) + end + + local vertex_is_leaf = true + values.visited[vertex] = true + + for _, arc in ipairs (self.tree:outgoing(vertex)) do + if not values.visited[arc.head] then + -- the current vertex is not a leaf! note: if the starting vertex is a leaf, vertex_is_leaf + -- will be set to 'false' for it anyway. as we're not interested in the distance + -- of the starting vertex to itself, this is fine. + vertex_is_leaf = false + local arc_length = self.lengths[vertex][arc.head] + values.length = values.length + arc_length + + -- add arc.head to path... + table.insert(values.path,arc.head) + + -- ... and go down that path + self:getPathLengthsToLeaves(arc.head, values) + + -- remove arc.head again to go a different path + table.remove(values.path) + values.length = values.length - arc_length + end + end + + if vertex_is_leaf then -- we store the information gained on the path to this leaf + values.path_lengths[vertex] = values.length + values.paths[vertex] = {} + table.insert(values.leaves, vertex) + for i,k in pairs(values.path) do + values.paths[vertex][i] = k + end + end + -- the path_lengths and the paths are stored in one table and + -- returned together + local path_information = + { path_lengths = values.path_lengths, + paths = values.paths, + leaves = values.leaves } + return path_information +end + + +-- Gets the root of a tree +-- checks whether a tree is already rooted, if not, computeCenterOfPath() is +-- called, which defines a node in the center of the graph as the root +-- +-- @return The root +function Maeusle2012:getRoot() + -- check whether a root exists (vertex with degree 2) + local root = lib.find (self.tree.vertices, function(v) return #self.tree:outgoing(v) == 2 end) + if root then + return root, self.tree:outgoing(root)[1].head + else + return self:computeCenterOfPath() + end +end + + +-- +-- @return The newly computed root and its nearest neighbor +function Maeusle2012:computeCenterOfPath() + local longest_path = self:findLongestPath() + local path = longest_path.path + local root, neighbor_of_root + + local length = 0 --length between first vertex on the path and the current vertex we're looking at + for i = 1, #path-1 do + local node1 = path[i] + local node2 = path[i+1] + local node3 = path[i+2] + + local dist_node_1_2, dist_node_2_3 --distances between node1 and node2, and node2 and node3 + dist_node_1_2 = self:edgeLength(node1, node2) + if node3 then dist_node_2_3 = self:edgeLength(node2, node3) end + length = length + dist_node_1_2 -- length between first vertex on the path and current node2 + + if length == longest_path.length/2 then + root = node2 -- if there is a node exactly at the half of the path, use this node as root + + -- and find nearest neighbor of the root + if node3 == nil or dist_node_1_2 < dist_node_2_3 then -- neu 3.8 + neighbor_of_root = node1 + else + neighbor_of_root = node3 + end + break + + elseif length > longest_path.length/2 then + -- else find node closest to the center of the path and use it as the root; + local node2_length = math.abs(longest_path.length/2 - length) + local node1_length = math.abs(longest_path.length/2 - (length - dist_node_1_2)) + if node2_length < node1_length then + root = node2 + neighbor_of_root = node1 + -- if node3 is closer to node2 than node1 is, use node3 as neighbor! + if node3 and dist_node_2_3 < dist_node_1_2 then neighbor_of_root = node3 end + else + root = node1 + neighbor_of_root = node2 + --check if node i-1 is closer to node1 + local dist_node_0_1 + if i>1 then + node0 = path[i-1] + dist_node_0_1 = self:edgeLength(node0, node1) + if dist_node_0_1 < dist_node_1_2 then neighbor_of_root = node0 end + end + end + break + end + end + + return root, neighbor_of_root +end + + +return Maeusle2012 diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/PhylogeneticTree.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/PhylogeneticTree.lua new file mode 100644 index 00000000000..16356aa7cfa --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/PhylogeneticTree.lua @@ -0,0 +1,91 @@ +-- Copyright 2013 by Sarah Mäusle and 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/phylogenetics/PhylogeneticTree.lua,v 1.2 2013/02/08 17:14:06 tantau Exp $ + + +local PhylogeneticTree = {} + + +-- Namespace +require("pgf.gd.phylogenetics").PhylogeneticTree = PhylogeneticTree + +-- Imports +local InterfaceToAlgorithms = require "pgf.gd.interface.InterfaceToAlgorithms" +local Storage = require "pgf.gd.lib.Storage" +local Direct = require "pgf.gd.lib.Direct" + +-- Shorthand: +local declare = InterfaceToAlgorithms.declare + + +--- +declare { + key = "phylogenetic tree layout", + algorithm = PhylogeneticTree, + + postconditions = { + upward_oriented = true + }, + + summary = [[" + Layout for drawing phylogenetic trees. + "]], + documentation = [[" + ... + "]], + examples = [[" + \tikz \graph [phylogenetic tree layout, upgma, + distance matrix={ + 0 4 9 9 9 9 9 + 4 0 9 9 9 9 9 + 9 9 0 2 7 7 7 + 9 9 2 0 7 7 7 + 9 9 7 7 0 3 5 + 9 9 7 7 3 0 5 + 9 9 7 7 5 5 0}] + { a, b, c, d, e, f, g }; + "]] +} + + +-- Computes a phylogenetic tree and/or visualizes it +-- - computes a phylogenetic tree according to what the "phylogenetic +-- algorithm" key is set to +-- - invokes a graph drawing algorithm according to what the +-- "phylogenetic layout" key is set to +function PhylogeneticTree:run() + + local options = self.digraph.options + + -- Two storages for some information computed by the phylogenetic + -- tree generation algorithm + local lengths = Storage.newTableStorage() + + -- First, compute the phylogenetic tree + local tree = options.algorithm_phases['phylogenetic tree generation'].new { + main_algorithm = self, + lengths = lengths + }:run() + + tree = Direct.ugraphFromDigraph(tree) + + -- Second, layout the tree + local layout_class = options.algorithm_phases['phylogenetic tree layout'] + layout_class.new { + main_algorithm = self, + distances = distances, + lengths = lengths, + tree = tree + }:run() + + tree:sync() +end + +return PhylogeneticTree diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/SokalMichener1958.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/SokalMichener1958.lua new file mode 100644 index 00000000000..c55a7a7467c --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/SokalMichener1958.lua @@ -0,0 +1,261 @@ +-- Copyright 2013 by Sarah Mäusle and 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/phylogenetics/SokalMichener1958.lua,v 1.1 2013/02/08 17:14:06 tantau Exp $ + + + + +local SokalMichener1958 = {} + + +-- Namespace +require("pgf.gd.phylogenetics").SokalMichener1958 = SokalMichener1958 + +-- Imports +local InterfaceToAlgorithms = require("pgf.gd.interface.InterfaceToAlgorithms") +local DistanceMatrix = require("pgf.gd.phylogenetics.DistanceMatrix") +local lib = require("pgf.gd.lib") +local Storage = require("pgf.gd.lib.Storage") +local Digraph = require("pgf.gd.model.Digraph") + +-- Shorthand: +local declare = InterfaceToAlgorithms.declare + + +--- +declare { + key = "unweighted pair group method using arithmetic averages", + algorithm = SokalMichener1958, + phase = "phylogenetic tree generation", + + summary = [[" + The UPGMA (Unweighted Pair Group Method using arithmetic + Averages) algorithm of Sokal and Michener, 1958. It generates a + graph on the basis of such a distance matrix by generating nodes + and computing the edge lengths. + "]], + documentation = [[" + This algorithm uses a distance matrix, ideally an ultrametric + one, to compute the graph. + "]], + examples = [[" + \tikz \graph [phylogenetic tree layout, sibling distance=0pt, sibling sep=2pt, + unweighted pair group method using arithmetic averages, + distance matrix={ + 0 4 9 9 9 9 9 + 4 0 9 9 9 9 9 + 9 9 0 2 7 7 7 + 9 9 2 0 7 7 7 + 9 9 7 7 0 3 5 + 9 9 7 7 3 0 5 + 9 9 7 7 5 5 0}] + { a, b, c, d, e, f, g }; + "]] +} + + +--- +declare { + key = "upgma", + use = { { key = "unweighted pair group method using arithmetic averages" } }, + summary = "An shorthand for |unweighted pair group method using arithmetic averages|" +} + + + + +-- +-- The run function of the upgma algorithm. +-- +-- You must setup the following fields: The |main_algorithm| must +-- store the main algorithm object (for phase |main|). The |distances| +-- field must be a |Storage| object that will get filled with the +-- distances computed by this algorithm. The |lengths| field must also +-- be a |Storage| for the computed distances. +-- + +function SokalMichener1958:run() + self.distances = Storage.newTableStorage() + + self.tree = Digraph.new(self.main_algorithm.digraph) + + -- store the phylogentic tree object, containing all user-specified + -- graph information + self:runUPGMA() + self:createFinalEdges() + + return self.tree +end + + + +-- UPGMA (Unweighted Pair Group Method using arithmetic Averages) algorithm +-- (Sokal and Michener, 1958) +-- +-- this function generates a graph on the basis of such a distance +-- matrix by generating nodes and computing the edge lengths; the x- +-- and y-positions of the nodes must be set separately +-- +-- requirement: a distance matrix, ideally an ultrametric +function SokalMichener1958:runUPGMA() + local matrix = DistanceMatrix.graphDistanceMatrix(self.tree) + + local g = self.tree + local clusters = {} + + -- create the clusters + for _,v in ipairs(g.vertices) do + clusters[#clusters+1] = self:newCluster(v) + end + + -- Iniitialise the distances of these clusters: + for _,cx in ipairs(clusters) do + for _,cy in ipairs(clusters) do + cx.distances[cy] = matrix[cx.root][cy.root] + end + end + + -- search for clusters with smallest distance and merge them + while #clusters > 1 do + local minimum_distance = math.huge + local min_cluster1 + local min_cluster2 + for i, cluster in ipairs (clusters) do + for j = i+1,#clusters do + local cluster2 = clusters[j] + local cluster_distance = self:getClusterDistance(cluster, cluster2) + if cluster_distance < minimum_distance then + minimum_distance, min_cluster1, min_cluster2 = cluster_distance, i, j + end + end + end + self:mergeClusters(clusters, min_cluster1, min_cluster2, minimum_distance) + end +end + + +-- a new cluster is created +-- +-- @param vertex The vertex the cluster is initialized with +-- +-- @return The new cluster +function SokalMichener1958:newCluster(vertex) + return { + root = vertex, -- the root of the cluster + size = 1, -- the number of vertices in the cluster, + distances = {}, -- cached cluster distances to all other clusters + cluster_height = 0 -- this value is equivalent to half the distance of the last two clusters + -- that have been merged to form the current cluster; + -- necessary for determining the distances of newly generated nodes to their children. + } +end + + +-- gets the distance between two clusters +-- +-- @param cluster1, cluster2 The two clusters +-- +-- @return the distance between the clusters +function SokalMichener1958:getClusterDistance(c,d) + return c.distances[d] or d.distances[c] or 0 +end + + +-- merges two clusters by doing the following: +-- - deletes cluster2 from the clusters table +-- - adds all vertices from cluster2 to the vertices table of cluster1 +-- - updates the distances of the new cluster to all remaining clusters +-- - generates a new node, as the new root of the cluster +-- - computes the distance of the new node to the former roots (for +-- later computation of the y-positions) +-- - generates edges, connecting the new node to the former roots +-- - updates the cluster height +-- +-- @param clusters The array of clusters +-- @param index_of_first_cluster The index of the first cluster +-- @param index_of_second_cluster The index of the second cluster +-- @param distance The distance between the two clusters + +function SokalMichener1958:mergeClusters(clusters, index_of_first_cluster, index_of_second_cluster, distance) + + local g = self.tree + local cluster1 = clusters[index_of_first_cluster] + local cluster2 = clusters[index_of_second_cluster] + + --update cluster distances + for i,cluster in ipairs (clusters) do + if cluster ~= cluster1 and cluster ~= cluster2 then + local dist1 = self:getClusterDistance (cluster1, cluster) + local dist2 = self:getClusterDistance (cluster2, cluster) + local dist = (dist1*cluster1.size + dist2*cluster2.size)/ (cluster1.size+cluster2.size) + cluster1.distances[cluster] = dist + cluster.distances[cluster1] = dist + end + end + + -- delete cluster2 + table.remove(clusters, index_of_second_cluster) + + --add node and connect last vertex of each cluster with new node + local new_node = InterfaceToAlgorithms.createVertex( + self.main_algorithm, + { + name = "UPGMA-node ".. #self.tree.vertices+1, + generated_options = { { key = "phylogenetic inner node" } }, + } + ) + g:add{new_node} + -- the distance of the new node ( = the new root of the cluster) to its children (= the former roots) is + -- equivalent to half the distance between the two former clusters + -- minus the respective cluster height + local distance1 = distance/2-cluster1.cluster_height + self.distances[new_node][cluster1.root] = distance1 + local distance2 = distance/2-cluster2.cluster_height + self.distances[new_node][cluster2.root] = distance2 + + -- these distances are also the final edge lengths, thus: + self.lengths[new_node][cluster1.root] = distance1 + self.lengths[cluster1.root][new_node] = distance1 + + self.lengths[new_node][cluster2.root] = distance2 + self.lengths[cluster2.root][new_node] = distance2 + + g:connect(new_node, cluster1.root) + g:connect(new_node, cluster2.root) + + cluster1.root = new_node + cluster1.size = cluster1.size + cluster2.size + cluster1.cluster_height = distance/2 -- set new height of the cluster +end + + + +-- generates edges for the final graph +-- +-- throughout the process of creating the tree, arcs have been +-- disconnected and connected, without truly creating edges. this is +-- done in this function +function SokalMichener1958:createFinalEdges() + local g = self.tree + local o_arcs = {} -- copy arcs since createEdge is going to modify the arcs array... + for _,arc in ipairs(g.arcs) do + o_arcs[#o_arcs+1] = arc + end + for _,arc in ipairs(o_arcs) do + InterfaceToAlgorithms.createEdge( + self.main_algorithm, arc.tail, arc.head, + { generated_options = { + { key = "phylogenetic edge", value = tostring(self.lengths[arc.tail][arc.head]) } + }}) + end +end + + +return SokalMichener1958 diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/library.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/library.lua new file mode 100644 index 00000000000..194e809ef2e --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/library.lua @@ -0,0 +1,35 @@ +-- 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/phylogenetics/library.lua,v 1.2 2013/04/04 20:43:45 tantau Exp $ + + + +--- +-- A phylogenetic tree (or network) depicts the evolutionary histroy +-- of species or, more generally, so called taxa. The present library +-- includes a number of algorithms for drawing phylogenetic trees. +-- +-- @library + +local phylogenetics -- Library name + +-- Main layout: +require "pgf.gd.phylogenetics.PhylogeneticTree" + +-- Phylogenetic tree drawing: +require "pgf.gd.phylogenetics.Maeusle2012" + +-- Phylogenetic tree generation: +require "pgf.gd.phylogenetics.SokalMichener1958" +require "pgf.gd.phylogenetics.BalancedMinimumEvolution" +require "pgf.gd.phylogenetics.BalancedNearestNeighbourInterchange" +require "pgf.gd.phylogenetics.AuthorDefinedPhylogeny" + + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/tools/make_gd_wrap.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/tools/make_gd_wrap.lua new file mode 100644 index 00000000000..b433e73a652 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/tools/make_gd_wrap.lua @@ -0,0 +1,183 @@ +-- 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/tools/make_gd_wrap.lua,v 1.2 2013/01/01 17:10:09 tantau Exp $ + + + +--- +-- This program generates a C wrap file around graph drawing +-- algorithms. The idea is that when you have a graph drawing +-- algorithm implemented in C and wish to invoke it from Lua, you need +-- a wrapper that manages the translation between Lua and C. This +-- program is intended to make it (reasonably) easy to produce such a +-- wraper. + + + +-- Sufficient number of arguments? + +if #arg < 4 or arg[1] == "-h" or arg[1] == "-?" or arg[1] == "--help" then + print([[" +Usage: make_gd_wrap library1 library2 ... libraryn template library_name target_c_file + +This program will read all of the graph drawing library files using +Lua's require. Then, it will iterate over all declared algorithm keys +(declared using declare { algorithm_written_in_c = ... }) and will +produce the code for library for the required target C files based on +the template. +"]]) + os.exit() +end + + +-- Imports + +local InterfaceToDisplay = require "pgf.gd.interface.InterfaceToDisplay" +local InterfaceCore = require "pgf.gd.interface.InterfaceCore" + + +-- Ok, setup: + +InterfaceToDisplay.bind(require "pgf.gd.bindings.Binding") + + +-- Now, read all libraries: + +for i=1,#arg-3 do + require(arg[i]) +end + + +-- Now, read the template: + +local file = io.open(arg[#arg-2]) +local template = file:read("*a") +file:close() + +-- Let us grab the declaration: + +local functions_dec = (template:match("%$functions(%b{})") or ""):match("^{(.*)}$") +local functions_reg_dec = (template:match("%$functions_registry(%b{})") or ""):match("^{(.*)}$") +local factories_dec = (template:match("%$factories(%b{})") or ""):match("^{(.*)}$") +local factories_reg_dec = (template:match("%$factories_registry(%b{})") or ""):match("^{(.*)}$") + +-- Now, handle all keys with a algorithm_written_in_c field + +local keys = InterfaceCore.keys +local filename = arg[#arg] +local target = arg[#arg-1] + +local includes = {} +local functions = {} +local functions_registry = {} + +local factories = {} +local factories_reg = {} + +for _,k in ipairs(keys) do + + if k.algorithm_written_in_c and k.code then + + local library, fun_name = k.algorithm_written_in_c:match("(.*)%.(.*)") + + if target == library then + -- First, gather the includes: + if type(k.includes) == "string" then + if not includes[k.includes] then + includes[#includes + 1] = k.includes + includes[k.includes] = true + end + elseif type(k.includes) == "table" then + for _,i in ipairs(k.includes) do + if not includes[i] then + includes[#includes + 1] = i + includes[i] = true + end + end + end + + -- Second, create a code block: + functions[#functions+1] = functions_dec:gsub("%$([%w_]-)%b{}", + { + function_name = fun_name, + function_body = k.code + }) + + -- Third, create functions_registry entry + functions_registry[#functions_registry + 1] = functions_reg_dec:gsub("%$([%w_]-)%b{}", + { + function_name = fun_name, + function_body = k.code + }) + end + end + + + if k.module_class then + + -- First, gather the includes: + if type(k.includes) == "string" then + if not includes[k.includes] then + includes[#includes + 1] = k.includes + includes[k.includes] = true + end + elseif type(k.includes) == "table" then + for _,i in ipairs(k.includes) do + if not includes[i] then + includes[#includes + 1] = i + includes[i] = true + end + end + end + + -- Second, create a code block: + factories[#factories+1] = factories_dec:gsub( + "%$([%w_]-)%b{}", + { + factory_class = k.module_class, + factory_code = k.code, + factory_base = k.module_base, + factory_name = k.module_class .. '_factory' + }) + + -- Third, create factories_registry entry + factories_reg[#factories_reg + 1] = factories_reg_dec:gsub( + "%$([%w_]-)%b{}", + { + factory_class = k.module_class, + factory_code = k.code, + factory_base = k.module_base, + factory_name = k.module_class .. '_factory' + }) + end +end + + +local file = io.open(filename, "w") + +if not file then + print ("failed to open file " .. filename) + os.exit(-1) +end + +file:write ((template:gsub( + "%$([%w_]-)%b{}", + { + factories = table.concat(factories, "\n\n"), + factories_registry = table.concat(factories_reg, "\n"), + functions = table.concat(functions, "\n\n"), + functions_registry = table.concat(functions_registry, "\n"), + includes = table.concat(includes, "\n"), + library_c_name = target:gsub("%.", "_"), + library_name = target + }))) +file:close() + +
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees.lua new file mode 100644 index 00000000000..9aff2aaf1d7 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees.lua @@ -0,0 +1,21 @@ +-- 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/trees.lua,v 1.1 2012/11/27 17:24:24 tantau Exp $ + + +local trees = {} + +-- Declare namespace +require("pgf.gd").trees = tree + + +-- Done + +return trees
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/ChildSpec.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/ChildSpec.lua new file mode 100644 index 00000000000..272af54e55e --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/ChildSpec.lua @@ -0,0 +1,227 @@ +-- 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/trees/ChildSpec.lua,v 1.4 2013/05/23 20:01:29 tantau Exp $ + + + +--- +-- @section subsection {Specifying Missing Children} +-- +-- \label{section-gd-missing-children} +-- +-- In the present section we discuss keys for specifying missing children +-- in a tree. For many certain kind of trees, in particular for binary +-- trees, there are not just ``a certain number of children'' at each +-- node, but, rather, there is a designated ``first'' (or ``left'') child +-- and a ``second'' (or ``right'') child. Even if one of these children +-- is missing and a node actually has only one child, the single child will +-- still be a ``first'' or ``second'' child and this information should +-- be taken into consideration when drawing a tree. +-- +-- The first useful key for specifying missing children is +-- |missing number of children| which allows you to state how many +-- children there are, at minimum. +-- +-- Once the minimum number of children has been set, we still need a way +-- of specifying ``missing first children'' or, more generally, missing +-- children that are not ``at the end'' of the list of children. For +-- this, there are three methods: +-- +-- \begin{enumerate} +-- \item When you use the |child| syntax, you can use the |missing| key +-- with the |child| command to indicate a missing child: +-- \begin{codeexample}[] +-- \tikz [binary tree layout, level distance=5mm] +-- \node {a} +-- child { node {b} +-- child { node {c} +-- child { node {d} } +-- } } +-- child { node {e} +-- child [missing] +-- child { node {f} +-- child [missing] +-- child { node {g} +-- } } }; +-- \end{codeexample} +-- \item When using the |graph| syntax, you can use an ``empty node'', +-- which really must be completely empty and may not even contain a +-- slash, to indicate a missing node: +-- \begin{codeexample}[] +-- \tikz [binary tree layout, level distance=5mm] +-- \graph { a -> { b -> c -> d, e -> { , f -> { , g} } } }; +-- \end{codeexample} +-- \item You can simply specify the index of a child directly using +-- the key |desired child index|. +-- \end{enumerate} +-- +-- @end + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + +--- +-- +declare { + key = "minimum number of children", + type = "number", + initial = "0", + + summary = [[" + Specifies how many children a tree node must have at least. If + there are less, ``virtual'' children are added. + "]], + documentation = [[" + When this key is set to |2| or more, the following happens: We first + compute a spanning tree for the graph, see + Section~\ref{subsection-gd-spanning-tree}. Then, whenever a node is + not a leaf in this spanning tree (when it has at least one child), + we add ``virtual'' or ``dummy'' nodes as children of the node until + the total number of real and dummy children is at least + \meta{number}. If there where at least \meta{number} children at the + beginning, nothing happens. + + The new children are added after the existing children. This means + that, for instance, in a tree with \meta{number} set to |2|, for + every node with a single child, this child will be the first child + and the second child will be missing. + "]], + examples = [[" + \tikz \graph [binary tree layout,level distance=5mm] + { a -> { b->c->d, e->f->g } }; + "]] +} + +--- + +declare { + key = "desired child index", + type = "number", + + summary = [[" + Pass this key to a node to tell the graph drawing engine which child + number you ``desired'' for the node. Whenever all desires for the + children of a node are conflict-free, they will all be met; children + for which no desired indices were given will remain at their + position, whenever possible, but will ``make way'' for children with + a desired position. + "]], + documentation = [[" + In detail, the following happens: We first + determine the total number of children (real or dummy) needed, which + is the maximum of the actual number of children, of the + \texttt{minimum number of children}, and of the highest desired + child index. Then we go over all children that have a desired child + index and put they at this position. If the position is already + taken (because some other child had the same desired index), the + next free position is used with a wrap-around occurring at the + end. Next, all children without a desired index are place using the + same mechanism, but they want to be placed at the position they had + in the original spanning tree. + + While all of this might sound a bit complicated, the application of + the key in a binary tree is pretty straightforward: To indicate that + a node is a ``right'' child in a tree, just add \texttt{desired child index=2} + to it. This will make it a second child, possibly causing the fist + child to be missing. If there are two nodes specified as children of + a node, by saying \texttt{desired child index=}\meta{number} for one + of them, you will cause it be first or second child, depending on + \meta{number}, and cause the \emph{other} child to become the other + child. + + Since |desired child index=2| is a bit long, the following shortcuts + are available: |first|, |second|, |third|, and |fourth|. + You might wonder why |second| is used rather than |right|. The + reason is that trees may also grow left and right and, additionally, + the |right| and |left| keys are already in use for + anchoring. Naturally, you can locally redefine them, if you want. + "]], + examples = { + [[" + \tikz \graph [binary tree layout, level distance=5mm] + { a -> b[second] }; + "]], + [[" + \tikz \graph [binary tree layout, level distance=5mm] + { a -> { b[second], c} }; + "]], + [[" + \tikz \graph [binary tree layout, level distance=5mm] + { a -> { b, c[first]} }; + "]], + [[" + \tikz \graph [binary tree layout, level distance=5mm] + { a -> { b[second], c[second]} }; + "]], + [[" + \tikz \graph [binary tree layout, level distance=5mm] + { a -> { b[third], c[first], d} }; + "]] + } +} + + +--- + +declare { + key = "first", + use = { + { key = "desired child index", value = 1}, + }, + + summary = [[" + A shorthand for setting the desired child number to |1|. + "]] + } + +--- + +declare { + key = "second", + use = { + { key = "desired child index", value = 2}, + }, + + summary = [[" + A shorthand for setting the desired child number to |2|. + "]] + } + + +--- + +declare { + key = "third", + use = { + { key = "desired child index", value = 3}, + }, + + summary = [[" + A shorthand for setting the desired child number to |3|. + "]] + } + + +--- + +declare { + key = "fourth", + use = { + { key = "desired child index", value = 4} + }, + + summary = [[" + A shorthand for setting the desired child number to |4|. + "]] + } + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/ReingoldTilford1981.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/ReingoldTilford1981.lua new file mode 100644 index 00000000000..2bcade8b967 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/ReingoldTilford1981.lua @@ -0,0 +1,211 @@ +-- 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/trees/ReingoldTilford1981.lua,v 1.10 2013/05/23 20:01:29 tantau Exp $ + + + +--- +-- @section subsubsection {The Reingold--Tilford Layout} +-- +-- @end + +local ReingoldTilford1981 = {} + +-- Imports +local layered = require "pgf.gd.layered" +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare +local Storage = require "pgf.gd.lib.Storage" + +--- +declare { + key = "tree layout", + algorithm = ReingoldTilford1981, + + preconditions = { + connected = true, + tree = true + }, + + postconditions = { + upward_oriented = true + }, + + documentation_in = "pgf.gd.doc.trees.ReingoldTilford1981" +} + + +--- +declare { + key = "missing nodes get space", + type = "boolean", + documentation_in = "pgf.gd.doc.trees.ReingoldTilford1981" +} + + + +--- +declare { + key = "significant sep", + type = "length", + initial = "0", + documentation_in = "pgf.gd.doc.trees.ReingoldTilford1981" +} + + +--- +declare { + key = "binary tree layout", + use = { + { key = "tree layout" }, + { key = "minimum number of children" , value=2 }, + { key = "significant sep", value = 10 }, + }, + documentation_in = "pgf.gd.doc.trees.ReingoldTilford1981" +} + +--- +declare { + key = "extended binary tree layout", + use = { + { key = "tree layout" }, + { key = "minimum number of children" , value=2 }, + { key = "missing nodes get space" }, + { key = "significant sep", value = 0 }, + }, + documentation_in = "pgf.gd.doc.trees.ReingoldTilford1981" +} + + + + +-- Now comes the implementation: + +function ReingoldTilford1981:run() + + local root = self.spanning_tree.root + + local layers = Storage.new() + local descendants = Storage.new() + + self.extended_version = self.digraph.options['missing nodes get space'] + + self:precomputeDescendants(root, 1, layers, descendants) + self:computeHorizontalPosition(root, layers, descendants) + layered.arrange_layers_by_baselines(layers, self.adjusted_bb, self.ugraph) + +end + + +function ReingoldTilford1981:precomputeDescendants(node, depth, layers, descendants) + local my_descendants = { node } + + for _,arc in ipairs(self.spanning_tree:outgoing(node)) do + local head = arc.head + self:precomputeDescendants(head, depth+1, layers, descendants) + for _,d in ipairs(descendants[head]) do + my_descendants[#my_descendants + 1] = d + end + end + + layers[node] = depth + descendants[node] = my_descendants +end + + + +function ReingoldTilford1981:computeHorizontalPosition(node, layers, descendants) + + local children = self.spanning_tree:outgoing(node) + + node.pos.x = 0 + + local child_depth = layers[node] + 1 + + if #children > 0 then + -- First, compute positions for all children: + for i=1,#children do + self:computeHorizontalPosition(children[i].head, layers, descendants) + end + + -- Now, compute minimum distances and shift them + local right_borders = {} + + for i=1,#children-1 do + + local local_right_borders = {} + + -- Advance "right border" of the subtree rooted at + -- the i-th child + for _,d in ipairs(descendants[children[i].head]) do + local layer = layers[d] + local x = d.pos.x + if self.extended_version or not (layer > child_depth and d.kind == "dummy") then + if not right_borders[layer] or right_borders[layer].pos.x < x then + right_borders[layer] = d + end + if not local_right_borders[layer] or local_right_borders[layer].pos.x < x then + local_right_borders[layer] = d + end + end + end + + local left_borders = {} + -- Now left for i+1 st child + for _,d in ipairs(descendants[children[i+1].head]) do + local layer = layers[d] + local x = d.pos.x + if self.extended_version or not (layer > child_depth and d.kind == "dummy") then + if not left_borders[layer] or left_borders[layer].pos.x > x then + left_borders[layer] = d + end + end + end + + -- Now walk down the lines and try to find out what the minimum + -- distance needs to be. + + local shift = -math.huge + local first_dist = left_borders[child_depth].pos.x - local_right_borders[child_depth].pos.x + local is_significant = false + + for layer,n2 in pairs(left_borders) do + local n1 = right_borders[layer] + if n1 then + shift = math.max( + shift, + layered.ideal_sibling_distance(self.adjusted_bb, self.ugraph, n1, n2) + n1.pos.x - n2.pos.x + ) + end + if local_right_borders[layer] then + if layer > child_depth and + (left_borders[layer].pos.x - local_right_borders[layer].pos.x <= first_dist) then + is_significant = true + end + end + end + + if is_significant then + shift = shift + self.ugraph.options['significant sep'] + end + + -- Shift all nodes in the subtree by shift: + for _,d in ipairs(descendants[children[i+1].head]) do + d.pos.x = d.pos.x + shift + end + end + + -- Finally, position root in the middle: + node.pos.x = (children[1].head.pos.x + children[#children].head.pos.x) / 2 + end +end + + + +return ReingoldTilford1981
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/SpanningTreeComputation.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/SpanningTreeComputation.lua new file mode 100644 index 00000000000..24e9a69c385 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/SpanningTreeComputation.lua @@ -0,0 +1,637 @@ +-- 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/trees/SpanningTreeComputation.lua,v 1.7 2013/05/23 20:01:29 tantau Exp $ + + + +--- +-- @section subsection {Spanning Tree Computation} +-- +-- \label{subsection-gd-spanning-tree} +-- Although the algorithms of this library are tailored to layout trees, +-- they will work for any graph as input. First, if the graph is not +-- connected, it is decomposed into connected components and these are +-- laid out individiually. Second, for each component, a spanning tree of +-- the graph is computed first and the layout is computed for this +-- spanning tree; all other edges will still be drawn, but they have no +-- impact on the placement of the nodes. If the graph is already a tree, +-- the spanning tree will be the original graph. +-- +-- The computation of the spanning tree is a non-trivial process since +-- a non-tree graph has many different possible spanning trees. You can +-- choose between different methods for deciding on a spanning tree, it +-- is even possible to implement new algorithms. (In the future, the +-- computation of spanning trees and the cylce removal in layered graph +-- drawing algorithms will be unified, but, currently, they are +-- implemented differently.) +-- +-- Selects the (sub)algorithm that is to be used for computing spanning +-- trees whenever this is requested by a tree layout algorithm. The +-- default algorithm is |breadth first spanning tree|. +-- +--\begin{codeexample}[] +--\tikz \graph [tree layout, breadth first spanning tree] +--{ +-- 1 -- {2,3,4,5} -- 6; +--}; +--\end{codeexample} +--\begin{codeexample}[] +--\tikz \graph [tree layout, depth first spanning tree] +--{ +-- 1 --[bend right] {2,3,4,5 [>bend left]} -- 6; +--}; +--\end{codeexample} +-- +-- @end + +local SpanningTreeComputation = {} + + + +-- Namespace +require("pgf.gd.trees").SpanningTreeComputation = SpanningTreeComputation + + +-- Imports +local lib = require "pgf.gd.lib" + +local Vertex = require "pgf.gd.model.Vertex" +local Digraph = require "pgf.gd.model.Digraph" + + +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + + +-- ------------------------- -- +-- General tree parameters -- +-- ------------------------- -- + + + + +--- +-- +declare { + key = "breadth first spanning tree", + algorithm = { + run = + function (self) + return SpanningTreeComputation.computeSpanningTree(self.ugraph, false, self.events) + end + }, + phase = "spanning tree computation", + phase_default = true, + + summary = [[" + This key selects ``breadth first'' as the (sub)algorithm for + computing spanning trees. Note that this key does not cause a graph + drawing scope to start; the key only has an effect in conjunction + with keys like |tree layout|. + "]], + documentation = [[" + The algorithm will be called whenever a graph drawing algorithm + needs a spanning tree on which to operate. It works as follows: + \begin{enumerate} + \item It looks for a node for which the |root| parameter is + set. If there are several such nodes, the first one is used. If there + are no such nodes, the first node is used. + + Let call the node determined in this way the \emph{root node}. + \item For every edge, a \emph{priority} is determined, which is a + number between 1 and 10. How this happens, exactly, will be + explained in a moment. Priority 1 means ``most important'' while + priority 10 means ``least important''. + \item Starting from the root node, we now perform a breadth first + search through the tree, thereby implicitly building a spanning + tree: Suppose for a moment that all edges have priority~1. Then, + the algorithm works just the way that a normal breadth first + search is performed: We keep a queue of to-be-visited nodes and + while this queue is not empty, we remove its first node. If this + node has not yet been visited, we add all its neighbors at the + end of the queue. When a node is taken out of the queue, we make + it the child of the node whose neighbor it was when it was + added. Since the queue follows the ``first in, first out'' + principle (it is a fifo queue), the children of the root will be + all nodes at distance $1$ form the root, their children will be + all nodes at distance $2$, and so on. + \item Now suppose that some edges have a priority different + from~1, in which case things get more complicated. We now keep + track of one fifo queue for each of the ten possible + priorities. When we consider the neighbors of a node, we actually + consider all its incident edges. Each of these edges has a certain + priority and the neighbor is put into the queue of the edge's + priority. Now, we still remove nodes normally from the queue for + priority~1; only if this queue is empty and there is still a node + in the queue for priority~2 we remove the first element from this + queue (and proceed as before). If the second queue is also empty, + we try the third, and so on up to the tenth queue. If all queues + are empty, the algorithm stops. + \end{enumerate} + + The effect of the ten queues is the following: If the edges of + priority $1$ span the whole graph, a spanning tree consisting solely + of these edges will be computed. However, if they do not, once we + have visited reachable using only priority 1 edges, we will extend + the spanning tree using a priority 2 edge; but then we once switch + back to using only priority 1 edges. If neither priority~1 nor + priority~2 edges suffice to cover the whole graph, priority~3 edges + are used, and so on. + "]] + } + +--- + +declare { + key = "depth first spanning tree", + algorithm = { + run = + function (self) + return SpanningTreeComputation.computeSpanningTree(self.ugraph, true, self.events) + end + }, + phase = "spanning tree computation", + + summary = [[" + Works exactly like |breadth first spanning tree| (same handling of + priorities), only the queues are now lifo instead of + fifo. + "]] + } + +--- +-- +declare { + key = "root", + type = "boolean", + default = true, + + summary = [[" + This Boolean parameter is used in the computation of spanning + trees. When can be set for a node, this node will be used as the + root for the spanning tree computation. If several nodes have this + option set, the first node will be used. + "]] + } + + +--- +-- +declare { + key = "span priority", + type = "number", + + summary = [[" + Explicitly sets the ``span priority'' of an edge to \meta{number}, which must be + a number between |1| and |10|. The priority of edges is used by + spanning tree computations, see |breadth first spanning tree|. + "]] + } + + + +--- +-- when it comes to choosing which edges are part of the spanning tree. +declare { + key = "span edge", + use = { + { key = "span priority", value = 1 }, + }, + + summary = [[" + An easy-to-remember shorthand for |span priority=1|. When this key + is used with an edge, it will always be preferred over other edges + "]] + } + + + + +--- +-- +declare { + key = "no span edge", + use = { + { key = "span priority", value = 10 }, + }, + + summary = [[" + An easy-to-remember shorthand for |span priority=10|. This causes + the edge to be used only as a last resort as part of a spanning + tree. + "]], + documentation = [[" + In the example, we add lots of edges that would normally be + preferred in the computation of the spanning tree, but use + |no span edge| to cause the algorithm to ignore these edges. + "]], + examples = [[" + \tikz \graph [tree layout, nodes={draw}, sibling distance=0pt, + every group/.style={ + default edge kind=->, no span edge, + path=source}] + { + 5 -> { + "1,3" -> {0,2,4}, + 11 -> { + "7,9" -> { 6, 8, 10 } + } + } + }; + "]] +} + + + +--- +declare { + key = "span priority ->", + type = "number", + initial = "3", + + summary = [[" + This key stores the span priority of all edges whose direction is + |->|. There are similar keys for all other directions, such as + |span priority <-| and so on. + "]], + documentation = [[" + When you write +\begin{codeexample}[code only] +graph { a -> b -- c <- [span priority=2] d } +\end{codeexample} + the priority of the edge from |a| to |b| would be the current + value of the key |span priority ->|, the priority of the edge from + |b| to |c| would be the current value of |span priority --|, and + the priority of the edge from |c| to |d| would be |2|, regardless + of the value of |span priority <-|. + + The defaults for the priorities are: + \begin{itemize} + \item |span priority -> = 3| + \item |span priority -- = 5| + \item |span priority <-> = 5| + \item |span priority <- = 8| + \item |span priority -!- = 10| + \end{itemize} + "]] +} + + + +--- + +declare { + key = "span priority reversed ->", + type = "number", + initial = "9", + + documentation = [[" + This key stores the span priority of traveling across reversed + edges whose actual direction is |->| (again, there are similar keys + for all other directions). + "]], + documentation = [[" + When you write +\begin{codeexample}[code only] +graph { a -> b -- c <- [span priority=2] d } +\end{codeexample} + there are, in addition to the priorities indicated above, also + further edge priorities: The priority of the (reversed) edge |b| + to |a| is |span priority reversed ->|, the priority of the + (reversed) edge |c| to |b| is |span priority reversed --|, and the + span priority of the reversed edge |d| to |c| is |2|, regardless + of the value of |span priority reversed <-|. + + The defaults for the priorities are: + \begin{itemize} + \item |span priority reversed -> = 9| + \item |span priority reversed -- = 5| + \item |span priority reversed <-> = 5| + \item |span priority reversed <- = 7| + \item |span priority reversed -!- = 10| + \end{itemize} + + The default priorities are set in such a way, that non-reversed |->| + edges have top priorities, |--| and |<->| edges have the same + priorities in either direction, and |<-| edges have low priority in + either direction (but going |a <- b| from |b| to |a| is given higher + priority than going from |a| to |b| via this edge and also higher + priority than going from |b| to |a| in |a -> b|). + + Keys like |span using directed| change the priorities ``en bloc''. + "]] +} + + +declare { + key = "span priority <-", + type = "number", + initial = "8", +} + +declare { + key = "span priority reversed <-", + type = "number", + initial = "7", +} + +declare { + key = "span priority --", + type = "number", + initial = "5", +} + +declare { + key = "span priority reversed --", + type = "number", + initial = "5", +} + +declare { + key = "span priority <->", + type = "number", + initial = "5", +} + +declare { + key = "span priority reversed <->", + type = "number", + initial = "5", +} + +declare { + key = "span priority -!-", + type = "number", + initial= "10", +} + +declare { + key = "span priority reversed -!-", + type = "number", + initial= "10", +} + +--- + +declare { + key = "span using directed", + use = { + { key = "span priority reversed <-", value = 3}, + { key = "span priority <->", value = 3}, + { key = "span priority reversed <->", value = 3}, + }, + summary = [[" + This style sets a priority of |3| for all edges that are directed + and ``go along the arrow direction'', that is, we go from |a| to + |b| with a priority of |3| for the cases |a -> b|, |b <- a|, + |a <-> b|, and |b <-> a|. + This strategy is nice with trees specified with both forward and + backward edges. + "]], + examples = [[" + \tikz \graph [tree layout, nodes={draw}, sibling distance=0pt, + span using directed] + { + 3 <- 5[root] -> 8, + 1 <- 3 -> 4, + 7 <- 8 -> 9, + 1 -- 4 -- 7 -- 9 + }; + "]] +} + +--- + +declare { + key = "span using all", + use = { + { key = "span priority <-", value = 5}, + { key = "span priority ->", value = 5}, + { key = "span priority <->", value = 5}, + { key = "span priority --", value = 5}, + { key = "span priority -!-", value = 5}, + { key = "span priority reversed <-", value = 5}, + { key = "span priority reversed ->", value = 5}, + { key = "span priority reversed <->", value = 5}, + { key = "span priority reversed --", value = 5}, + { key = "span priority reversed -!-", value = 5}, + }, + + summary = [[" + Assings a uniform priority of 5 to all edges. + "]] +} + + +-- The implementation + +-- +-- Compute a spanning tree of a graph +-- +-- The algorithm will favor nodes according to their priority. This is +-- determined through an edge priority function. +-- +-- @param ugraph An undirected graph for which the spanning tree +-- should be computed +-- @param dfs True if depth first should be used, false if breadth +-- first should be used. +-- +-- @return A new graph that is a spanning tree. + +function SpanningTreeComputation.computeSpanningTree (ugraph, dfs, events) + + local tree = Digraph.new (ugraph) -- copy vertices + + local edge_priorities = ugraph.options['/graph drawing/edge priorities'] + + local root = lib.find(ugraph.vertices, function (v) return v.options['root'] end) or ugraph.vertices[1] + + -- Traverse tree, giving preference to directed edges and, that + -- failing, to undirected and bidirected edges, and, that failing, + -- all other edges. + local marked = {} + + local stacks = { -- 10 stacks for 10 priorities, with 1 being the highest + { { parent = nil, node = root}, top = 1, bottom = 1 }, + { top = 0, bottom = 1}, + { top = 0, bottom = 1}, + { top = 0, bottom = 1}, + { top = 0, bottom = 1}, + { top = 0, bottom = 1}, + { top = 0, bottom = 1}, + { top = 0, bottom = 1}, + { top = 0, bottom = 1}, + { top = 0, bottom = 1} + } + + local function stack_is_non_empty (s) return s.top >= s.bottom end + + while lib.find(stacks, stack_is_non_empty) do + local parent, node + + for _,stack in ipairs(stacks) do + if stack_is_non_empty(stack) then + -- Pop + parent = stack[stack.top].parent + node = stack[stack.top].node + + stack[stack.top] = nil + stack.top = stack.top - 1 + + break + end + end + + if not marked[node] then + + -- The node is good! + marked[node] = true + + if parent then + tree:connect(parent,node) + end + + local arcs = ugraph:outgoing(node) + + for j=1,#arcs do + local arc = arcs[dfs and j or #arcs - j + 1] + local head = arc.head + + if not marked[head] then + local priority = arc:spanPriority() + local stack = assert(stacks[priority], "illegal edge priority") + if dfs then + stack.top = stack.top + 1 + stack[stack.top] = { parent = node, node = head} + else + stack.bottom = stack.bottom - 1 + stack[stack.bottom] = { parent = node, node = head} + end + end + end + end + end + + -- Now, copy vertex list + local copy = {} + for i,v in ipairs(tree.vertices) do + copy[i] = v + end + + -- Now, setup child lists + for _,v in ipairs(copy) do + + -- Children as they come from the spanning tree computation + tree:sortOutgoing(v, function (a,b) return a:eventIndex() < b:eventIndex() end) + local outgoings = tree:outgoing(v) + + -- Compute children as they come in the event list: + local children = {} + + local i = (v.event.index or 0)+1 + while i <= #events and events[i].kind == "edge" do + i = i + 1 + end + + if events[i] and events[i].kind == "begin" and events[i].parameters == "descendants" then + -- Ok, the node is followed by a descendants group + -- Now scan for nodes that are not inside a descendants group + local stop = events[i].end_index + local j = i+1 + while j <= stop do + if events[j].kind == "node" then + children[#children+1] = events[j].parameters + elseif events[j].kind == "begin" and events[j].parameters == "descendants" then + j = events[j].end_index + end + j = j + 1 + end + + -- Test, whether outgoings and children contain the same nodes: + local function same_elements() + local hash = {} + for v,c in ipairs(outgoings) do + hash[c.head] = true + end + local count = 0 + for _,c in pairs(children) do + if c ~= "" then + count = count + 1 + if not hash[c] or count > #outgoings then + return false + end + end + end + return count == #outgoings + end + + if same_elements() and #outgoings > 0 then + + -- increase number of children, if necessary + local needed = math.max(#children, lib.lookup_option('minimum number of children', v, ugraph)) + for i=1,#children do + if children[i] ~= "" then + local d = children[i].options['desired child index'] + needed = d and math.max(needed, d) or needed + end + end + + local new_children = {} + for i=1,#children do + if children[i] ~= "" then + local d = children[i].options['desired child index'] + if d then + local target = d + + while new_children[target] do + target = 1 + (target % #children) + end + new_children[target] = children[i] + end + end + end + for i=1,#children do + if children[i] ~= "" then + local d = children[i].options['desired child index'] + if not d then + local target = i + + while new_children[target] do + target = 1 + (target % #children) + end + new_children[target] = children[i] + end + end + end + for i=1,needed do + if not new_children[i] then + local new_child = Vertex.new{ kind = "dummy" } + new_children[i] = new_child + tree:add {new_child} + tree:connect(v,new_child) + end + end + + tree:orderOutgoing(v,new_children) + end + end + end + + tree.root = root + + return tree +end + + + +-- Done + +return SpanningTreeComputation
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/library.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/library.lua new file mode 100644 index 00000000000..f34aee06792 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/library.lua @@ -0,0 +1,35 @@ +-- 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/trees/library.lua,v 1.2 2013/04/04 20:43:45 tantau Exp $ + + + +--- +-- \tikzname\ offers several different syntax to specify trees (see +-- Sections \ref{section-library-graphs} +-- and~\ref{section-trees}). The job of the graph drawing algorithms from +-- this library is to turn the specification of trees into beautiful +-- layouts. +-- +-- We start this section with a description of algorithms, then we have a +-- look at how missing children can be specified and at what happens when +-- the input graph is not a tree. +-- +-- @library + +local trees -- Library name + +-- Load declarations from: +require "pgf.gd.trees.ChildSpec" +require "pgf.gd.trees.SpanningTreeComputation" + +-- Load algorithms from: +require "pgf.gd.trees.ReingoldTilford1981" + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.circular.code.tex b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.circular.code.tex new file mode 100644 index 00000000000..9c017b5577d --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.circular.code.tex @@ -0,0 +1,16 @@ +% Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster +% Copyright 2011 by Till Tantau +% +% This file may be distributed and/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 details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.circular.code.tex,v 1.4 2012/11/20 23:34:18 tantau Exp $ + + +\usegdlibrary{circular} + +\endinput
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.code.tex b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.code.tex new file mode 100644 index 00000000000..02d4d8ffa30 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.code.tex @@ -0,0 +1,1126 @@ +% Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster +% Copyright 2011 by Till Tantau +% +% This file may be distributed and/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 details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.code.tex,v 1.38 2013/08/28 11:47:35 tantau Exp $ + + + +% check if luatex is running + +\ifx\directlua\relax% + \pgferror{You need to run LuaTeX to use the graph drawing library} + \expandafter\endinput +\fi +\ifx\directlua\undefined% + \pgferror{You need to run LuaTeX to use the graph drawing library} + \expandafter\endinput +\fi + + + + +% +% All graph drawing keys normally live in the following namespace: +% /graph drawing. +% + +\def\pgfgdset{\pgfqkeys{/graph drawing}} + + +% Setup a key +% +% #1 = key +% +% Description: +% +% An internal macro that sets up #1 as a graph drawing key. + +\def\pgfgd@callbackkey#1{ + \pgf@gd@setup@forwards{#1} + \pgfutil@g@addto@macro\pgf@gd@forwards@list{\pgf@gd@setup@forwards{#1}} +} +\def\pgf@gd@setup@forwards#1{ + \let\pgf@temp\pgfutil@empty + \foreach \pgf@gd@path in \pgf@gd@forwarding@list { + \ifx\pgf@gd@path\pgfutil@empty\else% + \expandafter\pgfutil@g@addto@macro% + \expandafter\pgf@temp\expandafter{% + \expandafter\pgfkeys\expandafter{\pgf@gd@path#1/.forward to=/graph drawing/#1}} + \fi% + }% + \pgf@temp +} + +\let\pgf@gd@forwards@list\pgfutil@empty + + +% Append to the forwarding list: +% +% #1 = paths to append to the forwarding list +% +% Description: +% +% Append the paths in #1 (with trailing slashes) to the forwarding +% list. +% +% If algorithms have already been declared, forwarding will also be +% setup for them (using a bit of magic...). + +\def\pgfgdappendtoforwardinglist#1{% + \let\pgf@gd@forwarding@list@orig\pgf@gd@forwarding@list + \def\pgf@gd@forwarding@list{#1}% + \pgf@gd@forwards@list% + \expandafter\def\expandafter\pgf@gd@forwarding@list\expandafter{\pgf@gd@forwarding@list@orig,#1} +} +\let\pgf@gd@forwarding@list\pgfutil@empty + + + +% +% +% Callbacks +% +% The following macros are called *from* the binding layer. You do not +% call them from the pgf layer. +% +% + + +% Callback for declaring a graph parameter key +% +% #1 = Parameter key +% #2 = Parameter type +% +% Description: +% +% When a graph drawing algorithm starts working, a set of options, +% called "graph drawing parameters" in the following, can influence the +% way the algorithm works. For instance, an graph drawing parameter +% might be the average distance between vertices which the algorithm +% should take into account. Another example might be the fact the +% certain nodes are special nodes and that a certain edge should have +% a large label. +% +% These graph drawing parameters are different from "usual" pgf +% options: An alogrithmic parameter influenced the way the algorithm +% works, while usual options normally only influence how the result +% looks like. For instance, the fact that a node is red is not an +% graph drawing parameter (usually, at least), while the shape of a node +% might be an graph drawing parameter. +% +% Graph drawing parameters are declared by the algorithmic layer +% (since only this layer "knows" which parameters there are). The +% binding to TeX will call the \pgfgddeclareparameter function +% internally. +% +% Specifying the set of graph drawing parameters for a given graph or +% node or edge works as follows: When the graph drawing engine is +% started for a graph (using \pgfgdbeginscope), a snapshot is taken of +% all graph drawing parameters currently setup at this +% point. Similarly, when a node is created inside such a scope, a +% snapshot is taken of the set of all graph drawing parameters in +% force at this point is taken and stored together with the +% node. Finally, when an edge is created, a snapshot of the setting of +% the graph drawing parameters is taken. + +\def\pgfgdcallbackdeclareparameter#1#2{% + \pgfkeysdef{/graph drawing/#1}{\pgf@gd@handle@parameter{#1}{#2}{##1}}% + \pgfgd@callbackkey{#1}% +} +\def\pgf@gd@handle@parameter#1#2#3{% + \def\pgf@temp{#3}% + \ifx\pgf@temp\pgfkeysnovalue@text% + \let\pgfgdresult\pgfgd@niltext% + \else% + \pgfkeys{/graph drawing/conversions/#2={#3}}% + \fi% + \advance\pgf@gd@parameter@stack@height by1\relax% + \pgf@gd@parameter@stack@height\directlua{% + local new, main = pgf.gd.interface.InterfaceToDisplay.pushOption('\pgfutil@luaescapestring{#1}',\pgfgdresult,\the\pgf@gd@parameter@stack@height) + tex.print(new..'\pgfutil@luaescapestring{\relax}') + if main then + tex.print('\pgfutil@luaescapestring{\noexpand\pgfgdtriggerrequest}') + end}% +}% +\newcount\pgf@gd@parameter@stack@height + +\def\pgfgdtriggerrequest{\pgfgdset{@request scope and layout}} + + +% Conversions are used to adapt the syntactic description of a +% parameter on the TikZ layer to the one expected by Lua. The set of +% permissible conversions is described in +% InterfaceToAlgorithms.declareParameter. + +\pgfgdset{ + conversions/string/.code=\def\pgfgdresult{'\pgfutil@luaescapestring{\detokenize{#1}}'}, + conversions/raw/.code=\def\pgfgdresult{#1}, + conversions/nil/.code=\let\pgfgdresult\pgfgd@niltext, + conversions/boolean/.code=\def\pgf@test{#1}\ifx\pgf@test\pgf@truetext\def\pgfgdresult{true}\else\ifx\pgf@test\pgfkeysnovalue@text\def\pgfgdresult{true}\else\def\pgfgdresult{false}\fi\fi, + conversions/number/.code=\pgfmathparse{#1}\let\pgfgdresult\pgfmathresult, + conversions/length/.code=\pgfmathparse{#1}\let\pgfgdresult\pgfmathresult, + conversions/direction/.code=\pgf@lib@gd@grow@dir{#1}\let\pgfgdresult\pgfmathresult, + conversions/canvas coordinate/.code args={(#1pt,#2pt)}{\edef\pgfgdresult{pgf.gd.model.Coordinate.new(#1,#2)}}, + % deprecated, will be removed: + conversions/coordinate/.code args={(#1pt,#2pt)}{\edef\pgfgdresult{{#1,#2}}} +} +\def\pgf@truetext{true} +\def\pgfgd@niltext{nil} + +\def\pgf@lib@gd@grow@dir#1{% + \def\pgf@temp{#1}% + \ifx\pgf@temp\pgf@gd@lib@active@bar% + \def\pgfmathresult{-90} + \else% + \ifcsname pgf@orient@direction@#1\endcsname% + \expandafter\let\expandafter\pgfmathresult\csname pgf@orient@direction@#1\endcsname% + \else + \pgfmathparse{#1}% + \fi + \fi +} + +\def\pgf@orient@direction@down{-90} +\def\pgf@orient@direction@up{90} +\def\pgf@orient@direction@left{180} +\def\pgf@orient@direction@right{0} + +\def\pgf@orient@direction@south{-90} +\def\pgf@orient@direction@north{90} +\def\pgf@orient@direction@west{180} +\def\pgf@orient@direction@east{0} + +\expandafter\def\csname pgf@orient@direction@north east\endcsname{45} +\expandafter\def\csname pgf@orient@direction@north west\endcsname{135} +\expandafter\def\csname pgf@orient@direction@south east\endcsname{-45} +\expandafter\def\csname pgf@orient@direction@south west\endcsname{-135} + +\expandafter\def\csname pgf@orient@direction@-\endcsname{0} +\expandafter\def\csname pgf@orient@direction@|\endcsname{-90} + +{ + \catcode`\|=13 + \gdef\pgf@gd@lib@active@bar{|} +} + + + + + +% Callback for starting the rendering of a collection kind +% +% #1 = Kind +% #2 = Layer +% +% Description: +% +% Executes /graph drawing/#1/begin rendering/.try +% + +\def\pgfgdcallbackrendercollectionkindstart#1#2{% + \ifnum#2<0\relax + \setbox\pgf@gd@prekind@box=\hbox\bgroup% + \unhbox\pgf@gd@prekind@box% + \else% + \setbox\pgf@gd@postkind@box=\hbox\bgroup% + \unhbox\pgf@gd@postkind@box% + \fi% + \pgfgdset{/graph drawing/#1/begin rendering/.try}% +} + +% Callback for ending the rendering of a collection kind +% +% #1 = Kind +% #2 = Layer +% +% Description: +% +% Executes /graph drawing/#1/end rendering/.try +% + +\def\pgfgdcallbackrendercollectionkindstop#1#2{% + \pgfgdset{/graph drawing/#1/end rendering/.try}% + \egroup % close box +} + + + +% Callback for rendering a collection +% +% #1 = Kind +% #2 = Options +% +% Description: +% +% Executes /graph drawing/#1/render/.try={#2} +% + +\def\pgfgdcallbackrendercollection#1#2{ + \pgfgdset{/graph drawing/#1/render/.try={#2}} +} + + + + + +% Graph events +% +% Although a graph consists of nodes and edges, during the +% construction of the graph a lot of information concerning the +% structure of the graph is often available. For instance, as we +% specify a graph using the child-syntax, we do not only which edges +% are present, but we can implicitly specify an ordering on the +% nodes. Even more, there is even information availble concerning +% nodes that are not present at all: A child[missing] is not present +% as a node or an edge, but a tree drawing algorithm will want to know +% about this child nevertheless. +% +% In order to communicate such information to the graph drawing +% engine, "events" are used. As a graph is created, in addition to +% nodes and edges, "events" may happen. The events come in a +% sequential order and they are stored together with the graph. For +% each node and each edge, its index in the event sequence is +% stored, that is, it is stored how many events happened before the +% node or edge was created. +% +% Internally, an event consists of a name and, possibly, some +% parameters. When the parameter is created on the tikz level, it will +% be a string that is passed down to Lua. Internally created events +% will also have parameters that are objects. +% +% Two events are a bit special since they get special internal +% support: The begin and end events. The first signals that some kind +% of group has started; which is closed by the corresponding end +% event. The "kind" of group is indicated by the parameter of the +% begin event. +% +% +% +% Standard events are: +% +% For each node entered into a graph, a "node" event is automatically +% created internally with the parameter being the node. However, you +% can also create this event yourself. In this case, the parameter +% will be a string and will mean that the node is "virtual" or +% "missing", but space should be reserved for it, if possible (this is +% use, for instance, by certain tree layouts). +% +% For each edge entered into a graph, an "edge" event is automatically +% created, with the edge as the parameter. Again, an event with a +% string parameter corresponds to a "non-existing" node. +% +% +% Standard event groups are: +% +% +% The "descendants" event group include a set of nodes that, at least +% inside the specification, are descendants of the last node +% +% begin descendants +% ... +% end +% +% +% The "array" event group collects together some nodes in an array of +% nodes. This can be used, for instance, to specify matrices. +% +% begin array +% ... +% end + + + +% Create a new event +% +% #1 = event name (should be a valid lua identifier name) +% #2 = parameter (some text) +% +% Description: +% +% Adds a new event to the event sequence of the graph + +\def\pgfgdevent#1#2{% + \directlua{pgf.gd.interface.InterfaceToDisplay.createEvent('\pgfutil@luaescapestring{#1}', '\pgfutil@luaescapestring{#2}')}% +} + + +% Start an event group +% +% #1 = kind of event group +% +% Description: +% +% Creates a begin event with #1 as the parameter of the begin +% event. + +\def\pgfgdbegineventgroup#1{% + \pgfgdevent{begin}{#1}% +} + +% End an event group +% +% Description: +% +% Creates an end event. + +\def\pgfgdendeventgroup{% + \pgfgdevent{end}{}% +} + + +% Creates an event group for the current TeX group +% +% #1 = event group name +% +% Description: +% +% Issues a begin event for #1 and, using \aftergroup, adds an end +% event at the end of the current tex group. + +\def\pgfgdeventgroup#1{% + \pgfgdbegineventgroup{#1}% + \aftergroup\pgfgdendeventgroup% +} + + + + + +% +% Nodes +% + + + +% +% Callback method for \pgfpositionnodelater +% +% This function is called by \pgfnode whenever a node has been newly +% created inside a graph drawing scope. It will create a new vertex on +% the Lua layer. +% +\def\pgf@gd@positionnode@callback{% + {% + % evaluate coordinates + \pgfmathsetmacro{\pgf@gd@node@minx}{\pgfpositionnodelaterminx}% + \pgfmathsetmacro{\pgf@gd@node@miny}{\pgfpositionnodelaterminy}% + \pgfmathsetmacro{\pgf@gd@node@maxx}{\pgfpositionnodelatermaxx}% + \pgfmathsetmacro{\pgf@gd@node@maxy}{\pgfpositionnodelatermaxy}% + % Assemble the Path object: + \directlua{pgf.temp = require 'pgf.gd.model.Path'.new ()}% + \let\pgfsyssoftpath@movetotoken\pgf@gd@movetotoken% + \let\pgfsyssoftpath@linetotoken\pgf@gd@linetotoken% + \let\pgfsyssoftpath@rectcornertoken\pgf@gd@rectcornertoken% + \let\pgfsyssoftpath@curvetosupportatoken\pgf@gd@curvetosupportatoken% + \let\pgfsyssoftpath@closepathtoken\pgf@gd@closepathtoken% + \pgfpositionnodelaterpath% + % + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}% + % + {% + \pgf@process{\pgfpointanchor{\pgfpositionnodelatername}{center}} + \pgfsettransform{\csname pgf@sh@nt@\pgfpositionnodelatername\endcsname}% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x=\pgf@x% + \global\pgf@y=\pgf@y% + }% + % call lua system library to create a lua node object + \directlua{ + pgf.gd.interface.InterfaceToDisplay.createVertex( + string.sub('\pgfutil@luaescapestring{\pgfpositionnodelatername}',30), % strip "not yet positionedPGFINTERNAL" + '\pgfutil@luaescapestring{\csname pgf@sh@ns@\pgfpositionnodelatername\endcsname}', + pgf.temp:pad((\pgf@sys@tonumber\pgf@xa+\pgf@sys@tonumber\pgf@ya)/2), % Padded path + \the\pgf@gd@parameter@stack@height, % Stack height + {% Binding info + x_min = \pgf@gd@node@minx, + y_min = \pgf@gd@node@miny, + x_max = \pgf@gd@node@maxx, + y_max = \pgf@gd@node@maxy, + tex_box_number = \pgfpositionnodelaterbox + }, + {% Anchors + center = require 'pgf.gd.model.Coordinate'.new(\pgf@sys@tonumber\pgf@x,\pgf@sys@tonumber\pgf@y) + } + ) + pgf.temp = nil + } + }% +} + + +\def\pgf@gd@movetotoken#1#2{\directlua{pgf.temp:appendMoveto(\Pgf@geT#1,\Pgf@geT#2)}} +\def\pgf@gd@linetotoken#1#2{\directlua{pgf.temp:appendLineto(\Pgf@geT#1,\Pgf@geT#2)}} +\def\pgf@gd@rectcornertoken#1#2#3#4#5{% + \directlua{% + local x,y,dx,dy=\Pgf@geT#1,\Pgf@geT#2,\Pgf@geT#4,\Pgf@geT#5 + pgf.temp:appendMoveto(x,y) + pgf.temp:appendLineto(x,y+dy) + pgf.temp:appendLineto(x+dx,y+dy) + pgf.temp:appendLineto(x+dx,y) + pgf.temp:appendClosepath()% + }% +} +\def\pgf@gd@curvetosupportatoken#1#2#3#4#5#6#7#8{\directlua{pgf.temp:appendCurveto(\Pgf@geT#1,\Pgf@geT#2,\Pgf@geT#4,\Pgf@geT#5,\Pgf@geT#7,\Pgf@geT#8)}} +\def\pgf@gd@closepathtoken#1#2{\directlua{pgf.temp:appendClosepath()}} + + +% Set options for an already existing node +% +% #1 = node name +% +% These node parameters of #1 will be updated with the current values +% of the node parameters. The node #1 must previously have been passed +% to the gd engine. If some of the options have already been set for +% the node, these settings will be overruled. + +\def\pgfgdsetlatenodeoption#1{% + \directlua{ + pgf.gd.interface.InterfaceToDisplay.addToVertexOptions('\pgfutil@luaescapestring{#1}',\the\pgf@gd@parameter@stack@height) + } +} + + + +% +% A callback for rendering (finally positioning) a node +% +% #1 = name of the node +% #2 = x min of the bounding box +% #3 = x max of the bounding box +% #4 = y min of the bounding box +% #5 = y max of the bounding box +% #6 = desired x pos of the node +% #7 = desired y pos of the node +% #8 = box register number of the TeX node +% +% This callback will be called by the engine for every original node +% when it finally needs to placed at a final position. + +\def\pgfgdcallbackrendernode#1#2#3#4#5#6#7#8{% + {% + \def\pgfpositionnodelatername{#1} + \def\pgfpositionnodelaterminx{#2} + \def\pgfpositionnodelatermaxx{#3} + \def\pgfpositionnodelaterminy{#4} + \def\pgfpositionnodelatermaxy{#5} + \directlua{pgf.gd.interface.InterfaceCore.binding:retrieveBox(#8,\pgfpositionnodelaterbox)} + \pgfpositionnodenow{\pgfqpoint{#6}{#7}} + }% +} + + + +% Adds an edge to the graph +% +% #1 = first node +% #2 = second node +% #3 = edge direction +% #4 = edge options (will be executed in a protected environment) +% #5 = aux stuff (curtesy for TikZ -- edge nodes) +% +% Description: +% +% Creating an edge means that you tell the graph drawing algorithm +% that #1 and #2 are connected. The "kind" of connection is indicated +% by #3, which may be one of the following: +% +% -> = a directed edge (also known as an arc) from #1 to #2 +% -- = an undirected edge between #1 and #2 +% <- = a directed edge from #2 to #1, but with the "additional hint" +% that this is a "backward" edge. A graph drawing algorithm may +% or may not take this hint into account +% <-> = a bi-directed edge between #1 and #2. +% +% +% The parameters #4 and #5 are a bit more tricky. When an edge between +% two vertices of a graph is created via \pgfgdedge, nothing is +% actually done immediately. After all, without knowing the final +% positions of the nodes #1 and #2, there is no way of +% creating the actual drawing commands for the edge. Thus, the actual +% drawing of the edge is done only when the graph drawing algorithm is +% done (namely in the macro \pgfgdcallbackedge, see later). +% +% Because of this "delayed" drawing of edges, options that influence +% the edge must be retained until the moment when the edge is actually +% drawn. Parameters #4 and #5 store such options. +% +% Let us start with #4. This parameter should be set to a list of +% key-value pairs like +% +% /tikz/.cd, color=red, very thick, this edge must be vertical +% +% Some of these options may be of interest to the graph drawing +% algorithm (like the last option) while others will +% only be important during the drawing of edge (like the first +% option). The options that are important for the graph drawing +% algorithm must be passed to the algorithm via setting keys that have +% been declared using the handler .edge parameter (see +% above). +% +% The tricky part is that options that are of interest to the graph +% drawing algorithm must be executed *before* the algorithm starts, +% but the options as a whole are usually only executed during the +% drawing of the edges, which is *after* the algorithm has finished. +% +% To overcome this problem, the following happens: +% +% The options in #4 are executed "tentatively" inside +% \pgfgdedge. However, this execution is done in a "heavily guarded +% sandbox" where all effects of the options (like changing the +% color or the line width) do not propagate beyond the sandbox. Only +% the changes of the graph drawing edge parameters leave the +% sandbox. These parameters are then passed down to the graph drawing +% engine. +% +% Later, when the edge is drawn using \pgfgdcallbackedge, the options #4 +% are available once more and then they are executed normally. +% +% Note that when the options in #4 are executed, no path is +% preset. Thus, you typically need to start it with, say, /tikz/.cd. +% +% +% The text in #5 is some "auxilliary" text that is simply stored away +% and later directly to \pgfgdcallbackedge. This is a curtesy to TikZ, +% which can use it to store its node labels. +% +% Example: +% +% \pgfgdedge{A}{B}{->}{red}{} +% +\def\pgfgdedge#1#2#3#4#5{% + % Ok, setup sandbox + \begingroup% + \setbox0=\hbox{{% + \pgfinterruptpath% + \pgfgdprepareedge% + \pgfkeys{#4}% + % create edge in Lua + \toks0={#4}% + \toks1={#5}% + \directlua{ + pgf.gd.interface.InterfaceToDisplay.createEdge( + '\pgfutil@luaescapestring{#1}','\pgfutil@luaescapestring{#2}','\pgfutil@luaescapestring{#3}', + \the\pgf@gd@parameter@stack@height, + { pgf_options = '\pgfutil@luaescapestring{\the\toks0}', + pgf_edge_nodes = '\pgfutil@luaescapestring{\the\toks1}', + }) + }% + \endpgfinterruptpath% + }}% + \endgroup% +} + +\let\pgfgdprepareedge=\pgfutil@empty +\def\pgfgdaddprepareedgehook#1{\expandafter\def\expandafter\pgfgdprepareedge\expandafter{\pgfgdprepareedge#1}} + + +\newif\ifpgf@gd@nodes@behind@edges + + + +% Define a callback for rendering edges +% +% #1 = macro name +% +% Descriptions: +% +% This is a callback from the graph drawing engine. At the end of the +% creation of a graph, when the nodes have been positioned, this macro +% is called once for each edge. The macro should take the following +% parameters: +% +% #1 = from node, optionally followed by "." and the tail anchor +% #2 = to node, optionally followed by "." and the head anchor +% #3 = direction (<-, --, ->, or <->) +% #4 = original options +% #5 = aux text (typically edge nodes) +% #6 = algorithm-generated options +% #7 = bend information +% +% The first five parameters are the original values that were passed +% down to the \pgfgdedge command. +% +% #6 contains options that have been "computed by the algorithm". For +% instance, an algorithm might have determined, say, flow capacities +% for edges and it might now wish to communicate this information back +% to the upper layers. These options should be executed with the path +% /graph drawing. +% +% #7 contains algorithmically-computed information concerning how the +% edge should bend. This will be a text like +% "--(10pt,20pt)--(30pt,40pt)" in tikz-syntax, using the path +% operations "--", "..controls" and "--cycle". +% +% By default, a simple line is drawn between the nodes. Usually, you +% will wish to install a more "fancy" callback, here. + +\def\pgfgdsetedgecallback#1{\let\pgfgdcallbackedge=#1} + +\def\pgfgddefaultedgecallback#1#2#3#4#5#6#7{% + {% + \pgfscope + \pgfpathmoveto{ + \pgfutil@in@.{#1}% + \ifpgfutil@in@ + \pgf@gd@unravel#1\relax% + \else + \pgfpointshapeborder{#1}{\pgfpointanchor{#2}{center}} + \fi + } + \pgfpathlineto{ + \pgfutil@in@.{#2}% + \ifpgfutil@in@ + \pgf@gd@unravel#2\relax% + \else + \pgfpointshapeborder{#2}{\pgfpointanchor{#1}{center}} + \fi + } + \pgfusepath{stroke} + \endpgfscope + } +} + +\pgfgdsetedgecallback{\pgfgddefaultedgecallback} + +\def\pgf@gd@unravel#1.#2\relax{% + \pgfpointanchor{#1}{#2}% +} + + + + +% Callbacks: Called before the shipout of nodes and edges starts +% +% First, the general begin shipout is called. Then, the node shipout +% starts, the nodes are created, and then the end of the node shipout +% is signaled. Next, the edge shipout starts and ends. Finally, the +% end shipout is called. + +\def\pgfgdcallbackbeginshipout{% + \pgfscope% + \catcode`\@=11\relax% + \setbox\pgf@gd@prekind@box=\box\pgfutil@voidb@x% + \setbox\pgf@gd@postkind@box=\box\pgfutil@voidb@x% +} +\def\pgfgdcallbackendshipout{% + \box\pgf@gd@prekind@box% + \ifpgf@gd@nodes@behind@edges% + \box\pgf@gd@node@box% + \box\pgf@gd@edge@box% + \else% + \box\pgf@gd@edge@box% + \box\pgf@gd@node@box% + \fi% + \box\pgf@gd@postkind@box% + \endpgfscope +} + +\newbox\pgf@gd@node@box +\newbox\pgf@gd@edge@box +\newbox\pgf@gd@prekind@box +\newbox\pgf@gd@postkind@box + +\def\pgfgdcallbackbeginnodeshipout{% + \setbox\pgf@gd@node@box=\hbox\bgroup% +} +\def\pgfgdcallbackendnodeshipout{% + \egroup% +} + +\def\pgfgdcallbackbeginedgeshipout{% + \setbox\pgf@gd@edge@box=\hbox\bgroup% +} + +\def\pgfgdcallbackendedgeshipout{% + \egroup +} + + + + +% Generate a node +% +% This callback is called from the engine whenever an algorithm +% generates a new node internally. +% +% #1 = name of the node +% #2 = shape of the node +% #3 = options generated by the algorithm in key-value syntax. The set +% of generated options is algorithm-dependent. +% #4 = text +% +% This is an internal function and will be called by the binding layer + +\def\pgfgdcallbackcreatevertex#1#2#3#4{% + { + \pgfkeys{#3} + \pgfnode{#2}{\pgfkeysvalueof{/graph drawing/generated + node/anchor}}{#4}{#1}{\pgfkeysvalueof{/graph drawing/generated + node/use path}} + } +} + +\pgfkeys{ + /graph drawing/generated node/anchor/.initial=center, + /graph drawing/generated node/use path/.initial=\pgfusepath{} +} + + + +% +% Sublayouts +% +% Description: For a general introduction to (sub)layouts, see +% Section~\ref{section-gd-sublayouts} in the manual. +% + +\def\pgfgdbeginlayout{ + \begingroup + \pgfgdlayoutscopeactivetrue + \advance\pgf@gd@parameter@stack@height by1\relax% + \directlua{pgf.gd.interface.InterfaceToDisplay.pushLayout(\the\pgf@gd@parameter@stack@height)} +} + +\def\pgfgdendlayout{ + \endgroup% +} + + + + +% Creates a subgraph node +% +% #1 = name +% #2 = node options +% #3 = node text +% +% Description: +% +% A subgraph node is a node that "surrounds" the nodes 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 pgf level and on the lua level, but the +% actual node is only created inside the layout pipeline using a +% callback. The actual node creation happens when the innermost layout +% in which the subgraph node is declared has finished. +% +% When you create a subgraph node using this macro, you also start a +% collection (of an internal kind) that stores the subgraph. All +% following nodes in the current TeX scope will become part of this +% collection. +% +% See |InterfaceToDisplay.pushSubgraphVertex| for details. + +\def\pgfgdsubgraphnode#1#2#3{% + \advance\pgf@gd@parameter@stack@height by1\relax% + {% + % create edge in Lua + \toks0={#2}% + \toks1={#3}% + \directlua{pgf.gd.interface.InterfaceToDisplay.pushSubgraphVertex% + ('\pgfutil@luaescapestring{#1}',\the\pgf@gd@parameter@stack@height, + { + shape = 'rectangle', % typically overwritten by the pgf_options: + pgf_options = '\pgfutil@luaescapestring{\the\toks0}', + text = '\pgfutil@luaescapestring{\the\toks1}', + }) + }% + } +} + +\def\pgfgdsubgraphnodecontents#1{% helper function + \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{% + \vrule width0pt height\pgfkeysvalueof{/graph drawing/subgraph bounding box height}\hfil}% +} + +\pgfgdset{ + subgraph point cloud/.initial=, + subgraph bounding box width/.initial=, + subgraph bounding box height/.initial=, +} + + +% +% Requests +% +% Description: +% +% This key is used to ``request'' a graph drawing scope and a +% layout. The objective of this key is to make it easier for users and +% algorithm designers to control the slightly involved +% back-and-forth-calling between the different layers. +% +% This key does the following: When called inside a pgfpicture +% (otherwise, the call is "illegal"), it will call a call-back with +% two parameters. This callback will get passed some code that should +% be executed at the beginning of ``the next scope'' and some code +% that should be executed at the end of that scope. +% +% The code passed to the callbacks will have a different effect, +% depending on whether we are currently inside a layout scope or not +% (if no graph drawing scope is open, we are +% not inside a layout). If we are not inside a layout scope (or if the +% layout scope has been interrupted), the code will issue a +% \pgfgdbeginscope command in the opening code and a corresponding +% scope ending command in the closing code. Next, the two code pieces +% always contain \pgfgdbeginlayout and \pgfgdendlayout. +% +% Note that the "@request scope and layout" key will not immediately +% trigger a layout scope to be created; rather, the TikZ callback will +% call it only at the beginning of the scope, which will be after +% other options in the current list of options have been parsed. So, +% when you write \graph [binary tree layout, significant sep=2em] ..., +% the "significant sep" option has an effect despite being given +% *after* the "@request scope and layout" key since the actual opening +% of the scope happens only before the "..." part is parsed. + +\pgfgdset{@request scope and layout/.code=\pgfgd@requestcallback{\pgfgdbeginrequest}{\pgfgdendrequest}} + +\def\pgfgd@requestcallback#1#2{% + #1\def\pgf@gd@after@request{#2\egroup}\bgroup\aftergroup\pgf@gd@after@request% +} % Default for basic layer + +\def\pgfgdbeginrequest{% + \ifpgfgdlayoutscopeactive% + \else% + \expandafter\pgfgdbeginscope% + \fi% + \pgfgdbeginlayout% +} +\def\pgfgdendrequest{% + \pgfgdendlayout% + \ifpgfgdlayoutscopeactive% + \else% + \expandafter\pgfgdendscope% + \fi% +} +\newif\ifpgfgdlayoutscopeactive + + +% Set the request callback +% +% #1 = A macro +% +% Description: +% +% Sets the request callback as described in the "@request scope and +% layout" key. + +\def\pgfgdsetrequestcallback#1{\let\pgfgd@requestcallback#1} + + + + +% +% An if that is true exactly if we are inside a graph drawing scope +% + +\newif\ifpgfgdgraphdrawingscopeactive + + +% Begins a new graph drawing scope +% +% Description: +% +% Inside a graph drawing scope, all pgf nodes that are newly created +% are automatically passed to the graph drawing engine. In contrast, +% edges have to be indicated explicitly using the macro \pgfgdedge +% (this is because it is somewhat unclear what, exactly, should count +% as an edge). Naturally, users typically will not call \pgfgdedge +% explicitly, but have styles and keys invoke it internally. +% +% Usage: +% +% \pgfgdset{algorithm=somealgorithm} +% \pgfgdbeginscope +% \pgfnode{rectangle}{center}{A}{A}{} +% \pgfnode{rectangle}{center}{B}{B}{} +% \pgfnode{rectangle}{center}{C}{C}{} +% \pgfgdedge{A}{B}{->}{}{} +% \pgfgdedge{B}{C}{->}{}{} +% \pgfgdedge{C}{A}{->}{}{} +% \pgfgdendscope +% +% Naturally, users will typically use TikZ's somewhat simpler syntax: ' +% +% \tikz \graph [some algorithm] { A -> B -> C -> A }; + +\def\pgfgdbeginscope{% + \begingroup % Protecting scope + % get options + \directlua{ + pgf.gd.interface.InterfaceToDisplay.beginGraphDrawingScope(\the\pgf@gd@parameter@stack@height) + }% + \begingroup % Inner scope, the actual nodes will be inserted after + % this scope has been closed + % Indicate that we are now inside a graph drawing scope + \pgfgdgraphdrawingscopeactivetrue + % Switch on late positioning + \pgfpositionnodelater{\pgf@gd@positionnode@callback} + % Switch on late edges + \pgfgd@latecallback% + % Kill transformations (will be added by the position now + % macros) + \pgftransformreset +} + + +% Ends a graph drawing scope +% +% Description: +% +% This macro invokes the selected graph drawing algorithm and +% ships out all nodes within this scope +% +% See \pgfgdbeginscope + +\def\pgfgdendscope{% + \directlua{ + pgf.gd.interface.InterfaceToDisplay.runGraphDrawingAlgorithm() + } + \endgroup + % Late positioning has ended + \directlua{pgf.gd.interface.InterfaceToDisplay.renderGraph()} + \directlua{pgf.gd.interface.InterfaceToDisplay.endGraphDrawingScope()} + \endgroup +} + + + + + + +% Hook into graph specification +% +% #1 = code +% +% Description: +% +% Allows you to specify code that should be active while the graph +% drawing engine collects the information concerning the graph, but +% which should no longer be active when the graph is rendered. + +\def\pgfgdaddspecificationhook#1{ + \expandafter\def\expandafter\pgfgd@latecallback\expandafter{\pgfgd@latecallback#1} +} +\let\pgfgd@latecallback\pgfutil@empty + + + + + + + + +% Loading further libraries + +% Include a graph drawing library file. +% +% #1 = List of names of library file. +% +% Description: +% +% This command includes a list of graph drawing library files. For +% each file X in the list, the file pgf.gd.X.lua is included using +% |require|. +% +% For the convenience of Context users, both round and square brackets +% are possible for the argument. +% +% +% Example: +% +% \usegdlibrary{trees} +% \usegdlibrary[force,circular] + +\def\usegdlibrary{\pgfutil@ifnextchar[{\use@gdlibrary}{\use@@gdlibrary}}%} +\def\use@gdlibrary[#1]{\use@@gdlibrary{#1}} +\def\use@@gdlibrary#1{% + \edef\pgf@list{#1}% + \pgfutil@for\pgf@temp:=\pgf@list\do{% + \expandafter\pgfkeys@spdef\expandafter\pgf@temp\expandafter{\pgf@temp}% + \ifx\pgf@temp\pgfutil@empty + \else + \directlua{if not pgf_lookup_and_require('\pgf@temp') then + tex.print('\pgfutil@luaescapestring{\noexpand\pgferror{Graph drawing library '\pgf@temp' not found}}') + end} + \fi + } +} + +% In the following code: Does anyone know how to determine the +% file-system separator in Lua? Or in TeX? +{ + \catcode`\%=11 +\directlua{ + function pgf_lookup_and_require(name) + local sep = '/' + if string.find(os.getenv('PATH'),';') then + sep = '\string\\' + end + local function lookup(name) + local sub = name:gsub('%.',sep) + local find_func = function (name, suffix) + if resolvers then + local n = resolvers.findfile (name, suffix) + return (not (n == '')) and n or nil + else + return kpse.find_file(name,suffix) + end + end + if find_func(sub, 'lua') then + require(name) + elseif find_func(sub, 'clua') then + collectgarbage('stop') + require(name) + collectgarbage('restart') + else + return false + end + return true + end + return + lookup('pgf.gd.' .. name .. '.library') or + lookup('pgf.gd.' .. name) or + lookup(name .. '.library') or + lookup(name) + end +} +} + + +% +% Ok, fire up the system by creating the binding! +% +\directlua{ + require 'pgf.gd.interface.InterfaceToDisplay' + pgf.gd.interface.InterfaceToDisplay.bind(require 'pgf.gd.bindings.BindingToPGF') +} + + + +% +% Special setup for keys that are declared by the above libraries, but +% that have a special meaning on the display layer. +% + +\pgfkeys{/graph drawing/nodes behind edges/.append code=\csname pgf@gd@nodes@behind@edges#1\endcsname} +\pgfkeys{/graph drawing/nodes behind edges/.default=true} + + + + +\endinput
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.examples.code.tex b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.examples.code.tex new file mode 100644 index 00000000000..4bfe4a839a3 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.examples.code.tex @@ -0,0 +1,17 @@ +% Copyright 2012 by Till Tantau +% +% This file may be distributed and/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 details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.examples.code.tex,v 1.2 2012/11/20 23:34:18 tantau Exp $ + +\usepgflibrary{graphdrawing} + +\usegdlibrary{examples} + + +\endinput
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.force.code.tex b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.force.code.tex new file mode 100644 index 00000000000..3950a9062e1 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.force.code.tex @@ -0,0 +1,136 @@ +% Copyright 2011 by Jannis Pohlmann +% +% This file may be distributed and/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 details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.force.code.tex,v 1.7 2012/11/20 23:34:18 tantau Exp $ + + + +\usepgflibrary{graphdrawing} + +\usegdlibrary{force} + +\endinput + + + +% +% Definition of spring algorithms as well as options to configure them. +% + +\pgfgdset{ + force based/.cd, + % + iterations/.graph parameter=number, + iterations/.parameter initial=500, + % + cooling factor/.graph parameter=number, + cooling factor/.parameter initial=0.95, + % + initial step dimension/.graph parameter=number, + initial step dimension/.parameter initial=0, + % + convergence tolerance/.graph parameter=number, + convergence tolerance/.parameter initial=0.01, + % + spring constant/.graph parameter=number, + spring constant/.parameter initial=0.01, + % + approximate electric forces/.graph parameter=boolean, + approximate electric forces/.parameter initial=false, + approximate electric forces/.default=true, + % + electric force order/.graph parameter=number, + electric force order/.parameter initial=1, + % + % Parameters related to the multilevel approach where the input graph + % is iteratively coarsened into graphs with fewer nodes, until either + % the number of nodes is small enough or the number of nodes in the + % could not be reduced by at least a user-defined ratio. + % + coarsen/.graph parameter=boolean, + coarsen/.parameter initial=true, + coarsen/.default=true, + % + coarsening/.code=\pgfkeys{ + /graph drawing/force based/coarsening/.cd, + #1 + }, + % + coarsening/downsize ratio/.graph parameter=number, + coarsening/downsize ratio/.parameter initial=0.25, + % + coarsening/minimum graph size/.graph parameter=number, + coarsening/minimum graph size/.parameter initial=2, + % + coarsening/collapse independent edges/.graph parameter=boolean, + coarsening/collapse independent edges/.parameter initial=true, + coarsening/collapse independent edges/.default=true, + % + coarsening/connect independent nodes/.graph parameter=boolean, + coarsening/connect independent nodes/.parameter initial=false, + coarsening/connect independent nodes/.default=true, + % + % Node parameters for spring algorithms. + % + % + % Edge parameters for spring algorithms. + % +} + +\pgfgddeclareforwardedkeys{/graph drawing}{ + % + electric charge/.node parameter=number, + electric charge/.parameter initial=1, +} + + +% +% Spring algorithm based on the paper +% +% "Efficient, High-Quality Force-Directed Graph Drawing" +% Yifan Hu, 2006 +% +\pgfgddeclarealgorithmkey + {spring layout} + {force based} + { + algorithm=pgf.gd.force.SpringHu2006 + } + + +% +% Spring-electrical algorithm based on the paper +% +% "Efficient, High-Quality Force-Directed Graph Drawing" +% Yifan Hu, 2006 +% +\pgfgddeclarealgorithmkey + {spring electrical layout} + {force based} + { + algorithm=pgf.gd.force.SpringElectricalHu2006, + force based/spring constant=0.2, + } + + + +% +% Spring-electrical algorithm based on the paper +% +% "A Multilevel Algorithm for Force-Directed Graph Drawing" +% C. Walshaw, 2000 +% +\pgfgddeclarealgorithmkey + {spring electrical layout'} + {force based} + { + algorithm=pgf.gd.force.SpringElectricalWalshaw2000, + force based/spring constant=0.01, + force based/convergence tolerance=0.001, + } diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.layered.code.tex b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.layered.code.tex new file mode 100644 index 00000000000..37f28bc304a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.layered.code.tex @@ -0,0 +1,17 @@ +% Copyright 2011 by Jannis Pohlmann +% +% This file may be distributed and/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 details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.layered.code.tex,v 1.5 2012/11/20 23:34:18 tantau Exp $ + +\usepgflibrary{graphdrawing} + +\usegdlibrary{layered} + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.trees.code.tex b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.trees.code.tex new file mode 100644 index 00000000000..7d0a9ed35b0 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.trees.code.tex @@ -0,0 +1,19 @@ +% Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster +% Copyright 2011 by Till Tantau +% +% This file may be distributed and/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 details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.trees.code.tex,v 1.8 2012/11/20 23:34:18 tantau Exp $ + + +\usepgflibrary{graphdrawing} +\usepgflibrary{graphdrawing.layered} + +\usegdlibrary{trees} + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/tikzlibrarygraphdrawing.code.tex b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/tikzlibrarygraphdrawing.code.tex new file mode 100644 index 00000000000..3c3532b394d --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/tikzlibrarygraphdrawing.code.tex @@ -0,0 +1,240 @@ +% Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster +% Copyright 2011 by Till Tantau +% +% This file may be distributed and/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 details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/tex/tikzlibrarygraphdrawing.code.tex,v 1.20 2013/08/05 18:22:47 tantau Exp $ + +\usepgflibrary{graphdrawing} + +\def\tikz@lib@ensure@gd@loaded{} + + +% Patch the level and sibling distances so that gd and plain tikz are +% in sync +\tikzset{level distance=1cm, sibling distance=1cm} + +% Patch node distance because of its special syntax. + +\pgfkeysgetvalue{/graph drawing/node distance/.@cmd}\tikz@lib@gd@node@dist@path +\pgfkeyslet{/graph drawing/node distance/orig/.@cmd}\tikz@lib@gd@node@dist@path + +\pgfkeysdef{/graph drawing/node distance}{ + \pgfutil@in@{ and }{#1}% + \ifpgfutil@in@% + \tikz@gd@convert@and#1\pgf@stop% + \else% + \tikz@gd@convert@and#1 and #1\pgf@stop% + \fi% +} +\def\tikz@gd@convert@and#1 and #2\pgf@stop{\pgfkeys{/graph drawing/node distance/orig={#1}}} + + + + +% +% Setup graph drawing for tikz +% + +\def\tikz@gd@request@callback#1#2{% + \tikzset{ + execute at begin scope={ + \tikzset{ + --/.style={arrows=-}, + -!-/.style={draw=none,fill=none}, + } + \pgfgdsetedgecallback{\pgfgdtikzedgecallback}% + % + % Setup for plain syntax + % + \pgfgdaddspecificationhook{\tikz@lib@gd@spec@hook}% + #1 + \let\tikzgdeventcallback\pgfgdevent% + \let\tikzgdeventgroupcallback\pgfgdeventgroup% + \let\tikzgdlatenodeoptionacallback\pgfgdsetlatenodeoption% + }, + execute at end scope={% + #2% + } + }% +} + +\pgfgdsetrequestcallback\tikz@gd@request@callback + + + +\pgfgdappendtoforwardinglist{/tikz/,/tikz/graphs/} + +\def\tikz@lib@gd@spec@hook{% + \tikzset{ + edge macro=\tikz@gd@plain@edge@macro, + /tikz/at/.style={/graph drawing/desired at={##1}}, + % + % Setup for the tree syntax (do this late so that grow options + % are still valid after a layout has been chosen) + % + /tikz/growth function=\relax, + /tikz/edge from parent macro=\tikz@gd@edge@from@parent@macro, + % + % Setup for the graphs syntax + % + /tikz/graphs/new ->/.code n args={4}{\pgfgdedge{##1}{##2}{->}{/tikz,##3}{##4}}, + /tikz/graphs/new <-/.code n args={4}{\pgfgdedge{##1}{##2}{<-}{/tikz,##3}{##4}}, + /tikz/graphs/new --/.code n args={4}{\pgfgdedge{##1}{##2}{--}{/tikz,##3}{##4}}, + /tikz/graphs/new <->/.code n args={4}{\pgfgdedge{##1}{##2}{<->}{/tikz,##3}{##4}}, + /tikz/graphs/new -!-/.code n args={4}{\pgfgdedge{##1}{##2}{-!-}{/tikz,##3}{##4}}, + /tikz/graphs/placement/compute position/.code=,% + } +} + +\pgfgdaddprepareedgehook{ + \tikz@enable@edge@quotes% + \let\tikz@transform=\pgfutil@empty% + \let\tikz@options=\pgfutil@empty% + \let\tikz@tonodes=\pgfutil@empty% +} + + +\tikzset{ + parent anchor/.forward to=/graph drawing/tail anchor, + child anchor/.forward to=/graph drawing/head anchor +} + +\def\pgfgdtikzedgecallback#1#2#3#4#5#6#7{% + \draw (#1) + edge [to path={#7 \tikztonodes},#3,#4,/graph drawing/.cd,#6,/tikz/.cd] + #5 + (#2); +} + +\def\tikz@gd@edge@from@parent@macro#1#2{ + [/utils/exec=\pgfgdedge{\tikzparentnode}{\tikzchildnode}{--}{/tikz,#1}{#2}] +} + +\def\tikz@gd@plain@edge@macro#1#2{ + \pgfgdedge{\tikztostart}{\tikztotarget}{--}{/tikz,#1}{#2} +} + + + +% +% Conversions: Convert coordinates into pairs of values surrounded by +% braces. +% + +\pgfgdset{ + conversions/canvas coordinate/.code={% + \tikz@scan@one@point\pgf@process#1% + \pgfmathsetmacro{\tikz@gd@temp@x}{\pgf@x} + \pgfmathsetmacro{\tikz@gd@temp@y}{\pgf@y} + \edef\pgfgdresult{pgf.gd.model.Coordinate.new(\tikz@gd@temp@x,\tikz@gd@temp@y)} + }, + conversions/coordinate/.code={% + \tikz@scan@one@point\pgf@process#1% + \pgfmathsetmacro{\tikz@gd@temp@x}{\pgf@x} + \pgfmathsetmacro{\tikz@gd@temp@y}{\pgf@y} + \edef\pgfgdresult{pgf.gd.model.Coordinate.new(\tikz@gd@temp@x,\tikz@gd@temp@y)} + } +} + + + +% +% Overwrite node callback +% + +\def\pgfgdcallbackcreatevertex#1#2#3#4{% + \node[every generated node/.try,name={#1},shape={#2},/graph drawing/.cd,#3]{#4};% +} + + +% +% Subgraph handling +% + +% "General" text placement for subgraph nodes that works with all node +% kinds. + +\tikzset{ + subgraph text top/.code=\tikz@lg@simple@contents@top{#1},% + subgraph text top/.default=text ragged, + subgraph text bottom/.code=\tikz@lg@simple@contents@bottom{#1},% + subgraph text bottom/.default=text ragged, + subgraph text sep/.initial=.1em, + subgraph text none/.code={ + \def\pgfgdsubgraphnodecontents##1{% + \pgf@y=\pgfkeysvalueof{/graph drawing/subgraph bounding box height}\relax% + \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{% + \vrule width0pt height.5\pgf@y depth.5\pgf@y\hfil}% + }% + }, +} + +\def\tikz@lg@simple@contents@top#1{% + \def\pgfgdsubgraphnodecontents##1{% + \vbox{% + \def\pgf@temp{##1}% + \ifx\pgf@temp\pgfutil@empty% + \else% + \ifx\pgf@temp\pgfutil@sptoken% + \else% + \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{% + \hsize=\pgfkeysvalueof{/graph drawing/subgraph bounding box width}\relax% + \vbox{\noindent\strut\tikzset{#1}\tikz@text@action\pgf@temp}% + }% + \fi% + \fi% + \pgfmathparse{\pgfkeysvalueof{/tikz/subgraph text sep}}% + \kern\pgfmathresult pt\relax% + \pgf@y=\pgfkeysvalueof{/graph drawing/subgraph bounding box height}\relax% + \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{% + \vrule width0pt height.5\pgf@y depth.5\pgf@y\hfil}% + }% + }% +} + +\def\tikz@lg@simple@contents@bottom#1{% + \def\pgfgdsubgraphnodecontents##1{% + {% + \pgf@y=\pgfkeysvalueof{/graph drawing/subgraph bounding box height}\relax% + \setbox0=\vbox{% + \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{\vrule width0pt height\pgf@y\hfil}% + \pgfmathparse{\pgfkeysvalueof{/tikz/subgraph text sep}}% + \kern\pgfmathresult pt\relax% + \def\pgf@temp{##1}% + \ifx\pgf@temp\pgfutil@empty% + \else% + \ifx\pgf@temp\pgfutil@sptoken% + \else% + \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{% + \hsize=\pgfkeysvalueof{/graph drawing/subgraph bounding box width}\relax% + \vbox{\noindent\strut\tikzset{#1}\tikz@text@action\pgf@temp}% + }% + \fi% + \fi% + }% + \pgf@ya=\ht0\relax% + \advance\pgf@ya by-.5\pgf@y\relax% + \ht0=.5\pgf@y\relax% + \dp0=\pgf@ya\relax% + \box0\relax% + }% + }% +} + +\tikzset{subgraph text top} + +\tikzset{ + subgraph nodes/.style={/tikz/every subgraph node/.style={#1}}, + graphs/subgraph nodes/.style={/tikz/every subgraph node/.style={#1}}, + graphs/@graph drawing setup/.style={/graph drawing/anchor at={(\tikz@lastx,\tikz@lasty)}} +} + + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.formats.functions.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.formats.functions.code.tex index a5af1c95e17..ae62fd31839 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.formats.functions.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.formats.functions.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.formats.functions.code.tex,v 1.3 2008/12/09 00:12:10 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.formats.functions.code.tex,v 1.4 2011/03/14 23:17:52 tantau Exp $ \usepgfmodule{datavisualization} @@ -131,12 +131,17 @@ \expandafter\def\expandafter\pgf@lib@dv@parsed\expandafter{\pgf@lib@dv@parsed\pgf@lib@dv@eval@func{#1}{#2}} \pgf@lib@dv@func@parse% } -\def\pgf@lib@dv@var var #1 :#2interval#3[#4:#5]{% +\def\pgf@lib@dv@var var #1 :{\pgfutil@ifnextchar\bgroup{\pgf@lib@dv@var@group{#1}}{\pgf@lib@dv@var@int{#1}}} +\def\pgf@lib@dv@var@group#1#2;{% + \expandafter\def\expandafter\pgf@lib@dv@parsed\expandafter{\pgf@lib@dv@parsed\pgf@lib@dv@group@var{#1}{#2}}% + \pgf@lib@dv@func@parse% +} +\def\pgf@lib@dv@var@int#1#2[#3:#4]{% \pgfutil@ifnextchar s{% - \pgf@lib@dv@samplesorsteps{#1}{#4}{#5}% + \pgf@lib@dv@samplesorsteps{#1}{#3}{#4}% }{% \expandafter\def\expandafter\pgf@lib@dv@parsed\expandafter{% - \pgf@lib@dv@parsed\pgf@lib@dv@samples@var{#1}{#4}{#5}{\pgfkeysvalueof{/pgf/data/samples}}}% + \pgf@lib@dv@parsed\pgf@lib@dv@samples@var{#1}{#3}{#4}{\pgfkeysvalueof{/pgf/data/samples}}}% \expandafter\pgf@lib@dv@func@parse\pgfutil@gobble% } } @@ -188,6 +193,13 @@ }% } +\def\pgf@lib@dv@group@var#1#2#3\pgf@stop{% + \foreach \pgf@lib@dv@iterator in {#2} {% + \pgfkeyslet{/data point/#1}{\pgf@lib@dv@iterator}% + #3\pgf@stop% + }% +} + \def\pgf@lib@dv@eval@func#1#2{% \pgfkeysvalueof{/pgf/data/evaluator}{#2}% \pgfkeyslet{/data point/#1}{\pgfmathresult}% diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.polar.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.polar.code.tex index f39adbbedaa..36e51541cee 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.polar.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.polar.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.polar.code.tex,v 1.2 2008/11/24 18:31:22 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.polar.code.tex,v 1.4 2011/02/22 22:07:24 tantau Exp $ \usepgfmodule{datavisualization} @@ -90,6 +90,10 @@ \fi \ifx\pgf@dv@radius\pgfutil@empty\else% \ifx\pgf@dv@radius\relax\else% + \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@angle}% + \pgfdvmathexitbyscientificformat{\pgf@dv@angle}{\pgf@dv@val}% + \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@radius}% + \pgfdvmathexitbyscientificformat{\pgf@dv@radius}{\pgf@dv@val}% \pgfmathsincos{\pgf@dv@angle}% \pgfmathmultiply{\pgfmathresultx}{\pgf@dv@radius}% \let\pgf@dv@polar@temp=\pgfmathresult @@ -126,15 +130,23 @@ \pgfkeysgetvalue{/data point/\pgfoovalueof{radius}}\pgf@dv@current@rad \ifx\pgf@dv@current@rad\relax \else - \ifdim\pgf@dv@current@rad pt=\pgf@dv@prev@rad pt% + \ifx\pgf@dv@current@rad\pgf@dv@prev@rad% \pgfooget{prev angle}\pgf@dv@prev@angle \pgfkeysgetvalue{/data point/\pgfoovalueof{angle}}\pgf@dv@current@angle \ifx\pgf@dv@current@angle\relax \else - \ifdim\pgf@dv@current@angle pt=\pgf@dv@prev@angle pt% + \ifx\pgf@dv@current@angle\pgf@dv@prev@angle% % do nothing \else% % Do arc: + \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@prev@angle}% + \pgfdvmathexitbyscientificformat{\pgf@dv@prev@angle}{\pgf@dv@val}% + \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@prev@rad}% + \pgfdvmathexitbyscientificformat{\pgf@dv@prev@rad}{\pgf@dv@val}% + \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@current@angle}% + \pgfdvmathexitbyscientificformat{\pgf@dv@current@angle}{\pgf@dv@val}% + \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@current@rad}% + \pgfdvmathexitbyscientificformat{\pgf@dv@current@rad}{\pgf@dv@val}% \pgfpatharcaxes{\pgf@dv@prev@angle}{\pgf@dv@current@angle} {\pgfpointscale{\pgf@dv@current@rad}{\pgfoovalueof{unit vector 0 degrees}}} {\pgfpointscale{\pgf@dv@current@rad}{\pgfoovalueof{unit vector 90 degrees}}}% @@ -157,32 +169,28 @@ % \method direction(#1) {% \ifx#1\pgfdvdirectionfromtoken - % Record angle and radius + % Record from angle and radius \xdef\pgf@dv@polar@from@angle{\pgfkeysvalueof{/data point/\pgfoovalueof{angle}}} \xdef\pgf@dv@polar@from@radius{\pgfkeysvalueof{/data point/\pgfoovalueof{radius}}} + \else\ifx#1\pgfdvdirectiontotoken% + % Record to angle and radius + \xdef\pgf@dv@polar@to@angle{\pgfkeysvalueof{/data point/\pgfoovalueof{angle}}} + \xdef\pgf@dv@polar@to@radius{\pgfkeysvalueof{/data point/\pgfoovalueof{radius}}} \else% - \pgfkeysgetvalue{/data point/\pgfoovalueof{radius}}\pgf@dv@polar@to@radius - \ifx\pgf@dv@polar@to@radius\relax - \else - \ifdim\pgf@dv@polar@to@radius pt=\pgf@dv@polar@from@radius pt% - \pgfkeysgetvalue{/data point/\pgfoovalueof{angle}}\pgf@dv@polar@to@angle - \ifx\pgf@dv@polar@to@angle\relax - \else - \ifdim\pgf@dv@polar@to@angle pt=\pgf@dv@polar@from@angle pt% - % do nothing - \else% - % Output vector that it orthogonal to start angle: - \ifdim\pgf@dv@polar@to@angle pt>\pgf@dv@polar@from@angle pt% - \pgf@process{\pgfpointpolar{\pgf@dv@polar@from@angle+90}{1pt}} - \else - \pgf@process{\pgfpointpolar{\pgf@dv@polar@from@angle-90}{1pt}} - \fi - \pgfdvhandledtrue - \fi% - \fi% + \ifx\pgf@dv@polar@from@radius\pgf@dv@polar@to@radius% + \pgfdvmathenter{\pgf@dv@a}{\pgf@dv@polar@from@angle}% + \pgfdvmathenter{\pgf@dv@b}{\pgf@dv@polar@to@angle}% + \pgfdvmathifless{\pgf@dv@a}{\pgf@dv@b}{\def\pgf@dv@temp@sign{+}}{\def\pgf@dv@temp@sign{-}}% + \pgfkeysgetvalue{/data point/\pgfoovalueof{angle}}\pgf@temp% + \ifx\pgf@temp\relax% + \else% + \pgfdvmathenter{\pgf@dv@val}{\pgf@temp}% + \pgfdvmathexitbyscientificformat{\pgf@dv@polar@angle}{\pgf@dv@val}% + \pgf@process{\pgfpointpolar{\pgf@dv@polar@angle\pgf@dv@temp@sign90}{1pt}}% + \pgfdvhandledtrue% \fi% \fi% - \fi% + \fi\fi% } } diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.markings.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.markings.code.tex index dcb98da9119..546301c4d07 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.markings.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.markings.code.tex @@ -14,7 +14,7 @@ % scopes, essentially) at certain positions of a path. \pgfkeys{ - /pgf/decoration/reset marks/.code=\let\pgf@lib@dec@mark@marks=\pgfutil@empty, + /pgf/decoration/reset marks/.code=\let\pgf@lib@dec@mark@marks\pgfutil@empty, /pgf/decoration/mark/.code=\pgf@lib@dec@parsemark#1\pgf@lib@dec@stop, } @@ -33,17 +33,8 @@ } \def\pgf@lib@dec@arrowhead#1#2{% - \expandafter\ifx\csname tikz@special@arrow@end#2\endcsname\relax% be nice to TikZ - \pgfsetarrowsend{#2} - \else% - \pgfsetarrowsend{\csname tikz@special@arrow@end#2\endcsname}% - \fi% - \pgf@x=0pt% - \pgf@shorten@end% - \pgftransformxshift{-\pgf@x} \pgftransformxscale{#1} - \pgflowlevelsynccm% - \pgflowlevelobj{}{\pgf@endarrow}% + \pgfarrowdraw{#2}% } \def\pgf@lib@dec@doarrowhead#1{% diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.shapes.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.shapes.code.tex index 6e1b25101bd..8cf75a739bd 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.shapes.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.shapes.code.tex @@ -163,9 +163,9 @@ % Check the shape exists. % \pgfutil@ifundefined{pgf@sh@bg@\pgfkeysvalueof{/pgf/decoration/shape}}{% - \PackageError{PGF}{I do not know the shape `\pgfkeysvalueof{/pgf/decoration/shape}', + \pgferror{I do not know the shape `\pgfkeysvalueof{/pgf/decoration/shape}', so I cannot use it in a decoration. Check if its library been loaded or if you - simply mistyped the name}{}}{}% + simply mistyped the name}}{}% % % Calculate a `default' path size. % diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgflibraryluamath.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgflibraryluamath.code.tex new file mode 100644 index 00000000000..b06695a87fa --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgflibraryluamath.code.tex @@ -0,0 +1,499 @@ +% Copyright 2011 by Christophe Jorssen and Mark Wibrow +% +% This file may be distributed and/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 details. +% +% $Id: pgflibraryluamath.code.tex,v 1.11 2012/03/06 16:06:09 cjorssen Exp $ +% +% !!! Warning: this library does not work with fpu!!! + +% ******************************************************************* +% Some luatex stuff. Should be put elsewhere (e.g. in +% pgfutil-luatex-engine). + +% We assume luatex version > 0.39: +% - \directlua <general text> will work +% - \directlua is the only luatex primitive that we can assume +% accessible without being prefixed by the format via +% tex.enableprimitives. +% Ideas taken from the ifluatex package (Heiko Oberdiek) +\let\pgfutil@ifluatex\iffalse +\begingroup\expandafter\expandafter\expandafter\endgroup +\expandafter\ifx\csname directlua\endcsname\relax +\else + \expandafter\let\csname pgfutil@ifluatex\expandafter\endcsname + \csname iftrue\endcsname +\fi + +\pgfutil@ifluatex + \let\pgfutil@directlua\directlua + \pgfutil@directlua{% + tex.enableprimitives('pgfutil@',{'luaescapestring'})} +\else + \def\pgfutil@directlua#1{} + \def\pgfutil@luaescapestring#1{} +\fi + +% End of luatex stuff +% ******************************************************************* + +% Loading part: based on fpu library + +\newif\ifpgfluamathcomputationactive +\newif\ifpgfluamathparseractive + +\def\pgfluamath@makecomputationactive{% + \ifpgfluamathcomputationactive + \else + \pgfluamath@checkuninstallcmd% + \pgfluamath@install% + \pgfluamathcomputationactivetrue + \fi} + +\def\pgfluamath@makecomputationinactive{% + \ifpgfluamathcomputationactive + \pgfluamath@uninstall% + \pgfluamathcomputationactivefalse + \fi} + +\def\pgfluamath@makeparseractive{% + \ifpgfluamathparseractive + \else + \let\pgfluamath@pgfmathparse\pgfmathparse + \let\pgfmathparse\pgfluamathparse + \pgfluamathparseractivetrue + \fi} + +\def\pgfluamath@makeparserinactive{% + \ifpgfluamathparseractive + \let\pgfmathparse\pgfluamath@pgfmathparse + \pgfluamathparseractivefalse + \fi} + +\pgfqkeys{/pgf}{% + % Enable lua-side computation of \pgfmathresult + % (will be deactivated after the current TeX group) + luamath/.is choice, + luamath/only computation/.code={% + \pgfutil@ifluatex + \pgfluamath@makecomputationactive + \pgfluamath@makeparserinactive + \else + \pgfmath@error{Sorry, you need the luaTeX engine to use the + luamath library}% + \fi}, + luamath/parser and computation/.code={% + \pgfutil@ifluatex + \pgfluamath@makecomputationactive + \pgfluamath@makeparseractive + \else + \pgfmath@error{Sorry, you need the luaTeX engine to use the + luamath library}% + \fi}, + luamath/off/.code={% + \pgfluamath@makecomputationinactive + \pgfluamath@makeparserinactive}, + luamath/.default=only computation} + +\def\pgfluamath@uninstall@appendcmd#1{% + \expandafter\gdef\expandafter\pgfluamath@uninstall\expandafter{% + \pgfluamath@uninstall #1}} + +% If the uninstall command is already assembled, it will skip the +% uninstall assemblation. +\def\pgfluamath@checkuninstallcmd{% + \pgfutil@ifundefined{pgfluamath@uninstall}{% + \pgfutil@directlua{% + pgfluamathfunctions = require("pgfluamath.functions") + pgfluamathparser = require("pgfluamath.parser")} + \global\let\pgfluamath@uninstall=\pgfutil@empty + }{% + % We already HAVE an uninstall command (prepared globally). + % So: don't waste time assembling one! + \def\pgfluamath@uninstall@appendcmd##1{}% + \def\pgfluamath@prepareuninstallcmd##1{}% + }% +} + +% This assembles an uninstall command globally ON FIRST USAGE. +% See \pgfmathfloat@plots@checkuninstallcmd +\def\pgfluamath@prepareuninstallcmd#1{% + \expandafter\global\expandafter\let + \csname pgfluamath@backup@\string#1\endcsname=#1% + \expandafter\gdef\expandafter\pgfluamath@uninstall\expandafter{% + \pgfluamath@uninstall + \expandafter\let\expandafter#1\csname pgfluamath@backup@\string#1\endcsname}% +} + +\def\pgfluamath@install@function#1=#2{% + \pgfluamath@prepareuninstallcmd{#1}% + \let#1=#2% +} + +\def\pgfluamath@install{% + \pgfluamath@install@function\pgfmathadd@=\pgfluamathadd@% + \pgfluamath@install@function\pgfmathsubtract@=\pgfluamathsubtract@% + \pgfluamath@install@function\pgfmathneg@=\pgfluamathneg@% + \pgfluamath@install@function\pgfmathmultiply@=\pgfluamathmultiply@% + \pgfluamath@install@function\pgfmathdivide@=\pgfluamathdivide@% + % \pgfluamath@install@function\pgfmathdiv@=\pgfluamathdiv@% + \pgfluamath@install@function\pgfmathfactorial@=\pgfluamathfactorial@% + \pgfluamath@install@function\pgfmathsqrt@=\pgfluamathsqrt@% + % \pgfluamath@install@function\pgfmathpow@=\pgfluamathpow@% + \pgfluamath@install@function\pgfmathe@=\pgfluamathe@% + \pgfluamath@install@function\pgfmathexp@=\pgfluamathexp@% + \pgfluamath@install@function\pgfmathln@=\pgfluamathln@% + \pgfluamath@install@function\pgfmathlogten@=\pgfluamathlogten@% + % \pgfluamath@install@function\pgfmathlogtwo@=\pgfluamathlogtwo@% + \pgfluamath@install@function\pgfmathabs@=\pgfluamathabs@% + \pgfluamath@install@function\pgfmathmod@=\pgfluamathmod@% + \pgfluamath@install@function\pgfmathMod@=\pgfluamathMod@% + \pgfluamath@install@function\pgfmathround@=\pgfluamathround@% + \pgfluamath@install@function\pgfmathfloor@=\pgfluamathfloor@% + \pgfluamath@install@function\pgfmathceil@=\pgfluamathceil@% + % \pgfluamath@install@function\pgfmathint@=\pgfluamathint@% + % \pgfluamath@install@function\pgfmathfrac@=\pgfluamathfrac@% + % \pgfluamath@install@function\pgfmathreal@=\pgfluamathreal@% + \pgfluamath@install@function\pgfmathgcd@=\pgfluamathgcd@% + \pgfluamath@install@function\pgfmathisprime@=\pgfluamathisprime@% + \pgfluamath@install@function\pgfmathpi@=\pgfluamathpi@% + \pgfluamath@install@function\pgfmathrad@=\pgfluamathrad@% + \pgfluamath@install@function\pgfmathdeg@=\pgfluamathdeg@% + \pgfluamath@install@function\pgfmathsin@=\pgfluamathsin@% + \pgfluamath@install@function\pgfmathcos@=\pgfluamathcos@% + \pgfluamath@install@function\pgfmathtan@=\pgfluamathtan@% + \pgfluamath@install@function\pgfmathsec@=\pgfluamathsec@% + \pgfluamath@install@function\pgfmathcosec@=\pgfluamathcosec@% + \pgfluamath@install@function\pgfmathcot@=\pgfluamathcot@% + \pgfluamath@install@function\pgfmathasin@=\pgfluamathasin@% + \pgfluamath@install@function\pgfmathacos@=\pgfluamathacos@% + \pgfluamath@install@function\pgfmathatan@=\pgfluamathatan@% + \pgfluamath@install@function\pgfmathatantwo@=\pgfluamathatantwo@% + \pgfluamath@install@function\pgfmathmax@=\pgfluamathmax@% + \pgfluamath@install@function\pgfmathmin@=\pgfluamathmin@% + % \pgfluamath@install@function\pgfmath@pi=\pgfluamathpi@% + % \pgfluamath@install@function\pgfmathpi=\pgfluamathpi@% + % \pgfluamath@install@function\pgfmathe@=\pgfluamathe@% + % \pgfluamath@install@function\pgfmathe=\pgfluamathe@% + % \pgfluamath@install@function\pgfmathlessthan@=\pgfluamathlessthan@% + % \pgfluamath@install@function\pgfmathless@=\pgfluamathlessthan@% + % \pgfluamath@install@function\pgfmathgreaterthan@=\pgfluamathgreaterthan@% + % \pgfluamath@install@function\pgfmathgreater@=\pgfluamathgreaterthan@% + % \pgfluamath@install@function\pgfmathpow@=\pgfluamathpow@ + \pgfluamath@install@function\pgfmathrand@=\pgfluamathrand@ + \pgfluamath@install@function\pgfmathrand=\pgfluamathrand@ + \pgfluamath@install@function\pgfmathrnd@=\pgfluamathrnd@ + \pgfluamath@install@function\pgfmathrnd=\pgfluamathrnd@ + % \pgfluamath@install@function\pgfmathtrue@=\pgfluamathtrue@ + % \pgfluamath@install@function\pgfmathfalse@=\pgfluamathfalse@ + % \pgfluamath@install@function\pgfmathnot@=\pgfluamathnot@ + % \pgfluamath@install@function\pgfmathhex@=\pgfluamathhex@ + % \pgfluamath@install@function\pgfmathHex@=\pgfluamathHex@ + % \pgfluamath@install@function\pgfmathoct@=\pgfluamathoct@ + % \pgfluamath@install@function\pgfmathbin@=\pgfluamathbin@ + % \pgfluamath@install@function\pgfmathand@=\pgfluamathand@ + % \pgfluamath@install@function\pgfmathor@=\pgfluamathor@ + % \pgfluamath@install@function\pgfmathfactorial@=\pgfluamathfactorial@ + % \pgfluamath@install@function\pgfmathveclen@=\pgfluamathveclen@ + % \pgfluamath@install@function\pgfmathcosh@=\pgfluamathcosh@ + % \pgfluamath@install@function\pgfmathsinh@=\pgfluamathsinh@ + % \pgfluamath@install@function\pgfmathtanh@=\pgfluamathtanh@ + % \pgfluamath@install@function@unimplemented{ceil}% + % \pgfluamath@install@function@unimplemented{frac}% + % \pgfluamath@install@function@unimplemented{log2}% + % \pgfluamath@install@function@unimplemented{log10}% + % \pgfluamath@install@function@unimplemented{equalto}% + % \pgfluamath@install@function@unimplemented{random}% + % \pgfluamath@install@function@unimplemented{setseed}% + % \pgfluamath@install@function@unimplemented{Mod}% + % \pgfluamath@install@function@unimplemented{real}% + % \pgfluamath@install@function@unimplemented{notequal}% + \pgfluamath@install@function\pgfmathreciprocal=\pgfluamathreciprocal% + \pgfluamath@install@function\pgfpointnormalised=\pgfluamathpointnormalised +} + +\def\pgfluamathgetresult#1{% + \edef\pgfmathresult{\pgfutil@directlua{tex.print(-1,#1)}}} + +\def\pgfluamathpi@{% + \pgfluamathgetresult{pgfluamathfunctions.pi()}} +\def\pgfluamathe@{% + \pgfluamathgetresult{pgfluamathfunctions.e()}} +\def\pgfluamathadd@#1#2{% + \pgfluamathgetresult{pgfluamathfunctions.add(#1,#2)}} +\def\pgfluamathsubtract@#1#2{% + \pgfluamathgetresult{pgfluamathfunctions.substract(#1,#2)}} +\def\pgfluamathneg@#1{% + \pgfluamathgetresult{pgfluamathfunctions.neg(#1)}} +\def\pgfluamathmultiply@#1#2{% + \pgfluamathgetresult{pgfluamathfunctions.multiply(#1,#2)}} +\def\pgfluamathdivide@#1#2{% + \pgfluamathgetresult{pgfluamathfunctions.divide(#1,#2)}} +\def\pgfluamathabs@#1{% + \pgfluamathgetresult{pgfluamathfunctions.abs(#1)}} +\def\pgfluamathround@#1{% + \pgfluamathgetresult{pgfluamathfunctions.round(#1)}} +\def\pgfluamathfloor@#1{% + \pgfluamathgetresult{pgfluamathfunctions.floor(#1)}} +\def\pgfluamathceil@#1{% + \pgfluamathgetresult{pgfluamathfunctions.ceil(#1)}} +\def\pgfluamathgcd@#1#2{% + \pgfluamathgetresult{pgfluamathfunctions.gcd(#1,#2)}} +\def\pgfluamathisprime@#1{% + \pgfluamathgetresult{pgfluamathfunctions.isprime(#1)}} +\def\pgfluamathmax@#1{% + \pgfluamathgetresult{% + math.max(pgfluamathfunctions.split_braces_to_explist("#1"))}} +\def\pgfluamathmin@#1{% + \pgfluamathgetresult{% + math.min(pgfluamathfunctions.split_braces_to_explist("#1"))}} +\def\pgfluamathsin@#1{% + \pgfluamathgetresult{pgfluamathfunctions.Sin(#1)}} +\def\pgfluamathcos@#1{% + \pgfluamathgetresult{pgfluamathfunctions.Cos(#1)}} +\def\pgfluamathtan@#1{% + \pgfluamathgetresult{pgfluamathfunctions.Tan(#1)}} +\def\pgfluamathmod@#1#2{% + \pgfluamathgetresult{pgfluamathfunctions.mod(#1,#2)}} +\def\pgfluamathMod@#1#2{% + \pgfluamathgetresult{pgfluamathfunctions.Mod(#1,#2)}} +\def\pgfluamathrad@#1{% + \pgfluamathgetresult{pgfluamathfunctions.rad(#1)}} +\def\pgfluamathdeg@#1{% + \pgfluamathgetresult{pgfluamathfunctions.deg(#1)}} +\def\pgfluamathatan@#1{% + \pgfluamathgetresult{pgfluamathfunctions.aTan(#1)}} +\def\pgfluamathatantwo@#1#2{% + \pgfluamathgetresult{pgfluamathfunctions.aTan2(#1,#2)}} +\def\pgfluamathasin@#1{% + \pgfluamathgetresult{pgfluamathfunctions.aSin(#1)}} +\def\pgfluamathacos@#1{% + \pgfluamathgetresult{pgfluamathfunctions.aCos(#1)}} +\def\pgfluamathcot@#1{% + \pgfluamathgetresult{1/pgfluamathfunctions.Tan(#1)}} +\def\pgfluamathsec@#1{% + \pgfluamathgetresult{1/pgfluamathfunctions.Cos(#1)}} +\def\pgfluamathcosec@#1{% + \pgfluamathgetresult{1/pgfluamathfunctions.Sin(#1)}} +\def\pgfluamathexp@#1{% + \pgfluamathgetresult{pgfluamathfunctions.exp(#1)}} +\def\pgfluamathln@#1{% + \pgfluamathgetresult{pgfluamathfunctions.log(#1)}} +\def\pgfluamathlogten@#1{% + \pgfluamathgetresult{pgfluamathfunctions.log10(#1)}} +\def\pgfluamathsqrt@#1{% + \pgfluamathgetresult{pgfluamathfunctions.sqrt(#1)}} +\def\pgfluamathrnd@{% + \pgfluamathgetresult{pgfluamathfunctions.rnd()}} +\def\pgfluamathrand@{% + \pgfluamathgetresult{pgfluamathfunctions.rand(-1,1)}} +\def\pgfluamathfactorial@#1{% + \pgfluamathgetresult{pgfluamathfunctions.factorial(#1)}} +\def\pgfluamathreciprocal#1{% + \pgfluamathgetresult{1/#1}} +% \pgfluamath@install@function\pgfmath@pi=\pgfluamathpi@% +% \pgfluamath@install@function\pgfmathpi=\pgfluamathpi@% +% \pgfluamath@install@function\pgfmathe@=\pgfluamathe@% +% \pgfluamath@install@function\pgfmathe=\pgfluamathe@% +% \pgfluamath@install@function\pgfmathlessthan@=\pgfluamathlessthan@% +% \pgfluamath@install@function\pgfmathless@=\pgfluamathlessthan@% +% \pgfluamath@install@function\pgfmathgreaterthan@=\pgfluamathgreaterthan@% +% \pgfluamath@install@function\pgfmathgreater@=\pgfluamathgreaterthan@% +% \pgfluamath@install@function\pgfmathpow@=\pgfluamathpow@ +% \pgfluamath@install@function\pgfmathrand@=\pgfluamathrand@ +% \pgfluamath@install@function\pgfmathrand=\pgfluamathrand@ +% \pgfluamath@install@function\pgfmathrnd@=\pgfluamathrnd@ +% \pgfluamath@install@function\pgfmathrnd=\pgfluamathrnd@ +% \pgfluamath@install@function\pgfmathtrue@=\pgfluamathtrue@ +% \pgfluamath@install@function\pgfmathfalse@=\pgfluamathfalse@ +% \pgfluamath@install@function\pgfmathnot@=\pgfluamathnot@ +% \pgfluamath@install@function\pgfmathhex@=\pgfluamathhex@ +% \pgfluamath@install@function\pgfmathHex@=\pgfluamathHex@ +% \pgfluamath@install@function\pgfmathoct@=\pgfluamathoct@ +% \pgfluamath@install@function\pgfmathbin@=\pgfluamathbin@ +% \pgfluamath@install@function\pgfmathand@=\pgfluamathand@ +% \pgfluamath@install@function\pgfmathor@=\pgfluamathor@ +% \pgfluamath@install@function\pgfmathfactorial@=\pgfluamathfactorial@ +% \pgfluamath@install@function\pgfmathveclen@=\pgfluamathveclen@ +% \pgfluamath@install@function\pgfmathcosh@=\pgfluamathcosh@ +% \pgfluamath@install@function\pgfmathsinh@=\pgfluamathsinh@ +% \pgfluamath@install@function\pgfmathtanh@=\pgfluamathtanh@ + +\def\pgfluamathpointnormalised#1{% + \pgf@process{#1}% + \pgfutil@directlua{% + pgfluamathfunctions.pointnormalised(% + \pgf@sys@tonumber{\pgf@x},\pgf@sys@tonumber{\pgf@y})}% + \ignorespaces} + +% Parser + +\newif\ifpgfluamathunitsdeclared + +\def\pgfluamathparse#1{% + \pgfluamathunitsdeclaredfalse + % The following "two passes" (TeX -> lua -> TeX -> lua -> TeX) is + % required for chadef'ed named boxes. The parser + % adds \number in front of the box name (e.g. \mybox -> + % \number\mybox). Then this is expanded to the chardef'ed number via + % \edef expansion. + \edef\pgfluamath@temp{% + \pgfutil@directlua{% + % Double quotes " are needed here. On the lua side, single quotes + % ' are used. Take care to don't mix them. + pgfluamathparser.parse("\pgfutil@luaescapestring{#1}") + tex.sprint(parsed_expression)}}% + % We can now feed back the evaluator. + \edef\pgfluamathresult{% + \pgfutil@directlua{% + pgfluamathparser.eval('\pgfluamath@temp') + if pgfluamathparser.result == nil then + tex.print('nil') + else + tex.print(pgfluamathparser.result) + end}}% + \csname pgfluamathunitsdeclared\pgfutil@directlua{% + if pgfluamathparser.units_declared == true then + tex.print('true') + else + tex.print('false') + end}\endcsname + \ifpgfluamathparseractive + \let\pgfmathresult\pgfluamathresult + \let\ifpgfmathunitsdeclared=\ifpgfluamathunitsdeclared + \fi} + +\endinput +% NEW: CJ (06 March 2012) Work in progress +\documentclass{minimal} + +\usepackage{pgfmath} + +\makeatletter +\let\pgfutil@directlua\directlua + +\directlua{dofile('pgfmathparser.lua')} + +\def\pgfluamathdeclarefunction#1#2#3{% + \pgfutil@directlua{% + pgfluamath.declare_new_function('#1',#2,#3)}} + +\pgfluamathdeclarefunction{add}{2}{% + function (a,b) return a + b end} + +\pgfluamathdeclarefunction{substract}{2}{% + function (a,b) return a - (b) end} + +\pgfluamathdeclarefunction{neg}{1}{% + function (a) return -(a) end} + +\pgfluamathdeclarefunction{multiply}{2}{% + function (a,b) return a * b end} + +\pgfluamathdeclarefunction{divide}{2}{% + function (a,b) return a / b end} + +\pgfluamathdeclarefunction{pow}{2}{% + function (a,b) return math.pow(a,b) end} + +\pgfluamathdeclarefunction{deg}{1}{% + function (a) return math.deg(a) end} + +\pgfluamathdeclarefunction{ifthenelse}{3}{% + function (a,b,c) if a == 1 then return b else return c end end} + +\pgfluamathdeclarefunction{equal}{2}{% + function (a,b) if a == b then return 1 else return 0 end end} + +\pgfluamathdeclarefunction{greater}{2}{% + function (a,b) if a > b then return 1 else return 0 end end} + +\pgfluamathdeclarefunction{less}{2}{% + function (a,b) if a < b then return 1 else return 0 end end} + +\pgfluamathdeclarefunction{notequal}{2}{% + function (a,b) if a < b or a > b then return 1 else return 0 end end} + +\pgfluamathdeclarefunction{notless}{2}{% + function (a,b) if a >= b then return 1 else return 0 end end} + +\pgfluamathdeclarefunction{notgreater}{2}{% + function (a,b) if a <= b then return 1 else return 0 end end} + +\pgfluamathdeclarefunction{andPGF}{2}{% + function (a,b) if (a < 0 or a > 0) and (b < 0 or b > 0) then return + 1 else return 0 end end} + +\pgfluamathdeclarefunction{orPGF}{2}{% + function (a,b) if (a < 0 or a > 0) or (b < 0 or b > 0) then return 1 + else return 0 end end} + +\pgfluamathdeclarefunction{modulo}{2}{% + % This is the definition of the lua % modulo operator + % The % operator cannot be used here (catcode issue) + function (a,b) return a - math.floor(a/b)*b end} + +\pgfluamathdeclarefunction{int}{1}{% + function (a) return a - pgfluamath.defined_functions.modulo.code(a,1) end} + +\pgfluamathdeclarefunction{frac}{1}{% + function (a) return pgfluamath.defined_functions.modulo.code(a,1) end} + +\pgfluamathdeclarefunction{factorial}{1}{% + function (a) + a = math.abs(pgfluamath.defined_functions.int.code(a)) + if a == 1 then + return 1 + else + return a * pgfluamath.defined_functions.factorial.code(a-1) + end + end} + +\pgfluamathdeclarefunction{sqrt}{1}{% + function (a) return math.sqrt(a) end} + + + +\def\pgfluamathparseandresult#1{% + \pgfutil@directlua{% + local s = pgfluamath.transform_math_expr('#1',pgfluamath.defined_functions_pattern) + texio.write_nl('pgfluamath: parsed expression "' .. s .. '"') + loadstring('tex.sprint(-1,' .. s .. ')')()}} + +\makeatother +\begin{document} + +$\pgfluamathparseandresult{1+2} = 3$ + +$\pgfluamathparseandresult{2*3} = 6$ + +$\pgfluamathparseandresult{1--1} = 2$ + +$\pgfluamathparseandresult{6/2} = 3$ + +$\pgfluamathparseandresult{2^2} = 4$ + +$\pgfluamathparseandresult{1>2} = 0$ + +$\pgfluamathparseandresult{2>1} = 1$ + +$\pgfluamathparseandresult{1!=1} = 0$ + +$\pgfluamathparseandresult{1?2:3} = 2$ + +$\pgfluamathparseandresult{1.0||0} = 1$ + +$\pgfluamathparseandresult{1&&0} = 0$ + +$\pgfluamathparseandresult{sqrt(2)} = \pgfmathparse{sqrt(2)}\pgfmathresult$ + +%\pgfluamathparseandresult{{1,{2,3-7}[1],4}[1]^2} + +\end{document} +% Local Variables: +% TeX-engine: luatex +% End:
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.functions.lua b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.functions.lua new file mode 100644 index 00000000000..fa3c1872a58 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.functions.lua @@ -0,0 +1,313 @@ +-- Copyright 2011 by Christophe Jorssen +-- +-- This file may be distributed and/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 details. +-- +-- $Id: pgfluamath.functions.lua,v 1.9 2013/07/25 10:39:34 tantau Exp $ +-- + +local pgfluamathfunctions = pgfluamathfunctions or {} + +local mathabs, mathacos, mathasin = math.abs, math.acos, math.asin +local mathatan, mathatan2, mathceil = math.atan, math.atan2, math.ceil +local mathcos, mathcosh, mathdeg = math.cos, math.cosh, math.deg +local mathexp, mathfloor, mathfmod = math.exp, math.floor, math.fmod +local mathfrexp, mathhuge, mathldexp = math.frexp, math.huge, math.ldexp +local mathlog, mathlog10, mathmax = math.log, math.log10, math.max +local mathmin, mathmodf, mathpi = math.min, math.modf, math.pi +local mathpow, mathrad, mathrandom = math.pow, math.rad, math.random +local mathrandomseed, mathsin = math.randomseed, math.sin +local mathsinh, mathsqrt, mathtanh = math.sinh, math.sqrt, math.tanh +local mathtan = math.tan + +function pgfluamathfunctions.add(x,y) + return x+y +end + +function pgfluamathfunctions.substract(x,y) + return x-y +end + +function pgfluamathfunctions.neg(x) + return -x +end + +function pgfluamathfunctions.multiply(x,y) + return x*y +end + +function pgfluamathfunctions.divide(x,y) + return x/y +end + +function pgfluamathfunctions.pow(x,y) + return mathpow(x,y) +end + +function pgfluamathfunctions.factorial(x) +-- TODO: x must be an integer + if x == 0 then + return 1 + else + return x * factorial(x-1) + end +end + +function pgfluamathfunctions.deg(x) + return mathdeg(x) +end + +function pgfluamathfunctions.ifthenelse(x,y,z) + if x~= 0 then + return y + else + return z + end +end + +function pgfluamathfunctions.equal(x,y) + if x == y then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.greater(x,y) + if x > y then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.less(x,y) + if x < y then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.notequal(x,y) + if x ~= y then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.notless(x,y) + if x >= y then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.notgreater(x,y) + if x <= y then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.andPGF(x,y) + if (x ~= 0) and (y ~= 0) then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.orPGF(x,y) + if (x ~= 0) or (y ~= 0) then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.notPGF(x) + if x == 0 then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.pi() + return mathpi +end + +function pgfluamathfunctions.e() + return mathexp(1) +end + +function pgfluamathfunctions.abs(x) + return mathabs(x) +end + +function pgfluamathfunctions.floor(x) + return mathfloor(x) +end + +function pgfluamathfunctions.ceil(x) + return mathceil(x) +end + +function pgfluamathfunctions.exp(x) + return mathexp(x) +end + +function pgfluamathfunctions.log(x) + return mathlog(x) +end + +function pgfluamathfunctions.log10(x) + return mathlog10(x) +end + +function pgfluamathfunctions.sqrt(x) + return mathsqrt(x) +end + +function pgfluamathfunctions.rnd() + return mathrandom() +end + +function pgfluamathfunctions.rand() + return mathrandom(-1,1) +end + +function pgfluamathfunctions.deg(x) + return mathdeg(x) +end + +function pgfluamathfunctions.rad(x) + return mathrad(x) +end + +function pgfluamathfunctions.round(x) + if x<0 then + return -mathceil(mathabs(x)) + else + return mathceil(x) + end +end + +function pgfluamathfunctions.gcd(a, b) + if b == 0 then + return a + else + return gcd(b, a%b) + end +end + +function pgfluamathfunctions.isprime(a) + local ifisprime = true + if a == 1 then + ifisprime = false + elseif a == 2 then + ifisprime = true +-- if a > 2 then + else + local i, imax = 2, mathceil(mathsqrt(a)) + 1 + while ifisprime and (i < imax) do + if gcd(a,i) ~= 1 then + ifisprime = false + end + i = i + 1 + end + end + if ifisprime then + return 1 + else + return 0 + end +end + + +function pgfluamathfunctions.split_braces_to_explist(s) + -- (Thanks to mpg and zappathustra from fctt) + -- Make unpack available whatever lua version is used + -- (unpack in lua 5.1 table.unpack in lua 5.2) + local unpack = table.unpack or unpack + local t = {} + for i in s:gmatch('%b{}') do + table.insert(t, tonumber(i:sub(2, -2))) + end + return unpack(t) +end + +function pgfluamathfunctions.split_braces_to_table(s) + local t = {} + for i in s:gmatch('%b{}') do + table.insert(t, tonumber(i:sub(2, -2))) + end + return t +end + +function pgfluamathfunctions.mod(x,y) + if x/y < 0 then + return -(mathabs(x)%mathabs(y)) + else + return mathabs(x)%mathabs(y) + end +end + +function pgfluamathfunctions.Mod(x,y) + return mathabs(x)%mathabs(y) +end + +function pgfluamathfunctions.Sin(x) + return mathsin(mathrad(x)) +end + +function pgfluamathfunctions.Cos(x) + return mathcos(mathrad(x)) +end + +function pgfluamathfunctions.Tan(x) + return mathtan(mathrad(x)) +end + +function pgfluamathfunctions.aSin(x) + return mathdeg(mathasin(x)) +end + +function pgfluamathfunctions.aCos(x) + return mathdeg(mathacos(x)) +end + +function pgfluamathfunctions.aTan(x) + return mathdeg(mathatan(x)) +end + +function pgfluamathfunctions.aTan2(y,x) + return mathdeg(mathatan2(y,x)) +end + +function pgfluamathfunctions.pointnormalised (pgfx, pgfy) + local pgfx_normalised, pgfy_normalised + if pgfx == 0. and pgfy == 0. then + -- Orginal pgf macro gives this result + tex.dimen['pgf@x'] = "0pt" + tex.dimen['pgf@y'] = "1pt" + else + pgfx_normalised = pgfx/math.sqrt(pgfx^2 + pgfy^2) + pgfx_normalised = pgfx_normalised - pgfx_normalised%0.00001 + pgfy_normalised = pgfy/math.sqrt(pgfx^2 + pgfy^2) + pgfy_normalised = pgfy_normalised - pgfy_normalised%0.00001 + tex.dimen['pgf@x'] = tostring(pgfx_normalised) .. "pt" + tex.dimen['pgf@y'] = tostring(pgfy_normalised) .. "pt" + end + return nil +end + +return pgfluamathfunctions
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.parser.lua b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.parser.lua new file mode 100644 index 00000000000..b059e334358 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.parser.lua @@ -0,0 +1,647 @@ +-- Copyright 2011 by Christophe Jorssen and Mark Wibrow +-- +-- This file may be distributed and/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 details. +-- +-- $Id: pgfluamath.parser.lua,v 1.14 2012/04/29 20:36:29 ludewich Exp $ + +local pgfluamathparser = pgfluamathparser or {} + +require("pgfluamath.functions") + +-- lpeg is always present in luatex +local lpeg = require("lpeg") + +local S, P, R = lpeg.S, lpeg.P, lpeg.R +local C, Cc, Ct = lpeg.C, lpeg.Cc, lpeg.Ct +local Cf, Cg, Cs = lpeg.Cf, lpeg.Cg, lpeg.Cs +local V = lpeg.V + +local space_pattern = S(" \n\r\t")^0 + +local exponent_pattern = S("eE") + +local one_digit_pattern = R("09") +local positive_integer_pattern = one_digit_pattern^1 +local integer_pattern = P("-")^-1 * positive_integer_pattern +-- Valid positive decimals are |xxx.xxx|, |.xxx| and |xxx.| +local positive_decimal_pattern = (one_digit_pattern^1 * P(".") * + one_digit_pattern^1) + + (P(".") * one_digit_pattern^1) + + (one_digit_pattern^1 * P(".")) +local decimal_pattern = P("-")^-1 * positive_decimal_pattern +local float_pattern = decimal_pattern * exponent_pattern * integer_pattern +local number_pattern = float_pattern + decimal_pattern + integer_pattern + +local at_pattern = P("@") + +local underscore_pattern = P("_") + +local lower_letter_pattern = R("az") +local upper_letter_pattern = R("AZ") +local letter_pattern = lower_letter_pattern + upper_letter_pattern +local alphanum_pattern = letter_pattern + one_digit_pattern +local alphanum__pattern = alphanum_pattern + underscore_pattern +local alpha__pattern = letter_pattern + underscore_pattern + +local openparen_pattern = P("(") +local closeparen_pattern = P(")") +local opencurlybrace_pattern = P("{") +local closecurlybrace_pattern = P("}") +local openbrace_pattern = P("[") +local closebrace_pattern = P("]") + +-- local string = P('"') * C((1 - P('"'))^0) * P('"') + +local orop_pattern = P("||") +local andop_pattern = P("&&") + +local neqop_pattern = P("!=") + +local then_pattern = P("?") +local else_pattern = P(":") +local factorial_pattern = P("!") +local not_mark_pattern = P("!") +local radians_pattern = P("r") + +local comma_pattern = P(",") + +--[[ +local grammar = P { + -- "E" stands for expression + "ternary_logical_E", + ternary_logical_E = Cf(V("logical_or_E") * + Cg( then_mark * V("logical_or_E") * else_mark * V("logical_or_E"))^0,evalternary); + logical_or_E = Cf(V("logical_and_E") * Cg(orop * V("logical_and_E"))^0,evalbinary); + logical_and_E = Cf(V("equality_E") * Cg(andop * V("equality_E"))^0,evalbinary); + equality_E = Cf(V("relational_E") * + Cg((eqop * V("relational_E")) + (neqop * V("relational_E")))^0,evalbinary); + relational_E = Cf(V("additive_E") * Cg((lessop * V("additive_E")) + + (greatop * V("additive_E")) + + (lesseqop * V("additive_E")) + + (greateqop * V("additive_E")))^0,evalbinary); + additive_E = Cf(V("multiplicative_E") * Cg((addop * V("multiplicative_E")) + + (subop * V("multiplicative_E")))^0,evalbinary); + multiplicative_E = Cf(V("power_E") * Cg((mulop * V("power_E")) + + divop * V("power_E"))^0,evalbinary); + power_E = Cf(V("postfix_unary_E") * Cg(powop * V("postfix_unary_E"))^0,evalbinary); + postfix_unary_E = Cf(V("prefix_unary_E") * Cg(radians + factorial)^0,evalpostfixunary); + prefix_unary_E = Cf(Cg(not_mark + negop)^0 * V("E"),evalprefixunary), + E = string + float + decimal + integer / tonumber + + (openparen * V("ternary_logical_E") * closeparen) + + (func * param_beg * V("ternary_logical_E") * + (comma * V("ternary_logical_E"))^0 * param_end); +} + +local parser = space_pattern * grammar * -1 +--]] + +-- NOTE: \pgfmathparse{pi/3.14} will fail giving pgfluamathfunctions.pi()3.14 +-- (the / is missing, probably gobbled by one of the captures of the grammar). + +pgfluamathparser.transform_operands = P({ + 'transform_operands'; + + one_char = lpeg.P(1), + lowercase = lpeg.R('az'), + uppercase = lpeg.R('AZ'), + numeric = lpeg.R('09'), + dot = lpeg.P('.'), + exponent = lpeg.S('eE'), + sign_prefix = lpeg.S('-+'), + begingroup = lpeg.P('('), + endgroup = lpeg.P(')'), + backslash = lpeg.P'\\', + at = lpeg.P'@', + + alphabetic = lpeg.V'lowercase' + lpeg.V'uppercase', + alphanumeric = lpeg.V'alphabetic' + lpeg.V'numeric', + + integer = lpeg.V'numeric'^1, + real = lpeg.V'numeric'^0 * lpeg.V'dot' * lpeg.V'numeric'^1, + scientific = (lpeg.V'real' + lpeg.V'integer') * lpeg.V'exponent' * lpeg.V'sign_prefix'^0 * lpeg.V'integer', + + number = lpeg.V'scientific' + lpeg.V'real' + lpeg.V'integer', + function_name = lpeg.V('alphabetic') * lpeg.V('alphanumeric')^0, + + tex_cs = lpeg.V'backslash' * (lpeg.V'alphanumeric' + lpeg.V'at')^1, + tex_box_dimension_primative = lpeg.V'backslash' * (lpeg.P'wd' + lpeg.P'ht' + lpeg.P'dp'), + tex_register_primative = lpeg.V'backslash' * (lpeg.P'count' + lpeg.P'dimen'), + + tex_primative = lpeg.V'tex_box_dimension_primative' + lpeg.V'tex_register_primative', + tex_macro = -lpeg.V'tex_primative' * lpeg.V'tex_cs', + + tex_unit = + lpeg.P('pt') + lpeg.P('mm') + lpeg.P('cm') + lpeg.P('in') + + lpeg.P('ex') + lpeg.P('em') + lpeg.P('bp') + lpeg.P('pc') + + lpeg.P('dd') + lpeg.P('cc') + lpeg.P('sp'), + + tex_register_named = lpeg.C(lpeg.V'tex_macro'), + tex_register_numbered = lpeg.C(lpeg.V'tex_register_primative') * lpeg.C(lpeg.V'integer'), + tex_register_basic = lpeg.Cs(lpeg.Ct(lpeg.V'tex_register_numbered' + lpeg.V'tex_register_named') / pgfluamathparser.process_tex_register), + + tex_multiplier = lpeg.Cs((lpeg.V'tex_register_basic' + lpeg.C(lpeg.V'number')) / pgfluamathparser.process_muliplier), + + tex_box_width = lpeg.Cs(lpeg.P('\\wd') / 'width'), + tex_box_height = lpeg.Cs(lpeg.P('\\ht') / 'height'), + tex_box_depth = lpeg.Cs(lpeg.P('\\dp') / 'depth'), + tex_box_dimensions = lpeg.V'tex_box_width' + lpeg.V'tex_box_height' + lpeg.V'tex_box_depth', + tex_box_named = lpeg.Cs(lpeg.Ct(lpeg.V'tex_box_dimensions' * lpeg.C(lpeg.V'tex_macro')) / pgfluamathparser.process_tex_box_named), + tex_box_numbered = lpeg.Cs(lpeg.Ct(lpeg.V'tex_box_dimensions' * lpeg.C(lpeg.V'number')) / pgfluamathparser.process_tex_box_numbered), + tex_box_basic = lpeg.V'tex_box_named' + lpeg.V'tex_box_numbered', + + tex_register = lpeg.Cs(lpeg.V'tex_multiplier' * lpeg.V'tex_register_basic') + lpeg.V'tex_register_basic', + tex_box = lpeg.Cs(lpeg.Cs(lpeg.V'tex_multiplier') * lpeg.V'tex_box_basic') + lpeg.V'tex_box_basic', + tex_dimension = lpeg.Cs(lpeg.V'number' * lpeg.V'tex_unit' / pgfluamathparser.process_tex_dimension), + + tex_operand = lpeg.Cs(lpeg.V'tex_dimension' + lpeg.V'tex_box' + lpeg.V'tex_register'), + + function_name = lpeg.V'alphabetic' * (lpeg.V'alphanumeric'^1), + function_operand = lpeg.Cs(lpeg.Ct(lpeg.C(lpeg.V'function_name') * lpeg.C(lpeg.V'one_char') + lpeg.C(lpeg.V'function_name')) / pgfluamathparser.process_function), + + -- order is (always) important! + operands = lpeg.V'tex_operand' + lpeg.V'number' + lpeg.V'function_operand', + + transform_operands = lpeg.Cs((lpeg.V'operands' + 1)^0) + }) + +-- Namespaces will be searched in the following order. +pgfluamathparser.function_namespaces = { + 'pgfluamathfunctions', 'math', '_G'} + +pgfluamathparser.units_declared = false + +function pgfluamathparser.get_tex_box(box, dimension) + -- assume get_tex_box is only called when a dimension is required. + pgfluamathparser.units_declared = true + if dimension == 'width' then + return tex.box[box].width / 65536 -- return in points. + elseif dimension == 'height' then + return tex.box[box].height / 65536 + else + return tex.box[box].depth / 65536 + end +end + +function pgfluamathparser.get_tex_register(register) + -- register is a string which could be a count or a dimen. + if pcall(tex.getcount, register) then + return tex.count[register] + elseif pcall(tex.getdimen, register) then + pgfluamathparser.units_declared = true + return tex.dimen[register] / 65536 -- return in points. + else + pgfluamathparser.error = 'I do not know the TeX register "' .. register '"' + return nil + end + +end + +function pgfluamathparser.get_tex_count(count) + -- count is expected to be a number + return tex.count[tonumber(count)] +end + +function pgfluamathparser.get_tex_dimen(dimen) + -- dimen is expected to be a number + pgfluamathparser.units_declared = true + return tex.dimen[tonumber(dimen)] / 65536 +end + +function pgfluamathparser.get_tex_sp(dimension) + -- dimension should be a string + pgfluamathparser.units_declared = true + return tex.sp(dimension) / 65536 +end + + + +-- transform named box specification +-- e.g., \wd\mybox -> pgfluamathparser.get_tex_box["mybox"].width +-- +function pgfluamathparser.process_tex_box_named(box) + return 'pgfluamathparser.get_tex_box(\\number' .. box[2] .. ', "' .. box[1] .. '")' +end + +-- transform numbered box specification +-- e.g., \wd0 -> pgfluamathparser.get_tex_box["0"].width +-- +function pgfluamathparser.process_tex_box_numbered(box) + return 'pgfluamathparser.get_tex_box("' .. box[2] .. '", "' .. box[1] .. '")' +end + +-- transform a register +-- e.g., \mycount -> pgfluamathparser.get_tex_register["mycount"] +-- \dimen12 -> pgfluamathparser.get_tex_dimen[12] +-- +function pgfluamathparser.process_tex_register(register) + if register[2] == nil then -- a named register + return 'pgfluamathparser.get_tex_register("' .. register[1]:sub(2, register[1]:len()) .. '")' + else -- a numbered register + return 'pgfluamathparser.get_tex_' .. register[1]:sub(2, register[1]:len()) .. '(' .. register[2] .. ')' + end +end + +-- transform a 'multiplier' +-- e.g., 0.5 -> 0.5* (when followed by a box/register) +-- +function pgfluamathparser.process_muliplier(multiplier) + return multiplier .. '*' +end + +-- transform an explicit dimension to points +-- e.g., 1cm -> pgfluamathparser.get_tex_sp("1cm") +-- +function pgfluamathparser.process_tex_dimension(dimension) + return 'pgfluamathparser.get_tex_sp("' .. dimension .. '")' +end + +-- Check the type and 'namespace' of a function F. +-- +-- If F cannot be found as a Lua function or a Lua number in the +-- namespaces in containted in pgfluamathparser.function_namespaces +-- then an error results. +-- +-- if F is a Lua function and isn't followd by () (a requirement of Lua) +-- then the parentheses are inserted. +-- +-- e.g., random -> random() (if random is a function in the _G namespace) +-- pi -> math.pi (if pi is a constant that is only in the math namespace) +-- +function pgfluamathparser.process_function(function_table) + local function_name = function_table[1] + local char = function_table[2] + if (char == nil) then + char = '' + end + for _, namespace in pairs(pgfluamathparser.function_namespaces) do + local function_type = assert(loadstring('return type(' .. namespace .. '.' .. function_name .. ')'))() + if function_type == 'function' then + if not (char == '(') then + char = '()' + end + return namespace .. '.' .. function_name .. char + elseif function_type == 'number' then + return namespace .. '.' .. function_name .. char + end + end + pgfluamathparser.error = 'I don\'t know the function or constant \'' .. function_name .. '\'' +end + + +pgfluamathparser.remove_spaces = lpeg.Cs((lpeg.S' \n\t' / '' + 1)^0) + + +function pgfluamathparser.evaluate(expression) + assert(loadstring('pgfluamathparser._result=' .. expression))() + pgfluamathparser.result = pgfluamathparser._result +end + +function pgfluamathparser.parse(expression) + pgfluamathparser.write_to_log("Parsing expression:" .. expression) + pgfluamathparser.units_declared = false + + pgfluamathparser.error = nil + pgfluamathparser.result = nil + + -- Remove spaces + expression = pgfluamathparser.remove_spaces:match(expression) + + parsed_expression = + pgfluamathparser.transform_operands:match(expression) + pgfluamathparser.write_to_log("Transformed expression:" + .. parsed_expression) +end + +function pgfluamathparser.eval(expression) + pgfluamathparser.write_to_log("Evaluating expression:" .. expression) + pcall(pgfluamathparser.evaluate, expression) + pgfluamathparser.write_to_log("Result:" .. pgfluamathparser.result) + if pgfluamathparser.result == nil then + pgfluamathparser.error = "Sorry, I could not evaluate '" .. expression .. "'" + return nil + else + return pgfluamathparser.result + end +end + +pgfluamathparser.trace = true + +function pgfluamathparser.write_to_log (s) + if pgfluamathparser.trace then + texio.write_nl(s) + end +end + +return pgfluamathparser + +--[[ NEW: 2012/02/21, CJ, work in progress +-- We need 3 parsers (or 2, 2 and 3 could be merged) +-- (1) To get the number associated with a (\chardef'ed) box (e.g. +-- \ht\mybox -> \ht26) +-- This is part of a TeX ->(\directlua == \edef) -> lua -> (lpeg parser 1) +-- -> TeX -> (\directlua == \edef) +-- (2) To transform math and functions operands +-- (3) To transform units, dimen and count register + +-- TODO: strings delimited by "..." +-- TODO: units. \pgfmathparse{12+1cm}\pgfmathresult and \the\dimexpr 12pt+1cm\relax have the same result. Note: \pgfmathparse{(12+1)cm} won't work in plain pgfmath. +-- TODO: Parser 3 + + +pgfluamath = pgfluamath or {} + +pgfluamath.debug = true + +local lpeg = require('lpeg') +local P, R, S, V = lpeg.P, lpeg.R, lpeg.S, lpeg.V +local C, Cc, Cs = lpeg.C, lpeg.Cc, lpeg.Cs +local Cf, Cg, Ct = lpeg.Cf, lpeg.Cg, lpeg.Ct +local match = lpeg.match + +local space = S(' \n\t') + +local lowercase = R('az') +local uppercase = R('AZ') +local alphabetic = lowercase + uppercase + +local digit = R('09') + +local alphanumeric = alphabetic + digit + +local dot = P('.') +local exponent = S('eE') +local sign_prefix = S('+-') + +local integer = digit^1 +local float = (digit^1 * dot * digit^0) + (digit^0 * dot * digit^1) +local scientific = (float + integer) * exponent * sign_prefix^-1 * integer + +local number = scientific + float + integer + +local at = P('@') + +local backslash = P('\\') + +local box_width = P('\\wd') +local box_height = P('\\ht') +local box_depth = P('\\dp') +local box_dimension = box_width + box_height + box_depth + +local tex_cs = backslash * (alphabetic + at)^1 + +local lparen = P('(') +local rparen = P(')') + +local lbrace = P('{') +local rbrace = P('}') + +local lbracket = P('[') +local rbracket = P(']') + +local thenop = P('?') +local elseop = P(':') + +local orop = P('||') +local andop = P('&&') + +local eqop = P('==') +local neqop = P('!=') + +local greaterop = P('>') +local lessop = P('<') +local greatereqop = P('>=') +local lesseqop = P('<=') + +local addop = P('+') +local subop = P('-') + +local mulop = P('*') +local divop = P('/') + +local powop = P('^') + +local radop = P('r') + +local notop = P('!') +local negop = P('-') + +local comma = P(',') + +function pgfluamath.namedbox_to_numberedbox (s) + -- Transforms '{\wd|\ht|\dp}\mybox' to '{\wd|\ht|\dp}\number\mybox' + local function transform (capture) + print('Captured ' .. capture) + return '\\number' .. capture + end + local dimension_of_a_named_box = + box_dimension * space^0 * (tex_cs / transform) + -- P(1) matches exactly one character + -- V(1) is the entry of the grammar with index 1. It defines the initial rule. + -- The manual says: + -- "If that entry is a string, it is assumed to be the name of the initial rule. + -- Otherwise, LPeg assumes that the entry 1 itself is the initial rule." + local grammar = + P({ + [1] = (dimension_of_a_named_box + P(1)) * V(1) + P(true) + }) + return print(match(Cs(grammar),s)) +end +--[[ +namedbox_to_numberedbox('test') +namedbox_to_numberedbox('\\test') +namedbox_to_numberedbox('\\wd\\test') +namedbox_to_numberedbox('\\wd\\test0') +namedbox_to_numberedbox('\\wd\\test01') +namedbox_to_numberedbox('\\wd\\test@t 012') +namedbox_to_numberedbox(' \\wd \\test012') +namedbox_to_numberedbox('\\wd\\test012\\test \\ht\\zozo0') +namedbox_to_numberedbox('\\wd0') +--]] + +-- Grammar (from lowest to highest precedence) +-- Need to adjust to the precedences in plain pgfmath parser +-- IfThenElse Expression +local ITE_E = V('ITE_E') +-- logical OR Expression +local OR_E = V('OR_E') +-- logical AND Expression +local AND_E = V('AND_E') +-- EQuality Expression +local EQ_E = V('EQ_E') +-- Relational EQuality Expression +local REQ_E = V('REQ_E') +-- ADDitive Expression +local ADD_E = V('ADD_E') +-- MULtiplicative Expression +local MUL_E = V('MUL_E') +-- POWer Expression +local POW_E = V('POW_E') +-- POSTfix Expression +local POST_E = V('POST_E') +-- PREfix Expression +local PRE_E = V('PRE_E') +-- ARRAY Expression +local ARRAY_E = V('ARRAY_E') +-- Expression +local E = V('E') + +function pgfluamath.transform_math_expr (s, f_patt) + if pgfluamath.debug then + texio.write_nl('pgfluamath: parsing expression "' .. s ..'"') + end + -- f_patt extends the grammar dynamically at the time of the call to the + -- parser. + -- The idea is to have a set of predefined acceptable functions (via e.g. + -- \pgfmathdeclarefunction) + if not f_patt then + -- P(false) is a pattern that always fails + -- (neutral element for the + operator on patterns) + f_patt = P(false) + end + local function transform_ITE(a, b, c) + if not b then + return a + else + return string.format('pgfluamath.defined_functions.ifthenelse.code(%s,%s,%s)', a, b, c) + end + end + local function transform_binary(a, b, c) + if not b then + return a + else + return string.format('pgfluamath.defined_functions.%s.code(%s,%s)', b, a, c) + end + end + local function transform_postunary(a, b) + if not b then + return a + else + return string.format('pgfluamath.defined_functions.%s.code(%s)', b, a) + end + end + local function transform_preunary(a, b) + if not b then + return a + else + return string.format('pgfluamath.defined_functions.%s.code(%s)', a, b) + end + end + local function transform_array(a, b) + -- One exception to the mimmic of plain pgfmath. I do not use the equivalent array function to transform the arrays because I don't know how to handle both cases {1,{2,3}[1],4}[1] and {1,{2,3},4}[1][1] with the parser and the array function. + -- So I convert a pgf array to a lua table. One can access one entry of the table like this ({1,2})[1] (note the parenthesis, ie {1,2}[1] won't work). + local s + if not b then + s = '{' + else + s = '({' + end + for i = 1,#a do + -- We change the index to fit with pgfmath plain convention (index starts at 0 while in lua index starts at 1) + s = s .. '[' .. tostring(i-1) .. ']=' .. a[i] + if i < #a then + s = s .. ',' + end + end + if b then + s = s .. '})' + for i = 1,#b do + s = s .. '[' .. b[i] .. ']' + end + else + s = s .. '}' + end + return s + end + local grammar = + lpeg.P({ + 'ITE_E', + ITE_E = (OR_E * (thenop * OR_E * elseop * OR_E)^-1) / transform_ITE, + OR_E = (AND_E * (orop * Cc('orPGF') * AND_E)^-1) / transform_binary, + AND_E = (EQ_E * (andop * Cc('andPGF') * EQ_E)^-1) / transform_binary, + EQ_E = (REQ_E * ((eqop * Cc('equal') + neqop * Cc('notequal')) * REQ_E)^-1) / transform_binary, + REQ_E = (ADD_E * ((lessop * Cc('less') + greaterop * Cc('greater') + lesseqop * Cc('notgreater') + greatereqop * Cc('notless')) * ADD_E)^-1) / transform_binary, + ADD_E = Cf(MUL_E * Cg((addop * Cc('add') + subop * Cc('substract')) * MUL_E)^0,transform_binary), + MUL_E = Cf(POW_E * Cg((mulop * Cc('multiply') + divop * Cc('divide')) * POW_E)^0,transform_binary), + POW_E = Cf(POST_E * Cg(powop * Cc('pow') * POST_E)^0,transform_binary), + POST_E = (PRE_E * (radop * Cc('rad'))^-1) / transform_postunary, + PRE_E = ((notop * Cc('notPGF') + negop * Cc('neg'))^-1 * E) / transform_preunary, + ARRAY_E = (lbrace * Ct(ITE_E * (comma * ITE_E)^0) * rbrace * Ct((lbracket * ITE_E * rbracket)^0)) / transform_array, + E = ((integer + float)^-1 * tex_cs^1) + f_patt + C(number) + (lparen * ITE_E * rparen) + ARRAY_E + lbrace * ITE_E * rbrace + }) + return lpeg.match(Cs(grammar),s) +end + +function pgfluamath.ptransform_math_expr(s, f_patt) + local st = pgfluamath.transform_math_expr(s, f_patt) + if st ~= nil then + return texio.write_nl(st) + end +end + +pgfluamath.defined_functions = {} +pgfluamath.defined_functions_pattern = P(false) + +function pgfluamath.declare_new_function (name, nargs, code) + -- nil is true + -- The function name CANNOT be a lua reserved word (so no 'and' nor 'or') + if pgfluamath.defined_functions[name] then + print('Function ' .. name .. ' is already defined. ' .. + 'I overwrite it!') + end + pgfluamath.defined_functions[name] = {['name'] = name, ['nargs'] = nargs, ['code'] = code} + + -- TODO + -- We need a function to dynamically (depending on the number of arguments) define a patten (in order to avoid the long ifcase-type structure). + local pattern + if nargs == 0 then + pattern = P(name) / function (s) return name .. '()' end + else if nargs == 1 then + pattern = ((P(name) * lparen * Cs(ITE_E) * rparen) / function (s) return 'pgfluamath.defined_functions.' .. name .. '.code(' .. s .. ')' end) + else if nargs == 2 then + pattern = (P(name) * lparen * Cs(ITE_E) * comma * Cs(ITE_E) * rparen / function (s1,s2) return 'pgfluamath.defined_functions.' .. name .. 'code(' .. s1 .. ',' .. s2 .. ')' end) + else if nargs == 3 then + pattern = (P(name) * lparen * Cs(ITE_E) * comma * Cs(ITE_E) * comma * Cs(ITE_E) * rparen / function (s1,s2,s3) return 'pgfluamath.defined_functions.' .. name .. 'code(' .. s1 .. ',' .. s2 .. ',' .. s3 .. ')' end) + end + end + end + end + -- TODO + -- This needs to be regenerated every time a new function is added, in conjunction with a sort of the table (see IMPORTANT below) + pgfluamath.defined_functions_pattern = pgfluamath.defined_functions_pattern + pattern +end + +-- IMPORTANT: for 'function' with *0* argument, the longest string, the first +-- ie declaring pi before pit won't work. +pgfluamath.declare_new_function('pit',0) +pgfluamath.declare_new_function('pi',0) +pgfluamath.declare_new_function('exp',1) +pgfluamath.declare_new_function('toto',1) +pgfluamath.declare_new_function('gauss',2) + +pgfluamath.ptransform_math_expr('exp(exp(1+1))',pgfluamath.defined_functions_pattern) + +pgfluamath.ptransform_math_expr('1?(2?3:4^5):gauss(6+toto(7),8+9>10?11:12))',pgfluamath.defined_functions_pattern) + +pgfluamath.ptransform_math_expr('!(1!=-2)>3?(4+5*6+7?8||9&&10:11):12^13r||14') +pgfluamath.ptransform_math_expr('-1^2\\test\\toto^3') +pgfluamath.ptransform_math_expr('{1,{2+3,4}[1],5}[2]+6') +pgfluamath.ptransform_math_expr('{1,{2+3,4},5}[1][1]') +pgfluamath.ptransform_math_expr('{1,{2,3},4}[1][1]') +pgfluamath.ptransform_math_expr('{1,{2,3}[1],4}[1]') + +--Loadstring: If it succeeds in converting the string to a *function*, it returns that function; otherwise, it returns nil and an error message. +toto = loadstring('texio.write_nl(' .. pgfluamath.transform_math_expr('{1,{2,3},4}[1][1]') .. ')') +toto() + +-- IMPORTANT NOTE!! +-- local function add (a,b) will fail within loadstring. Needs to be global. loadstring opens a new chunk that does not know the local variables of other chunks. + +--toto = loadstring('texio.write_nl(' .. pgfluamath.transform_math_expr('{1,{2,3E-1+7}[1],4}[1]') .. ')') +--toto() + +return pgfluamath diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.code.tex index d91a83b111f..9c4a48aeaca 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.code.tex @@ -7,12 +7,12 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryarrows.code.tex,v 1.9 2008/10/27 21:00:46 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryarrows.code.tex,v 1.16 2013/09/23 18:04:35 tantau Exp $ % A square bracket shaped arrow -\pgfarrowsdeclare{[}{]} +\pgfarrowsdeclare{square bracket}{square bracket} { \pgfutil@tempdima=1pt% \advance\pgfutil@tempdima by1.25\pgflinewidth% @@ -33,6 +33,7 @@ \pgfpathlineto{\pgfqpoint{-.5\pgfutil@tempdimb}{\pgfutil@tempdima}} \pgfusepathqstroke } +\pgfdeclarearrow{name=[-], means=square bracket} \pgfarrowsdeclarereversed{]}{[}{[}{]} @@ -148,7 +149,7 @@ { \pgfutil@tempdima=0.4pt% \advance\pgfutil@tempdima by.2\pgflinewidth% - \pgfutil@tempdimb=5.5\pgfutil@tempdima\advance\pgfutil@tempdimb by\pgflinewidth + \pgfutil@tempdimb=7.5\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth \pgfarrowsleftextend{+-\pgfutil@tempdimb} \pgfutil@tempdimb=1.5\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth \pgfarrowsrightextend{+\pgfutil@tempdimb} @@ -234,7 +235,7 @@ { \arrowsize=0.4pt \advance\arrowsize by.275\pgflinewidth% - \pgfarrowsleftextend{+-\arrowsize} + \pgfarrowsleftextend{-7\arrowsize-.5\pgflinewidth} \advance\arrowsize by.5\pgflinewidth \pgfarrowsrightextend{+\arrowsize} } @@ -509,6 +510,7 @@ {\pgfqpoint{-1\pgfutil@tempdima}{-1.5\pgfutil@tempdima}} {\pgfqpoint{3.5\pgfutil@tempdima}{-.5\pgfutil@tempdima}} {\pgfqpoint{6\pgfutil@tempdima}{0\pgfutil@tempdima}} + \pgfpathclose \pgfusepathqfill } @@ -825,6 +827,7 @@ \pgfpathlineto{\pgfqpoint{\pgflinewidth}{0pt}} \pgfpathlineto{\pgfqpoint{.5\pgflinewidth}{-.5\pgflinewidth}} \pgfpathlineto{\pgfqpoint{-.1\pgflinewidth}{-0.5\pgflinewidth}} + \pgfpathclose \pgfusepathqfill } @@ -839,6 +842,7 @@ \pgfpathlineto{\pgfqpoint{-.1\pgflinewidth}{-.5\pgflinewidth}} \pgfpathlineto{\pgfqpoint{1\pgflinewidth}{-.5\pgflinewidth}} \pgfpathlineto{\pgfqpoint{0.5\pgflinewidth}{0\pgflinewidth}} + \pgfpathclose \pgfusepathqfill } @@ -904,12 +908,13 @@ { \pgfmathsetlength{\pgfutil@tempdima}{.25\pgflinewidth+.25*\pgfinnerlinewidth}% \pgfmathsetlength{\pgfutil@tempdimb}{.5\pgflinewidth-.5*\pgfinnerlinewidth}% - \pgfarrowsrightextend{2\pgfutil@tempdima+.5\pgfutil@tempdimb} - \pgfarrowsleftextend{1.3\pgfutil@tempdima+.5\pgfutil@tempdimb} + \pgfarrowsrightextend{2.06\pgfutil@tempdima+.5\pgfutil@tempdimb} + \pgfarrowsleftextend{-1.36\pgfutil@tempdima-.5\pgfutil@tempdimb} } { \pgfmathsetlength{\pgfutil@tempdima}{.25\pgflinewidth+.25*\pgfinnerlinewidth}% \pgfmathsetlength{\pgfutil@tempdimb}{.5\pgflinewidth-.5*\pgfinnerlinewidth}% + \pgftransformxshift{.06\pgfutil@tempdima} \pgfsetlinewidth{\pgfutil@tempdimb} \pgfsetdash{}{+0pt} \pgfsetroundcap diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.meta.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.meta.code.tex new file mode 100644 index 00000000000..77edfcd8dc6 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.meta.code.tex @@ -0,0 +1,1612 @@ +% Copyright 2013 by Till Tantau +% +% This file may be distributed and/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 details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryarrows.meta.code.tex,v 1.12 2013/12/13 15:11:58 tantau Exp $ + + + +% +% +% Meta keys +% +% + + +\newdimen\pgfarrowinset +\newdimen\pgfarrowlength +\newdimen\pgfarrowwidth +\newdimen\pgfarrowlinewidth +\newif\ifpgfarrowroundcap +\newif\ifpgfarrowroundjoin + +\pgfarrowsaddtolengthscalelist\pgfarrowlength +\pgfarrowsaddtolengthscalelist\pgfarrowinset +\pgfarrowsaddtowidthscalelist\pgfarrowwidth + + +\pgfkeys{ + /pgf/arrow keys/.cd, + length/.code={% + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\pgfarrowslinewidthdependent\pgfarrowstheparameters\pgfarrowlength\pgf@x}% + }, + inset/.code={% + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtolateoptions\expandafter{\expandafter\pgfarrowslinewidthdependent\pgfarrowstheparameters\pgfarrowinset\pgf@x}% + }, + inset'/.code={ + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtolateoptions\expandafter{\expandafter\pgfarrowslengthdependent\pgfarrowstheparameters\pgfarrowinset}% + }, + line width/.code={% + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtolateoptions\expandafter{\expandafter\pgfarrowslinewidthdependent\pgfarrowstheparameters\pgfarrowlinewidth\pgf@x}% + }, + line width'/.code={ + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtolateoptions\expandafter{\expandafter\pgfarrowslengthdependent\pgfarrowstheparameters\pgfarrowlinewidth}% + }, + width/.code={% + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtolateoptions\expandafter{\expandafter\pgfarrowslinewidthdependent\pgfarrowstheparameters\pgfarrowwidth\pgf@x}% + }, + width'/.code={% + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtolateoptions\expandafter{\expandafter\pgfarrowslengthdependent\pgfarrowstheparameters\pgfarrowwidth}% + }, + angle/.code={% + \pgfarrowsfourparameters{#1}% + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\pgfarrows@angle@setup\pgfarrowstheparameters}% + }, + angle'/.code={ + \pgfarrowsaddtolateoptions{\pgfarrows@angle@setup@prime{#1}}% + }, + % + line cap/.is choice, + line cap/butt/.code=\pgfarrowsaddtooptions{\pgfarrowroundcapfalse}, + line cap/round/.code=\pgfarrowsaddtooptions{\pgfarrowroundcaptrue}, + line join/.is choice, + line join/miter/.code=\pgfarrowsaddtooptions{\pgfarrowroundjoinfalse}, + line join/round/.code=\pgfarrowsaddtooptions{\pgfarrowroundjointrue}, + round/.style={line cap=round,line join=round}, + sharp/.style={line cap=butt,line join=miter}, +} + + + + +% +% +% Classificaiton of arrow tips: +% +% +% Barbs +% ----- +% +% These arrow tips consisting of stroked lines starting at the tip, +% typically going backward. They cannot be filled, only stroked +% +% A special case are the arrows mimicking the tip at the end of a +% \rightarrow command. +% +% +% Geometric +% --------- +% +% The arrow tips have a geometric form like a triangle or a +% "stealth" fighter or a kite. They can be filled and/or stroked. +% +% +% Caps +% ---- +% +% These arrow tips have their width fixed to the line width and +% provide different ways of adding a "cap" to the end of a line. This +% allows one to use more than just the standard "round cap", "butt +% cap" and "rect cap" and, additionally, one can one kind of cap at +% one end and another at the other end. +% +% +% Other +% ----- +% +% Special purpose arrow tips. +% + + + +% +% +% Barbs arrow tips +% +% + + +% An Straight Barb yields a simple angle + +\pgfdeclarearrow{ + name = Straight Barb, + defaults = { + length = +1.5pt 2, + width' = +0pt 2, + line width = +0pt 1 1, + }, + setup code = { + % Compute front miter length: + \pgfmathdivide@\pgfarrowlength\pgfarrowwidth% + \let\pgf@temp@quot\pgfmathresult% + \pgf@x\pgfmathresult pt% + \pgf@x\pgfmathresult\pgf@x% + \pgf@x4\pgf@x% + \advance\pgf@x by1pt% + \pgfmathsqrt@\pgf@x% + \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter + \pgf@xc.5\pgf@xc + \pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter + % Set ends + \ifpgfarrowroundjoin + \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth} + \else + \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by\pgf@xc\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi} + \fi + \pgfarrowssetvisualbackend{\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth} + \pgfarrowssetbackend{-.5\pgfarrowlinewidth} + % harpoon miter correction + \ifpgfarrowreversed + \pgfarrowssetlineend{\pgfarrowlength\ifpgfarrowharpoon\advance\pgf@x by.5\pgfarrowlinewidth\fi} + \else + \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth} + \fi + % The hull: + \ifpgfarrowroundjoin + \pgfarrowshullpoint{\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}% + \else% + \ifpgfarrowharpoon + \pgfarrowshullpoint{\pgfarrowlength\advance\pgf@x by\pgf@xc\advance\pgf@x by\pgf@xa}{-.5\pgfarrowlinewidth}% + \else + \pgfarrowshullpoint{\pgfarrowlength\advance\pgf@x by\pgf@xc\advance\pgf@x by\pgf@xa}{0pt}% + \fi% + \fi + \pgfarrowsupperhullpoint{.5\pgfarrowlinewidth}{.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}% + \pgfarrowsupperhullpoint{-.5\pgfarrowlinewidth}{.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}% + \ifpgfarrowharpoon + \pgfarrowshullpoint{-.5\pgfarrowlinewidth}{-.5\pgfarrowlinewidth}% + \fi + % The following are needed in the code: + \pgfarrowssavethe\pgfarrowlinewidth + \pgfarrowssavethe\pgfarrowlength + \pgfarrowssavethe\pgfarrowwidth + }, + drawing code = { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + \pgfpathmoveto{\pgfqpoint{0pt}{.5\pgfarrowwidth}} + \pgfpathlineto{\pgfqpoint{\pgfarrowlength}{0pt}} + \ifpgfarrowharpoon + \pgfpathlineto{\pgfqpoint{\pgfarrowlength\advance\pgf@x by\ifpgfarrowreversed\else-\fi\pgfarrowlinewidth}{0pt}} + \else + \pgfpathlineto{\pgfqpoint{0pt}{-.5\pgfarrowwidth}} + \fi + \pgfusepathqstroke + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowroundjoin j\fi% + \ifpgfarrowroundcap c\fi% + }, +} + + + +% Hooks are barbs that consist of an arc going forward from the line +% end and curving back by a given angle speficied using the |arc| +% key. + +\pgfkeys{ + /pgf/arrow keys/.cd, + arc/.code={% + \pgfmathparse{#1}% + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrowarc\expandafter{\pgfmathresult}} + } +} + +\def\pgfarrowarc{180} + +\pgfdeclarearrow{ + name = Hooks, + defaults = { + length = +0.75pt 1.25, + width' = +0pt 4 -1, + line width = +0pt 1 1, + }, + setup code = { + \ifpgfarrowharpoon + \pgfarrowshullpoint{.5\pgfarrowlength}{-.5\pgfarrowlinewidth} + \pgfarrowshullpoint{\pgfarrowlength}{-.5\pgfarrowlinewidth\advance\pgf@y by.125\pgfarrowwidth} + \fi + \ifdim\pgfarrowarc pt<90.1pt + \pgfarrowsupperhullpoint{0pt}{.25\pgfarrowwidth\ifpgfarrowroundcap\else\advance\pgf@y by-.25\pgfarrowlinewidth\fi} + \pgfarrowsupperhullpoint{\pgfarrowlength}{.25\pgfarrowwidth\ifpgfarrowroundcap\else\advance\pgf@y by-.25\pgfarrowlinewidth\fi} + \else% + \pgfarrowsupperhullpoint{\pgfarrowlength}{.375\pgfarrowwidth} + \pgfarrowsupperhullpoint{.5\pgfarrowlength}{.5\pgfarrowwidth} + \ifdim\pgfarrowarc pt>180pt + \pgfarrowsupperhullpoint{-.5\pgfarrowlength}{.5\pgfarrowwidth} + \pgfarrowsupperhullpoint{-\pgfarrowlength}{.375\pgfarrowwidth} + \pgfarrowsupperhullpoint{-\pgfarrowlength}{.25\pgfarrowwidth} + \else + \pgfarrowsupperhullpoint{\ifpgfarrowroundcap-.5\pgfarrowlinewidth\else0pt\fi}{.25\pgfarrowwidth} + \pgfarrowsupperhullpoint{\ifpgfarrowroundcap-.5\pgfarrowlinewidth\else0pt\fi}{.5\pgfarrowwidth} + \fi + \fi + % Adjust width and length: Take line thickness into account: + \advance\pgfarrowlength by-.5\pgfarrowlinewidth + \advance\pgfarrowwidth by-\pgfarrowlinewidth + \ifpgfarrowreversed + \ifpgfarrowroundjoin + \pgfarrowssetbackend{-.5\pgfarrowlinewidth} + \fi + \fi + % There are four different intervals for the values of + % \pgfarrowsarc that give rise to four different settings of tip + % ends and so on: + % + % Case 1: 0 <= Angle < 90 + % + \ifdim\pgfarrowarc pt<90pt% + % Tip end is given by sin(pgfarrowarc)*length + \pgfmathsin@{\pgfarrowarc} + \pgfarrowssettipend{\pgfmathresult\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth}% + \else\ifdim\pgfarrowarc pt<180pt% + \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth}% + \ifpgfarrowroundcap\pgfarrowssetbackend{-.5\pgfarrowlinewidth}\fi% + \else\ifdim\pgfarrowarc pt<270pt% + \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth}% + \ifdim\pgfarrowarc pt>180pt + % Back end is given by sin(pgfarrowarc)*length + \pgfmathsin@{\pgfarrowarc} + \pgfarrowssetbackend{\pgfmathresult\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth}% + \else + \ifpgfarrowroundcap\pgfarrowssetbackend{-.5\pgfarrowlinewidth}\fi% + \fi% + \else% + \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth}% + \pgfarrowssetbackend{-\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth}% + \fi\fi\fi% + \ifpgfarrowreversed + \pgfarrowssetlineend{.5\pgfarrowlinewidth} + \else% + \ifpgfarrowharpoon + \pgfarrowssetlineend{0pt} + \else + \pgfarrowssetlineend{.25\pgfarrowlinewidth} + \fi + \fi + % Adjust arc: + \pgf@x\pgfarrowarc pt% + \advance\pgf@x by-90pt% + \edef\pgfarrowarc{\pgf@sys@tonumber\pgf@x}% + % The following are needed in the code: + \pgfarrowssavethe\pgfarrowlinewidth + \pgfarrowssavethe\pgfarrowlength + \pgfarrowssavethe\pgfarrowwidth + \pgfarrowssave\pgfarrowarc + }, + drawing code = { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + {% + \pgftransformxscale{+\pgfarrowlength} + \pgftransformyscale{+.25\pgfarrowwidth} + \pgfpathmoveto{\pgfpointpolar{+\pgfarrowarc}{+1pt}\advance\pgf@y by1pt} + \pgfpatharc{\pgfarrowarc}{+-90}{+1pt} + \ifpgfarrowharpoon + \else + \pgfpatharc{+90}{+-\pgfarrowarc}{+1pt} + \fi + } + \ifpgfarrowharpoon\ifpgfarrowreversed + \pgfpathlineto{\pgfqpoint{\pgflinewidth}{0pt}} + \fi\fi + \pgfusepathqstroke + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \pgfarrowarc,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowroundjoin j\fi% + \ifpgfarrowroundcap c\fi% + }, +} + + +\pgfdeclarearrow{ + name = Arc Barb, + defaults = { + length = +1.5pt 2, + width' = +0pt 2, + line width = +0pt 1 1, + }, + setup code = { + % Adjust arc: + \pgf@x\pgfarrowarc pt% + \pgf@x.5\pgf@x% + \edef\pgfarrowarc{\pgf@sys@tonumber\pgf@x}% + % The tips: + \pgfarrowssettipend{\pgfarrowlength} + \pgfarrowssetvisualbackend{\pgfarrowlength} + \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth} + % The hull: + \pgfarrowsupperhullpoint{\pgfarrowlength}{.25\pgfarrowwidth} + \ifpgfarrowharpoon\pgfarrowshullpoint{\pgfarrowlength}{-.5\pgflinewidth}\fi + \pgfmathsincos@{\pgfarrowarc}% + \pgf@xa.5\pgfarrowwidth% + \pgfarrowsupperhullpoint{\pgfmathresultx\pgfarrowlength}{\pgfmathresulty\pgf@xa} + \ifdim\pgfarrowarc pt>60pt + \pgfarrowsupperhullpoint{.5\pgfarrowlength}{\ifdim\pgfarrowarc pt<90pt\pgfmathresulty\pgf@xa\else.5\pgfarrowwidth\fi} + \fi + \ifdim\pgfarrowarc pt>90pt + \ifdim\pgfarrowarc pt<120pt + \pgfarrowsupperhullpoint{\pgfmathresultx\pgfarrowlength}{.5\pgfarrowwidth} + \else + \pgfarrowsupperhullpoint{-.5\pgfarrowlength}{.5\pgfarrowwidth} + \ifdim\pgfarrowarc pt>150pt + \pgfarrowsupperhullpoint{-\pgfarrowlength}{.25\pgfarrowwidth} + \fi + \fi + \fi + \pgfutil@tempswafalse + \ifdim\pgfarrowarc pt<90pt + \pgfutil@tempswatrue + \fi + \ifpgfarrowharpoon + \pgfutil@tempswatrue + \fi + \ifpgfutil@tempswa + \pgf@xa.5\pgfarrowwidth\advance\pgf@xa by-\pgfarrowlinewidth% + \pgf@ya\pgfarrowlength\advance\pgf@ya by-\pgfarrowlinewidth% + \pgfarrowsupperhullpoint{\pgfmathresultx\pgf@ya}{\pgfmathresulty\pgf@xa} + \fi + % Compute back end + \ifpgfarrowroundcap + \pgf@y\pgfarrowlength + \advance\pgf@y by-.5\pgfarrowlinewidth + \pgf@x\pgfmathresultx\pgf@y% + \else + \ifdim\pgfarrowarc pt<90pt + \pgf@y\pgfarrowlength + \advance\pgf@y by-\pgfarrowlinewidth + \pgf@x\pgfmathresultx\pgf@y% + \else + \pgf@x\pgfmathresultx\pgfarrowlength% + \fi + \fi + \pgfarrowssetbackend{\pgf@x\ifpgfarrowroundcap\advance\pgf@x by-.5\pgfarrowlinewidth\fi} + % Adjust width and length: Take line thickness into account: + \advance\pgfarrowlength by-.5\pgfarrowlinewidth + \advance\pgfarrowwidth by-\pgfarrowlinewidth + % The following are needed in the code: + \pgfarrowssavethe\pgfarrowlinewidth + \pgfarrowssavethe\pgfarrowlength + \pgfarrowssavethe\pgfarrowwidth + \pgfarrowssave\pgfarrowarc + }, + drawing code = { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + {% + \pgftransformxscale{+\pgfarrowlength} + \pgftransformyscale{+.5\pgfarrowwidth} + \pgfpathmoveto{\pgfpointpolar{+\pgfarrowarc}{+1pt}} + \ifpgfarrowharpoon + \pgfpatharc{+\pgfarrowarc}{0pt}{+1pt} + \else + \pgfpatharc{+\pgfarrowarc}{+-\pgfarrowarc}{+1pt} + \fi + } + \ifpgfarrowharpoon + \pgfpathlineto{\pgfqpoint{\pgfarrowlength\advance\pgf@x by\ifpgfarrowreversed\else-\fi.5\pgflinewidth}{0pt}} + \fi + \pgfusepathqstroke + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \pgfarrowarc,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowroundcap c\fi% + \ifpgfarrowroundjoin j\fi% + }, +} + + + +% Tee Barb are barb arrows heads that look like a T + +\pgfdeclarearrow{ + name = Tee Barb, + defaults = { + length = +1.5pt 2, + width = +3pt 4, + inset' = +0pt .5, + line width = +0pt 1 1, + }, + bending mode=polar, + setup code = { + % Two useful numbers... + \pgfutil@tempswafalse% + \pgfutil@tempswbfalse% + \pgfutil@tempdima\pgfarrowlength\advance\pgfutil@tempdima by-\pgfarrowinset\ifdim\pgfutil@tempdima<.5\pgfarrowlinewidth\pgfutil@tempdima.5\pgfarrowlinewidth\pgfutil@tempswatrue\fi% + \pgfutil@tempdimb-\pgfarrowinset\ifdim\pgfutil@tempdimb>-.5\pgfarrowlinewidth\pgfutil@tempdimb-.5\pgfarrowlinewidth\pgfutil@tempswbtrue\fi + % The following are needed in the code: + \pgfarrowssavethe\pgfarrowwidth + \pgfarrowssavethe\pgfutil@tempdima + \pgfarrowssavethe\pgfutil@tempdimb + % Infos: + \pgfarrowssettipend{\pgfutil@tempdima\ifpgfarrowroundcap\ifpgfutil@tempswa\else\advance\pgf@x by.5\pgfarrowlinewidth\fi\fi} + \pgfarrowssetvisualbackend{.5\pgfarrowlinewidth} + \pgfarrowssetbackend{\pgfutil@tempdimb\ifpgfarrowroundcap\ifpgfutil@tempswb\else\advance\pgf@x by-.5\pgfarrowlinewidth\fi\fi} + \pgfarrowssetlineend{\ifpgfarrowreversed\else-\fi.25\pgfarrowlinewidth}% + % The hull: + \pgfarrowsupperhullpoint{\pgfutil@tempdima\ifpgfarrowroundcap\ifpgfutil@tempswa\else\advance\pgf@x by.5\pgfarrowlinewidth\fi\fi}{.5\pgfarrowwidth}% + \pgfarrowsupperhullpoint{\pgfutil@tempdimb\ifpgfarrowroundcap\ifpgfutil@tempswb\else\advance\pgf@x by-.5\pgfarrowlinewidth\fi\fi}{.5\pgfarrowwidth}% + \ifpgfarrowharpoon + \pgfarrowshullpoint{.5\pgfarrowlinewidth}{-.5\pgfarrowlinewidth}% + \fi + }, + drawing code = { + \pgfsetdash{}{+0pt} + \pgf@yc\pgflinewidth% save... + \ifdim\pgflinewidth=\pgfarrowlinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \pgf@x\pgfutil@tempdima\advance\pgf@x by-.5\pgfarrowlinewidth% + \pgf@y\pgfutil@tempdimb\advance\pgf@y by.5\pgfarrowlinewidth% + % Case 1: No bar atop the I: + \ifdim\pgf@x=\pgf@y% + \pgfpathmoveto{\pgfqpoint{0pt}{.5\pgfarrowwidth}} + \pgfpathlineto{\pgfqpoint{0pt}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else-.5\pgfarrowwidth\fi}} + \else + % Case 2: Bar, but only in one direction: + \ifdim\pgfutil@tempdima=.5\pgfarrowlinewidth% + \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdimb}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}} + \pgfpathlineto{\pgfqpoint{0pt}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}} + \ifpgfarrowharpoon% + \pgfpathlineto{\pgfqpoint{0pt}{-.5\pgf@yc}}% + \else% + \pgfpathlineto{\pgfqpoint{0pt}{-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}} + \pgfpathlineto{\pgfqpoint{\pgfutil@tempdimb}{-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}} + \fi + \else% Case 3: Complete I: + \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdimb}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}} + \pgfpathlineto{\pgfqpoint{\pgfutil@tempdima}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}} + \pgfpathmoveto{\pgfqpoint{0pt}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}} + \ifpgfarrowharpoon% + \pgfpathlineto{\pgfqpoint{0pt}{-.5\pgf@yc}}% + \else% + \pgfpathlineto{\pgfqpoint{0pt}{-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}} + \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdimb}{-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}} + \pgfpathlineto{\pgfqpoint{\pgfutil@tempdima}{-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}} + \fi + \fi + \fi + \pgfusepathqstroke + }, + parameters = { + \the\pgfarrowwidth,% + \the\pgfarrowlength,% + \the\pgfarrowinset,% + \the\pgfarrowlinewidth,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowroundjoin j\fi% + \ifpgfarrowroundcap c\fi% + }, +} + + +% Math barbs that resemble \rightarrow in different fonts: + + + +% The original default arrow head used in TikZ. It is modeled on an +% old version of the \rightarrow head of the *old* Computer Modern +% fonts. + +\pgfdeclarearrow{ + name = Classical TikZ Rightarrow, + defaults = { + length = +1.05pt 1.925, + width' = +0pt 1.9237, + line width = 0pt 0.8 1, + round + }, + setup code = + { + \ifpgfarrowharpoon\pgfarrowroundjointrue\fi + % inner length: + \pgfutil@tempdima\pgfarrowlength + \advance\pgfutil@tempdima by-\pgfarrowlinewidth + \pgfutil@tempdimb\pgfarrowwidth + \advance\pgfutil@tempdimb by-\pgfarrowlinewidth + \ifpgfarrowroundjoin% + \else% + \pgfmathdivide@\pgfutil@tempdima\pgfutil@tempdimb% + \let\pgf@temp@quot\pgfmathresult% + \pgf@x\pgfmathresult pt% + \pgf@x\pgfmathresult\pgf@x% + \pgf@x40.96\pgf@x% + \advance\pgf@x by1pt% \pgflinewidth^2 + (6.4 \pgftempdim@a / \pgfutil@tempdimb) \pgflinewidth^2 + \pgfmathsqrt@\pgf@x% + \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter + \pgf@xc.5\pgf@xc + \fi% + % The following are needed in the code: + \pgfarrowssavethe\pgfutil@tempdima + \pgfarrowssavethe\pgfutil@tempdimb + % The extend: + \pgfarrowssettipend{\pgfutil@tempdima\ifpgfarrowroundjoin\advance\pgf@x by.5\pgfarrowlinewidth\else\advance\pgf@x by\pgf@xc\fi}% + \pgfarrowssetvisualbackend{\pgfutil@tempdima\advance\pgf@x by.5\pgfarrowlinewidth}% + \ifpgfarrowreversed% + \ifpgfarrowharpoon% + % A reversed arrow needs a slightly different line end: + \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by.5\pgflinewidth}% + \else% + % A reversed arrow needs a slightly different line end: + \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by-.25\pgflinewidth}% + \fi% + \else% + \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by-.6\pgflinewidth}% + \fi% + \pgfarrowssetbackend{-.5\pgfarrowlinewidth}% + % The hull: + % Tip: + \pgfarrowshullpoint{\pgfutil@tempdima\ifpgfarrowroundjoin\advance\pgf@x by.5\pgfarrowlinewidth\else\advance\pgf@x by\pgf@xc\fi}{.5\pgfarrowlinewidth}% + \pgfarrowshullpoint{\pgfutil@tempdima\ifpgfarrowroundjoin\advance\pgf@x by.5\pgfarrowlinewidth\else\advance\pgf@x by\pgf@xc\fi}{-.5\pgfarrowlinewidth}% + % Upper end: + \pgfarrowsupperhullpoint{.5\pgfarrowlinewidth}{.5\pgfutil@tempdimb\advance\pgf@y by.5\pgfarrowlinewidth}% + \pgfarrowsupperhullpoint{-.5\pgfarrowlinewidth}{.5\pgfutil@tempdimb\advance\pgf@y by.5\pgfarrowlinewidth}% + % Lower end: + \ifpgfarrowharpoon + \pgfarrowshullpoint{\pgfutil@tempdima\advance\pgf@x by-\pgflinewidth}{-.5\pgflinewidth}% + \pgfarrowshullpoint{-.5\pgfarrowlinewidth}{.5\pgfutil@tempdimb\advance\pgf@y by-.5\pgflinewidth}% + \fi + }, + drawing code = + { + \pgfsetdash{}{+0pt} + \edef\pgf@orig@linewidth{\the\pgflinewidth} + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + \ifpgfarrowharpoon\pgfarrowroundjointrue\fi + \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \pgfpathmoveto + {\pgfqpoint{0pt}{.5\pgfutil@tempdimb}} + \ifpgfarrowharpoon + \pgf@arrows@old@tikz@harpoon + \else + \pgfpathcurveto + {\pgfqpoint{0.066666\pgfutil@tempdima}{0.3125\pgfutil@tempdimb}} + {\pgfqpoint{.8\pgfutil@tempdima}{0.03125\pgfutil@tempdimb}} + {\pgfqpoint{\pgfutil@tempdima}{0pt}} + \pgfpathcurveto + {\pgfqpoint{.8\pgfutil@tempdima}{-.03125\pgfutil@tempdimb}} + {\pgfqpoint{0.066666\pgfutil@tempdima}{-.3125\pgfutil@tempdimb}} + {\pgfqpoint{0pt}{-.5\pgfutil@tempdimb}} + \pgfsetlinewidth{+\pgfarrowlinewidth} + \pgfusepathqstroke + \fi + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowroundjoin j\fi% + \ifpgfarrowroundcap c\fi% + }, +} + +\def\pgf@arrows@old@tikz@harpoon{ + \ifpgfarrowreversed + \pgf@arrows@old@tikz@harpoon@reversed + \else + \pgfpathcurveto + {\pgfqpoint{0.066666\pgfutil@tempdima}{0.3125\pgfutil@tempdimb}} + {\pgfqpoint{.8\pgfutil@tempdima}{0.03125\pgfutil@tempdimb}} + {\pgfqpoint{\pgfutil@tempdima}{0pt}} + \pgfpathcurveto + {\pgfqpoint{0.95\pgfutil@tempdima}{-0.125\pgflinewidth}} + {\pgfqpoint{0.933333\pgfutil@tempdima}{-0.125\pgflinewidth}} + {\pgfqpoint{0.933333\pgfutil@tempdima}{-0.125\pgflinewidth}} + \pgfpathlineto + {\pgfqpoint{0.8\pgfutil@tempdima\advance\pgf@x by-.5\pgflinewidth}{-0.125\pgflinewidth}} + \pgfusepathqstroke + \fi +} +\def\pgf@arrows@old@tikz@harpoon@reversed{ + \pgfpathcurveto + {\pgfqpoint{0.066666\pgfutil@tempdima}{0.3125\pgfutil@tempdimb}} + {\pgfqpoint{.8\pgfutil@tempdima}{0.03125\pgfutil@tempdimb}} + {\pgfqpoint{\pgfutil@tempdima}{0.125\pgflinewidth}} + \pgfpathmoveto + {\pgfqpoint{0pt}{.5\pgfutil@tempdimb}} + \pgfpathcurveto + {\pgfqpoint{0.066666\pgfutil@tempdima}{0.3125\pgfutil@tempdimb}} + {\pgfqpoint{.8\pgfutil@tempdima}{0.03125\pgfutil@tempdimb}} + {\pgfqpoint{\pgfutil@tempdima}{-0.125\pgflinewidth}} + \pgfusepathqstroke + \pgfsetlinewidth{+\pgf@orig@linewidth} + \pgfsetroundcap + \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima\advance\pgf@x by0.6\pgflinewidth}{0pt}} + \pgfpathlineto{\pgfqpoint{\pgfutil@tempdima}{0pt}} + \pgfusepathqstroke +} + + +% An approximation to the new (past 1992) Computer Modern math arrow +% heads. This would be a better version of "to", so consider saying +% to/.tips=Computer Modern Rightarrow + +\pgfdeclarearrow{ + name = Computer Modern Rightarrow, + defaults = { + length = +1.6pt 2.2, % 0pt 5.2 + width' = +0pt 2.096774, + line width = 0pt 1 1, + round + }, + setup code = + { + % inner length: + \pgfutil@tempdima\pgfarrowlength + \advance\pgfutil@tempdima by-\pgfarrowlinewidth + \pgfutil@tempdimb\pgfarrowwidth + \advance\pgfutil@tempdimb by-\pgfarrowlinewidth + % The following are needed in the code: + \pgfarrowssavethe\pgfutil@tempdima + \pgfarrowssavethe\pgfutil@tempdimb + % Front miter: + \ifpgfarrowroundjoin% + \else% + \pgfmathdivide@\pgfutil@tempdima\pgfutil@tempdimb% + \let\pgf@temp@quot\pgfmathresult% + \pgf@x\pgfmathresult pt% + \pgf@x\pgfmathresult\pgf@x% + \pgf@x49.44662\pgf@x% + \advance\pgf@x by1pt% \pgfarrowlinewidth^2 + (0.41019/0.0583333 \pgftempdim@a / \pgfutil@tempdimb) \pgfarrowlinewidth^2 + \pgfmathsqrt@\pgf@x% + \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter + \pgf@xc.5\pgf@xc + \pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter + \pgf@xa3.51591\pgf@xa% xa is extra harpoon miter + \fi% + % The extend: + \pgfarrowssettipend{\ifpgfarrowroundjoin.5\pgfarrowlinewidth\else\pgf@xc\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi\fi}% + \pgfarrowssetvisualbackend{.5\pgfarrowlinewidth}% + \ifpgfarrowreversed% + \ifpgfarrowharpoon% + \pgfarrowssetlineend{.5\pgfarrowlinewidth}% + \else% + \pgfarrowssetlineend{-.5\pgfarrowlinewidth}% + \fi% + \else% + \pgfarrowssetlineend{-.5\pgfarrowlinewidth}% + \fi% + \pgfarrowssetbackend{-\pgfutil@tempdima\advance\pgf@x by-.5\pgfarrowlinewidth}% + % The hull: + % Tip: + \pgfarrowshullpoint{\ifpgfarrowroundjoin.5\pgfarrowlinewidth\else\pgf@xc\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi\fi}{.5\pgfarrowlinewidth}% + \pgfarrowshullpoint{\ifpgfarrowroundjoin.5\pgfarrowlinewidth\else\pgf@xc\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi\fi}{-.5\pgfarrowlinewidth}% + % Upper end: + \pgfarrowsupperhullpoint{-\pgfutil@tempdima\advance\pgf@x by.5\pgfarrowlinewidth}{.5\pgfutil@tempdimb\advance\pgf@y by.5\pgfarrowlinewidth}% + \pgfarrowsupperhullpoint{-\pgfutil@tempdima\advance\pgf@x by-.5\pgfarrowlinewidth}{.5\pgfutil@tempdimb\advance\pgf@y by.5\pgfarrowlinewidth}% + % Lower end: + \ifpgfarrowharpoon + \pgfarrowshullpoint{-\pgfarrowlinewidth}{-.5\pgfarrowlinewidth}% + \pgfarrowshullpoint{-\pgfutil@tempdima\advance\pgf@x by-.5\pgfarrowlinewidth}{.5\pgfutil@tempdimb\advance\pgf@y by-.5\pgfarrowlinewidth}% + \fi + }, + drawing code = + { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + \pgfpathmoveto + {\pgfqpoint{-\pgfutil@tempdima}{.5\pgfutil@tempdimb}} + \pgfpathcurveto + {\pgfqpoint{-0.81731\pgfutil@tempdima}{.2\pgfutil@tempdimb}} + {\pgfqpoint{-0.41019\pgfutil@tempdima}{0.05833333\pgfutil@tempdimb}} + {\pgfpointorigin} + \ifpgfarrowharpoon + \pgfpathlineto + {\pgfqpoint{\ifpgfarrowreversed.5\else-\fi\pgfarrowlinewidth}{0pt}} + \else + \pgfpathcurveto + {\pgfqpoint{-0.41019\pgfutil@tempdima}{-0.05833333\pgfutil@tempdimb}} + {\pgfqpoint{-0.81731\pgfutil@tempdima}{-.2\pgfutil@tempdimb}} + {\pgfqpoint{-\pgfutil@tempdima}{-.5\pgfutil@tempdimb}} + \fi + \pgfusepathqstroke + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \ifpgfarrowharpoon h\fi + \ifpgfarrowharpoon r\fi + \ifpgfarrowroundjoin j\fi% + \ifpgfarrowroundcap c\fi% + }, +} + + + +% The arrow tip of an \implies arrow, to be used with an inner +% line. Cannot be configured otherwise. + +\pgfdeclarearrow{ + name = Implies, + setup code = { + \pgf@xa\pgfinnerlinewidth + \pgfutil@tempdima.25\pgflinewidth + \advance\pgfutil@tempdima by.25\pgf@xa% + \pgfutil@tempdimb.5\pgflinewidth + \advance\pgfutil@tempdimb by-.5\pgf@xa% + \pgfarrowssettipend{2.06\pgfutil@tempdima\advance\pgf@x by.5\pgfutil@tempdimb} + \pgfarrowssetbackend{-1.36\pgfutil@tempdima\advance\pgf@x by.5\pgfutil@tempdimb} + \pgfarrowsupperhullpoint{-1.4\pgfutil@tempdima}{2.8\pgfutil@tempdima} + \pgfarrowsupperhullpoint{2\pgfutil@tempdima}{.5\pgfutil@tempdimb} + \pgfarrowssavethe\pgfutil@tempdima + \pgfarrowssavethe\pgfutil@tempdimb + }, + drawing code = { + \pgftransformxshift{.06\pgfutil@tempdima} + \pgfsetlinewidth{\pgfutil@tempdimb} + \pgfsetdash{}{+0pt} + \pgfsetroundcap + \pgfsetroundjoin + \pgfpathmoveto{\pgfpoint{-1.4\pgfutil@tempdima}{2.65\pgfutil@tempdima}} + \pgfpathcurveto + {\pgfpoint{-0.75\pgfutil@tempdima}{1.25\pgfutil@tempdima}} + {\pgfpoint{1\pgfutil@tempdima}{0.05\pgfutil@tempdima}} + {\pgfpoint{2\pgfutil@tempdima}{0pt}} + \pgfpathcurveto + {\pgfpoint{1\pgfutil@tempdima}{-0.05\pgfutil@tempdima}} + {\pgfpoint{-.75\pgfutil@tempdima}{-1.25\pgfutil@tempdima}} + {\pgfpoint{-1.4\pgfutil@tempdima}{-2.65\pgfutil@tempdima}} + \pgfusepathqstroke + }, + parameters = {\the\pgfarrowlength} +} + + + + +% +% +% Geomatric arrow tips +% +% + + +% Generic "latex-like" arrow tip. This is the basic arrow tip used in +% latex's picture environment. You can configure its length and width. + +\pgfdeclarearrow{ + name = Latex, + defaults = { + length = +3pt 4.5 .8,% +2.8pt 3 0.8, + width' = +0pt .75, + line width = +0pt 1 1, + }, + setup code = { + % Cap the line width at 1/4th distance from inset to tip + \pgf@x.2\pgfarrowlength + \ifdim\pgf@x<\pgfarrowlinewidth + \pgfarrowlinewidth\pgf@x + \fi + \pgfarrowssavethe\pgfarrowlinewidth% + % Compute front miter length: + \pgfmathdivide@\pgfarrowlength\pgfarrowwidth% + \let\pgf@temp@quot\pgfmathresult% + \pgf@x\pgfmathresult pt% + \pgf@x\pgfmathresult\pgf@x% + \pgf@x9\pgf@x% + \advance\pgf@x by1pt% + \pgfmathsqrt@\pgf@x% + \pgf@xc\pgfmathresult\pgfarrowlinewidth% + \pgf@xa\pgf@temp@quot\pgfarrowlinewidth + % Inner length (pgfutil@tempdima) is now arrowlength - front miter + % - 0.5 linewidth (back thickness) + \pgfutil@tempdima\pgfarrowlength% + \advance\pgfutil@tempdima by-.5\pgf@xc% + \advance\pgfutil@tempdima by-.5\pgfarrowlinewidth% + % harpoon miter correction + \pgfarrowssetbackend{-.5\pgfarrowlinewidth} + \ifpgfarrowreversed + \ifdim\pgfinnerlinewidth>0pt + \pgfarrowssetlineend{0pt} + \else + \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by-.5\pgflinewidth} + \fi + \else + \pgfarrowssetlineend{0pt} + \fi + \ifpgfarrowroundjoin + \pgfarrowssettipend{\pgfutil@tempdima\advance\pgf@x by.5\pgfarrowlinewidth} + \else + \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth\ifpgfarrowharpoon\advance\pgf@x by1.5\pgf@xa\fi} + \fi + % The following are needed in the code: + \pgfarrowssavethe\pgfutil@tempdima + % Now, compute back tip miter limit: + \pgf@process{\pgfpointnormalised{\pgfqpoint{.3\pgfarrowlength}{.2333333\pgfarrowwidth}}}% + \advance\pgf@y by1pt% + \pgf@yc\pgf@y\pgf@xc\pgf@x% + \pgfmathdivide@\pgf@yc\pgf@xc% + \pgfutil@tempdimb\pgfmathresult\pgfarrowlinewidth% + \pgfutil@tempdimb-.5\pgfutil@tempdimb% + \advance\pgfutil@tempdimb by.5\pgfarrowwidth% + \pgfarrowssavethe\pgfutil@tempdimb% + % The hull: + \pgfarrowshullpoint{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth\ifpgfarrowroundjoin\else\ifpgfarrowharpoon\advance\pgf@x by1.5\pgf@xa\fi\fi}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}% + \pgfarrowshullpoint{-.5\pgfarrowlinewidth}{.5\pgfarrowwidth\ifpgfarrowharpoon\advance\pgf@y by-.5\pgfarrowlinewidth\fi}% + \pgfarrowshullpoint{-.5\pgfarrowlinewidth}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else-.5\pgfarrowwidth\fi}% + }, + drawing code = { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + \pgfpathmoveto {\pgfqpoint{\pgfutil@tempdima}{0pt}} + \pgfpathcurveto {\pgfqpoint{.877192\pgfutil@tempdima}{.077922\pgfutil@tempdimb}} + {\pgfqpoint{.337381\pgfutil@tempdima}{.519480\pgfutil@tempdimb}} + {\pgfqpoint{0pt}{\pgfutil@tempdimb}} + \ifpgfarrowharpoon + \pgfpathlineto {\pgfpointorigin} + \else + \pgfpathlineto {\pgfqpoint{0pt}{-\pgfutil@tempdimb}} + \pgfpathcurveto {\pgfqpoint{.337381\pgfutil@tempdima}{-.519480\pgfutil@tempdimb}} + {\pgfqpoint{.877192\pgfutil@tempdima}{-.077922\pgfutil@tempdimb}} + {\pgfqpoint{\pgfutil@tempdima}{0pt}} + \fi + \pgfpathclose + \ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt\pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowopen o\fi% + \ifpgfarrowroundjoin j\fi% + }, +} + + + +% A basic stealth-fighter-like pointed arrow + +\pgfdeclarearrow{ + name = Stealth, + defaults = { + length = +3pt 4.5 .8, + width' = +0pt .75, + inset' = +0pt 0.325, + line width = +0pt 1 1, + }, + setup code = { + % Cap the line width at 1/4th distance from inset to tip + \pgf@x\pgfarrowlength + \advance\pgf@x by-\pgfarrowinset + \pgf@x.25\pgf@x + \ifdim\pgf@x<\pgfarrowlinewidth + \pgfarrowlinewidth\pgf@x + \fi + % Compute front miter length: + \pgfmathdivide@\pgfarrowlength\pgfarrowwidth% + \let\pgf@temp@quot\pgfmathresult% + \pgf@x\pgfmathresult pt% + \pgf@x\pgfmathresult\pgf@x% + \pgf@x4\pgf@x% + \advance\pgf@x by1pt% + \pgfmathsqrt@\pgf@x% + \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter + \pgf@xc.5\pgf@xc + \pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter + % Compute back miter length: + \pgf@ya.5\pgfarrowwidth% + \csname pgfmathatan2@\endcsname{\pgfmath@tonumber\pgfarrowlength}{\pgfmath@tonumber\pgf@ya}% + \pgf@yb\pgfmathresult pt% + \csname pgfmathatan2@\endcsname{\pgfmath@tonumber\pgfarrowinset}{\pgfmath@tonumber\pgf@ya}% + \pgf@ya\pgfmathresult pt% + \advance\pgf@yb by-\pgf@ya% + \pgf@yb.5\pgf@yb% half angle in yb + \pgfmathtan@{\pgf@yb}% + \pgfmathreciprocal@{\pgfmathresult}% + \pgf@yc\pgfmathresult\pgfarrowlinewidth% + \pgf@yc.5\pgf@yc% + \advance\pgf@ya by\pgf@yb% + \pgfmathsincos@{\pgf@ya}% + \pgf@ya\pgfmathresulty\pgf@yc% ya is the back miter + \pgf@yb\pgfmathresultx\pgf@yc% yb is the top miter + \ifdim\pgfarrowinset=0pt% + \pgf@ya.5\pgfarrowlinewidth% easy: back miter is half linewidth + \fi + % Compute inset miter length: + \pgfmathdivide@\pgfarrowinset\pgfarrowwidth% + \let\pgf@temp@quot\pgfmathresult% + \pgf@x\pgfmathresult pt% + \pgf@x\pgfmathresult\pgf@x% + \pgf@x4\pgf@x% + \advance\pgf@x by1pt% + \pgfmathsqrt@\pgf@x% + \pgf@yc\pgfmathresult\pgfarrowlinewidth% yc is inset miter + \pgf@yc.5\pgf@yc% + % Inner length (pgfutil@tempdima) is now arrowlength - front miter - back miter + \pgfutil@tempdima\pgfarrowlength% + \advance\pgfutil@tempdima by-\pgf@xc% + \advance\pgfutil@tempdima by-\pgf@ya% + \pgfutil@tempdimb.5\pgfarrowwidth% + \advance\pgfutil@tempdimb by-\pgf@yb% + % harpoon miter correction + \ifpgfarrowroundjoin + \pgfarrowssetbackend{\pgf@ya\advance\pgf@x by-.5\pgfarrowlinewidth} + \else + \pgfarrowssetbackend{0pt} + \fi + \ifpgfarrowharpoon + \pgfarrowssetlineend{\pgfarrowinset\advance\pgf@x + by\pgf@yc\advance\pgf@x by.5\pgfarrowlinewidth} + \else + \pgfarrowssetlineend{\pgfarrowinset\advance\pgf@x by\pgf@yc\advance\pgf@x by-.25\pgfarrowlinewidth} + \ifpgfarrowreversed + \ifdim\pgfinnerlinewidth>0pt + \pgfarrowssetlineend{\pgfarrowinset} + \else + \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by\pgf@ya\advance\pgf@x by-.25\pgfarrowlinewidth} + \fi + \fi + \fi + \ifpgfarrowroundjoin + \pgfarrowssettipend{\pgfutil@tempdima\advance\pgf@x by\pgf@ya\advance\pgf@x by.5\pgfarrowlinewidth} + \else + \pgfarrowssettipend{\pgfarrowlength\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi} + \fi + % The hull: + \pgfarrowshullpoint{\pgfarrowlength\ifpgfarrowroundjoin\else\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi\fi}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}% + \pgfarrowsupperhullpoint{0pt}{.5\pgfarrowwidth}% + \pgfarrowshullpoint{\pgfarrowinset}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else 0pt\fi}% + % Adjust inset + \pgfarrowssetvisualbackend{\pgfarrowinset} + \advance\pgfarrowinset by\pgf@yc% + % The following are needed in the code: + \pgfarrowssavethe\pgfutil@tempdima + \pgfarrowssavethe\pgfutil@tempdimb + \pgfarrowssavethe\pgfarrowlinewidth + \pgfarrowssavethe\pgf@ya + \pgfarrowssavethe\pgfarrowinset + }, + drawing code = { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima\advance\pgf@x by\pgf@ya}{0pt}} + \pgfpathlineto{\pgfqpoint{\pgf@ya}{\pgfutil@tempdimb}} + \pgfpathlineto{\pgfqpoint{\pgfarrowinset}{0pt}} + \ifpgfarrowharpoon \else + \pgfpathlineto{\pgfqpoint{\pgf@ya}{-\pgfutil@tempdimb}} + \fi + \pgfpathclose + \ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt\pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \the\pgfarrowinset,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowopen o\fi% + \ifpgfarrowroundjoin j\fi% + }, +} + + + +% A Kite is like a Stealth, only the inset counts in the other direction + +\pgfdeclarearrow{ + name = Kite, + defaults = { + length = +3.6pt +5.4, + width' = +0pt +0.5, + inset' = +0pt 0.25, + line width = +0pt 1 1, + }, + setup code = { + % Cap the line width at 1/4th of the length + \pgf@x.4\pgfarrowlength + \ifdim\pgf@x<\pgfarrowlinewidth + \pgfarrowlinewidth\pgf@x + \fi + \pgf@x.4\pgfarrowwidth + \ifdim\pgf@x<\pgfarrowlinewidth + \pgfarrowlinewidth\pgf@x + \fi + % Compute front miter length: + \pgf@xa\pgfarrowlength% + \advance\pgf@xa by-\pgfarrowinset% + \pgfmathdivide@\pgf@xa\pgfarrowwidth% + \let\pgf@temp@quot\pgfmathresult% + \pgf@x\pgfmathresult pt% + \pgf@x\pgfmathresult\pgf@x% + \pgf@x4\pgf@x% + \advance\pgf@x by1pt% + \pgfmathsqrt@\pgf@x% + \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter + \pgf@xc.5\pgf@xc + \pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter + % Compute back miter length: + \pgfmathdivide@\pgfarrowinset\pgfarrowwidth% + \let\pgf@temp@quot\pgfmathresult% + \pgf@x\pgfmathresult pt% + \pgf@x\pgfmathresult\pgf@x% + \pgf@x4\pgf@x% + \advance\pgf@x by1pt% + \pgfmathsqrt@\pgf@x% + \pgf@yc\pgfmathresult\pgfarrowlinewidth% yc is back miter + \pgf@yc.5\pgf@yc + \pgf@ya\pgf@temp@quot\pgfarrowlinewidth% ya is extra harpoon miter + % Compute top miter length: + {% + \pgfutil@tempdimb.5\pgfarrowwidth% + \pgfutil@tempdima\pgfarrowlength\advance\pgfutil@tempdima by-\pgfarrowinset% + \csname pgfmathatan2@\endcsname{\pgfmath@tonumber\pgfutil@tempdima}{\pgfmath@tonumber\pgfutil@tempdimb}% + \pgf@yb\pgfmathresult pt% + \csname pgfmathatan2@\endcsname{\pgfmath@tonumber\pgfarrowinset}{\pgfmath@tonumber\pgfutil@tempdimb}% + \pgf@ya\pgfmathresult pt% + \advance\pgf@yb by\pgf@ya% + \pgf@yb.5\pgf@yb% half angle in yb + \ifdim\pgf@yb=45pt% + \def\pgfmathresult{1.414213}% + \else% + \pgfmathsin@{\pgf@yb}% + \pgfmathreciprocal@{\pgfmathresult}% + \fi% + \pgf@yc\pgfmathresult\pgfarrowlinewidth% + \pgf@yc.5\pgf@yc% + \pgf@ya-\pgf@ya% + \advance\pgf@ya by-90pt% + \advance\pgf@ya by\pgf@yb% + \pgfmathsincos@{\pgf@ya}% + \pgf@xb\pgfmathresultx\pgf@yc% ya is the back miter + \pgf@yb\pgfmathresulty\pgf@yc% yb is the top miter + \expandafter\expandafter\expandafter% + }\expandafter\expandafter\expandafter\pgf@xb\expandafter\the\expandafter\pgf@xb\expandafter\pgf@yb\the\pgf@yb% + % Inner length (pgfutil@tempdima) is now arrowlength - front miter - back miter + \pgfutil@tempdima\pgfarrowlength% + \advance\pgfutil@tempdima by-\pgf@xc% + \pgfutil@tempdimb.5\pgfarrowwidth% + \advance\pgfutil@tempdimb by\pgf@yb% + % Set back end + \ifpgfarrowroundjoin + \pgfarrowssetbackend{\pgf@ya\advance\pgf@x by-.5\pgfarrowlinewidth} + \else + \pgfarrowssetbackend{0pt} + \fi + % harpoon miter correction + \ifpgfarrowreversed + \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by-\pgflinewidth\advance\pgf@x by\pgfarrowlinewidth} + \else + \pgfarrowssetlineend{\pgf@yc\advance\pgf@x by\pgflinewidth\advance\pgf@x by-\pgfarrowlinewidth} + \fi + \ifpgfarrowroundjoin + \pgfarrowssettipend{\pgfutil@tempdima\advance\pgf@x by.5\pgfarrowlinewidth} + \else + \pgfarrowssettipend{\pgfarrowlength\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi} + \fi + % The hull: + \pgfarrowshullpoint{\pgfarrowlength\ifpgfarrowroundjoin\else\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi\fi}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}% + \pgfarrowsupperhullpoint{\pgfarrowinset}{.5\pgfarrowwidth}% + \pgfarrowshullpoint{0pt}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}% + % Adjust the inset: + \advance\pgfarrowinset by\pgf@xb% + % The following are needed in the code: + \pgfarrowssavethe\pgfutil@tempdima + \pgfarrowssavethe\pgfutil@tempdimb + \pgfarrowssavethe\pgfarrowlinewidth + \pgfarrowssavethe\pgf@yc + \pgfarrowssavethe\pgfarrowinset + }, + drawing code = { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{\pgfarrowlinewidth}\fi + \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima}{0pt}} + \pgfpathlineto{\pgfqpoint{\pgfarrowinset}{\pgfutil@tempdimb}} + \pgfpathlineto{\pgfqpoint{\pgf@yc}{0pt}} + \ifpgfarrowharpoon \else + \pgfpathlineto{\pgfqpoint{\pgfarrowinset}{-\pgfutil@tempdimb}} + \fi + \pgfpathclose + \ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt\pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \the\pgfarrowinset,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowopen o\fi% + \ifpgfarrowroundjoin j\fi% + }, +} + + + + +% A simple rectangle shape + +\pgfdeclarearrow{ + name = Square, + defaults = { + length = +2.12132pt +2.828427, + width' = +0pt +1, + line width = +0pt +1 +1, + }, + setup code = { + % Cap the line width at 1/2th of the length + \pgf@x.5\pgfarrowlength + \ifdim\pgf@x<\pgfarrowlinewidth + \pgfarrowlinewidth\pgf@x + \fi + \ifpgfarrowreversed + \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth} + \else + \pgfarrowssetlineend{.5\pgfarrowlinewidth} + \fi + \pgfarrowssettipend{\pgfarrowlength} + % The hull: + \pgfarrowshullpoint{\pgfarrowlength}{.5\pgfarrowwidth} + \pgfarrowshullpoint{0pt}{.5\pgfarrowwidth} + \pgfarrowshullpoint{\pgfarrowlength}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else-.5\pgfarrowwidth\fi} + \pgfarrowshullpoint{0pt}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else-.5\pgfarrowwidth\fi} + % The following are needed in the code: + \pgfarrowssavethe\pgfarrowlinewidth + \pgfarrowssavethe\pgfarrowlength + \pgfarrowssavethe\pgfarrowwidth + }, + drawing code = { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + \pgfpathmoveto{\pgfqpoint{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}} + \pgfpathlineto{\pgfqpoint{.5\pgfarrowlinewidth}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}} + \pgfpathlineto{\pgfqpoint{.5\pgfarrowlinewidth}{\ifpgfarrowharpoon0pt\else-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth\fi}} + \pgfpathlineto{\pgfqpoint{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth}{\ifpgfarrowharpoon0pt\else-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth\fi}} + \pgfpathclose + \ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt\pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowopen o\fi% + \ifpgfarrowroundjoin j\fi% + }, +} + + +% A simple rectangle shape + +\pgfdeclarearrow{ + name = Circle, + defaults = { + length = +2.39365pt +3.191538, + width' = +0pt 1, + line width = +0pt 1 1, + }, + setup code = { + % Cap the line width at 1/2th of the length + \pgf@x.5\pgfarrowlength + \ifdim\pgf@x<\pgfarrowlinewidth + \pgfarrowlinewidth\pgf@x + \fi + \ifpgfarrowreversed + \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth} + \else + \pgfarrowssetlineend{.5\pgfarrowlinewidth} + \fi + \pgfarrowssettipend{\pgfarrowlength} + % The hull: + \pgfarrowsupperhullpoint{\pgfarrowlength}{.25\pgfarrowwidth} + \pgfarrowsupperhullpoint{.75\pgfarrowlength}{.5\pgfarrowwidth} + \pgfarrowsupperhullpoint{.25\pgfarrowlength}{.5\pgfarrowwidth} + \pgfarrowsupperhullpoint{0pt}{.25\pgfarrowwidth} + \ifpgfarrowharpoon% + \pgfarrowshullpoint{0pt}{-.5\pgfarrowlinewidth} + \pgfarrowshullpoint{\pgfarrowlength}{-.5\pgfarrowlinewidth} + \fi% + % The following are needed in the code: + \pgfarrowssavethe\pgfarrowlinewidth + \pgfarrowssavethe\pgfarrowlength + \pgfarrowssavethe\pgfarrowwidth + }, + drawing code = { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + \ifpgfarrowharpoon + \pgfpathmoveto{\pgfqpoint{\pgfarrowlength\advance\pgf@x + by-.5\pgfarrowlinewidth}{0pt}} + {% + \pgf@xa.5\pgfarrowlength + \advance\pgf@xa by-.5\pgfarrowlinewidth + \pgftransformxscale{+\the\pgf@xa} + \pgf@xa.5\pgfarrowwidth + \advance\pgf@xa by-.5\pgfarrowlinewidth + \pgftransformyscale{+\the\pgf@xa} + \pgfpatharc{0}{180}{1pt} + } + \pgfpathclose + \else% + \pgfpathellipse{\pgfqpoint{.5\pgfarrowlength}{0pt}}{\pgfqpoint{.5\pgfarrowlength\advance\pgf@x + by-.5\pgfarrowlinewidth}{0pt}}{\pgfqpoint{0pt}{.5\pgfarrowwidth\advance\pgf@y + by-.5\pgfarrowlinewidth}} + \fi + \ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt\pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowopen o\fi% + \ifpgfarrowroundjoin j\fi% + }, +} + +% Round cap + +\pgfdeclarearrow{ + name = Round Cap, + defaults = { + length = +0pt .5 + }, + setup code = { + \ifpgfarrowreversed + \pgfarrowssettipend{\pgfarrowlength} + \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by.5\pgflinewidth} + \else + \pgfarrowssettipend{\pgfarrowlength} + \pgfarrowssetlineend{-.5\pgflinewidth} + \fi + \pgfarrowssavethe\pgfarrowlength + \pgfarrowsupperhullpoint{0pt}{.5\pgflinewidth} + \pgfarrowsupperhullpoint{\pgfarrowlength}{.5\pgflinewidth} + }, + drawing code = { + \ifpgfarrowreversed + \pgftransformxscale{-1} + \pgftransformxshift{-\pgfarrowlength} + \fi + \pgfutil@tempdima.5\pgflinewidth + \pgfpathmoveto {\pgfqpoint{-0.75\pgflinewidth}{\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{0pt}{\pgfutil@tempdima}} + \ifpgfarrowreversed + \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{\pgfutil@tempdima}} + \begingroup + \pgftransformxshift{\pgfarrowlength} + \pgftransformxscale{-1} + \fi + \pgfpathcurveto {\pgfqpoint{0.55228475\pgfarrowlength}{\pgfutil@tempdima}} + {\pgfqpoint{\pgfarrowlength}{0.55228475\pgfutil@tempdima}} + {\pgfqpoint{\pgfarrowlength}{0pt}} + \pgfpathcurveto {\pgfqpoint{\pgfarrowlength}{-0.55228475\pgfutil@tempdima}} + {\pgfqpoint{0.55228475\pgfarrowlength}{-\pgfutil@tempdima}} + {\pgfqpoint{0pt}{-\pgfutil@tempdima}} + \ifpgfarrowreversed + \endgroup + \fi + \pgfpathlineto {\pgfqpoint{-.75\pgflinewidth}{-\pgfutil@tempdima}} + \pgfpathclose + \pgfusepathqfill + }, + parameters = {\the\pgfarrowlength} +} + + + +\pgfdeclarearrow{ + name = Butt Cap, + defaults = { + length = +0pt .5 + }, + setup code = { + \pgfarrowssettipend{\pgfarrowlength} + \pgfarrowssetlineend{-.5\pgflinewidth} + \pgfarrowssavethe\pgfarrowlength + \pgfarrowsupperhullpoint{0pt}{.5\pgflinewidth} + \pgfarrowsupperhullpoint{\pgfarrowlength}{.5\pgflinewidth} + }, + drawing code = { + \pgfutil@tempdima.5\pgflinewidth + \pgfpathmoveto {\pgfqpoint{-0.75\pgflinewidth}{\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{0pt}{\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{-\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{-.75\pgflinewidth}{-\pgfutil@tempdima}} + \pgfpathclose + \pgfusepathqfill + }, + parameters = {\the\pgfarrowlength} +} + + + +\pgfkeys{ + /pgf/arrow keys/.cd, + cap angle/.code={% + \pgfmathsetlength\pgf@x{#1}% + \pgf@x.5\pgf@x + \pgfmathtan@{\pgf@x}% + \pgfmathreciprocal@{\pgfmathresult}% + \pgf@x\pgfmathresult pt% + \pgf@x.5\pgf@x% + \edef\pgf@marshal{\noexpand\pgfarrowsaddtooptions{\noexpand\pgfarrowslinewidthdependent{+0pt}{\pgf@sys@tonumber\pgf@x}{0}\pgfarrowlength\pgf@x}} + \pgf@marshal + } +} + + +\pgfdeclarearrow{ + name = Triangle Cap, + defaults = { + length = +0pt .5 + }, + setup code = { + \ifpgfarrowreversed + \pgfarrowssettipend{\pgfarrowlength} + \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by.5\pgflinewidth} + \else + \pgfarrowssettipend{\pgfarrowlength} + \pgfarrowssetlineend{-.5\pgflinewidth} + \fi + \pgfarrowssavethe\pgfarrowlength + \pgfarrowsupperhullpoint{0pt}{.5\pgflinewidth} + \pgfarrowshullpoint{\pgfarrowlength}{0pt} + }, + drawing code = { + \ifpgfarrowreversed + \pgftransformxscale{-1} + \pgftransformxshift{-\pgfarrowlength} + \fi + \pgfutil@tempdima.5\pgflinewidth + \pgfpathmoveto {\pgfqpoint{-0.75\pgflinewidth}{\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{0pt}{\pgfutil@tempdima}} + \ifpgfarrowreversed + \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{\pgfutil@tempdima}} + \begingroup + \pgftransformxshift{\pgfarrowlength} + \pgftransformxscale{-1} + \fi + \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{0pt}} + \ifpgfarrowreversed + \endgroup + \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{-\pgfutil@tempdima}} + \fi + \pgfpathlineto {\pgfqpoint{0pt}{-\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{-.75\pgflinewidth}{-\pgfutil@tempdima}} + \pgfpathclose + \pgfusepathqfill + }, + parameters = {\the\pgfarrowlength} +} + + + +\pgfdeclarearrow{ + name = Fast Triangle, + defaults = { + length = +0pt .5, + inset = +0pt .5, + }, + setup code = { + \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by\pgfarrowinset} + \ifpgfarrowreversed\pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by\pgfarrowinset}\fi + \pgfarrowssavethe\pgfarrowlength + \pgfarrowssavethe\pgfarrowinset + \pgfarrowsupperhullpoint{0pt}{.5\pgflinewidth} + \pgfarrowsupperhullpoint{\pgfarrowinset}{.5\pgflinewidth} + \pgfarrowshullpoint{\pgfarrowlength\advance\pgf@x by\pgfarrowinset}{0pt} + }, + drawing code = { + \pgfutil@tempdima.5\pgflinewidth + \pgfpathmoveto {\pgfqpoint{0pt}{\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{\pgfarrowinset}{\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{\pgfarrowinset\advance\pgf@x by\pgfarrowlength}{0pt}} + \pgfpathlineto {\pgfqpoint{\pgfarrowinset}{-\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{0pt}{-\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{0pt}} + \pgfpathclose + \pgfusepathqfill + }, + parameters = {\the\pgfarrowlength,\the\pgfarrowinset} +} + + +\pgfdeclarearrow{ + name = Fast Round, + defaults = { + length = +0pt .5, + inset = +0pt .5, + }, + setup code = { + \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by\pgfarrowinset} + \ifpgfarrowreversed\pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by\pgfarrowinset}\fi + \pgfarrowssavethe\pgfarrowlength + \pgfarrowssavethe\pgfarrowinset + \pgfarrowsupperhullpoint{0pt}{.5\pgflinewidth} + \pgfarrowsupperhullpoint{\pgfarrowlength\advance\pgf@x by\pgfarrowinset}{.5\pgflinewidth} + }, + drawing code = { + \pgfutil@tempdima.5\pgflinewidth + \pgfpathmoveto {\pgfqpoint{0pt}{\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{\pgfarrowinset}{\pgfutil@tempdima}} + { + \pgftransformxshift{\pgfarrowinset} + \pgfpathcurveto{\pgfqpoint{0.55228475\pgfarrowlength}{\pgfutil@tempdima}} + {\pgfqpoint{\pgfarrowlength}{0.55228475\pgfutil@tempdima}} + {\pgfqpoint{\pgfarrowlength}{0pt}} + \pgfpathcurveto{\pgfqpoint{\pgfarrowlength}{-0.55228475\pgfutil@tempdima}} + {\pgfqpoint{0.55228475\pgfarrowlength}{-\pgfutil@tempdima}} + {\pgfqpoint{0pt}{-\pgfutil@tempdima}} + } + \pgfpathlineto {\pgfqpoint{0pt}{-\pgfutil@tempdima}} + \pgfpathcurveto {\pgfqpoint{0.55228475\pgfarrowlength}{-\pgfutil@tempdima}} + {\pgfqpoint{\pgfarrowlength}{-0.55228475\pgfutil@tempdima}} + {\pgfqpoint{\pgfarrowlength}{0pt}} + \pgfpathcurveto {\pgfqpoint{\pgfarrowlength}{0.55228475\pgfutil@tempdima}} + {\pgfqpoint{0.55228475\pgfarrowlength}{\pgfutil@tempdima}} + {\pgfqpoint{0pt}{\pgfutil@tempdima}} + \pgfpathclose + \pgfusepathqfill + }, + parameters = {\the\pgfarrowlength,\the\pgfarrowinset} +} + + + + +% +% +% Other arrow tips. +% +% + + +\pgfkeys{ + /pgf/arrow keys/.cd, + n/.code={% + \pgfmathparse{#1}% + \expandafter\pgf@lib@meta@strip@dot\pgfmathresult.\relax% + } +} +\def\pgf@lib@meta@strip@dot#1.#2\relax{% + \pgfarrowsaddtooptions{\def\pgfarrown{#1}}% +} + +\def\pgfarrown{4} + +\pgfdeclarearrow{ + name = Rays, + defaults = { + length = +3pt 4, + width' = +0pt 1, + line width = +0pt 1 1, + }, + setup code = { + \pgfmathdivide@{360}{\pgfarrown}% + \let\pgfarrow@inc\pgfmathresult% + % Compute tips: + \pgf@xa\pgfarrow@inc pt% + \ifodd\pgfarrown\pgf@ya.25\pgf@xa\else\pgf@ya.5\pgf@xa\fi% + \pgfmathsincos@\pgf@ya% + \pgf@x.5\pgfarrowlength% + \pgf@xa\pgfmathresultx\pgf@x% + \ifpgfarrowroundcap + \advance\pgf@xa by.5\pgfarrowlinewidth + \else + \pgf@process{\pgfpointnormalised{\pgfqpoint{\pgfmathresultx\pgfarrowlength}{\pgfmathresulty\pgfarrowwidth}}}% + \pgf@x.5\pgfarrowlinewidth% + \advance\pgf@xa by\pgf@sys@tonumber{\pgf@y}\pgf@x% + \fi% + \pgfarrowssettipend{\pgf@xa} + \pgfarrowssetbackend{-\pgf@xa} + % Hull is alwyas 8-point hull, except for tip + % The following are needed in the code: + \pgfarrowsupperhullpoint{\pgf@xa}{.25\pgfarrowwidth} + \pgfarrowsupperhullpoint{.25\pgfarrowlength}{.5\pgfarrowwidth\ifpgfarrowroundcap\advance\pgf@y by.5\pgfarrowlinewidth\fi} + \pgfarrowsupperhullpoint{-.25\pgfarrowlength}{.5\pgfarrowwidth\ifpgfarrowroundcap\advance\pgf@y by.5\pgfarrowlinewidth\fi} + \pgfarrowsupperhullpoint{-\pgf@xa}{.25\pgfarrowwidth} + \ifpgfarrowharpoon + \pgfarrowshullpoint{-.5\pgfarrowlength\ifpgfarrowroundcap\advance\pgf@x by-.5\pgfarrowlinewidth\fi}{-.5\pgfarrowlinewidth} + \pgfarrowshullpoint{.5\pgfarrowlength\ifpgfarrowroundcap\advance\pgf@x by.5\pgfarrowlinewidth\fi}{-.5\pgfarrowlinewidth} + \fi + \pgfarrowssavethe\pgfarrowlinewidth + \pgfarrowssavethe\pgfarrowlength + \pgfarrowssavethe\pgfarrowwidth + \pgfarrowssave\pgfarrow@inc + \pgfarrowssave\pgfarrown + }, + drawing code = { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + {% + \pgfgettransform\pgf@temp@trans + \pgftransformxscale{+.5\pgfarrowlength} + \pgftransformyscale{+.5\pgfarrowwidth} + \pgf@xa\pgfarrow@inc pt% + \ifodd\pgfarrown\pgf@ya.25\pgf@xa\else\pgf@ya.5\pgf@xa\fi% + \ifpgfarrowharpoon\pgf@yb180pt\else\pgf@yb360pt\fi + \pgfutil@loop% + \ifdim\pgf@ya<\pgf@yb% + \pgfpathmoveto{\pgfpointpolar{+\pgf@ya}{+1pt}} + \pgfpathlineto{\pgfpointorigin} + \ifpgfarrowharpoon\ifdim\pgf@ya>\pgf@xa\else{\pgfsettransform\pgf@temp@trans\pgfpathlineto{\pgfqpoint{-.5\pgflinewidth}{0pt}}}\fi\fi + \advance\pgf@ya by\pgf@xa\relax% + \pgfutil@repeat% + } + \pgfusepathqstroke + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \pgfarrown,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowroundcap c\fi% + } +} + + + +% Shorthands and Aliases: + +\pgfkeys{ + LaTeX /.tip = {Latex}, + Triangle /.tip = {Stealth[inset=+0pt, angle=+60:+2.7pt +3.6]}, + Rectangle /.tip = {Square[length=+3pt +4.5,width'=+0pt +.5]}, + Ellipse /.tip = {Circle[length=+3.3pt +4.95, width'=+0pt +0.5]}, + Diamond /.tip = {Kite[inset'=+0pt .5]}, + Turned Square /.tip = {Kite[length=+3pt 4,width'= +0pt 1,inset'= +0pt 0.5]}, + To /.tip = {Computer Modern Rightarrow}, + Bar /.tip = {Tee Barb[length=+0pt]}, + Bracket /.tip = {Tee Barb[inset'=+0pt +1,length=+0.75pt +1]}, + Parenthesis /.tip = {Arc Barb[arc=+120,length=+1.725pt +2.3]} +} + + + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.spaced.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.spaced.code.tex new file mode 100644 index 00000000000..b6d1728363d --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.spaced.code.tex @@ -0,0 +1,92 @@ +% Copyright 2012 by Till Tantau +% +% This file may be distributed and/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 details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryarrows.spaced.code.tex,v 1.3 2013/09/23 18:04:36 tantau Exp $ + + +\usepgflibrary{arrows} + + +% This library offers "spaced" versions of existing arrows, where a +% bit of additional space is inserted at the tip. This often looks +% better than the normal arrow. +% +% These arrows are called "spaced whatever" where "whatever" is the +% original name of the arrow. + + +\pgfarrowsdeclarecombine*{spaced to}{spaced to}{to}{to}{space}{space} +\pgfarrowsdeclarecombine*{spaced to reversed}{spaced to reversed}{to reversed}{to reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced implies}{spaced implies}{implies}{implies}{space}{space} +\pgfarrowsdeclarecombine*{spaced latex}{spaced latex}{latex}{latex}{space}{space} +\pgfarrowsdeclarecombine*{spaced latex reversed}{spaced latex reversed}{latex reversed}{latex reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced latex'}{spaced latex'}{latex'}{latex'}{space}{space} +\pgfarrowsdeclarecombine*{spaced latex' reversed}{spaced latex' reversed}{latex' reversed}{latex' reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced stealth}{spaced stealth}{stealth}{stealth}{space}{space} +\pgfarrowsdeclarecombine*{spaced stealth reversed}{spaced stealth reversed}{stealth reversed}{stealth reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced stealth'}{spaced stealth'}{stealth'}{stealth'}{space}{space} +\pgfarrowsdeclarecombine*{spaced stealth' reversed}{spaced stealth' reversed}{stealth' reversed}{stealth' reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced triangle 90}{spaced triangle 90}{triangle 90}{triangle 90}{space}{space} +\pgfarrowsdeclarecombine*{spaced triangle 90 reversed}{spaced triangle 90 reversed}{triangle 90 reversed}{triangle 90 reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced triangle 60}{spaced triangle 60}{triangle 60}{triangle 60}{space}{space} +\pgfarrowsdeclarecombine*{spaced triangle 60 reversed}{spaced triangle 60 reversed}{triangle 60 reversed}{triangle 60 reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced triangle 45}{spaced triangle 45}{triangle 45}{triangle 45}{space}{space} +\pgfarrowsdeclarecombine*{spaced triangle 45 reversed}{spaced triangle 45 reversed}{triangle 45 reversed}{triangle 45 reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced open triangle 90}{spaced open triangle 90}{open triangle 90}{open triangle 90}{space}{space} +\pgfarrowsdeclarecombine*{spaced open triangle 90 reversed}{spaced open triangle 90 reversed}{open triangle 90 reversed}{open triangle 90 reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced open triangle 60}{spaced open triangle 60}{open triangle 60}{open triangle 60}{space}{space} +\pgfarrowsdeclarecombine*{spaced open triangle 60 reversed}{spaced open triangle 60 reversed}{open triangle 60 reversed}{open triangle 60 reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced open triangle 45}{spaced open triangle 45}{open triangle 45}{open triangle 45}{space}{space} +\pgfarrowsdeclarecombine*{spaced open triangle 45 reversed}{spaced open triangle 45 reversed}{open triangle 45 reversed}{open triangle 45 reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced angle 90}{spaced angle 90}{angle 90}{angle 90}{space}{space} +\pgfarrowsdeclarecombine*{spaced angle 90 reversed}{spaced angle 90 reversed}{angle 90 reversed}{angle 90 reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced angle 60}{spaced angle 60}{angle 60}{angle 60}{space}{space} +\pgfarrowsdeclarecombine*{spaced angle 60 reversed}{spaced angle 60 reversed}{angle 60 reversed}{angle 60 reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced angle 45}{spaced angle 45}{angle 45}{angle 45}{space}{space} +\pgfarrowsdeclarecombine*{spaced angle 45 reversed}{spaced angle 45 reversed}{angle 45 reversed}{angle 45 reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced hooks}{spaced hooks}{hooks}{hooks}{space}{space} +\pgfarrowsdeclarecombine*{spaced hooks reversed}{spaced hooks reversed}{hooks reversed}{hooks reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced o}{spaced o}{o}{o}{space}{space} +\pgfarrowsdeclarecombine*{spaced *}{spaced *}{*}{*}{space}{space} +\pgfarrowsdeclarecombine*{spaced diamond}{spaced diamond}{diamond}{diamond}{space}{space} +\pgfarrowsdeclarecombine*{spaced open diamond}{spaced open diamond}{open diamond}{open diamond}{space}{space} +\pgfarrowsdeclarecombine*{spaced square}{spaced square}{square}{square}{space}{space} +\pgfarrowsdeclarecombine*{spaced open square}{spaced open square}{open square}{open square}{space}{space} +\pgfarrowsdeclarecombine*{spaced serif cm}{spaced serif cm}{serif cm}{serif cm}{space}{space} +\pgfarrowsdeclarecombine*{spaced left to}{spaced left to}{left to}{left to}{space}{space} +\pgfarrowsdeclarecombine*{spaced left to reversed}{spaced left to reversed}{left to reversed}{left to reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced right to}{spaced right to}{right to}{right to}{space}{space} +\pgfarrowsdeclarecombine*{spaced right to reversed}{spaced right to reversed}{right to reversed}{right to reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced left hook}{spaced left hook}{left hook}{left hook}{space}{space} +\pgfarrowsdeclarecombine*{spaced left hook reversed}{spaced left hook reversed}{left hook reversed}{left hook reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced right hook}{spaced right hook}{right hook}{right hook}{space}{space} +\pgfarrowsdeclarecombine*{spaced right hook reversed}{spaced right hook reversed}{right hook reversed}{right hook reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced round cap}{spaced round cap}{round cap}{round cap}{space}{space} +\pgfarrowsdeclarecombine*{spaced butt cap}{spaced butt cap}{butt cap}{butt cap}{space}{space} +\pgfarrowsdeclarecombine*{spaced triangle 90 cap}{spaced triangle 90 cap}{triangle 90 cap}{triangle 90 cap}{space}{space} +\pgfarrowsdeclarecombine*{spaced triangle 90 cap reversed}{spaced triangle 90 cap reversed}{triangle 90 cap reversed}{triangle 90 cap reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced fast cap}{spaced fast cap}{fast cap}{fast cap}{space}{space} +\pgfarrowsdeclarecombine*{spaced fast cap reversed}{spaced fast cap reversed}{fast cap reversed}{fast cap reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced (}{spaced )}{(}{)}{space}{space} +\pgfarrowsdeclarecombine*{spaced )}{spaced (}{)}{(}{space}{space} +\pgfarrowsdeclarecombine*{spaced |}{spaced |}{|}{|}{space}{space} + +\pgfdeclarearrow{ + name = spaced [-spaced ], + means = square bracket[].space +} + +\pgfdeclarearrow{ + name = spaced ]-spaced [, + means = square bracket[reversed].space +} + + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarycurvilinear.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarycurvilinear.code.tex new file mode 100644 index 00000000000..18fa1951b05 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarycurvilinear.code.tex @@ -0,0 +1,378 @@ +% Copyright 2013 by Till Tantau +% +% This file may be distributed and/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 details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibrarycurvilinear.code.tex,v 1.3 2013/10/07 15:51:46 tantau Exp $ + +% +% This file defines commands for computing points in curvilinear +% coordinate systems. +% + + +% +% Curvilinear coordinate systems defined in terms of a Bezier curve. +% +% For the following coordinate systems, you must first provide a +% Bezier curve (using, as always, four points), which will be set for +% the current scope. When the curve is "installed" some expensive +% precomputations are done; subsequent calls to +% \pgfpointcurvilinearxxx based on this Bezier curve will be +% relatively quick. +% + + + +% Install a Bezier curve +% +% #1 = start point +% #2 = first control point +% #3 = second control point +% #4 = end point +% +% Description: +% +% Subsequent calls to functions like +% \pgfpointcurvilinearbezierorthogonal will be relative to the curve +% installed using this command. The main job of this macro is a +% precomputation for computing length along the curve. +% All lengths along the Bezier curve are approximated using a lookup table +% of four time/length points. For this, an approximate time for length +% 1pt is computed first, and then the length for twice this time, four +% times this time, and eight times this time are approximated. A +% distance-to-time conversion is then done by a linear interpolation +% of distance-to-time for these four points. Note that all of these +% computations are not particularly precise, but a compromise trading +% speed against precision. Also note that the results will only be +% best near the start of the curve and may be far off near the end if +% that end is degenerate (second control point very near to end +% point). +% +% Example: +% +% \pgfsetcurvilinearbeziercurve +% {\pgfpoint{0mm}{10mm}} +% {\pgfpoint{5.5mm}{10mm}} +% {\pgfpoint{10mm}{5.5mm}} +% {\pgfpoint{10mm}{0mm}} % nearly a quarter circle +% \pgfpointcurvilinearbezierorthogonal{5mm}{5mm} +% % should be 5mm along the circle, put at +% % distance 15mm from the origin (5mm from the circle line). + +\def\pgfsetcurvilinearbeziercurve#1#2#3#4{% + \pgf@process{#1}% + \edef\pgf@curvilinear@line@a{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \pgf@xa=-\pgf@x% + \pgf@ya=-\pgf@y% + \pgf@process{#2}% + \edef\pgf@curvilinear@line@b{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \pgf@xb=-\pgf@x% + \pgf@yb=-\pgf@y% + \advance\pgf@x by\pgf@xa% + \advance\pgf@y by\pgf@ya% + \pgfmathveclen@{\pgf@x}{\pgf@y}% + \let\pgf@curvilinear@lenab\pgfmathresult% + \pgf@process{#3}% + \edef\pgf@curvilinear@line@c{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \pgf@xc=-\pgf@x% + \pgf@yc=-\pgf@y% + \advance\pgf@x by\pgf@xb% + \advance\pgf@y by\pgf@yb% + \pgfmathveclen@{\pgf@x}{\pgf@y}% + \let\pgf@curvilinear@lenbc\pgfmathresult% + \pgf@process{#4}% + \edef\pgf@curvilinear@line@d{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \advance\pgf@x by\pgf@xc% + \advance\pgf@y by\pgf@yc% + \pgfmathveclen@{\pgf@x}{\pgf@y}% + \let\pgf@curvilinear@lencd\pgfmathresult + % + \pgf@x=\pgf@curvilinear@lenab pt% + \advance\pgf@x by\pgf@curvilinear@lenbc pt% + \advance\pgf@x by\pgf@curvilinear@lencd pt% + \pgfmathreciprocal@{\pgf@x}% + \pgf@curvilinear@time@a\pgfmathresult pt% + \pgf@process{\pgfpointcurveattime{\pgf@curvilinear@time@a}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}}% + \pgf@xb=-\pgf@x% + \pgf@yb=-\pgf@y% + \advance\pgf@x by\pgf@xa% + \advance\pgf@y by\pgf@ya% + \pgfmathveclen@{\pgf@x}{\pgf@y}% + \pgf@curvilinear@length@a\pgfmathresult pt% + \ifdim\pgf@curvilinear@length@a>1pt\relax% + % Ok, too large, let us make this smaller + \pgfmathdivide@{\pgf@curvilinear@time@a}{\pgf@curvilinear@length@a}% + \pgf@curvilinear@time@a\pgfmathresult pt% + \pgf@process{\pgfpointcurveattime{\pgf@curvilinear@time@a}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}} + \pgf@xb=-\pgf@x% + \pgf@yb=-\pgf@y% + \advance\pgf@x by\pgf@xa% + \advance\pgf@y by\pgf@ya% + \pgfmathveclen@{\pgf@x}{\pgf@y}% + \pgf@curvilinear@length@a\pgfmathresult pt% + \fi% + % Compute three positions: + \pgf@process{\pgfpointcurveattime{2\pgf@curvilinear@time@a}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}} + \pgf@xa=-\pgf@x% + \pgf@ya=-\pgf@y% + \advance\pgf@x by\pgf@xb% + \advance\pgf@y by\pgf@yb% + \pgfmathveclen@{\pgf@x}{\pgf@y}% + \pgf@curvilinear@length@b\pgfmathresult pt% + \advance\pgf@curvilinear@length@b by\pgf@curvilinear@length@a% + \pgf@process{\pgfpointcurveattime{4\pgf@curvilinear@time@a}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}} + \pgf@xb=-\pgf@x% + \pgf@yb=-\pgf@y% + \advance\pgf@x by\pgf@xa% + \advance\pgf@y by\pgf@ya% + \pgfmathveclen@{\pgf@x}{\pgf@y}% + \pgf@curvilinear@length@c\pgfmathresult pt% + \advance\pgf@curvilinear@length@c by\pgf@curvilinear@length@b% + \pgf@process{\pgfpointcurveattime{8\pgf@curvilinear@time@a}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}} + \advance\pgf@x by\pgf@xb% + \advance\pgf@y by\pgf@yb% + \pgfmathveclen@{\pgf@x}{\pgf@y}% + \pgf@curvilinear@length@d\pgfmathresult pt% + \advance\pgf@curvilinear@length@d by\pgf@curvilinear@length@c% + \let\pgf@curvilinear@comp@a\pgf@curvilinear@comp@a@initial% + \let\pgf@curvilinear@comp@b\pgf@curvilinear@comp@b@initial% + \let\pgf@curvilinear@comp@c\pgf@curvilinear@comp@c@initial% + \let\pgf@curvilinear@comp@d\pgf@curvilinear@comp@d@initial% + \let\pgf@curvilinear@comp@e\pgf@curvilinear@comp@e@initial% + \let\pgf@curvilinear@point\pgf@curvilinear@curve@point% +} +\newdimen\pgf@curvilinear@time@a +\newdimen\pgf@curvilinear@length@a +\newdimen\pgf@curvilinear@length@b +\newdimen\pgf@curvilinear@length@c +\newdimen\pgf@curvilinear@length@d + + +\def\pgf@curvilinear@comp@a@initial{% + \pgfmathdivide@\pgf@curvilinear@time@a\pgf@curvilinear@length@a% + \let\pgf@curvilinear@quot@a\pgfmathresult% + \let\pgf@curvilinear@comp@a\pgf@curvilinear@comp@a@cont% + \pgf@curvilinear@comp@a@cont% +} +\def\pgf@curvilinear@comp@a@cont{% + \pgf@x\pgf@curvilinear@quot@a\pgf@x% +} + +\def\pgf@curvilinear@comp@b@initial{% + \pgf@y=\pgf@curvilinear@length@b% + \advance\pgf@y by-\pgf@curvilinear@length@a% + \pgfmathdivide@\pgf@curvilinear@time@a\pgf@y% + \let\pgf@curvilinear@quot@b\pgfmathresult% + \pgf@y\pgfmathresult\pgf@curvilinear@length@a% + \pgf@y-\pgf@y% + \advance\pgf@y by\pgf@curvilinear@time@a% + \edef\pgf@curvilinear@correct@b{\pgf@sys@tonumber\pgf@y}% + \let\pgf@curvilinear@comp@b\pgf@curvilinear@comp@b@cont% + \pgf@curvilinear@comp@b@cont% +} +\def\pgf@curvilinear@comp@b@cont{% + \pgf@x\pgf@curvilinear@quot@b\pgf@x% + \advance\pgf@x by\pgf@curvilinear@correct@b pt% +} + +\def\pgf@curvilinear@comp@c@initial{% + \pgf@y=\pgf@curvilinear@length@c% + \advance\pgf@y by-\pgf@curvilinear@length@b% + \pgf@y.5\pgf@y% + \pgfmathdivide@\pgf@curvilinear@time@a\pgf@y% + \let\pgf@curvilinear@quot@c\pgfmathresult% + \pgf@y\pgf@curvilinear@quot@c\pgf@curvilinear@length@b% + \pgf@y-\pgf@y% + \advance\pgf@y by2\pgf@curvilinear@time@a% + \edef\pgf@curvilinear@correct@c{\pgf@sys@tonumber\pgf@y}% + \let\pgf@curvilinear@comp@c\pgf@curvilinear@comp@c@cont% + \pgf@curvilinear@comp@c@cont% +} +\def\pgf@curvilinear@comp@c@cont{% + \pgf@x\pgf@curvilinear@quot@c\pgf@x% + \advance\pgf@x by\pgf@curvilinear@correct@c pt% +} + +\def\pgf@curvilinear@comp@d@initial{% + \pgf@y=\pgf@curvilinear@length@d% + \advance\pgf@y by-\pgf@curvilinear@length@c% + \pgf@y.25\pgf@y% + \pgfmathdivide@\pgf@curvilinear@time@a\pgf@y% + \let\pgf@curvilinear@quot@d\pgfmathresult% + \pgf@y\pgf@curvilinear@quot@d\pgf@curvilinear@length@c% + \pgf@y-\pgf@y% + \advance\pgf@y by4\pgf@curvilinear@time@a% + \edef\pgf@curvilinear@correct@d{\pgf@sys@tonumber\pgf@y}% + \let\pgf@curvilinear@comp@d\pgf@curvilinear@comp@d@cont% + \pgf@curvilinear@comp@d@cont% +} +\def\pgf@curvilinear@comp@d@cont{% + \pgf@x\pgf@curvilinear@quot@d\pgf@x% + \advance\pgf@x by\pgf@curvilinear@correct@d pt% +} + +\def\pgf@curvilinear@comp@e@initial{% + \pgfmathdivide@{8\pgf@curvilinear@time@a}{\pgf@curvilinear@length@d}% + \let\pgf@curvilinear@quot@e\pgfmathresult% + \let\pgf@curvilinear@comp@e\pgf@curvilinear@comp@e@cont% + \pgf@curvilinear@comp@e@cont% +} +\def\pgf@curvilinear@comp@e@cont{% + \pgf@x\pgf@curvilinear@quot@e\pgf@x% +} + + +% Convert a distance into a time +% +% #1 = a distance +% +% Description: +% +% After having called \pgfsetcurvilinearbeziercurve, you can use this +% macro to convert a distance into a time along the curve set in that +% command. The result will be stored in \pgf@x. It will only be +% reasonably precise for small nonnegative #1 (in particular, #1 +% should not be more than about half the length of the curve). + +\def\pgfcurvilineardistancetotime#1{% + \pgfmathsetlength{\pgf@x}{#1}% + \ifdim\pgf@x<\pgf@curvilinear@length@c\relax% + \ifdim\pgf@x<\pgf@curvilinear@length@a\relax% + \pgf@curvilinear@comp@a% + \else\ifdim\pgf@x<\pgf@curvilinear@length@b\relax% + \pgf@curvilinear@comp@b% + \else% + \pgf@curvilinear@comp@c% + \fi\fi% + \else\ifdim\pgf@x<\pgf@curvilinear@length@d\relax% + \pgf@curvilinear@comp@d% + \else% + \pgf@curvilinear@comp@e% + \fi\fi% +} + + + +% Compute a "Bezier-orthogonal" point for use in a nonlinear transformation. +% +% #1 = x +% #2 = y +% +% Description: +% +% In this coordinate system, the x-axis "goes along" the Bezier curve +% installed using \pgfsetcurvilinearbeziercurve +% and the y-axis is always perpendicular to the (Bezier) curve at the +% given x-coordinate. Formally, given a pair (x,y), let B(x) be the point on +% the Bezier curve B at distance x from the start of the curve. Let +% T(x) be the tangent of B at B(x) and let P(x) be the (normalized) +% vector perpendicular to T(x). Then (x,y) would be mapped to B(x) + +% y*P(x). As an example, if B is a circle, then the corresponding +% curvilinear coordinate system is (essentially, except for an offset in +% the y value) the polar coordinate system. +% +% In addition to setting \pgf@x and \pgf@y, \pgf@xa/ya will be set to +% a tangent along the curve at the given point and \pgf@xb/yb to a +% tanget orthogonal to the curve. + +\def\pgfpointcurvilinearbezierorthogonal#1#2{% + \pgfmathsetmacro\pgf@curvilinear@yfactor{#2}% + \pgfcurvilineardistancetotime{#1}% + \pgfpointcurveattime{\pgf@x}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d} + \pgf@xc\pgf@x% save + \pgf@yc\pgf@y% save + % compute normal: + \advance\pgf@xb by-\pgf@xa% + \advance\pgf@yb by-\pgf@ya% + \ifdim\pgf@xb<0.0001pt\ifdim\pgf@xb>-0.0001pt\ifdim\pgf@yb<0.0001pt\ifdim\pgf@yb>-0.0001pt\pgf@diff@curvi@ac\fi\fi\fi\fi + \pgf@process{\pgfpointnormalised{\pgf@x=\pgf@yb\pgf@y=-\pgf@xb}} + \pgf@x\pgf@curvilinear@yfactor\pgf@x% + \pgf@y\pgf@curvilinear@yfactor\pgf@y% + \advance\pgf@x by\pgf@xc% + \advance\pgf@y by\pgf@yc% +} + +\def\pgf@diff@curvi@ac{% + \pgf@curvilinear@line@a% + \pgf@xa\pgf@x\pgf@ya\pgf@y% + \pgf@curvilinear@line@c% + \pgf@xb\pgf@x\pgf@yb\pgf@y% + \advance\pgf@xb by-\pgf@xa% + \advance\pgf@yb by-\pgf@ya% + \ifdim\pgf@xb<0.0001pt\ifdim\pgf@xb>-0.0001pt\ifdim\pgf@yb<0.0001pt\ifdim\pgf@yb>-0.0001pt% still degenerate! + \pgf@curvilinear@line@d% + \pgf@xb\pgf@x\pgf@yb\pgf@y% + \advance\pgf@xb by-\pgf@xa% + \advance\pgf@yb by-\pgf@ya% + \fi\fi\fi\fi% + \pgf@xb-\pgf@xb% + \pgf@yb-\pgf@yb% +} + + + +% Compute a "Bezier-polar" point. +% +% #1 = x +% #2 = y +% +% Description: +% +% Let (r:d) be the point (x,y) in polar coordinates, that is, r is the +% angle and d the distance of (x,y) to the origin. The point returned +% by \pgfpointcurvilinearbezierpolar is now defined as follows: First, +% we compute that point at distance d along the Bezier curve B. Let +% B(d) be this point. Then, we rotate this point around the start of +% the curve (B(0)) by r degrees. +% +% As an example, consider a triangle with one tip at the origin and +% the other tips as (4cm,3cm) and (4cm,-3cm). Then this triangle would be +% transformed as follows: We take the first 5cm of the Bezier curve +% and rotate it by roughly 37 degrees to the left and by 37 degrees to +% the right. +% +% Note that this command is pretty expensive. + +\def\pgfpointcurvilinearbezierpolar#1#2{% + \pgfmathsetlength\pgfutil@tempdima{#1}% + \pgfmathsetlength\pgfutil@tempdimb{#2}% + % Compute angle: + \pgfpointnormalised{\pgfqpoint{\pgfutil@tempdima}{\pgfutil@tempdimb}}% + \ifdim\pgfutil@tempdimb=0pt\relax\ifdim\pgfutil@tempdima=0pt\pgf@x1pt\pgf@y0pt\fi\fi% + \ifdim\pgfutil@tempdima<0pt% + \pgf@x-\pgf@x% + \pgf@y-\pgf@y% + \fi% + \pgf@ya=-\pgf@y% + \pgfsettransformentries% + {\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}% + {\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@x}{0pt}{0pt}% + \pgftransformshift{\pgfpointscale{-1}{\pgf@curvilinear@line@a}}% + \pgfmathveclen@{\pgfutil@tempdima}{\pgfutil@tempdimb}% + \ifdim\pgfutil@tempdima<0pt% + \edef\pgfmathresult{-\pgfmathresult}% + \fi% + \pgfcurvilineardistancetotime{\pgfmathresult}% + % Now, transform: + \pgf@process{% + \pgfpointadd{% + \pgfpointtransformed{% + \pgfpointcurveattime% + {\pgf@x}% + {\pgf@curvilinear@line@a}% + {\pgf@curvilinear@line@b}% + {\pgf@curvilinear@line@c}% + {\pgf@curvilinear@line@d}% + }% + }% + \pgf@curvilinear@line@a% + }% +} + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfixedpointarithmetic.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfixedpointarithmetic.code.tex index 240eddf4435..f82f8640c4f 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfixedpointarithmetic.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfixedpointarithmetic.code.tex @@ -83,8 +83,8 @@ \def\pgfmathfp@parser@install{% % \expandafter\ifx\csname FP@version\endcsname\relax% - \PackageError{pgf}{You need to say `\string\usepackage{fp}' to use % - fixed point arithmetic}{}% + \pgferror{You need to say `\string\usepackage{fp}' to use % + fixed point arithmetic}% \else% % % Don't want messages. diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfpu.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfpu.code.tex index cecc76d593e..dbaf9847cd1 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfpu.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfpu.code.tex @@ -157,11 +157,26 @@ \expandafter\let\expandafter#1\csname pgfmathfloat@backup@\string#1\endcsname% }% } +\def\pgfmathfloat@prepareuninstallcmd@csname#1{% + % and store backup information (globally - I don't want to do that + % all the time when the FPU is used!): + {% + \globaldefs=1 + \pgfutil@namelet{pgfmathfloat@backup@#1}{#1}% + \expandafter\gdef\expandafter\pgfmathfloat@uninstall\expandafter{\pgfmathfloat@uninstall + \pgfutil@namelet{#1}{pgfmathfloat@backup@#1}% + }% + }% +} \def\pgfmathfloat@install#1=#2{% \pgfmathfloat@prepareuninstallcmd{#1}% \let#1=#2% } +\def\pgfmathfloat@install@csname#1#2{% + \pgfmathfloat@prepareuninstallcmd@csname{#1}% + \pgfutil@namelet{#1}{#2}% +} \def\pgfmathfloat@install@unimplemented#1{% \expandafter\pgfmathfloat@prepareuninstallcmd\csname pgfmath@#1@\endcsname% \expandafter\def\csname pgfmath#1@\endcsname##1{\pgfmathfloat@notimplemented{#1}}% @@ -216,15 +231,24 @@ \pgfmathfloat@install\pgfmathcosec@=\pgfmathfloatcosec@% \pgfmathfloat@install\pgfmathexp@=\pgfmathfloatexp@% \pgfmathfloat@install\pgfmathln@=\pgfmathfloatln@% + \pgfmathfloat@install@csname{pgfmathlog10@}{pgfmathfloatlog10@}% + \pgfmathfloat@install@csname{pgfmathlog2@}{pgfmathfloatlog2@}% \pgfmathfloat@install\pgfmathsqrt@=\pgfmathfloatsqrt@% \pgfmathfloat@install\pgfmath@pi=\pgfmathfloatpi@% \pgfmathfloat@install\pgfmathpi=\pgfmathfloatpi@% \pgfmathfloat@install\pgfmathe@=\pgfmathfloate@% \pgfmathfloat@install\pgfmathe=\pgfmathfloate@% \pgfmathfloat@install\pgfmathlessthan@=\pgfmathfloatlessthan@% + \pgfmathfloat@install\pgfmathnotless@=\pgfmathfloatnotless@% + \pgfmathfloat@install\pgfmathnotgreater@=\pgfmathfloatnotgreater@% \pgfmathfloat@install\pgfmathless@=\pgfmathfloatlessthan@% \pgfmathfloat@install\pgfmathgreaterthan@=\pgfmathfloatgreaterthan@% \pgfmathfloat@install\pgfmathgreater@=\pgfmathfloatgreaterthan@% + \pgfmathfloat@install\pgfmathifthenelse@=\pgfmathfloatifthenelse@% + \pgfmathfloat@install\pgfmathequal@=\pgfmathfloatequal@% + \pgfmathfloat@install\pgfmathequalto@=\pgfmathfloatequal@% + \pgfmathfloat@install\pgfmathnotequal@=\pgfmathfloatnotequal@% + \pgfmathfloat@install\pgfmathnotequalto@=\pgfmathfloatnotequal@% \pgfmathfloat@install\pgfmathpow@=\pgfmathfloatpow@ \pgfmathfloat@install\pgfmathrand@=\pgfmathfloatrand@ \pgfmathfloat@install\pgfmathrand=\pgfmathfloatrand@ @@ -246,14 +270,10 @@ \pgfmathfloat@install\pgfmathtanh@=\pgfmathfloattanh@ \pgfmathfloat@install@unimplemented{ceil}% \pgfmathfloat@install@unimplemented{frac}% - \pgfmathfloat@install@unimplemented{log2}% - \pgfmathfloat@install@unimplemented{log10}% - \pgfmathfloat@install@unimplemented{equalto}% \pgfmathfloat@install@unimplemented{random}% \pgfmathfloat@install@unimplemented{setseed}% \pgfmathfloat@install@unimplemented{Mod}% \pgfmathfloat@install@unimplemented{real}% - \pgfmathfloat@install@unimplemented{notequal}% % \pgfmathfloat@install@unimplemented{atan2}% % \pgfmathfloat@install@unimplemented{height}% % @@ -551,6 +571,7 @@ \let\pgfmath@basic@lessthan@=\pgfmathlessthan@ \let\pgfmath@basic@greaterthan@=\pgfmathgreaterthan@ \let\pgfmath@basic@equalto@=\pgfmathequalto@ +\let\pgfmath@basic@equal@=\pgfmathequal@ \let\pgfmath@basic@true@=\pgfmathtrue@ \let\pgfmath@basic@false@=\pgfmathfalse@ @@ -628,6 +649,25 @@ \let\pgfmathfloatlessthan=\pgfmathfloatlessthan@ \let\pgfmathfloatless@=\pgfmathfloatlessthan@ +% ! (#1 < #2) <=> (#1 >= #2) +\def\pgfmathfloatnotless@#1#2{% + \pgfmathfloatless@{#1}{#2}% + \ifpgfmathfloatcomparison + \def\pgfmathresult{0.0}% + \else + \def\pgfmathresult{1.0}% + \fi +}% +% ! (#1 > #2) <=> (#1 <= #2) +\def\pgfmathfloatnotgreater@#1#2{% + \pgfmathfloatless@{#2}{#1}% + \ifpgfmathfloatcomparison + \def\pgfmathresult{0.0}% + \else + \def\pgfmathresult{1.0}% + \fi +}% + % compares \pgfmathfloat@a@[SME] < \pgfmathfloat@b@[SME] \def\pgfmathfloatlessthan@positive{% \ifnum\pgfmathfloat@a@E<\pgfmathfloat@b@E @@ -730,7 +770,7 @@ % 100 <= m < 1000 % instead of 1 <= m < 10. % -% The 'extended precision' means we have higher accuracy when we apply pgfmath operations to mantisses. +% The 'extended precision' means we have higher accuracy when we apply pgfmath operations to mantissas. % % The input argument is expected to be a normalized floating point number; the output argument is a non-normalized floating point number (well, normalized to extended precision). % @@ -885,6 +925,34 @@ \ifnum\pgfmathfloatiffinite@>2 #3\else #2\fi }% +\def\pgfmathfloatifthenelse@#1#2#3{% + \pgfmathfloatifflags{#1}{0}{% + \edef\pgfmathresult{#3}%% + }{% + \edef\pgfmathresult{#2}% + }% +} +\def\pgfmathfloatequal@#1#2{% + \pgfmathfloatifapproxequalrel{#1}{#2}{% + \def\pgfmathresult{1}% + \pgfmathfloatcomparisontrue + }{% + \def\pgfmathresult{0}% + \pgfmathfloatcomparisonfalse + }% +} +\let\pgfmathfloatequalto@=\pgfmathfloatequal@ + +\def\pgfmathfloatnotequal@#1#2{% + \pgfmathfloatifapproxequalrel{#1}{#2}{% + \def\pgfmathresult{0}% + \pgfmathfloatcomparisonfalse + }{% + \def\pgfmathresult{1}% + \pgfmathfloatcomparisontrue + }% +} +\let\pgfmathfloatnotequalto@=\pgfmathfloatnotequal@ % Computes the relative error between #1 and #2 (assuming #2 != 0) and % invokes #3 if the relative error is below `/pgf/fpu/rel thresh' and @@ -933,7 +1001,7 @@ #4\relax \fi \else - \if\pgfmathfloat@loc@TMPa#2 + \if\pgfmathfloat@loc@TMPa#2% #3\relax \else #4\relax @@ -1421,8 +1489,13 @@ % assuming #2 != 0. \def\pgfmathfloatrelerror@#1#2{% \pgfmathfloatsubtract@{#1}{#2}% - \pgfmathfloatdivide@{\pgfmathresult}{#2}% - \pgfmathfloatabs@{\pgfmathresult}% + \let\pgfmathfloat@subtract=\pgfmathresult + \pgfmathfloatifflags{#2}{0}{% + \let\pgfmathresult=\pgfmathfloat@subtract + }{% + \pgfmathfloatdivide@{\pgfmathfloat@subtract}{#2}% + \pgfmathfloatabs@{\pgfmathresult}% + }% }% \let\pgfmathfloatrelerror=\pgfmathfloatrelerror@ @@ -1589,6 +1662,19 @@ } \let\pgfmathfloatln=\pgfmathfloatln@ +\expandafter\def\csname pgfmathfloatlog10@\endcsname#1{% + \pgfmathfloatln@{#1}% + \let\pgfmathfloat@log@ten=\pgfmathresult + \pgfmathfloatcreate{1}{4.34294481903252}{-1}% 1/ln(10) + \pgfmathfloatmultiply@{\pgfmathresult}{\pgfmathfloat@log@ten}% +}% +\expandafter\def\csname pgfmathfloatlog2@\endcsname#1{% + \pgfmathfloatln@{#1}% + \let\pgfmathfloat@log@two=\pgfmathresult + \pgfmathfloatcreate{1}{1.44269504088896}{0}% 1/ln(2) + \pgfmathfloatmultiply@{\pgfmathresult}{\pgfmathfloat@log@two}% +}% + % Computes log(x) into \pgfmathresult. % % This allows numbers such at 10000000 or 5.23e-10 to be represented @@ -1794,12 +1880,25 @@ \divide\c@pgfmath@counta by2\relax% \repeatpgfmathloop% \else - % employ #1^#2 = exp( #2 * ln(#1) ) - \pgfmathfloatln@{#1}% - \let\pgfmathfloat@loc@TMPa=\pgfmathresult - \edef\pgfmathfloat@loc@TMPb{#2}% - \pgfmathfloatmultiply@{\pgfmathfloat@loc@TMPa}{\pgfmathfloat@loc@TMPb}% - \pgfmathfloatexp@{\pgfmathresult}% + \pgfmathfloatgetflags{#1}\c@pgfmath@counta + \ifnum0=\c@pgfmath@counta + % ah: 0^x + \pgfmathfloatgetflags{#2}\c@pgfmath@counta + \ifnum0=\c@pgfmath@counta + % ah: 0^0 + \pgfmathfloatcreate{1}{1.0}{0}% + \else + % ah: 0^x with x!=0: + \pgfmathfloatcreate{0}{0.0}{0}% + \fi + \else + % employ #1^#2 = exp( #2 * ln(#1) ) + \pgfmathfloatln@{#1}% + \let\pgfmathfloat@loc@TMPa=\pgfmathresult + \edef\pgfmathfloat@loc@TMPb{#2}% + \pgfmathfloatmultiply@{\pgfmathfloat@loc@TMPa}{\pgfmathfloat@loc@TMPb}% + \pgfmathfloatexp@{\pgfmathresult}% + \fi \fi } diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex index 698ec524ba8..b90e96c8b5a 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex @@ -7,6 +7,9 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. +% Note: at the time of this writing, the library has quadratic runtime. +% Experimentally, it performed well while computing ~12 intersections of two +% plots, each with 600 samples. It failed when the number of samples exceeded 700. \newcount\pgf@intersect@solutions @@ -23,6 +26,8 @@ \pgf@intersect@sort@by@second@pathtrue% } +% #1: the index. It starts at 1 and ends with \pgfintersectionsolutions (inclusive). +% Invalid values will implicitly result in the origin. \def\pgfpointintersectionsolution#1{% \ifnum#1<1\relax% \pgfpoint@intersect@solution@orgin% @@ -35,6 +40,31 @@ \fi% } +% Gets the segment indices of solution #1. +% +% #1: the solution index (i.e. the same argument as in \pgfpointintersectionsolution) +% #2: [output] a macro name which will contain the segment index of the first path which contains the solution +% #3: [output] a macro name which will contain the segment index of the second path which contains the solution +% +% Example: \pgfintersectiongetsolutionsegmentindices{0}{\first}{\second} +% +% -> \first may be 0 if point #0 is in the 0'th segment +% -> \second may be 42 if point #0 is in the 42'th segment +\def\pgfintersectiongetsolutionsegmentindices#1#2#3{% + \ifnum#1<1\relax% + \let#2=\pgfutil@empty + \let#3=\pgfutil@empty + \else% + \ifnum#1>\pgfintersectionsolutions\relax% + \let#2=\pgfutil@empty + \let#3=\pgfutil@empty + \else% + \edef#2{\csname pgf@intersect@solution@segment@a@#1\endcsname}% + \edef#3{\csname pgf@intersect@solution@segment@b@#1\endcsname}% + \fi% + \fi% +}% + \def\pgfpoint@intersect@solution@orgin{% \begingroup% \pgftransforminvert% @@ -45,6 +75,11 @@ \endgroup% } +% #1 code which assigns the first path using \pgfsetpath. +% #2 code which assigns the second path using \pgfsetpath. +% +% On output, the points, their properties, and the number of points are set. +% Use \pgfintersectionsolutions which expands to the number of intersections \long\def\pgfintersectionofpaths#1#2{% \begingroup% \pgfinterruptpath% @@ -72,6 +107,10 @@ \let\pgf@intersect@path@a=\pgf@intersect@path@b% \let\pgf@intersect@path@b=\pgf@intersect@temp% \fi% + % + \pgfprocessround\pgf@intersect@path@a\pgf@intersect@path@a% + \pgfprocessround\pgf@intersect@path@b\pgf@intersect@path@b% + % \let\pgf@intersect@token@after=\pgf@intersect@path@process@a% \expandafter\pgf@intersectionofpaths\pgf@intersect@path@a\pgf@stop% \edef\pgfintersectionsolutions{\the\pgf@intersect@solutions}% @@ -80,6 +119,8 @@ \else% \pgfutil@namelet{pgfpoint@intersect@solution@\pgfmathcounter}% {pgfpoint@g@intersect@solution@\pgfmathcounter}% + \edef\pgf@marshal{\noexpand\pgf@intersection@set@properties\csname pgfpoint@g@intersect@solution@\pgfmathcounter @props\endcsname}% + \pgf@marshal \ifpgf@intersect@sort% \pgfutil@namelet{pgf@intersect@solution@\pgfmathcounter @time@a}% {pgf@g@intersect@solution@\pgfmathcounter @time@a}% @@ -90,6 +131,17 @@ \fi% } +\def\pgf@intersection@set@properties#1#2{% + \pgfutil@namedef{pgf@intersect@solution@segment@a@\pgfmathcounter}{#1}% + \pgfutil@namedef{pgf@intersect@solution@segment@b@\pgfmathcounter}{#2}% +}% + +% #1 a global name prefix to store properties. +\def\pgf@intersection@store@properties#1{% + % we store the time offsets as well and make them available programmatically: + \expandafter\xdef\csname #1@props\endcsname{{\pgf@intersect@time@offset}{\pgf@intersect@time@offset@b}}% +} + \def\pgf@intersectionofpaths#1{% \ifx#1\pgf@stop% \let\pgf@intersect@next=\relax% @@ -152,6 +204,7 @@ \def\pgf@intersect@path@process@a{% \pgf@intersect@path@getpoints@a% \let\pgf@intersect@token@after=\pgf@intersect@path@process@b% + \def\pgf@intersect@time@offset@b{0}% \expandafter\pgf@intersectionofpaths\pgf@intersect@path@b\pgf@stop% \let\pgfpoint@intersect@start=\pgfpoint@intersect@end@a% \let\pgf@intersect@token@after=\pgf@intersect@path@process@a% @@ -173,6 +226,9 @@ \pgf@intersect@path@getpoints@b% \csname pgf@intersect@\pgf@intersect@type@a @and@\pgf@intersect@type@b\endcsname% \let\pgfpoint@intersect@start=\pgfpoint@intersect@end@b% + \c@pgf@counta=\pgf@intersect@time@offset@b\relax% + \advance\c@pgf@counta by1\relax% + \edef\pgf@intersect@time@offset@b{\the\c@pgf@counta}% \pgf@intersectionofpaths} \def\pgf@intersect@path@getpoints@b{% @@ -224,6 +280,8 @@ \pgfpointintersectionoflines{\pgfpoint@intersect@start@a}{\pgfpoint@intersect@end@a}% {\pgfpoint@intersect@start@b}{\pgfpoint@intersect@end@b}% }% + \pgf@intersection@store@properties{pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions}% + % \ifpgf@intersect@sort% \pgf@xc=\pgf@x% \pgf@yc=\pgf@y% @@ -567,6 +625,7 @@ \pgf@ifsolution@duplicate\pgf@intersect@solution@candidate{}% {% \global\advance\pgf@intersect@solutions by1\relax% + \pgf@intersection@store@properties{pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions}% \expandafter\global\expandafter\let% \csname pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions\endcsname=% \pgf@intersect@solution@candidate% @@ -747,15 +806,16 @@ \csname pgf@intersect@solution@\the\pgfutil@tempcnta @time@a\endcsname pt\relax% \pgf@intersect@solutions@sortfinishfalse% % - \pgfutil@namelet{pgf@intersect@temp}{pgfpoint@intersect@solution@\pgfmathcounter}% - \pgfutil@namelet{pgfpoint@intersect@solution@\pgfmathcounter}% + \pgfintersectionsolutionsortbytime@swap{pgfpoint@intersect@solution@\pgfmathcounter}% {pgfpoint@intersect@solution@\the\pgfutil@tempcnta}% - \pgfutil@namelet{pgfpoint@intersect@solution@\the\pgfutil@tempcnta}{pgf@intersect@temp}% % - \pgfutil@namelet{pgf@intersect@temp}{pgf@intersect@solution@\pgfmathcounter @time@a}% - \pgfutil@namelet{pgf@intersect@solution@\pgfmathcounter @time@a}% + \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@\pgfmathcounter @time@a}% {pgf@intersect@solution@\the\pgfutil@tempcnta @time@a}% - \pgfutil@namelet{pgf@intersect@solution@\the\pgfutil@tempcnta @time@a}{pgf@intersect@temp}% + % + \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@segment@a@\pgfmathcounter}% + {pgf@intersect@solution@segment@a@\the\pgfutil@tempcnta}% + \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@segment@b@\pgfmathcounter}% + {pgf@intersect@solution@segment@b@\the\pgfutil@tempcnta}% \fi% \repeatpgfmathloop% \ifpgf@intersect@solutions@sortfinish% @@ -764,4 +824,10 @@ \fi% } +\def\pgfintersectionsolutionsortbytime@swap#1#2{% + \pgfutil@namelet{pgf@intersect@temp}{#1}% + \pgfutil@namelet{#1}{#2}% + \pgfutil@namelet{#2}{pgf@intersect@temp}% +}% + \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarylindenmayersystems.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarylindenmayersystems.code.tex index d7bb3d9dd57..ab6a067835e 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarylindenmayersystems.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarylindenmayersystems.code.tex @@ -56,7 +56,7 @@ #2% \endgroup% }% - {\PackageError{pgf}{Lindenmayer system `#1' is already defined}{}}% + {\pgferror{Lindenmayer system `#1' is already defined}}% } \def\pgf@lsystem@symbol#1#2{% diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplothandlers.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplothandlers.code.tex index 5ab9e84a796..38ccd94d0b9 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplothandlers.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplothandlers.code.tex @@ -7,9 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryplothandlers.code.tex,v 1.15 2010/05/31 10:11:22 tantau Exp $ - -\newif\ifpgf@plot@started +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryplothandlers.code.tex,v 1.20 2013/08/31 13:02:59 ludewich Exp $ % This handler converts each plot stream command into a curveto @@ -23,13 +21,16 @@ % \pgfplothandlercurveto % \pgfplotxyfile{mytable} -\def\pgfplothandlercurveto{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@curveto@handler@initial% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgf@plot@curveto@handler@finish% - \global\pgf@plot@startedfalse% - }% +\pgfdeclareplothandler{\pgfplothandlercurveto}{}{% + point macro=\pgf@plot@curveto@handler@initial, + jump macro=\pgf@plot@smooth@next@moveto, + end macro=\pgf@plot@curveto@handler@finish +} + +\def\pgf@plot@smooth@next@moveto{% + \pgf@plot@curveto@handler@finish% + \global\pgf@plot@startedfalse% + \global\let\pgf@plotstreampoint\pgf@plot@curveto@handler@initial% } \def\pgf@plot@curveto@handler@initial#1{% @@ -113,12 +114,16 @@ % \pgfplothandlerclosedcurve % \pgfplotxyfile{mytable} -\def\pgfplothandlerclosedcurve{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@closedcurve@handler@initial% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgf@plot@closedcurve@handler@finish% - }% +\pgfdeclareplothandler{\pgfplothandlerclosedcurve}{}{% + point macro=\pgf@plot@closedcurve@handler@initial, + end macro=\pgf@plot@closedcurve@handler@finish, + jump macro=\pgf@plot@closedsmooth@next@moveto +} + +\def\pgf@plot@closedsmooth@next@moveto{% + \pgf@plot@closedcurve@handler@finish% + \global\pgf@plot@startedfalse% + \global\let\pgf@plotstreampoint\pgf@plot@closedcurve@handler@initial% } \def\pgf@plot@closedcurve@handler@initial#1{% @@ -276,13 +281,10 @@ % \pgfplothandlerxcomb % \pgfplotxyfile{mytable} -\def\pgfplothandlerxcomb{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@xcomb@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgfplotxzerolevelstreamend% - \pgfplotxzerolevelstreamstart - }% +\pgfdeclareplothandler{\pgfplothandlerxcomb}{}{% + start macro=\pgfplotxzerolevelstreamstart, + point macro=\pgf@plot@xcomb@handler, + end macro=\pgfplotxzerolevelstreamend, } \def\pgf@plot@xcomb@handler#1{% @@ -307,13 +309,10 @@ % \pgfplothandlerycomb % \pgfplotxyfile{mytable} -\def\pgfplothandlerycomb{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@ycomb@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgfplotyzerolevelstreamend% - \pgfplotyzerolevelstreamstart - }% +\pgfdeclareplothandler{\pgfplothandlerycomb}{}{% + start macro=\pgfplotyzerolevelstreamstart, + point macro=\pgf@plot@ycomb@handler, + end macro=\pgfplotyzerolevelstreamend } \def\pgf@plot@ycomb@handler#1{% @@ -375,12 +374,19 @@ \pgfplotyzerolevelstreamconstant{0pt}% \def\pgfplotbarwidth{\pgfkeysvalueof{/pgf/bar width}} +\def\pgfplotbarshift{\pgfkeysvalueof{/pgf/bar shift}} \pgfqkeys{/pgf}{% bar width/.initial=10pt, bar shift/.initial=0pt, bar interval width/.initial=1, bar interval shift/.initial=0.5, + % + % hook which is executed right before a new bar is begun. + at begin bar/.initial=, + % hook which is executed right after a bar path has been finished. + % In this context, the bar's path has not been used. + at end bar/.initial=, } % This handler places a rectangle at each point in the plot stream, a @@ -395,20 +401,21 @@ % % \pgfplothandlerybar % \pgfplotxyfile{mytable} -\def\pgfplothandlerybar{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@ybar@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgfplotyzerolevelstreamend% - \pgfmathparse{\pgfplotbarwidth}% - \xdef\pgfplotbarwidth@{\pgfmathresult pt}% - \pgfmathparse{\pgfkeysvalueof{/pgf/bar shift}}% - \xdef\pgfplotbarshift@{\pgfmathresult pt}% - \pgfplotyzerolevelstreamstart - }% + +\pgfdeclareplothandler{\pgfplothandlerybar}{}{% + start={ + \pgfmathparse{\pgfplotbarwidth}% + \xdef\pgfplotbarwidth@{\pgfmathresult pt}% + \pgfmathparse{\pgfplotbarshift}% + \xdef\pgfplotbarshift@{\pgfmathresult pt}% + \pgfplotyzerolevelstreamstart + }, + end macro=\pgfplotyzerolevelstreamend, + point macro=\pgf@plot@ybar@handler } \def\pgf@plot@ybar@handler#1{% + \pgfkeysvalueof{/pgf/at begin bar}% \pgf@process{#1}% \pgf@ya=\pgf@y \expandafter\pgf@xb\pgfplotbarwidth@\relax @@ -423,6 +430,7 @@ \pgfpathrectangle {\pgfqpoint{\pgf@xc}{\pgf@yb}}% {\pgfqpoint{\pgf@xb}{\pgf@ya}}% + \pgfkeysvalueof{/pgf/at end bar}% } % This handler places a rectangle at each point in the plot stream, a @@ -437,20 +445,20 @@ % % \pgfplothandlerxbar % \pgfplotxyfile{mytable} -\def\pgfplothandlerxbar{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@xbar@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgfplotxzerolevelstreamend% - \pgfmathparse{\pgfplotbarwidth}% - \xdef\pgfplotbarwidth@{\pgfmathresult pt}% - \pgfmathparse{\pgfkeysvalueof{/pgf/bar shift}}% - \xdef\pgfplotbarshift@{\pgfmathresult pt}% - \pgfplotxzerolevelstreamstart - }% +\pgfdeclareplothandler{\pgfplothandlerxbar}{}{% + start={ + \pgfmathparse{\pgfplotbarwidth}% + \xdef\pgfplotbarwidth@{\pgfmathresult pt}% + \pgfmathparse{\pgfplotbarshift}% + \xdef\pgfplotbarshift@{\pgfmathresult pt}% + \pgfplotxzerolevelstreamstart + }, + end macro=\pgfplotxzerolevelstreamend, + point macro=\pgf@plot@xbar@handler } \def\pgf@plot@xbar@handler#1{% + \pgfkeysvalueof{/pgf/at begin bar}% \pgf@process{#1}% \pgf@ya=\pgf@x \expandafter\pgf@xb\pgfplotbarwidth@\relax @@ -465,6 +473,7 @@ \pgfpathrectangle {\pgfqpoint{\pgf@yb}{\pgf@xc}}% {\pgfqpoint{\pgf@ya}{\pgf@xb}}% + \pgfkeysvalueof{/pgf/at end bar}% } % This handler is a variant of \pgfplothandlerybar which works with @@ -500,17 +509,16 @@ % % \pgfplothandlerybarinterval % \pgfplotxyfile{mytable} -\def\pgfplothandlerybarinterval{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@ybarinterval@handler@first% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgfplotyzerolevelstreamend% - \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval width}}% - \xdef\pgfplotbarintervalwidth@{\pgfmathresult}% - \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval shift}}% - \xdef\pgfplotbarintervalshift@{\pgfmathresult}% - \pgfplotyzerolevelstreamstart - }% +\pgfdeclareplothandler{\pgfplothandlerybarinterval}{}{% + start={ + \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval width}}% + \xdef\pgfplotbarintervalwidth@{\pgfmathresult}% + \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval shift}}% + \xdef\pgfplotbarintervalshift@{\pgfmathresult}% + \pgfplotyzerolevelstreamstart + }, + end macro=\pgfplotyzerolevelstreamend, + point macro=\pgf@plot@ybarinterval@handler@first } \def\pgf@plot@ybarinterval@handler@first#1{% @@ -520,6 +528,7 @@ \global\let\pgf@plotstreampoint=\pgf@plot@ybarinterval@handler% } \def\pgf@plot@ybarinterval@handler#1{% + \pgfkeysvalueof{/pgf/at begin bar}% \pgf@process{#1}% \pgf@ya=\pgf@plot@barinterval@bar \xdef\pgf@plot@barinterval@bar{\the\pgf@y}% @@ -538,20 +547,20 @@ \pgfpathrectangle {\pgfqpoint{\pgf@xc}{\pgf@yb}}% {\pgfqpoint{\pgf@xb}{\pgf@ya}}% + \pgfkeysvalueof{/pgf/at end bar}% } % Like \pgfplothandlerybarinterval but for xbar. -\def\pgfplothandlerxbarinterval{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@xbarinterval@handler@first% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgfplotxzerolevelstreamend% - \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval width}}% - \xdef\pgfplotbarintervalwidth@{\pgfmathresult}% - \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval shift}}% - \xdef\pgfplotbarintervalshift@{\pgfmathresult}% - \pgfplotxzerolevelstreamstart - }% +\pgfdeclareplothandler{\pgfplothandlerxbarinterval}{}{% + start={ + \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval width}}% + \xdef\pgfplotbarintervalwidth@{\pgfmathresult}% + \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval shift}}% + \xdef\pgfplotbarintervalshift@{\pgfmathresult}% + \pgfplotxzerolevelstreamstart + }, + end macro=\pgfplotxzerolevelstreamend, + point macro=\pgf@plot@xbarinterval@handler@first } \def\pgf@plot@xbarinterval@handler@first#1{% @@ -561,6 +570,7 @@ \global\let\pgf@plotstreampoint=\pgf@plot@xbarinterval@handler% } \def\pgf@plot@xbarinterval@handler#1{% + \pgfkeysvalueof{/pgf/at begin bar}% \pgf@process{#1}% \pgf@ya=\pgf@plot@barinterval@bar \xdef\pgf@plot@barinterval@bar{\the\pgf@x}% @@ -579,6 +589,7 @@ \pgfpathrectangle {\pgfqpoint{\pgf@yb}{\pgf@xc}}% {\pgfqpoint{\pgf@ya}{\pgf@xb}}% + \pgfkeysvalueof{/pgf/at end bar}% } @@ -595,13 +606,11 @@ % % \pgfplothandlerconstantlineto % \pgfplotxyfile{mytable} -\def\pgfplothandlerconstantlineto{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@const@line@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% + +\pgfdeclareplothandler{\pgfplothandlerconstantlineto}{}{% + point macro=\pgf@plot@const@line@handler } + \def\pgf@plot@const@line@handler#1{% \pgf@process{#1}% \xdef\pgf@plot@const@line@handler@last{\the\pgf@y}% @@ -630,13 +639,11 @@ % % \pgfplothandlerconstantlinetomarkright % \pgfplotxyfile{mytable} -\def\pgfplothandlerconstantlinetomarkright{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@const@line@mark@right@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% + +\pgfdeclareplothandler{\pgfplothandlerconstantlinetomarkright}{}{% + point macro=\pgf@plot@const@line@mark@right@handler } + \def\pgf@plot@const@line@mark@right@handler#1{% \pgf@process{#1}% \xdef\pgf@plot@const@line@handler@last{\the\pgf@x}% @@ -653,6 +660,43 @@ \xdef\pgf@plot@const@line@handler@last{\the\pgf@xa}% } +% A variant of \pgfplothandlerconstantlineto which places its mark on +% the middle of the line segment. +% +% ----x +% | +% --x--- | +% | |--x---- +% x-- +% +% Example: +% +% \pgfplothandlerconstantlinetomarkmid +% \pgfplotxyfile{mytable} + +\pgfdeclareplothandler{\pgfplothandlerconstantlinetomarkmid}{}{% + point macro=\pgf@plot@const@line@mark@mid@handler +} + +\def\pgf@plot@const@line@mark@mid@handler#1{% + \pgf@process{#1}% + \xdef\pgf@plot@const@line@handler@last{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}% + \pgf@plot@first@action{}% + \global\let\pgf@plotstreampoint=\pgf@plot@const@line@mark@mid@handler@@% +} +\def\pgf@plot@const@line@mark@mid@handler@@#1{% + \pgf@process{#1}% + \pgf@xa=\pgf@x + \pgf@ya=\pgf@y + \pgf@plot@const@line@handler@last + \pgf@xc=.5\pgf@xa + \advance\pgf@xc by.5\pgf@x + \pgfpathlineto{\pgfqpoint{\pgf@xc}{\pgf@y}}% + \pgfpathlineto{\pgfqpoint{\pgf@xc}{\pgf@ya}}% + \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}% + \xdef\pgf@plot@const@line@handler@last{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}% +} + % This handler is in fact a variant of \pgfplothandlerconstantlineto, % but it does not draw vertical lines. It produces a sequence of % line-to and move-to operations such that plot marks are placed at @@ -667,13 +711,11 @@ % % \pgfplothandlerjumpmarkright % \pgfplotxyfile{mytable} -\def\pgfplothandlerjumpmarkright{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@jumpmarkright@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% + +\pgfdeclareplothandler{\pgfplothandlerjumpmarkright}{}{% + point macro=\pgf@plot@jumpmarkright@handler } + \def\pgf@plot@jumpmarkright@handler#1{% \pgf@process{#1}% \xdef\pgf@plot@const@line@handler@last{\the\pgf@x}% @@ -704,12 +746,9 @@ % % \pgfplothandlerjumpmarkleft % \pgfplotxyfile{mytable} -\def\pgfplothandlerjumpmarkleft{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@jumpmarkleft@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% + +\pgfdeclareplothandler{\pgfplothandlerjumpmarkleft}{}{% + point macro=\pgf@plot@jumpmarkleft@handler } \def\pgf@plot@jumpmarkleft@handler#1{% \pgf@process{#1}% @@ -727,6 +766,44 @@ \xdef\pgf@plot@const@line@handler@last{\the\pgf@ya}% } +% This handler is in fact a variant of +% \pgfplothandlerconstantlinetomarkmid, +% but it does not draw vertical lines. It produces a sequence of +% line-to and move-to operations such that plot marks are placed like +% +% ----x +% +% --x-- +% --x---- +% x-- +% +% Example: +% +% \pgfplothandlerjumpmarkmid +% \pgfplotxyfile{mytable} + +\pgfdeclareplothandler{\pgfplothandlerjumpmarkmid}{}{% + point macro=\pgf@plot@jump@mark@mid@handler +} + +\def\pgf@plot@jump@mark@mid@handler#1{% + \pgf@process{#1}% + \xdef\pgf@plot@const@line@handler@last{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}% + \pgf@plot@first@action{}% + \global\let\pgf@plotstreampoint=\pgf@plot@jump@mark@mid@handler@@% +} +\def\pgf@plot@jump@mark@mid@handler@@#1{% + \pgf@process{#1}% + \pgf@xa=\pgf@x + \pgf@ya=\pgf@y + \pgf@plot@const@line@handler@last + \pgf@xc=.5\pgf@xa + \advance\pgf@xc by.5\pgf@x + \pgfpathlineto{\pgfqpoint{\pgf@xc}{\pgf@y}}% + \pgfpathmoveto{\pgfqpoint{\pgf@xc}{\pgf@ya}}% + \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}% + \xdef\pgf@plot@const@line@handler@last{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}% +} % This handler converts each point in a stream into a line from the @@ -737,12 +814,8 @@ % \pgfplothandlerpolarcomb % \pgfplotxyfile{mytable} -\def\pgfplothandlerpolarcomb{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@polarcomb@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% +\pgfdeclareplothandler{\pgfplothandlerpolarcomb}{}{% + point macro=\pgf@plot@polarcomb@handler } \def\pgf@plot@polarcomb@handler#1{% @@ -767,30 +840,24 @@ % \pgfplothandlermark{\pgfuseplotmark{*}} % \pgfplotxyfile{mytable} -\def\pgfplothandlermark#1{% - \pgf@plothandlermark{% - \ifnum\pgf@plot@mark@count<\pgf@plot@mark@repeat\relax% - \else% - \global\pgf@plot@mark@count=0\relax% - #1% - \fi% +\pgfdeclareplothandler{\pgfplothandlermark}{#1}{% + start={ + \def\pgf@plot@mark{% + \ifnum\pgf@plot@mark@count<\pgf@plot@mark@repeat\relax% + \else% + \global\pgf@plot@mark@count=0\relax% + #1% + \fi% }% + \global\pgf@plot@mark@count=\pgf@plot@mark@repeat\relax% + \global\advance\pgf@plot@mark@count by-\pgf@plot@mark@phase\relax% + }, + point macro=\pgf@plot@mark@handler } \newcount\pgf@plot@mark@count \def\pgf@plot@mark@phase{0} -\def\pgf@plothandlermark#1{% - \def\pgf@plot@mark{#1}% - \def\pgf@plotstreamstart{% - \global\pgf@plot@mark@count=\pgf@plot@mark@repeat\relax% - \global\advance\pgf@plot@mark@count by-\pgf@plot@mark@phase\relax% - \global\let\pgf@plotstreampoint=\pgf@plot@mark@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% -} - \def\pgf@plot@mark@handler#1{% \global\advance\pgf@plot@mark@count by1\relax% {\pgftransformshift{#1}\pgf@plot@mark}% @@ -837,16 +904,32 @@ % \pgfplothandlermarklisted{\pgfuseplotmark{*}}{1,2,4,...,9} % \pgfplotxyfile{mytable} -\def\pgfplothandlermarklisted#1#2{% - \let\pgf@plot@mark@list=\pgfutil@empty% - \edef\pgf@marshal{\noexpand\foreach\noexpand\pgf@temp in{#2}} - \pgf@marshal{\xdef\pgf@plot@mark@list{\pgf@plot@mark@list(\pgf@temp)}}% - \pgf@plothandlermark{% - \edef\pgf@marshal{\noexpand\pgfutil@in@{(\the\pgf@plot@mark@count)}{\pgf@plot@mark@list}}% - \pgf@marshal% - \ifpgfutil@in@#1\fi}% +\pgfdeclareplothandler{\pgfplothandlermarklisted}{#1#2}{% + start={ + \let\pgf@plot@mark@list=\pgfutil@empty% + \edef\pgf@marshal{\noexpand\foreach\noexpand\pgf@temp in{#2}} + \pgf@marshal{\xdef\pgf@plot@mark@list{\pgf@plot@mark@list(\pgf@temp)}}% + \def\pgf@plot@mark{% + \edef\pgf@marshal{\noexpand\pgfutil@in@{(\the\pgf@plot@mark@count)}{\pgf@plot@mark@list}}% + \pgf@marshal% + \ifpgfutil@in@#1\fi% + }% + \global\pgf@plot@mark@count=\pgf@plot@mark@repeat\relax% + \global\advance\pgf@plot@mark@count by-\pgf@plot@mark@phase\relax% + }, + point macro=\pgf@plot@mark@handler } +% \def\pgfplothandlermarklisted#1#2{% +% \let\pgf@plot@mark@list=\pgfutil@empty% +% \edef\pgf@marshal{\noexpand\foreach\noexpand\pgf@temp in{#2}} +% \pgf@marshal{\xdef\pgf@plot@mark@list{\pgf@plot@mark@list(\pgf@temp)}}% +% \pgf@plothandlermark{% +% \edef\pgf@marshal{\noexpand\pgfutil@in@{(\the\pgf@plot@mark@count)}{\pgf@plot@mark@list}}% +% \pgf@marshal% +% \ifpgfutil@in@#1\fi}% +% } + % Define a new plot mark for use with \pgfplotmark. % @@ -888,7 +971,7 @@ \pgfdeclareplotmark{*} {% - \pgfpathcircle{\pgfpointorigin}{\pgfplotmarksize} + \pgfpathellipse{\pgfpointorigin}{\pgfqpoint{\pgfplotmarksize}{0sp}}{\pgfqpoint{0sp}{\pgfplotmarksize}}% \pgfusepathqfillstroke } @@ -932,12 +1015,13 @@ \pgfkeys{/pgf/gap around stream point/.initial=1.5pt} -\def\pgfplothandlergaplineto{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@gap@lineto@handler@initial% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% +\pgfdeclareplothandler{\pgfplothandlergaplineto}{}{% + point macro=\pgf@plot@gap@lineto@handler@initial, + jump macro=\pgf@plot@gap@next@moveto +} + +\def\pgf@plot@gap@next@moveto{% + \global\let\pgf@plotstreampoint=\pgf@plot@gap@lineto@handler@initial% } \def\pgf@plot@gap@lineto@handler@initial#1{% @@ -976,13 +1060,17 @@ % \pgfplothandlergapcycle % \pgfplotxyfile{mytable} -\def\pgfplothandlergapcycle{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@gap@cycle@handler@initial% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgf@plot@gap@cycle@handler@finish% - \global\let\pgf@plot@gap@cycle@first=\relax% - }% +\pgfdeclareplothandler{\pgfplothandlergapcycle}{}{% + point macro=\pgf@plot@gap@cycle@handler@initial, + jump macro=\pgf@plot@gapcycle@next@moveto, + end macro=\pgf@plot@gap@cycle@handler@finish, + start={\global\let\pgf@plot@gap@cycle@first\relax} +} + +\def\pgf@plot@gapcycle@next@moveto{% + \pgf@plot@gap@cycle@handler@finish% + \global\let\pgf@plot@gap@cycle@first=\relax% + \global\let\pgf@plotstreampoint=\pgf@plot@gap@cycle@handler@initial% } \def\pgf@plot@gap@cycle@handler@initial#1{% @@ -1020,3 +1108,7 @@ \endinput + +% Local Variables: +% tab-width: 2 +% End: diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplotmarks.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplotmarks.code.tex index 57df579e3f3..94862191a3a 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplotmarks.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplotmarks.code.tex @@ -7,14 +7,14 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryplotmarks.code.tex,v 1.12 2010/10/15 07:34:06 ludewich Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryplotmarks.code.tex,v 1.13 2013/07/20 13:56:18 ludewich Exp $ % A stroked circle mark \pgfdeclareplotmark{o} {% - \pgfpathcircle{\pgfpointorigin}{\pgfplotmarksize} + \pgfpathellipse{\pgfpointorigin}{\pgfqpoint{\pgfplotmarksize}{0sp}}{\pgfqpoint{0sp}{\pgfplotmarksize}}% \pgfusepathqstroke } diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryprofiler.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryprofiler.code.tex index 1043825d60f..ea1f469abe8 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryprofiler.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryprofiler.code.tex @@ -20,9 +20,24 @@ %-------------------------------------------- \pgfutil@ifundefined{pdfelapsedtime}{% - \PackageError{pgf}{library 'profiler' can only be used with pdftex Rev. >= 1.671 because it needs the \string\pdfelapsedtime\space command}{}% - \global\let\pdfelapsedtime=\c@pgf@counta -}{} + % Ok, \pdfelapsedtime is not defined. + % Maybe we run luatex? + \pgfutil@ifluatex + % Yes. So we emulate the primitive by a macro. + % (see http://tex.stackexchange.com/q/32507/8425) + \def\pgfutil@pdfelapsedtime{% + \numexpr\pgfutil@directlua{% + tex.print(math.floor((os.clock())*65536+0.5))}\relax} + \else + % Raise an error + \pgferror{% + Library 'profiler' can only be used with pdftex Rev. >= 1.671 + because it needs the \string\pdfelapsedtime\space command or + with luatex}% + \global\let\pgfutil@pdfelapsedtime=\c@pgf@counta + \fi}{% + % We run pdftex. That's ok. + \let\pgfutil@pdfelapsedtime\pdfelapsedtime} % Defines a new profiler entry named `#1'. @@ -64,7 +79,7 @@ \def\pgfprofilenewforenvironment@[#1]#2{% \expandafter\pgfprofile@@to@pgfretval\pgfprofile@TeX@DIALECT@toenvironment@begin{#2}% \ifx\pgfretval\relax - \PackageError{pgf}{\string\pgfprofilenewforenvironment{#2} doesn't work: the environment `#2' is (not yet?) known or not known in this context}{}% + \pgferror{\string\pgfprofilenewforenvironment{#2} doesn't work: the environment `#2' is (not yet?) known or not known in this context}{}% \else \expandafter\global\expandafter\let\csname pgfprofile@orig@begin@#2\endcsname=\pgfretval \expandafter\pgfprofile@@to@pgfretval\pgfprofile@TeX@DIALECT@toenvironment@end{#2}% @@ -132,7 +147,7 @@ \or \pgfprofilenewforcommandpattern[#1]{#2}{##1##2##3##4##5##6##7}{{##1}{##2}{##3}{##4}{##5}{##6}{##7}}% \else - \PackageError{pgf}{library 'profiler' can't replace control sequences with '#3' arguments automatically, sorry.}% + \pgferror{library 'profiler' can't replace control sequences with '#3' arguments automatically, sorry.}{}% \fi \fi }% @@ -155,7 +170,7 @@ \fi \fi \if\pgfprofile@known0% - \PackageError{pgf}{\string\pgfprofilenewforcommandpattern{\string#2} doesn't work: the command `\string#2' is (not yet?) known or not known in this context}{}% + \pgferror{\string\pgfprofilenewforcommandpattern{\string#2} doesn't work: the command `\string#2' is (not yet?) known or not known in this context}% \else \begingroup \pgfprofile@cs@to@name{#2}% @@ -189,7 +204,7 @@ \def\pgfprofileshowinvocationsfor#1{% \pgfutil@ifundefined{b@pgfprofile@show@#1}{% - \PackageError{pgf}{\string\pgfprofileshowinvocationsfor{#1} doesn't work: the argument is no profiler entry}{}% + \pgferror{\string\pgfprofileshowinvocationsfor{#1} doesn't work: the argument is no profiler entry}% }{% \expandafter\gdef\csname b@pgfprofile@show@#1\endcsname{1}% \expandafter\gdef\csname b@pgfprofile@show@edef@#1\endcsname{0}% @@ -197,7 +212,7 @@ }% \def\pgfprofileshowinvocationsexpandedfor#1{% \pgfutil@ifundefined{b@pgfprofile@show@#1}{% - \PackageError{pgf}{\string\pgfprofileshowinvocationsfor{#1} doesn't work: the argument is no profiler entry}{}% + \pgferror{\string\pgfprofileshowinvocationsfor{#1} doesn't work: the argument is no profiler entry}% }{% \expandafter\gdef\csname b@pgfprofile@show@#1\endcsname{1}% \expandafter\gdef\csname b@pgfprofile@show@edef@#1\endcsname{1}% @@ -290,7 +305,7 @@ \pgfprofileifisrunning{#1}{% \relax }{% - \expandafter\xdef\csname c@pgfprofile@elapsed@at@start@#1\endcsname{\the\pdfelapsedtime}% + \expandafter\xdef\csname c@pgfprofile@elapsed@at@start@#1\endcsname{\the\pgfutil@pdfelapsedtime}% \expandafter\gdef\csname c@pgfprofile@subtractforself@#1\endcsname{0}% \pgfprofile@advance{c@pgfprofile@numinvocations@#1}{1}% \pgfprofilestackpush{#1}% @@ -305,7 +320,7 @@ \relax }{% \begingroup - \c@pgf@countb=\pdfelapsedtime\relax + \c@pgf@countb=\pgfutil@pdfelapsedtime\relax \advance\c@pgf@countb by-\csname c@pgfprofile@elapsed@at@start@#1\endcsname\relax % \pgfprofilestackpop\pgfretval diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarysnakes.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarysnakes.code.tex index f6c89af3efe..90f26eb7211 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarysnakes.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarysnakes.code.tex @@ -7,10 +7,9 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibrarysnakes.code.tex,v 1.24 2008/01/19 16:52:30 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibrarysnakes.code.tex,v 1.25 2013/07/15 12:05:34 tantau Exp $ -\PackageWarning{pgf}{Snakes have been superseded by decorations. Use -the decoration libraries instead of the snakes library} +\pgfwarning{Snakes have been superseded by decorations. Use the decoration libraries instead of the snakes library} \usepgflibrary{decorations.pathmorphing,decorations.pathreplacing,decorations.shapes} diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarysvg.path.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarysvg.path.code.tex index 16d1b2eab0e..a385cf199f5 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarysvg.path.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarysvg.path.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibrarysvg.path.code.tex,v 1.6 2009/01/24 17:07:14 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibrarysvg.path.code.tex,v 1.7 2013/09/23 18:04:36 tantau Exp $ \usepgfmodule{parser} @@ -179,6 +179,10 @@ } +% Ignore spaces if no other rules says differently: + +\pgfparserdef{svgpath}{all}{blank space \space}{} + diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.ee.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.ee.code.tex index ddf8a29f629..30ecbff3c4d 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.ee.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.ee.code.tex @@ -88,17 +88,14 @@ \pgfdeclareshape{direction ee} { \savedanchor\northeast{ - % Right border is given by right extend \pgf@x=0pt% - \csname pgf@arrow@right@\pgfkeysvalueof{/pgf/direction ee arrow}\endcsname % Height is given by minimum height/2 \pgfmathsetlength{\pgf@y}{\pgfkeysvalueof{/pgf/minimum height}}% \pgf@y=.5\pgf@y } \savedanchor\southwest{ % Left border is given by left extend - \pgf@x=0pt% - \csname pgf@arrow@left@\pgfkeysvalueof{/pgf/direction ee arrow}\endcsname + \pgfarrowtotallength{\pgfkeysvalueof{/pgf/direction ee arrow}}% \pgf@x=-\pgf@x% % Height is given by minimum height/2 \pgfmathsetlength{\pgf@y}{\pgfkeysvalueof{/pgf/minimum height}}% @@ -131,10 +128,8 @@ \beforebackgroundpath{ { - \pgfsetarrowsend{\pgfkeysvalueof{/pgf/direction ee arrow}} \pgfsys@beginscope - \pgflowlevelsynccm% - \pgflowlevelobj{}{\pgf@endarrow}% + \pgfarrowdraw{\pgfkeysvalueof{/pgf/direction ee arrow}}% \pgfsys@endscope } } diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.IEC.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.IEC.code.tex index 5b2beb2b0fb..e137e113cdc 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.IEC.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.IEC.code.tex @@ -10,131 +10,131 @@ \usepgflibrary{shapes.gates.logic} \pgfkeys{/pgf/.cd, - and gate IEC symbol/.initial=$\char`\&$, - nand gate IEC symbol/.initial=$\char`\&$, - or gate IEC symbol/.initial=$\geq1$, - nor gate IEC symbol/.initial=$\geq1$, - xor gate IEC symbol/.initial={$=1$}, - xnor gate IEC symbol/.initial={$=1$}, - not gate IEC symbol/.initial=1, - buffer gate IEC symbol/.initial=1, - logic gate IEC symbol align/.initial=top, - logic gate IEC symbol color/.initial=% no value + and gate IEC symbol/.initial=$\char`\&$, + nand gate IEC symbol/.initial=$\char`\&$, + or gate IEC symbol/.initial=$\geq1$, + nor gate IEC symbol/.initial=$\geq1$, + xor gate IEC symbol/.initial={$=1$}, + xnor gate IEC symbol/.initial={$=1$}, + not gate IEC symbol/.initial=1, + buffer gate IEC symbol/.initial=1, + logic gate IEC symbol align/.initial=top, + logic gate IEC symbol color/.initial=% no value } \pgfkeys{/pgf/logic gate IEC symbol align/.cd, - top/.code=\pgftransformyshift{\innerhalfheight}, - bottom/.code=\pgftransformyshift{-\innerhalfheight}, - left/.code=\pgftransformxshift{-\innerhalfwidth}, - right/.code=\pgftransformxshift{\innerhalfwidth} + top/.code=\pgftransformyshift{\innerhalfheight}, + bottom/.code=\pgftransformyshift{-\innerhalfheight}, + left/.code=\pgftransformxshift{-\innerhalfwidth}, + right/.code=\pgftransformxshift{\innerhalfwidth} } \def\pgf@lib@sh@logicgates@IEC@foregroundpath#1{% - \dimensions% - {% - \pgftransformshift{\centerpoint}% - \edef\pgf@lib@sh@temp{\pgfkeysvalueof{/pgf/logic gate IEC symbol align}}% - \edef\pgf@lib@sh@@temp{/pgf/logic gate IEC symbol align/.cd, \pgf@lib@sh@temp}% - \expandafter\pgfkeys\expandafter{\pgf@lib@sh@@temp}% - \expandafter\pgftext\expandafter[\pgf@lib@sh@temp]{% - \pgfkeysgetvalue{/pgf/logic gate IEC symbol color}{\pgf@lib@sh@temp}% - \ifx\pgf@lib@sh@temp\pgfutil@empty% - \else% - \expandafter\color\expandafter{\pgf@lib@sh@temp}% - \fi% - \pgfkeysvalueof{/pgf/#1 gate IEC symbol}% - }% - }% -} + \dimensions% + {% + \pgftransformshift{\centerpoint}% + \edef\pgf@lib@sh@temp{\pgfkeysvalueof{/pgf/logic gate IEC symbol align}}% + \edef\pgf@lib@sh@@temp{/pgf/logic gate IEC symbol align/.cd, \pgf@lib@sh@temp}% + \expandafter\pgfkeys\expandafter{\pgf@lib@sh@@temp}% + \expandafter\pgftext\expandafter[\pgf@lib@sh@temp]{% + \pgfkeysgetvalue{/pgf/logic gate IEC symbol color}{\pgf@lib@sh@temp}% + \ifx\pgf@lib@sh@temp\pgfutil@empty% + \else% + \expandafter\color\expandafter{\pgf@lib@sh@temp}% + \fi% + \pgfkeysvalueof{/pgf/#1 gate IEC symbol}% + }% + }% +} \def\pgf@lib@sh@logicgates@dimensions@IEC#1{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y.5\dp\pgfnodeparttextbox% - % - % Adjust for the width of the gate symbol. - % - \setbox\pgf@hbox\hbox{{\pgfkeysvalueof{/pgf/#1 gate IEC symbol}}}% add braces as color-aftergroup-fix TT - \pgf@xa.5\wd\pgf@hbox% - \pgf@ya.5\ht\pgf@hbox% - \advance\pgf@ya.5\dp\pgf@hbox% - \ifdim\pgf@x<\pgf@xa% - \pgf@x\pgf@xa% - \fi% - \ifdim\pgf@y<\pgf@ya% - \pgf@y\pgf@ya% - \fi% - \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% - \pgfmathaddtolength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% - % - % Adjust for minimum height and width. - % - \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}% - \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}% - \ifdim\pgf@x<.5\pgf@xa% - \pgf@x.5\pgf@xa% - \fi% - \ifdim\pgf@y<.5\pgf@ya% - \pgf@y.5\pgf@ya% - \fi% - % - % Adjust the height for the number of inputs. - % - \c@pgf@counta\pgf@lib@sh@logicgate@numinputs% - \advance\c@pgf@counta1\relax% - \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - \pgf@yb2.0\pgf@yb% - \advance\pgf@yb\pgflinewidth% - \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/logic gate input sep}}% - \edef\inputsep{\the\pgf@yc}% - \addtosavedmacro\inputsep% - \ifdim\pgf@yb<\pgf@yc% - \pgf@yb\pgf@yc% - \fi% - \multiply\pgf@yb\c@pgf@counta% - \ifdim\pgf@y<.5\pgf@yb% - \pgf@y.5\pgf@yb% - \fi% - % - \pgf@xa\pgf@y% - \pgfmathaddtolength\pgf@xa{-\pgfkeysvalueof{/pgf/inner xsep}}% - \edef\innerhalfwidth{\the\pgf@xa}% - \addtosavedmacro\innerhalfwidth% - % - \pgf@ya\pgf@y% - \pgfmathaddtolength\pgf@ya{-\pgfkeysvalueof{/pgf/inner ysep}}% - \edef\innerhalfheight{\the\pgf@ya}% - \addtosavedmacro\innerhalfheight% - % - % Take into account the outer sep. - % - \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}% - \pgfmathaddtolength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}% - % - \edef\halfwidth{\the\pgf@x}% - \edef\halfheight{\the\pgf@y}% - \addtosavedmacro\halfwidth% - \addtosavedmacro\halfheight% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y.5\dp\pgfnodeparttextbox% + % + % Adjust for the width of the gate symbol. + % + \setbox\pgf@hbox\hbox{{\pgfkeysvalueof{/pgf/#1 gate IEC symbol}}}% add braces as color-aftergroup-fix TT + \pgf@xa.5\wd\pgf@hbox% + \pgf@ya.5\ht\pgf@hbox% + \advance\pgf@ya.5\dp\pgf@hbox% + \ifdim\pgf@x<\pgf@xa% + \pgf@x\pgf@xa% + \fi% + \ifdim\pgf@y<\pgf@ya% + \pgf@y\pgf@ya% + \fi% + \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% + \pgfmathaddtolength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% + % + % Adjust for minimum height and width. + % + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgf@x<.5\pgf@xa% + \pgf@x.5\pgf@xa% + \fi% + \ifdim\pgf@y<.5\pgf@ya% + \pgf@y.5\pgf@ya% + \fi% + % + % Adjust the height for the number of inputs. + % + \c@pgf@counta\pgf@lib@sh@logicgate@numinputs% + \advance\c@pgf@counta1\relax% + \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + \pgf@yb2.0\pgf@yb% + \advance\pgf@yb\pgflinewidth% + \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/logic gate input sep}}% + \edef\inputsep{\the\pgf@yc}% + \addtosavedmacro\inputsep% + \ifdim\pgf@yb<\pgf@yc% + \pgf@yb\pgf@yc% + \fi% + \multiply\pgf@yb\c@pgf@counta% + \ifdim\pgf@y<.5\pgf@yb% + \pgf@y.5\pgf@yb% + \fi% + % + \pgf@xa\pgf@x% + \pgfmathaddtolength\pgf@xa{-\pgfkeysvalueof{/pgf/inner xsep}}% + \edef\innerhalfwidth{\the\pgf@xa}% + \addtosavedmacro\innerhalfwidth% + % + \pgf@ya\pgf@y% + \pgfmathaddtolength\pgf@ya{-\pgfkeysvalueof{/pgf/inner ysep}}% + \edef\innerhalfheight{\the\pgf@ya}% + \addtosavedmacro\innerhalfheight% + % + % Take into account the outer sep. + % + \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathaddtolength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}% + % + \edef\halfwidth{\the\pgf@x}% + \edef\halfheight{\the\pgf@y}% + \addtosavedmacro\halfwidth% + \addtosavedmacro\halfheight% }% \def\pgf@lib@sh@logicgate@IEC@inputanchor#1{% - \dimensions% - \centerpoint% - \advance\pgf@x-\halfwidth% - \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-#1\endcsname% - \advance\pgf@x-\invertedradius% - \advance\pgf@x-\outerinvertedradius% - \fi% - % - \pgfutil@tempdima\halfheight% - \multiply\pgfutil@tempdima2\relax% - \c@pgf@counta\numinputs% - \advance\c@pgf@counta1\relax% - \divide\pgfutil@tempdima\c@pgf@counta% - \multiply\pgfutil@tempdima#1\relax% - \advance\pgf@y\halfheight% - \advance\pgf@y-\pgfutil@tempdima% + \dimensions% + \centerpoint% + \advance\pgf@x-\halfwidth% + \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-#1\endcsname% + \advance\pgf@x-\invertedradius% + \advance\pgf@x-\outerinvertedradius% + \fi% + % + \pgfutil@tempdima\halfheight% + \multiply\pgfutil@tempdima2\relax% + \c@pgf@counta\numinputs% + \advance\c@pgf@counta1\relax% + \divide\pgfutil@tempdima\c@pgf@counta% + \multiply\pgfutil@tempdima#1\relax% + \advance\pgf@y\halfheight% + \advance\pgf@y-\pgfutil@tempdima% } @@ -142,117 +142,117 @@ % Shape and gate IEC % \pgfdeclareshape{and gate IEC}{ - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@and gate IEC\endcsname{% - \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. - % - \pgfmathloop% - \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% - \else% - \pgfutil@ifundefined{pgf@anchor@and gate IEC@input \pgfmathcounter}{% - \expandafter\xdef\csname pgf@anchor@and gate IEC@input \pgfmathcounter\endcsname{% - \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% - }% - }{}% - \repeatpgfmathloop% - \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{An and gate must have at least two inputs}{}% - \fi% - }% - \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% - \saveddimen\invertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - }% - \saveddimen\outerinvertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - \advance\pgf@x.5\pgflinewidth% - } - \savedmacro\dimensions{% - \pgf@lib@sh@logicgates@dimensions@IEC{and}% - } - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+0.5ex}% - } - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \anchor{center}{\centerpoint}% - \anchor{mid}{\midpoint} - \anchor{mid west}{% - \dimensions% - \midpoint% - \advance\pgf@x-\halfwidth}% - \anchor{mid east}{% - \dimensions% - \midpoint% - \advance\pgf@x\halfwidth}% - \anchor{base}{\basepoint} - \anchor{base west}{% - \dimensions% - \basepoint% - \advance\pgf@x-\halfwidth}% - \anchor{base east}{% - \dimensions% - \basepoint% - \advance\pgf@x\halfwidth}% - \anchor{north}{\dimensions\centerpoint\advance\pgf@y\halfheight}% - \anchor{south}{\dimensions\centerpoint\advance\pgf@y-\halfheight}% - \anchor{east}{\dimensions\centerpoint\advance\pgf@x\halfwidth}% - \anchor{west}{\dimensions\centerpoint\advance\pgf@x-\halfwidth}% - \anchor{north east}{\dimensions\centerpoint\advance\pgf@x\halfwidth\advance\pgf@y\halfheight}% - \anchor{north west}{\dimensions\centerpoint\advance\pgf@x-\halfwidth\advance\pgf@y\halfheight}% - \anchor{south east}{\dimensions\centerpoint\advance\pgf@x\halfwidth\advance\pgf@y-\halfheight}% - \anchor{south west}{\dimensions\centerpoint\advance\pgf@x-\halfwidth\advance\pgf@y-\halfheight}% - \anchor{output}{\dimensions\centerpoint\advance\pgf@x\halfwidth} - \backgroundpath{% - \dimensions% - \pgf@xc\halfwidth% - \pgf@yc\halfheight% - \pgfmathaddtolength\pgf@xc{-\pgfkeysvalueof{/pgf/outer xsep}}% - \pgfmathaddtolength\pgf@yc{-\pgfkeysvalueof{/pgf/outer xsep}}% - {% - \pgftransformshift{\centerpoint}% - \pgfpathrectangle{\pgfqpoint{-\pgf@xc}{-\pgf@yc}}% - {% - \pgf@xc2.0\pgf@xc% - \pgf@yc2.0\pgf@yc% - \pgfqpoint{\pgf@xc}{\pgf@yc}% - }% - \pgfpathclose% - % - % Draw inputs. - % - \pgf@xc-\halfwidth% - \advance\pgf@xc-\invertedradius% - \pgf@yc\halfheight% - \pgfutil@tempdima2.0\pgf@yc% - \c@pgf@counta\numinputs% - \advance\c@pgf@counta1\relax% - \divide\pgfutil@tempdima\c@pgf@counta% - \pgfmathloop% - \ifnum\pgfmathcounter>\numinputs% - \else% - \advance\pgf@yc-\pgfutil@tempdima% - \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-\pgfmathcounter\endcsname% - {% - \pgfpathcircle{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\invertedradius}% - }% - \fi% - \repeatpgfmathloop% - }% - } - \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{and}} - \anchorborder{% - \pgfextract@process\externalpoint{}% - \dimensions% - \pgfpointadd{\centerpoint}{\pgfpointborderrectangle{\externalpoint}{\pgfqpoint{\halfwidth}{\halfheight}}}% - }% + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@and gate IEC\endcsname{% + \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. + % + \pgfmathloop% + \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% + \else% + \pgfutil@ifundefined{pgf@anchor@and gate IEC@input \pgfmathcounter}{% + \expandafter\xdef\csname pgf@anchor@and gate IEC@input \pgfmathcounter\endcsname{% + \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% + }% + }{}% + \repeatpgfmathloop% + \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% + \pgferror{An and gate must have at least two inputs}% + \fi% + }% + \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% + \saveddimen\invertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + }% + \saveddimen\outerinvertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + \advance\pgf@x.5\pgflinewidth% + } + \savedmacro\dimensions{% + \pgf@lib@sh@logicgates@dimensions@IEC{and}% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + } + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \anchor{center}{\centerpoint}% + \anchor{mid}{\midpoint} + \anchor{mid west}{% + \dimensions% + \midpoint% + \advance\pgf@x-\halfwidth}% + \anchor{mid east}{% + \dimensions% + \midpoint% + \advance\pgf@x\halfwidth}% + \anchor{base}{\basepoint} + \anchor{base west}{% + \dimensions% + \basepoint% + \advance\pgf@x-\halfwidth}% + \anchor{base east}{% + \dimensions% + \basepoint% + \advance\pgf@x\halfwidth}% + \anchor{north}{\dimensions\centerpoint\advance\pgf@y\halfheight}% + \anchor{south}{\dimensions\centerpoint\advance\pgf@y-\halfheight}% + \anchor{east}{\dimensions\centerpoint\advance\pgf@x\halfwidth}% + \anchor{west}{\dimensions\centerpoint\advance\pgf@x-\halfwidth}% + \anchor{north east}{\dimensions\centerpoint\advance\pgf@x\halfwidth\advance\pgf@y\halfheight}% + \anchor{north west}{\dimensions\centerpoint\advance\pgf@x-\halfwidth\advance\pgf@y\halfheight}% + \anchor{south east}{\dimensions\centerpoint\advance\pgf@x\halfwidth\advance\pgf@y-\halfheight}% + \anchor{south west}{\dimensions\centerpoint\advance\pgf@x-\halfwidth\advance\pgf@y-\halfheight}% + \anchor{output}{\dimensions\centerpoint\advance\pgf@x\halfwidth} + \backgroundpath{% + \dimensions% + \pgf@xc\halfwidth% + \pgf@yc\halfheight% + \pgfmathaddtolength\pgf@xc{-\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathaddtolength\pgf@yc{-\pgfkeysvalueof{/pgf/outer xsep}}% + {% + \pgftransformshift{\centerpoint}% + \pgfpathrectangle{\pgfqpoint{-\pgf@xc}{-\pgf@yc}}% + {% + \pgf@xc2.0\pgf@xc% + \pgf@yc2.0\pgf@yc% + \pgfqpoint{\pgf@xc}{\pgf@yc}% + }% + \pgfpathclose% + % + % Draw inputs. + % + \pgf@xc-\halfwidth% + \advance\pgf@xc-\invertedradius% + \pgf@yc\halfheight% + \pgfutil@tempdima2.0\pgf@yc% + \c@pgf@counta\numinputs% + \advance\c@pgf@counta1\relax% + \divide\pgfutil@tempdima\c@pgf@counta% + \pgfmathloop% + \ifnum\pgfmathcounter>\numinputs% + \else% + \advance\pgf@yc-\pgfutil@tempdima% + \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-\pgfmathcounter\endcsname% + {% + \pgfpathcircle{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\invertedradius}% + }% + \fi% + \repeatpgfmathloop% + }% + } + \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{and}} + \anchorborder{% + \pgfextract@process\externalpoint{}% + \dimensions% + \pgfpointadd{\centerpoint}{\pgfpointborderrectangle{\externalpoint}{\pgfqpoint{\halfwidth}{\halfheight}}}% + }% } @@ -262,76 +262,76 @@ % Shape nand gate IEC % \pgfdeclareshape{nand gate IEC}{ - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@nand gate IEC\endcsname{% - \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. - % - \pgfmathloop% - \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% - \else% - \pgfutil@ifundefined{pgf@anchor@nand gate IEC@input \pgfmathcounter}{% - \expandafter\xdef\csname pgf@anchor@nand gate IEC@input \pgfmathcounter\endcsname{% - \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% - }% - }{}% - \repeatpgfmathloop% - \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{A nand gate must have at least two inputs}{}% - \fi% - }% - \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% - \saveddimen\invertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - }% - \saveddimen\outerinvertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - \advance\pgf@x.5\pgflinewidth% - } - \savedmacro\dimensions{% - \pgf@lib@sh@logicgates@dimensions@IEC{nand}% - } - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+0.5ex}% - } - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \inheritanchor[from=and gate IEC]{center} - \inheritanchor[from=and gate IEC]{mid} - \inheritanchor[from=and gate IEC]{mid west} - \inheritanchor[from=and gate IEC]{mid east} - \inheritanchor[from=and gate IEC]{base} - \inheritanchor[from=and gate IEC]{base west} - \inheritanchor[from=and gate IEC]{base east} - \inheritanchor[from=and gate IEC]{north} - \inheritanchor[from=and gate IEC]{south} - \inheritanchor[from=and gate IEC]{east} - \inheritanchor[from=and gate IEC]{west} - \inheritanchor[from=and gate IEC]{north east} - \inheritanchor[from=and gate IEC]{north west} - \inheritanchor[from=and gate IEC]{south east} - \inheritanchor[from=and gate IEC]{south west} - \anchor{output}{% - \csname pgf@anchor@and gate IEC@east\endcsname% - \advance\pgf@x\invertedradius% - \advance\pgf@x\outerinvertedradius% - } - \backgroundpath{% - \csname pgf@sh@bg@and gate IEC\endcsname% - \pgfpathcircle{% - \centerpoint% - \advance\pgf@x\halfwidth% - \advance\pgf@x\invertedradius% - }{+\invertedradius}% - } - \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{nand}} - \inheritanchorborder[from=and gate IEC] + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@nand gate IEC\endcsname{% + \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. + % + \pgfmathloop% + \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% + \else% + \pgfutil@ifundefined{pgf@anchor@nand gate IEC@input \pgfmathcounter}{% + \expandafter\xdef\csname pgf@anchor@nand gate IEC@input \pgfmathcounter\endcsname{% + \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% + }% + }{}% + \repeatpgfmathloop% + \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% + \pgferror{A nand gate must have at least two inputs}% + \fi% + }% + \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% + \saveddimen\invertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + }% + \saveddimen\outerinvertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + \advance\pgf@x.5\pgflinewidth% + } + \savedmacro\dimensions{% + \pgf@lib@sh@logicgates@dimensions@IEC{nand}% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + } + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \inheritanchor[from=and gate IEC]{center} + \inheritanchor[from=and gate IEC]{mid} + \inheritanchor[from=and gate IEC]{mid west} + \inheritanchor[from=and gate IEC]{mid east} + \inheritanchor[from=and gate IEC]{base} + \inheritanchor[from=and gate IEC]{base west} + \inheritanchor[from=and gate IEC]{base east} + \inheritanchor[from=and gate IEC]{north} + \inheritanchor[from=and gate IEC]{south} + \inheritanchor[from=and gate IEC]{east} + \inheritanchor[from=and gate IEC]{west} + \inheritanchor[from=and gate IEC]{north east} + \inheritanchor[from=and gate IEC]{north west} + \inheritanchor[from=and gate IEC]{south east} + \inheritanchor[from=and gate IEC]{south west} + \anchor{output}{% + \csname pgf@anchor@and gate IEC@east\endcsname% + \advance\pgf@x\invertedradius% + \advance\pgf@x\outerinvertedradius% + } + \backgroundpath{% + \csname pgf@sh@bg@and gate IEC\endcsname% + \pgfpathcircle{% + \centerpoint% + \advance\pgf@x\halfwidth% + \advance\pgf@x\invertedradius% + }{+\invertedradius}% + } + \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{nand}} + \inheritanchorborder[from=and gate IEC] } @@ -341,65 +341,65 @@ % Shape or gate IEC % \pgfdeclareshape{or gate IEC}{ - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@or gate IEC\endcsname{% - \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. - % - \pgfmathloop% - \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% - \else% - \pgfutil@ifundefined{pgf@anchor@or gate IEC@input \pgfmathcounter}{% - \expandafter\xdef\csname pgf@anchor@or gate IEC@input \pgfmathcounter\endcsname{% - \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% - }% - }{}% - \repeatpgfmathloop% - \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{An or gate must have at least two inputs}{}% - \fi% - }% - \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% - \saveddimen\invertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - }% - \saveddimen\outerinvertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - \advance\pgf@x.5\pgflinewidth% - } - \savedmacro\dimensions{% - \pgf@lib@sh@logicgates@dimensions@IEC{or}% - } - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+0.5ex}% - } - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \inheritanchor[from=and gate IEC]{center} - \inheritanchor[from=and gate IEC]{mid} - \inheritanchor[from=and gate IEC]{mid west} - \inheritanchor[from=and gate IEC]{mid east} - \inheritanchor[from=and gate IEC]{base} - \inheritanchor[from=and gate IEC]{base west} - \inheritanchor[from=and gate IEC]{base east} - \inheritanchor[from=and gate IEC]{north} - \inheritanchor[from=and gate IEC]{south} - \inheritanchor[from=and gate IEC]{east} - \inheritanchor[from=and gate IEC]{west} - \inheritanchor[from=and gate IEC]{north east} - \inheritanchor[from=and gate IEC]{north west} - \inheritanchor[from=and gate IEC]{south east} - \inheritanchor[from=and gate IEC]{south west} - \inheritanchor[from=and gate IEC]{output} - \inheritbackgroundpath[from=and gate IEC] - \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{or}} - \inheritanchorborder[from=and gate IEC] + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@or gate IEC\endcsname{% + \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. + % + \pgfmathloop% + \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% + \else% + \pgfutil@ifundefined{pgf@anchor@or gate IEC@input \pgfmathcounter}{% + \expandafter\xdef\csname pgf@anchor@or gate IEC@input \pgfmathcounter\endcsname{% + \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% + }% + }{}% + \repeatpgfmathloop% + \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% + \pgferror{An or gate must have at least two inputs}% + \fi% + }% + \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% + \saveddimen\invertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + }% + \saveddimen\outerinvertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + \advance\pgf@x.5\pgflinewidth% + } + \savedmacro\dimensions{% + \pgf@lib@sh@logicgates@dimensions@IEC{or}% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + } + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \inheritanchor[from=and gate IEC]{center} + \inheritanchor[from=and gate IEC]{mid} + \inheritanchor[from=and gate IEC]{mid west} + \inheritanchor[from=and gate IEC]{mid east} + \inheritanchor[from=and gate IEC]{base} + \inheritanchor[from=and gate IEC]{base west} + \inheritanchor[from=and gate IEC]{base east} + \inheritanchor[from=and gate IEC]{north} + \inheritanchor[from=and gate IEC]{south} + \inheritanchor[from=and gate IEC]{east} + \inheritanchor[from=and gate IEC]{west} + \inheritanchor[from=and gate IEC]{north east} + \inheritanchor[from=and gate IEC]{north west} + \inheritanchor[from=and gate IEC]{south east} + \inheritanchor[from=and gate IEC]{south west} + \inheritanchor[from=and gate IEC]{output} + \inheritbackgroundpath[from=and gate IEC] + \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{or}} + \inheritanchorborder[from=and gate IEC] } @@ -409,65 +409,65 @@ % Shape nor gate IEC % \pgfdeclareshape{nor gate IEC}{ - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@nor gate IEC\endcsname{% - \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. - % - \pgfmathloop% - \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% - \else% - \pgfutil@ifundefined{pgf@anchor@nor gate IEC@input \pgfmathcounter}{% - \expandafter\xdef\csname pgf@anchor@nor gate IEC@input \pgfmathcounter\endcsname{% - \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% - }% - }{}% - \repeatpgfmathloop% - \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{A nor gate must have at least two inputs}{}% - \fi% - }% - \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% - \saveddimen\invertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - }% - \saveddimen\outerinvertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - \advance\pgf@x.5\pgflinewidth% - } - \savedmacro\dimensions{% - \pgf@lib@sh@logicgates@dimensions@IEC{nor}% - } - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+0.5ex}% - } - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \inheritanchor[from=and gate IEC]{center} - \inheritanchor[from=and gate IEC]{mid} - \inheritanchor[from=and gate IEC]{mid west} - \inheritanchor[from=and gate IEC]{mid east} - \inheritanchor[from=and gate IEC]{base} - \inheritanchor[from=and gate IEC]{base west} - \inheritanchor[from=and gate IEC]{base east} - \inheritanchor[from=and gate IEC]{north} - \inheritanchor[from=and gate IEC]{south} - \inheritanchor[from=and gate IEC]{east} - \inheritanchor[from=and gate IEC]{west} - \inheritanchor[from=and gate IEC]{north east} - \inheritanchor[from=and gate IEC]{north west} - \inheritanchor[from=and gate IEC]{south east} - \inheritanchor[from=and gate IEC]{south west} - \inheritanchor[from=nand gate IEC]{output}% - \inheritbackgroundpath[from=nand gate IEC] - \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{nor}} - \inheritanchorborder[from=and gate IEC] + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@nor gate IEC\endcsname{% + \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. + % + \pgfmathloop% + \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% + \else% + \pgfutil@ifundefined{pgf@anchor@nor gate IEC@input \pgfmathcounter}{% + \expandafter\xdef\csname pgf@anchor@nor gate IEC@input \pgfmathcounter\endcsname{% + \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% + }% + }{}% + \repeatpgfmathloop% + \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% + \pgferror{A nor gate must have at least two inputs}% + \fi% + }% + \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% + \saveddimen\invertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + }% + \saveddimen\outerinvertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + \advance\pgf@x.5\pgflinewidth% + } + \savedmacro\dimensions{% + \pgf@lib@sh@logicgates@dimensions@IEC{nor}% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + } + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \inheritanchor[from=and gate IEC]{center} + \inheritanchor[from=and gate IEC]{mid} + \inheritanchor[from=and gate IEC]{mid west} + \inheritanchor[from=and gate IEC]{mid east} + \inheritanchor[from=and gate IEC]{base} + \inheritanchor[from=and gate IEC]{base west} + \inheritanchor[from=and gate IEC]{base east} + \inheritanchor[from=and gate IEC]{north} + \inheritanchor[from=and gate IEC]{south} + \inheritanchor[from=and gate IEC]{east} + \inheritanchor[from=and gate IEC]{west} + \inheritanchor[from=and gate IEC]{north east} + \inheritanchor[from=and gate IEC]{north west} + \inheritanchor[from=and gate IEC]{south east} + \inheritanchor[from=and gate IEC]{south west} + \inheritanchor[from=nand gate IEC]{output}% + \inheritbackgroundpath[from=nand gate IEC] + \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{nor}} + \inheritanchorborder[from=and gate IEC] } @@ -477,65 +477,65 @@ % Shape xor gate IEC % \pgfdeclareshape{xor gate IEC}{ - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@xor gate IEC\endcsname{% - \pgf@lib@sh@logicgate@parseinputs{2}% Maximum 1024 (!) inputs. - % - \pgfmathloop% - \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% - \else% - \pgfutil@ifundefined{pgf@anchor@xor gate IEC@input \pgfmathcounter}{% - \expandafter\xdef\csname pgf@anchor@xor gate IEC@input \pgfmathcounter\endcsname{% - \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% - }% - }{}% - \repeatpgfmathloop% - \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{An xor gate must have two inputs}{}% - \fi% - }% - \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% - \saveddimen\invertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - }% - \saveddimen\outerinvertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - \advance\pgf@x.5\pgflinewidth% - } - \savedmacro\dimensions{% - \pgf@lib@sh@logicgates@dimensions@IEC{xor}% - } - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+0.5ex}% - } - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \inheritanchor[from=and gate IEC]{center} - \inheritanchor[from=and gate IEC]{mid} - \inheritanchor[from=and gate IEC]{mid west} - \inheritanchor[from=and gate IEC]{mid east} - \inheritanchor[from=and gate IEC]{base} - \inheritanchor[from=and gate IEC]{base west} - \inheritanchor[from=and gate IEC]{base east} - \inheritanchor[from=and gate IEC]{north} - \inheritanchor[from=and gate IEC]{south} - \inheritanchor[from=and gate IEC]{east} - \inheritanchor[from=and gate IEC]{west} - \inheritanchor[from=and gate IEC]{north east} - \inheritanchor[from=and gate IEC]{north west} - \inheritanchor[from=and gate IEC]{south east} - \inheritanchor[from=and gate IEC]{south west} - \inheritanchor[from=and gate IEC]{output} - \inheritbackgroundpath[from=and gate IEC] - \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{xor}} - \inheritanchorborder[from=and gate IEC] + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@xor gate IEC\endcsname{% + \pgf@lib@sh@logicgate@parseinputs{2}% Maximum 1024 (!) inputs. + % + \pgfmathloop% + \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% + \else% + \pgfutil@ifundefined{pgf@anchor@xor gate IEC@input \pgfmathcounter}{% + \expandafter\xdef\csname pgf@anchor@xor gate IEC@input \pgfmathcounter\endcsname{% + \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% + }% + }{}% + \repeatpgfmathloop% + \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% + \pgferror{An xor gate must have two inputs}% + \fi% + }% + \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% + \saveddimen\invertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + }% + \saveddimen\outerinvertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + \advance\pgf@x.5\pgflinewidth% + } + \savedmacro\dimensions{% + \pgf@lib@sh@logicgates@dimensions@IEC{xor}% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + } + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \inheritanchor[from=and gate IEC]{center} + \inheritanchor[from=and gate IEC]{mid} + \inheritanchor[from=and gate IEC]{mid west} + \inheritanchor[from=and gate IEC]{mid east} + \inheritanchor[from=and gate IEC]{base} + \inheritanchor[from=and gate IEC]{base west} + \inheritanchor[from=and gate IEC]{base east} + \inheritanchor[from=and gate IEC]{north} + \inheritanchor[from=and gate IEC]{south} + \inheritanchor[from=and gate IEC]{east} + \inheritanchor[from=and gate IEC]{west} + \inheritanchor[from=and gate IEC]{north east} + \inheritanchor[from=and gate IEC]{north west} + \inheritanchor[from=and gate IEC]{south east} + \inheritanchor[from=and gate IEC]{south west} + \inheritanchor[from=and gate IEC]{output} + \inheritbackgroundpath[from=and gate IEC] + \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{xor}} + \inheritanchorborder[from=and gate IEC] } @@ -545,65 +545,65 @@ % \pgfdeclareshape{xnor gate IEC}{ - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@xnor gate IEC\endcsname{% - \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. - % - \pgfmathloop% - \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% - \else% - \pgfutil@ifundefined{pgf@anchor@xnor gate IEC@input \pgfmathcounter}{% - \expandafter\xdef\csname pgf@anchor@xnor gate IEC@input \pgfmathcounter\endcsname{% - \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% - }% - }{}% - \repeatpgfmathloop% - \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{A xnor gate must have two inputs}{}% - \fi% - }% - \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% - \saveddimen\invertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - }% - \saveddimen\outerinvertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - \advance\pgf@x.5\pgflinewidth% - } - \savedmacro\dimensions{% - \pgf@lib@sh@logicgates@dimensions@IEC{xnor}% - } - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+0.5ex}% - } - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \inheritanchor[from=and gate IEC]{center} - \inheritanchor[from=and gate IEC]{mid} - \inheritanchor[from=and gate IEC]{mid west} - \inheritanchor[from=and gate IEC]{mid east} - \inheritanchor[from=and gate IEC]{base} - \inheritanchor[from=and gate IEC]{base west} - \inheritanchor[from=and gate IEC]{base east} - \inheritanchor[from=and gate IEC]{north} - \inheritanchor[from=and gate IEC]{south} - \inheritanchor[from=and gate IEC]{east} - \inheritanchor[from=and gate IEC]{west} - \inheritanchor[from=and gate IEC]{north east} - \inheritanchor[from=and gate IEC]{north west} - \inheritanchor[from=and gate IEC]{south east} - \inheritanchor[from=and gate IEC]{south west} - \inheritanchor[from=nand gate IEC]{output} - \inheritbackgroundpath[from=nand gate IEC] - \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{xnor}} - \inheritanchorborder[from=and gate IEC] + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@xnor gate IEC\endcsname{% + \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. + % + \pgfmathloop% + \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% + \else% + \pgfutil@ifundefined{pgf@anchor@xnor gate IEC@input \pgfmathcounter}{% + \expandafter\xdef\csname pgf@anchor@xnor gate IEC@input \pgfmathcounter\endcsname{% + \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% + }% + }{}% + \repeatpgfmathloop% + \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% + \pgferror{A xnor gate must have two inputs}% + \fi% + }% + \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% + \saveddimen\invertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + }% + \saveddimen\outerinvertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + \advance\pgf@x.5\pgflinewidth% + } + \savedmacro\dimensions{% + \pgf@lib@sh@logicgates@dimensions@IEC{xnor}% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + } + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \inheritanchor[from=and gate IEC]{center} + \inheritanchor[from=and gate IEC]{mid} + \inheritanchor[from=and gate IEC]{mid west} + \inheritanchor[from=and gate IEC]{mid east} + \inheritanchor[from=and gate IEC]{base} + \inheritanchor[from=and gate IEC]{base west} + \inheritanchor[from=and gate IEC]{base east} + \inheritanchor[from=and gate IEC]{north} + \inheritanchor[from=and gate IEC]{south} + \inheritanchor[from=and gate IEC]{east} + \inheritanchor[from=and gate IEC]{west} + \inheritanchor[from=and gate IEC]{north east} + \inheritanchor[from=and gate IEC]{north west} + \inheritanchor[from=and gate IEC]{south east} + \inheritanchor[from=and gate IEC]{south west} + \inheritanchor[from=nand gate IEC]{output} + \inheritbackgroundpath[from=nand gate IEC] + \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{xnor}} + \inheritanchorborder[from=and gate IEC] } @@ -612,59 +612,59 @@ % Shape buffer gate IEC % \pgfdeclareshape{buffer gate IEC}{ - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@buffer gate IEC\endcsname{% - \pgf@lib@sh@logicgate@parseinputs{1}% Maximum 1 input. - % - \expandafter\gdef\csname pgf@anchor@buffer gate IEC@input\endcsname{% - \pgf@lib@sh@logicgate@IEC@inputanchor{1}% - }% - \ifnum\pgf@lib@sh@logicgate@numinputs=0\relax% - \PackageError{PGF}{A buffer gate must have one inputs}{}% - \fi% - }% - \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% - \saveddimen\invertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - }% - \saveddimen\outerinvertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - \advance\pgf@x.5\pgflinewidth% - } - \savedmacro\dimensions{% - \pgf@lib@sh@logicgates@dimensions@IEC{xor}% - } - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+0.5ex}% - } - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \inheritanchor[from=and gate IEC]{center} - \inheritanchor[from=and gate IEC]{mid} - \inheritanchor[from=and gate IEC]{mid west} - \inheritanchor[from=and gate IEC]{mid east} - \inheritanchor[from=and gate IEC]{base} - \inheritanchor[from=and gate IEC]{base west} - \inheritanchor[from=and gate IEC]{base east} - \inheritanchor[from=and gate IEC]{north} - \inheritanchor[from=and gate IEC]{south} - \inheritanchor[from=and gate IEC]{east} - \inheritanchor[from=and gate IEC]{west} - \inheritanchor[from=and gate IEC]{north east} - \inheritanchor[from=and gate IEC]{north west} - \inheritanchor[from=and gate IEC]{south east} - \inheritanchor[from=and gate IEC]{south west} - \inheritanchor[from=and gate IEC]{output} - \inheritbackgroundpath[from=and gate IEC] - \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{buffer}} - \inheritanchorborder[from=and gate IEC] + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@buffer gate IEC\endcsname{% + \pgf@lib@sh@logicgate@parseinputs{1}% Maximum 1 input. + % + \expandafter\gdef\csname pgf@anchor@buffer gate IEC@input\endcsname{% + \pgf@lib@sh@logicgate@IEC@inputanchor{1}% + }% + \ifnum\pgf@lib@sh@logicgate@numinputs=0\relax% + \pgferror{A buffer gate must have one inputs}% + \fi% + }% + \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% + \saveddimen\invertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + }% + \saveddimen\outerinvertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + \advance\pgf@x.5\pgflinewidth% + } + \savedmacro\dimensions{% + \pgf@lib@sh@logicgates@dimensions@IEC{xor}% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + } + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \inheritanchor[from=and gate IEC]{center} + \inheritanchor[from=and gate IEC]{mid} + \inheritanchor[from=and gate IEC]{mid west} + \inheritanchor[from=and gate IEC]{mid east} + \inheritanchor[from=and gate IEC]{base} + \inheritanchor[from=and gate IEC]{base west} + \inheritanchor[from=and gate IEC]{base east} + \inheritanchor[from=and gate IEC]{north} + \inheritanchor[from=and gate IEC]{south} + \inheritanchor[from=and gate IEC]{east} + \inheritanchor[from=and gate IEC]{west} + \inheritanchor[from=and gate IEC]{north east} + \inheritanchor[from=and gate IEC]{north west} + \inheritanchor[from=and gate IEC]{south east} + \inheritanchor[from=and gate IEC]{south west} + \inheritanchor[from=and gate IEC]{output} + \inheritbackgroundpath[from=and gate IEC] + \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{buffer}} + \inheritanchorborder[from=and gate IEC] } @@ -674,60 +674,60 @@ % Shape not gate IEC % \pgfdeclareshape{not gate IEC}{ - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@not gate IEC\endcsname{% - \pgf@lib@sh@logicgate@parseinputs{1}% - % - \pgfutil@ifundefined{pgf@anchor@not gate IEC@input}{% - \expandafter\gdef\csname pgf@anchor@not gate IEC@input\endcsname{% - \pgf@lib@sh@logicgate@IEC@inputanchor{1}% - }}{}% - \ifnum\pgf@lib@sh@logicgate@numinputs=0\relax% - \PackageError{PGF}{A not gate must have one input}{}% - \fi% - }% - \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% - \saveddimen\invertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - }% - \saveddimen\outerinvertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - \advance\pgf@x.5\pgflinewidth% - } - \savedmacro\dimensions{% - \pgf@lib@sh@logicgates@dimensions@IEC{not}% - } - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+0.5ex}% - } - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \inheritanchor[from=and gate IEC]{center} - \inheritanchor[from=and gate IEC]{mid} - \inheritanchor[from=and gate IEC]{mid west} - \inheritanchor[from=and gate IEC]{mid east} - \inheritanchor[from=and gate IEC]{base} - \inheritanchor[from=and gate IEC]{base west} - \inheritanchor[from=and gate IEC]{base east} - \inheritanchor[from=and gate IEC]{north} - \inheritanchor[from=and gate IEC]{south} - \inheritanchor[from=and gate IEC]{east} - \inheritanchor[from=and gate IEC]{west} - \inheritanchor[from=and gate IEC]{north east} - \inheritanchor[from=and gate IEC]{north west} - \inheritanchor[from=and gate IEC]{south east} - \inheritanchor[from=and gate IEC]{south west} - \inheritanchor[from=nand gate IEC]{output} - \inheritbackgroundpath[from=nand gate IEC] - \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{not}} - \inheritanchorborder[from=and gate IEC] + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@not gate IEC\endcsname{% + \pgf@lib@sh@logicgate@parseinputs{1}% + % + \pgfutil@ifundefined{pgf@anchor@not gate IEC@input}{% + \expandafter\gdef\csname pgf@anchor@not gate IEC@input\endcsname{% + \pgf@lib@sh@logicgate@IEC@inputanchor{1}% + }}{}% + \ifnum\pgf@lib@sh@logicgate@numinputs=0\relax% + \pgferror{A not gate must have one input}% + \fi% + }% + \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% + \saveddimen\invertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + }% + \saveddimen\outerinvertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + \advance\pgf@x.5\pgflinewidth% + } + \savedmacro\dimensions{% + \pgf@lib@sh@logicgates@dimensions@IEC{not}% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + } + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \inheritanchor[from=and gate IEC]{center} + \inheritanchor[from=and gate IEC]{mid} + \inheritanchor[from=and gate IEC]{mid west} + \inheritanchor[from=and gate IEC]{mid east} + \inheritanchor[from=and gate IEC]{base} + \inheritanchor[from=and gate IEC]{base west} + \inheritanchor[from=and gate IEC]{base east} + \inheritanchor[from=and gate IEC]{north} + \inheritanchor[from=and gate IEC]{south} + \inheritanchor[from=and gate IEC]{east} + \inheritanchor[from=and gate IEC]{west} + \inheritanchor[from=and gate IEC]{north east} + \inheritanchor[from=and gate IEC]{north west} + \inheritanchor[from=and gate IEC]{south east} + \inheritanchor[from=and gate IEC]{south west} + \inheritanchor[from=nand gate IEC]{output} + \inheritbackgroundpath[from=nand gate IEC] + \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{not}} + \inheritanchorborder[from=and gate IEC] } \endinput
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.US.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.US.code.tex index ae857c6fd42..f941abd2647 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.US.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.US.code.tex @@ -217,7 +217,7 @@ }{}% \repeatpgfmathloop% \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{An and gate must have at least two inputs}{}% + \pgferror{An and gate must have at least two inputs}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% @@ -454,7 +454,7 @@ }{}% \repeatpgfmathloop% \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{A nand gate must have at least two inputs}{}% + \pgferror{A nand gate must have at least two inputs}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% @@ -619,7 +619,7 @@ }{}% \repeatpgfmathloop% \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{An or gate must have at least two inputs}{}% + \pgferror{An or gate must have at least two inputs}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% @@ -967,7 +967,7 @@ }{}% \repeatpgfmathloop% \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{A nor gate must have at least two inputs}{}% + \pgferror{A nor gate must have at least two inputs}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% @@ -1166,7 +1166,7 @@ }{}% \repeatpgfmathloop% \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{An xor gate must have at two inputs}{}% + \pgferror{An xor gate must have at two inputs}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% @@ -1497,7 +1497,7 @@ }{}% \repeatpgfmathloop% \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{An xnor gate must have two inputs}{}% + \pgferror{An xnor gate must have two inputs}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% @@ -1657,7 +1657,7 @@ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@not gate US\endcsname{% \pgf@lib@sh@logicgate@parseinputs{1}% \ifnum\pgf@lib@sh@logicgate@numinputs=0\relax% - \PackageError{PGF}{A not gate must have one input}{}% + \pgferror{A not gate must have one input}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% @@ -1960,7 +1960,7 @@ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@buffer gate US\endcsname{% \pgf@lib@sh@logicgate@parseinputs{1}% \ifnum\pgf@lib@sh@logicgate@numinputs=0\relax% - \PackageError{PGF}{A buffer gate must have one input}{}% + \pgferror{A buffer gate must have one input}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% @@ -2153,7 +2153,7 @@ }{}% \repeatpgfmathloop% \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{An and gate must have at least two inputs}{}% + \pgferror{An and gate must have at least two inputs}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% @@ -2405,7 +2405,7 @@ }{}% \repeatpgfmathloop% \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{A nand gate must have at least two inputs}{}% + \pgferror{A nand gate must have at least two inputs}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.callouts.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.callouts.code.tex index 440681b7b87..cfa1d80d442 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.callouts.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.callouts.code.tex @@ -247,9 +247,9 @@ \pgf@lib@callouts@shortenpointer% \pgf@lib@ellipsecallout@getpoints% \calloutpointeranchor% - \ifx\pgf@test\pgfutil@empty% + \ifx\pgf@node@name\pgfutil@empty% \else% - \edef\pgf@sh@@temp{\noexpand\expandafter\noexpand\pgfutil@g@addto@macro\noexpand\csname pgf@sh@np@\pgf@test\noexpand\endcsname}% + \edef\pgf@sh@@temp{\noexpand\expandafter\noexpand\pgfutil@g@addto@macro\noexpand\csname pgf@sh@np@\pgf@node@name\noexpand\endcsname}% \edef\pgf@sh@@@temp{% \noexpand\def\noexpand\calloutpointeranchor{% \noexpand\pgf@x\the\pgf@x% @@ -568,15 +568,15 @@ \pgfmathsetlengthmacro\pointerwidth{\pgfkeysvalueof{/pgf/callout pointer width}}% \pgf@lib@rectanglecallout@pointer% % - % \pgf@test = the shape name (from \pgfmultipartnode) + % \pgf@node@name = the shape name (from \pgfmultipartnode) % - \ifx\pgf@test\pgfutil@empty% + \ifx\pgf@node@name\pgfutil@empty% \else% % % Now hack an extra saved anchor \calloutpointeranchor, % with the new anchor for the callout pointer. % - \edef\pgf@sh@@temp{\noexpand\expandafter\noexpand\pgfutil@g@addto@macro\noexpand\csname pgf@sh@np@\pgf@test\noexpand\endcsname}% + \edef\pgf@sh@@temp{\noexpand\expandafter\noexpand\pgfutil@g@addto@macro\noexpand\csname pgf@sh@np@\pgf@node@name\noexpand\endcsname}% \edef\pgf@sh@@@temp{% \noexpand\def\noexpand\calloutpointeranchor{% \noexpand\pgf@x\the\pgf@x% @@ -809,7 +809,7 @@ \pgfdeclareshape{cloud callout}{% \savedanchor\calloutpointer{% \pgfutil@ifundefined{pgf@sh@s@cloud}{% - \PackageError{PGF}{I cannot find the cloud shape. Please load the `symbol shapes' library}{}}{}% + \pgferror{I cannot find the cloud shape. Please load the `symbol shapes' library}}{}% \pgf@sh@s@cloud% \pgf@sh@savedmacros% % @@ -862,9 +862,9 @@ \pgfextract@process\calloutpointer{% \pgfpointanchor{pgf@lib@callout@pointer}{center}% }% - \ifx\pgf@test\pgfutil@empty% + \ifx\pgf@node@name\pgfutil@empty% \else% - \edef\pgf@sh@@temp{\noexpand\expandafter\noexpand\pgfutil@g@addto@macro\noexpand\csname pgf@sh@np@\pgf@test\noexpand\endcsname}% + \edef\pgf@sh@@temp{\noexpand\expandafter\noexpand\pgfutil@g@addto@macro\noexpand\csname pgf@sh@np@\pgf@node@name\noexpand\endcsname}% \edef\pgf@sh@@@temp{% \noexpand\def\noexpand\calloutpointeranchor{% \noexpand\pgf@x\the\pgf@x% diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.misc.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.misc.code.tex index a57b0cd4511..5466b1a27f2 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.misc.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.misc.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/shapes/pgflibraryshapes.misc.code.tex,v 1.3 2008/10/07 18:23:25 vibrovski Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/shapes/pgflibraryshapes.misc.code.tex,v 1.5 2013/07/18 14:15:25 tantau Exp $ \pgfdeclareshape{cross out} @@ -37,6 +37,8 @@ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}} \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yb}} \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}} + \pgfsetarrowsstart{} + \pgfsetarrowsend{} } } @@ -63,6 +65,8 @@ \foregroundpath{ \pgfpathmoveto{\southwest} \pgfpathlineto{\northeast} + \pgfsetarrowsstart{} + \pgfsetarrowsend{} } } @@ -1085,7 +1089,7 @@ \pgfmathanglebetweenpoints{\centerpoint}{\after@sw@anchor}% \ifdim\externalangle pt<\pgfmathresult pt\relax% after south west. \pgfpointintersectionoflines{\centerpoint}{\externalpoint}% - {\before@sw@anchor}{\after@sw@anchor}% + {\sw@anchor}{\after@sw@anchor}% \else% \pgfpointintersectionoflines{\centerpoint}{\externalpoint}% {\after@sw@anchor}{\centerpoint\pgf@xa\pgf@x\after@sw@anchor\pgf@x\pgf@xa}% diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.symbols.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.symbols.code.tex index b419a8cb624..efa492cc024 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.symbols.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.symbols.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/shapes/pgflibraryshapes.symbols.code.tex,v 1.3 2009/10/27 23:03:12 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/shapes/pgflibraryshapes.symbols.code.tex,v 1.6 2013/09/11 06:15:59 vibrovski Exp $ \pgfdeclareshape{forbidden sign} { @@ -43,6 +43,48 @@ \fi% \pgfpathmoveto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{-0.707107\pgfutil@tempdima}{-0.707107\pgfutil@tempdima}}} \pgfpathlineto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{0.707107\pgfutil@tempdima}{0.707107\pgfutil@tempdima}}} + \pgfsetarrowsstart{} + \pgfsetarrowsend{} + } +} + + +\pgfdeclareshape{correct forbidden sign} +{ + \inheritsavedanchors[from=circle] % this is nearly a circle + \inheritanchorborder[from=circle] + \inheritanchor[from=circle]{north} + \inheritanchor[from=circle]{north west} + \inheritanchor[from=circle]{north east} + \inheritanchor[from=circle]{center} + \inheritanchor[from=circle]{west} + \inheritanchor[from=circle]{east} + \inheritanchor[from=circle]{mid} + \inheritanchor[from=circle]{mid west} + \inheritanchor[from=circle]{mid east} + \inheritanchor[from=circle]{base} + \inheritanchor[from=circle]{base west} + \inheritanchor[from=circle]{base east} + \inheritanchor[from=circle]{south} + \inheritanchor[from=circle]{south west} + \inheritanchor[from=circle]{south east} + \inheritbackgroundpath[from=circle] + \foregroundpath{ + \centerpoint% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \pgfutil@tempdima=\radius% + \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@xb<\pgf@yb% + \advance\pgfutil@tempdima by-\pgf@yb% + \else% + \advance\pgfutil@tempdima by-\pgf@xb% + \fi% + \pgfpathmoveto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{0.707107\pgfutil@tempdima}{-0.707107\pgfutil@tempdima}}} + \pgfpathlineto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{-0.707107\pgfutil@tempdima}{0.707107\pgfutil@tempdima}}} + \pgfsetarrowsstart{} + \pgfsetarrowsend{} } } @@ -57,468 +99,468 @@ % /pgf/random starburst : The seed for the random number generator. % \pgfkeys{/pgf/random starburst/% - .code={% - \ifx\pgfkeysnovalue#1% - \pgfmathgeneratepseudorandomnumber% - \else% - \pgfmathtruncatemacro\pgfmathresult{#1}% - \fi% - \pgfkeyslet{/pgf/random starburst}{\pgfmathresult}% - }% + .code={% + \ifx\pgfkeysnovalue#1% + \pgfmathgeneratepseudorandomnumber% + \else% + \pgfmathtruncatemacro\pgfmathresult{#1}% + \fi% + \pgfkeyslet{/pgf/random starburst}{\pgfmathresult}% + }% } \pgfkeys{/pgf/random starburst=100} \pgfkeys{/pgf/starburst point height/.value required} \pgfkeys{/pgf/starburst point height/.code={% - \pgfmathparse{#1}% - \edef\pgfmathresult{\pgfmathresult pt}% - \pgfkeyslet{/pgf/starburst point height}{\pgfmathresult}% - }% + \pgfmathparse{#1}% + \edef\pgfmathresult{\pgfmathresult pt}% + \pgfkeyslet{/pgf/starburst point height}{\pgfmathresult}% + }% }% \pgfkeys{/pgf/starburst point height=.5cm} \pgfkeys{/pgf/starburst points/.value required} \pgfkeys{/pgf/starburst points/.code={% - \pgfmathtruncatemacro\pgfmathresult{#1}% - \pgfkeyslet{/pgf/starburst points}{\pgfmathresult}% - }% + \pgfmathtruncatemacro\pgfmathresult{#1}% + \pgfkeyslet{/pgf/starburst points}{\pgfmathresult}% + }% }% \pgfkeys{/pgf/starburst points=17} \pgfdeclareshape{starburst}{% - \savedmacro\anglestep{% - \pgfmathdivide@{180}{\pgfkeysvalueof{/pgf/starburst points}}% - \let\anglestep\pgfmathresult% - } - \savedmacro\calculatestarburstpoints{% - % - % Get the angle step. - % - \pgfmathdivide@{180}{\pgfkeysvalueof{/pgf/starburst points}}% - \let\anglestep\pgfmathresult% - % - % Get the total number of points. - % - \pgfmathsetcounter{pgf@counta}{\pgfkeysvalueof{/pgf/starburst points}}% - \multiply\c@pgf@counta2\relax% - \edef\totalpoints{\the\c@pgf@counta}% - \addtosavedmacro{\totalpoints}% - % - % Calculate the centerpoint. - % - \pgfextract@process\centerpoint{% - \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% - \pgfmathsetlength\pgf@y{+.5\ht\pgfnodeparttextbox}% - \pgfmathaddtolength\pgf@y{+-.5\dp\pgfnodeparttextbox}% - }% - % - % Get the larger of the outer sep. - % - \pgfmathsetlength\pgf@x{+\pgfkeysvalueof{/pgf/outer xsep}}% - \pgfmathsetlength\pgf@y{+\pgfkeysvalueof{/pgf/outer ysep}}% - \ifdim\pgf@x<\pgf@y% - \pgf@x\pgf@y% - \fi% - \edef\outersep{\the\pgf@x}% - % - % Get the node dimensions. - % - \pgfmathsetlength\pgf@x{+\pgfkeysvalueof{/pgf/inner xsep}}% - \pgfmathaddtolength\pgf@x{+.5\wd\pgfnodeparttextbox}% - \pgfmathsetlength\pgf@y{+\pgfkeysvalueof{/pgf/inner ysep}}% - \pgfmathaddtolength\pgf@y{+.5\ht\pgfnodeparttextbox}% - \pgfmathaddtolength\pgf@y{+.5\dp\pgfnodeparttextbox}% - % - % Calculate the inner radii. - % - \ifpgfshapeborderusesincircle% - \pgfkeysgetvalue{/pgf/shape border rotate}{\rotate}% - % - % Use the incircle... - % - \ifdim\pgf@y>\pgf@x% - \pgf@x\pgf@y% - \fi% - \pgf@x1.41421\pgf@x% - \pgf@y\pgf@x% - \else% - % - % Get the rotation (with rounding). - % - \pgfkeysgetvalue{/pgf/shape border rotate}{\rotate}% - \pgfmathmod@{\rotate}{360}% - \afterassignment\pgfmath@gobbletilpgfmath@% - \expandafter\c@pgf@counta\pgfmathresult\relax\pgfmath@% - \advance\c@pgf@counta45\relax% - \divide\c@pgf@counta90\relax% - \multiply\c@pgf@counta90\relax% - \ifnum\c@pgf@counta<0\relax% - \advance\c@pgf@counta360\relax% - \fi% - % - % Calculate the width and height of the node - % contents, according to any border rotation. - % - \ifnum\c@pgf@counta=90\relax% - \pgf@xc\pgf@x% - \pgf@x\pgf@y% - \pgf@y\pgf@xc% - \else% - \ifnum\c@pgf@counta=270\relax% - \pgf@xc\pgf@x% - \pgf@x\pgf@y% - \pgf@y\pgf@xc% - \fi% - \fi% - \edef\rotate{\the\c@pgf@counta}% - % - % ...or not. - % - \pgf@x=1.41421\pgf@x% - \pgf@y=1.41421\pgf@y% - \fi% - \addtosavedmacro{\rotate}% - % - % Adjust innerradius for minimum width and height. - % - \pgf@xa\pgf@x% - \pgfmathsetlength\pgf@xb{+\pgfkeysvalueof{/pgf/starburst point height}}% - \advance\pgf@xa\pgf@xb% - \pgfmathsetlength\pgf@xc{+\pgfkeysvalueof{/pgf/minimum width}}% - \ifdim\pgf@xa<.5\pgf@xc% - \pgf@x.5\pgf@xc% - \advance\pgf@x-\pgf@xb% - \fi% - \pgf@ya\pgf@y% - \pgfmathsetlength\pgf@yb{+\pgfkeysvalueof{/pgf/starburst point height}}% - \advance\pgf@ya\pgf@yb% - \pgfmathsetlength\pgf@yc{+\pgfkeysvalueof{/pgf/minimum height}}% - \ifdim\pgf@ya<.5\pgf@yc% - \pgf@y.5\pgf@yc% - \advance\pgf@y-\pgf@yb% - \fi% - \edef\xinnerradius{\the\pgf@x}% - \edef\yinnerradius{\the\pgf@y}% - \addtosavedmacro{\xinnerradius}% - \addtosavedmacro{\yinnerradius}% - % - % Calculate a radius outside the starburst. - % - \ifdim\pgf@y>\pgf@x% - \pgf@x\pgf@y% - \fi% - \pgfmathaddtolength\pgf@x{+\pgfkeysvalueof{/pgf/starburst point height}}% - \edef\externalradius{\the\pgf@x}% - \addtosavedmacro{\externalradius}% - % - % Set the seed for the random number generator. - % - \pgfmathsetseed{\pgfkeysvalueof{/pgf/random starburst}}% - % - % Now create the points on the shape and also - % the miter length and angle for each point. - % - \def\angle{90}% Start at the top. - % - % At point a, the miter length and angle are calculated for point b = a - 1. - % - \c@pgf@counta1\relax% - \c@pgf@countb0\relax% - % - % As 3 consecutive points are required to be defined for miter - % calculations, it is necessary to go over the first two points - % again. - % - \c@pgf@countc\totalpoints\relax% - \advance\c@pgf@countc2\relax% - \edef\looppoints{\the\c@pgf@countc}% - \let\secondpoint\pgfutil@empty% - \let\thirdpoint\pgfutil@empty% - \pgfmathloop% - % - % Cycle the point definitions. - % - \let\firstpoint\secondpoint% - \let\secondpoint\thirdpoint% - \ifnum\pgfmathcounter>\looppoints% - \else% - \ifnum\pgfmathcounter>\totalpoints% - \expandafter\let\expandafter\thirdpoint\csname point@\the\c@pgf@counta @\endcsname% - \else% - \ifodd\pgfmathcounter% - % - % An outer point. - % - \ifnum\pgfkeysvalueof{/pgf/random starburst}=0\relax% - \pgf@xa\pgfkeysvalueof{/pgf/starburst point height}\relax% - \else% - \pgf@x\pgfkeysvalueof{/pgf/starburst point height}\relax% - \pgf@xa.75\pgf@x% - \pgf@xb.25\pgf@x% - \pgfmathrnd% - \pgf@xa\pgfmathresult\pgf@xa% - \advance\pgf@xa\pgf@xb% - \fi% - \pgf@x\xinnerradius\relax% - \advance\pgf@x\pgf@xa% - \pgf@y\yinnerradius\relax% - \advance\pgf@y\pgf@xa% - \expandafter\pgfextract@process\csname point@\the\c@pgf@counta @\endcsname{% - \pgfpointpolar{\angle}{\the\pgf@x and \the\pgf@y}% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \centerpoint% - \advance\pgf@x\pgf@xa% - \advance\pgf@y\pgf@ya% - }% - \else% - % - % An inner point. - % - \expandafter\pgfextract@process\csname point@\the\c@pgf@counta @\endcsname{% - \pgfpointpolar{\angle}{\xinnerradius and \yinnerradius}% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \centerpoint% - \advance\pgf@x\pgf@xa% - \advance\pgf@y\pgf@ya% - }% - \fi% - % - % Add the points to the saved macro. - % - \expandafter\let\expandafter\thirdpoint\csname point@\the\c@pgf@counta @\endcsname% - \expandafter\addtosavedmacro\expandafter{\csname point@\the\c@pgf@counta @\endcsname}% - \fi% - % - % It is only possible to do the miter calculations if three points are defined. - % - \ifx\firstpoint\pgfutil@empty% - \else% - % - % Calculate the miter length... - % - \pgfmathanglebetweenlines{\secondpoint}{\thirdpoint}{\secondpoint}{\firstpoint}% - \pgfmathdivide@{\pgfmathresult}{2}% - \let\defaultmiterangle\pgfmathresult% - \pgfmathcosec@{\pgfmathresult}% - \pgf@x\outersep\relax% - \pgf@x\pgfmathresult\pgf@x% - \edef\miterlength{\the\pgf@x}% - % - % ...the miter angle... - % - \pgfmathanglebetweenlines{\firstpoint}{\secondpoint}{\firstpoint}{\thirdpoint}% - \pgfmathadd@{\pgfmathresult}{\defaultmiterangle}% - \pgfmathsubtract@{180}{\pgfmathresult}% - \let\angletemp\pgfmathresult% - \pgfmathanglebetweenpoints{\firstpoint}{\thirdpoint}% - \pgfmathsubtract@{180}{\pgfmathresult}% - \pgfmathsubtract@{\angletemp}{\pgfmathresult}% - \edef\miterangle{\pgfmathresult}% - % - % ...and thus the border point. - % - \pgfextract@process\borderpoint{% - \secondpoint% - \pgf@xa\pgf@x - \pgf@ya\pgf@y% - \pgfpointpolar{\miterangle}{\miterlength}% - \advance\pgf@x\pgf@xa% - \advance\pgf@y\pgf@ya% - }% - % - % Get the angle from the centerpoint to the *unrotated* border points. - % - \pgfmathanglebetweenpoints{\centerpoint}{\borderpoint}% - \expandafter\edef\csname angletoborderpoint@\the\c@pgf@countb @\endcsname{\pgfmathresult}% - \expandafter\addtosavedmacro\expandafter{\csname angletoborderpoint@\the\c@pgf@countb @\endcsname}% - % - % Rotatee the border points and save. - % - \expandafter\pgfextract@process\csname borderpoint@\the\c@pgf@countb @\endcsname{% - \pgfmathrotatepointaround{\borderpoint}{\centerpoint}{\rotate}% - }% - \expandafter\addtosavedmacro\expandafter{\csname borderpoint@\the\c@pgf@countb @\endcsname}% - % - % Now create the anchors. - % - \c@pgf@countc\c@pgf@countb% - \advance\c@pgf@countc1\relax% - \divide\c@pgf@countc2\relax% - \ifodd\c@pgf@countb\relax% - \pgfutil@ifundefined{pgf@anchor@starburst@outer point\space\the\c@pgf@countc}{% - \expandafter\xdef\csname pgf@anchor@starburst@outer point\space\the\c@pgf@countc\endcsname{% - \noexpand\calculatestarburstpoints% - \noexpand\csname borderpoint@\the\c@pgf@countb @\noexpand\endcsname% - }% - }{}% - \else% - \pgfutil@ifundefined{pgf@anchor@starburst@inner point\space\the\c@pgf@countc}{% - \expandafter\xdef\csname pgf@anchor@starburst@inner point\space\the\c@pgf@countc\endcsname{% - \noexpand\calculatestarburstpoints% - \noexpand\csname borderpoint@\the\c@pgf@countb @\noexpand\endcsname% - }% - }{}% - \fi% - \fi% - \pgfmathadd@{\angle}{\anglestep}% - \pgfmathmod@{\pgfmathresult}{360}% - \let\angle\pgfmathresult% - \advance\c@pgf@counta1\relax% - \ifnum\c@pgf@counta>\totalpoints% - \c@pgf@counta1\relax% - \fi% - \advance\c@pgf@countb1\relax% - \ifnum\c@pgf@countb>\totalpoints% - \c@pgf@countb1\relax% - \fi% - \repeatpgfmathloop% - } - \savedanchor\centerpoint{% - \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% - \pgfmathsetlength\pgf@y{+.5\ht\pgfnodeparttextbox}% - \pgfmathaddtolength\pgf@y{+-.5\dp\pgfnodeparttextbox}% - }% - \savedanchor\midpoint{% - \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% - \pgfmathsetlength\pgf@y{+.5ex}% - }% - \savedanchor\basepoint{% - \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% - \pgf@y0pt\relax% - }% - \anchor{center}{\centerpoint} - \anchor{base}{\basepoint} - \anchor{mid}{\midpoint} - \anchor{north}{% - \calculatestarburstpoints% - \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{0pt}{\externalradius}}% - } - \anchor{south}{% - \calculatestarburstpoints% - \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{0pt}{-\externalradius}}% - } - \anchor{east}{% - \calculatestarburstpoints% - \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{\externalradius}{0pt}}% - } - \anchor{west}{% - \calculatestarburstpoints% - \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}% - } - \anchor{north west}{% - \calculatestarburstpoints% - \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{-\externalradius}{\externalradius}}% - } - \anchor{south west}{% - \calculatestarburstpoints% - \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{-\externalradius}{-\externalradius}}% - } - \anchor{north east}{% - \calculatestarburstpoints% - \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{\externalradius}{\externalradius}}% - } - \anchor{south east}{% - \calculatestarburstpoints% - \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{\externalradius}{-\externalradius}}% - } - \backgroundpath{% - \calculatestarburstpoints% - \pgfmathloop% - \ifnum\pgfmathcounter>\totalpoints% - \else% - \ifnum\pgfmathcounter=1\relax% - \let\starburstaction\pgfpathmoveto% - \else% - \let\starburstaction\pgfpathlineto% - \fi% - \starburstaction{% - %\pgfmathrotatepointaround{\csname point@\pgfmathcounter @\endcsname}{\centerpoint}{\rotate}}% - \csname point@\pgfmathcounter @\endcsname} - \repeatpgfmathloop% - \pgfpathclose% - } - \anchorborder{% - % - % Save x and y. - % - \edef\externalx{\the\pgf@x}% - \edef\externaly{\the\pgf@y}% - % - % Adjust the location of the external - % point relative to \centerpoint. - % - \centerpoint% - \pgf@xa\externalx\relax% - \pgf@ya\externaly\relax% - \advance\pgf@xa\pgf@x% - \advance\pgf@ya\pgf@y% - \edef\externalx{\the\pgf@xa}% - \edef\externaly{\the\pgf@ya}% - % - % Get the starburst points. - % - \calculatestarburstpoints% - % - % Get the angle of the external point to the \centerpoint. - % - \pgfmathanglebetweenpoints{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% - \pgfmathsubtract@{\pgfmathresult}{\rotate}% - \ifdim\pgfmathresult pt<0pt\relax% - \pgfmathadd@{\pgfmathresult}{360}% - \fi% - \let\externalangle\pgfmathresult% - % - % Locate the appropriate sides on the starburst border... - % - \ifdim\externalangle pt<90pt\relax% - \c@pgf@counta0\relax% - \c@pgf@countb\totalpoints\relax% - \pgfmathloop% - \ifnum\c@pgf@counta>0\relax% - \else% - \ifdim\csname angletoborderpoint@\the\c@pgf@countb @\endcsname pt>90pt\relax% - \c@pgf@counta\c@pgf@countb% - \else% - \ifdim\externalangle pt>\csname angletoborderpoint@\the\c@pgf@countb @\endcsname pt\relax% - \c@pgf@counta\c@pgf@countb% - \fi% - \fi% - \advance\c@pgf@countb-1\relax% - \repeatpgfmathloop% - \edef\first{\the\c@pgf@counta}% - \advance\c@pgf@counta1\relax% - \ifnum\c@pgf@counta>\totalpoints\relax% - \c@pgf@counta1\relax% - \fi% - \edef\second{\the\c@pgf@counta}% - \else% - \c@pgf@counta0\relax% - \pgfmathloop% - \ifnum\c@pgf@counta>0\relax% - \else% - \ifdim\csname angletoborderpoint@\pgfmathcounter @\endcsname pt<90pt\relax% - \c@pgf@counta\pgfmathcounter% - \else% - \ifdim\externalangle pt<\csname angletoborderpoint@\pgfmathcounter @\endcsname pt\relax% - \c@pgf@counta\pgfmathcounter% - \fi% - \fi% - \repeatpgfmathloop% - \edef\first{\the\c@pgf@counta}% - \advance\c@pgf@counta-1\relax% - \ifnum\c@pgf@counta=0\relax% - \c@pgf@counta\totalpoints\relax% - \fi% - \edef\second{\the\c@pgf@counta}% - \fi% - % - % ...and thus, the point on the star border. - % - \pgfpointintersectionoflines{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% - {\csname borderpoint@\first @\endcsname}{\csname borderpoint@\second @\endcsname}% - }% + \savedmacro\anglestep{% + \pgfmathdivide@{180}{\pgfkeysvalueof{/pgf/starburst points}}% + \let\anglestep\pgfmathresult% + } + \savedmacro\calculatestarburstpoints{% + % + % Get the angle step. + % + \pgfmathdivide@{180}{\pgfkeysvalueof{/pgf/starburst points}}% + \let\anglestep\pgfmathresult% + % + % Get the total number of points. + % + \pgfmathsetcounter{pgf@counta}{\pgfkeysvalueof{/pgf/starburst points}}% + \multiply\c@pgf@counta2\relax% + \edef\totalpoints{\the\c@pgf@counta}% + \addtosavedmacro{\totalpoints}% + % + % Calculate the centerpoint. + % + \pgfextract@process\centerpoint{% + \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% + \pgfmathsetlength\pgf@y{+.5\ht\pgfnodeparttextbox}% + \pgfmathaddtolength\pgf@y{+-.5\dp\pgfnodeparttextbox}% + }% + % + % Get the larger of the outer sep. + % + \pgfmathsetlength\pgf@x{+\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@y{+\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@x<\pgf@y% + \pgf@x\pgf@y% + \fi% + \edef\outersep{\the\pgf@x}% + % + % Get the node dimensions. + % + \pgfmathsetlength\pgf@x{+\pgfkeysvalueof{/pgf/inner xsep}}% + \pgfmathaddtolength\pgf@x{+.5\wd\pgfnodeparttextbox}% + \pgfmathsetlength\pgf@y{+\pgfkeysvalueof{/pgf/inner ysep}}% + \pgfmathaddtolength\pgf@y{+.5\ht\pgfnodeparttextbox}% + \pgfmathaddtolength\pgf@y{+.5\dp\pgfnodeparttextbox}% + % + % Calculate the inner radii. + % + \ifpgfshapeborderusesincircle% + \pgfkeysgetvalue{/pgf/shape border rotate}{\rotate}% + % + % Use the incircle... + % + \ifdim\pgf@y>\pgf@x% + \pgf@x\pgf@y% + \fi% + \pgf@x1.41421\pgf@x% + \pgf@y\pgf@x% + \else% + % + % Get the rotation (with rounding). + % + \pgfkeysgetvalue{/pgf/shape border rotate}{\rotate}% + \pgfmathmod@{\rotate}{360}% + \afterassignment\pgfmath@gobbletilpgfmath@% + \expandafter\c@pgf@counta\pgfmathresult\relax\pgfmath@% + \advance\c@pgf@counta45\relax% + \divide\c@pgf@counta90\relax% + \multiply\c@pgf@counta90\relax% + \ifnum\c@pgf@counta<0\relax% + \advance\c@pgf@counta360\relax% + \fi% + % + % Calculate the width and height of the node + % contents, according to any border rotation. + % + \ifnum\c@pgf@counta=90\relax% + \pgf@xc\pgf@x% + \pgf@x\pgf@y% + \pgf@y\pgf@xc% + \else% + \ifnum\c@pgf@counta=270\relax% + \pgf@xc\pgf@x% + \pgf@x\pgf@y% + \pgf@y\pgf@xc% + \fi% + \fi% + \edef\rotate{\the\c@pgf@counta}% + % + % ...or not. + % + \pgf@x=1.41421\pgf@x% + \pgf@y=1.41421\pgf@y% + \fi% + \addtosavedmacro{\rotate}% + % + % Adjust innerradius for minimum width and height. + % + \pgf@xa\pgf@x% + \pgfmathsetlength\pgf@xb{+\pgfkeysvalueof{/pgf/starburst point height}}% + \advance\pgf@xa\pgf@xb% + \pgfmathsetlength\pgf@xc{+\pgfkeysvalueof{/pgf/minimum width}}% + \ifdim\pgf@xa<.5\pgf@xc% + \pgf@x.5\pgf@xc% + \advance\pgf@x-\pgf@xb% + \fi% + \pgf@ya\pgf@y% + \pgfmathsetlength\pgf@yb{+\pgfkeysvalueof{/pgf/starburst point height}}% + \advance\pgf@ya\pgf@yb% + \pgfmathsetlength\pgf@yc{+\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgf@ya<.5\pgf@yc% + \pgf@y.5\pgf@yc% + \advance\pgf@y-\pgf@yb% + \fi% + \edef\xinnerradius{\the\pgf@x}% + \edef\yinnerradius{\the\pgf@y}% + \addtosavedmacro{\xinnerradius}% + \addtosavedmacro{\yinnerradius}% + % + % Calculate a radius outside the starburst. + % + \ifdim\pgf@y>\pgf@x% + \pgf@x\pgf@y% + \fi% + \pgfmathaddtolength\pgf@x{+\pgfkeysvalueof{/pgf/starburst point height}}% + \edef\externalradius{\the\pgf@x}% + \addtosavedmacro{\externalradius}% + % + % Set the seed for the random number generator. + % + \pgfmathsetseed{\pgfkeysvalueof{/pgf/random starburst}}% + % + % Now create the points on the shape and also + % the miter length and angle for each point. + % + \def\angle{90}% Start at the top. + % + % At point a, the miter length and angle are calculated for point b = a - 1. + % + \c@pgf@counta1\relax% + \c@pgf@countb0\relax% + % + % As 3 consecutive points are required to be defined for miter + % calculations, it is necessary to go over the first two points + % again. + % + \c@pgf@countc\totalpoints\relax% + \advance\c@pgf@countc2\relax% + \edef\looppoints{\the\c@pgf@countc}% + \let\secondpoint\pgfutil@empty% + \let\thirdpoint\pgfutil@empty% + \pgfmathloop% + % + % Cycle the point definitions. + % + \let\firstpoint\secondpoint% + \let\secondpoint\thirdpoint% + \ifnum\pgfmathcounter>\looppoints% + \else% + \ifnum\pgfmathcounter>\totalpoints% + \expandafter\let\expandafter\thirdpoint\csname point@\the\c@pgf@counta @\endcsname% + \else% + \ifodd\pgfmathcounter% + % + % An outer point. + % + \ifnum\pgfkeysvalueof{/pgf/random starburst}=0\relax% + \pgf@xa\pgfkeysvalueof{/pgf/starburst point height}\relax% + \else% + \pgf@x\pgfkeysvalueof{/pgf/starburst point height}\relax% + \pgf@xa.75\pgf@x% + \pgf@xb.25\pgf@x% + \pgfmathrnd% + \pgf@xa\pgfmathresult\pgf@xa% + \advance\pgf@xa\pgf@xb% + \fi% + \pgf@x\xinnerradius\relax% + \advance\pgf@x\pgf@xa% + \pgf@y\yinnerradius\relax% + \advance\pgf@y\pgf@xa% + \expandafter\pgfextract@process\csname point@\the\c@pgf@counta @\endcsname{% + \pgfpointpolar{\angle}{\the\pgf@x and \the\pgf@y}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \centerpoint% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + \else% + % + % An inner point. + % + \expandafter\pgfextract@process\csname point@\the\c@pgf@counta @\endcsname{% + \pgfpointpolar{\angle}{\xinnerradius and \yinnerradius}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \centerpoint% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + \fi% + % + % Add the points to the saved macro. + % + \expandafter\let\expandafter\thirdpoint\csname point@\the\c@pgf@counta @\endcsname% + \expandafter\addtosavedmacro\expandafter{\csname point@\the\c@pgf@counta @\endcsname}% + \fi% + % + % It is only possible to do the miter calculations if three points are defined. + % + \ifx\firstpoint\pgfutil@empty% + \else% + % + % Calculate the miter length... + % + \pgfmathanglebetweenlines{\secondpoint}{\thirdpoint}{\secondpoint}{\firstpoint}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\defaultmiterangle\pgfmathresult% + \pgfmathcosec@{\pgfmathresult}% + \pgf@x\outersep\relax% + \pgf@x\pgfmathresult\pgf@x% + \edef\miterlength{\the\pgf@x}% + % + % ...the miter angle... + % + \pgfmathanglebetweenlines{\firstpoint}{\secondpoint}{\firstpoint}{\thirdpoint}% + \pgfmathadd@{\pgfmathresult}{\defaultmiterangle}% + \pgfmathsubtract@{180}{\pgfmathresult}% + \let\angletemp\pgfmathresult% + \pgfmathanglebetweenpoints{\firstpoint}{\thirdpoint}% + \pgfmathsubtract@{180}{\pgfmathresult}% + \pgfmathsubtract@{\angletemp}{\pgfmathresult}% + \edef\miterangle{\pgfmathresult}% + % + % ...and thus the border point. + % + \pgfextract@process\borderpoint{% + \secondpoint% + \pgf@xa\pgf@x + \pgf@ya\pgf@y% + \pgfpointpolar{\miterangle}{\miterlength}% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + % + % Get the angle from the centerpoint to the *unrotated* border points. + % + \pgfmathanglebetweenpoints{\centerpoint}{\borderpoint}% + \expandafter\edef\csname angletoborderpoint@\the\c@pgf@countb @\endcsname{\pgfmathresult}% + \expandafter\addtosavedmacro\expandafter{\csname angletoborderpoint@\the\c@pgf@countb @\endcsname}% + % + % Rotatee the border points and save. + % + \expandafter\pgfextract@process\csname borderpoint@\the\c@pgf@countb @\endcsname{% + \pgfmathrotatepointaround{\borderpoint}{\centerpoint}{\rotate}% + }% + \expandafter\addtosavedmacro\expandafter{\csname borderpoint@\the\c@pgf@countb @\endcsname}% + % + % Now create the anchors. + % + \c@pgf@countc\c@pgf@countb% + \advance\c@pgf@countc1\relax% + \divide\c@pgf@countc2\relax% + \ifodd\c@pgf@countb\relax% + \pgfutil@ifundefined{pgf@anchor@starburst@outer point\space\the\c@pgf@countc}{% + \expandafter\xdef\csname pgf@anchor@starburst@outer point\space\the\c@pgf@countc\endcsname{% + \noexpand\calculatestarburstpoints% + \noexpand\csname borderpoint@\the\c@pgf@countb @\noexpand\endcsname% + }% + }{}% + \else% + \pgfutil@ifundefined{pgf@anchor@starburst@inner point\space\the\c@pgf@countc}{% + \expandafter\xdef\csname pgf@anchor@starburst@inner point\space\the\c@pgf@countc\endcsname{% + \noexpand\calculatestarburstpoints% + \noexpand\csname borderpoint@\the\c@pgf@countb @\noexpand\endcsname% + }% + }{}% + \fi% + \fi% + \pgfmathadd@{\angle}{\anglestep}% + \pgfmathmod@{\pgfmathresult}{360}% + \let\angle\pgfmathresult% + \advance\c@pgf@counta1\relax% + \ifnum\c@pgf@counta>\totalpoints% + \c@pgf@counta1\relax% + \fi% + \advance\c@pgf@countb1\relax% + \ifnum\c@pgf@countb>\totalpoints% + \c@pgf@countb1\relax% + \fi% + \repeatpgfmathloop% + } + \savedanchor\centerpoint{% + \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% + \pgfmathsetlength\pgf@y{+.5\ht\pgfnodeparttextbox}% + \pgfmathaddtolength\pgf@y{+-.5\dp\pgfnodeparttextbox}% + }% + \savedanchor\midpoint{% + \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% + \pgfmathsetlength\pgf@y{+.5ex}% + }% + \savedanchor\basepoint{% + \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% + \pgf@y0pt\relax% + }% + \anchor{center}{\centerpoint} + \anchor{base}{\basepoint} + \anchor{mid}{\midpoint} + \anchor{north}{% + \calculatestarburstpoints% + \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{0pt}{\externalradius}}% + } + \anchor{south}{% + \calculatestarburstpoints% + \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{0pt}{-\externalradius}}% + } + \anchor{east}{% + \calculatestarburstpoints% + \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{\externalradius}{0pt}}% + } + \anchor{west}{% + \calculatestarburstpoints% + \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}% + } + \anchor{north west}{% + \calculatestarburstpoints% + \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{-\externalradius}{\externalradius}}% + } + \anchor{south west}{% + \calculatestarburstpoints% + \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{-\externalradius}{-\externalradius}}% + } + \anchor{north east}{% + \calculatestarburstpoints% + \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{\externalradius}{\externalradius}}% + } + \anchor{south east}{% + \calculatestarburstpoints% + \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{\externalradius}{-\externalradius}}% + } + \backgroundpath{% + \calculatestarburstpoints% + \pgfmathloop% + \ifnum\pgfmathcounter>\totalpoints% + \else% + \ifnum\pgfmathcounter=1\relax% + \let\starburstaction\pgfpathmoveto% + \else% + \let\starburstaction\pgfpathlineto% + \fi% + \starburstaction{% + %\pgfmathrotatepointaround{\csname point@\pgfmathcounter @\endcsname}{\centerpoint}{\rotate}}% + \csname point@\pgfmathcounter @\endcsname} + \repeatpgfmathloop% + \pgfpathclose% + } + \anchorborder{% + % + % Save x and y. + % + \edef\externalx{\the\pgf@x}% + \edef\externaly{\the\pgf@y}% + % + % Adjust the location of the external + % point relative to \centerpoint. + % + \centerpoint% + \pgf@xa\externalx\relax% + \pgf@ya\externaly\relax% + \advance\pgf@xa\pgf@x% + \advance\pgf@ya\pgf@y% + \edef\externalx{\the\pgf@xa}% + \edef\externaly{\the\pgf@ya}% + % + % Get the starburst points. + % + \calculatestarburstpoints% + % + % Get the angle of the external point to the \centerpoint. + % + \pgfmathanglebetweenpoints{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% + \pgfmathsubtract@{\pgfmathresult}{\rotate}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\externalangle\pgfmathresult% + % + % Locate the appropriate sides on the starburst border... + % + \ifdim\externalangle pt<90pt\relax% + \c@pgf@counta0\relax% + \c@pgf@countb\totalpoints\relax% + \pgfmathloop% + \ifnum\c@pgf@counta>0\relax% + \else% + \ifdim\csname angletoborderpoint@\the\c@pgf@countb @\endcsname pt>90pt\relax% + \c@pgf@counta\c@pgf@countb% + \else% + \ifdim\externalangle pt>\csname angletoborderpoint@\the\c@pgf@countb @\endcsname pt\relax% + \c@pgf@counta\c@pgf@countb% + \fi% + \fi% + \advance\c@pgf@countb-1\relax% + \repeatpgfmathloop% + \edef\first{\the\c@pgf@counta}% + \advance\c@pgf@counta1\relax% + \ifnum\c@pgf@counta>\totalpoints\relax% + \c@pgf@counta1\relax% + \fi% + \edef\second{\the\c@pgf@counta}% + \else% + \c@pgf@counta0\relax% + \pgfmathloop% + \ifnum\c@pgf@counta>0\relax% + \else% + \ifdim\csname angletoborderpoint@\pgfmathcounter @\endcsname pt<90pt\relax% + \c@pgf@counta\pgfmathcounter% + \else% + \ifdim\externalangle pt<\csname angletoborderpoint@\pgfmathcounter @\endcsname pt\relax% + \c@pgf@counta\pgfmathcounter% + \fi% + \fi% + \repeatpgfmathloop% + \edef\first{\the\c@pgf@counta}% + \advance\c@pgf@counta-1\relax% + \ifnum\c@pgf@counta=0\relax% + \c@pgf@counta\totalpoints\relax% + \fi% + \edef\second{\the\c@pgf@counta}% + \fi% + % + % ...and thus, the point on the star border. + % + \pgfpointintersectionoflines{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% + {\csname borderpoint@\first @\endcsname}{\csname borderpoint@\second @\endcsname}% + }% } @@ -533,22 +575,22 @@ \newif\ifpgfcloudignoresaspect% \pgfcloudignoresaspectfalse% \pgfkeys{/pgf/.cd, - cloud puffs/.initial=10, - cloud puff arc/.initial=150, - cloud ignores aspect/.is if=pgfcloudignoresaspect, - cloud anchors use ellipse/.is if=pgfcloudanchorsuseellipse + cloud puffs/.initial=10, + cloud puff arc/.initial=150, + cloud ignores aspect/.is if=pgfcloudignoresaspect, + cloud anchors use ellipse/.is if=pgfcloudanchorsuseellipse }% % If symbol library is loaded separately these need to be defined. % \pgfkeys{/pgf/.cd, - aspect/.code={\pgfsetshapeaspect{#1}},% this for tikz... - shape aspect/.initial=1,% but this is consistent with other pgfset stuff. - shape aspect/.code={% - \pgfkeys{/pgf/aspect=#1}% - \pgfkeyssetvalue{/pgf/shape aspect}{#1} - }% + aspect/.code={\pgfsetshapeaspect{#1}},% this for tikz... + shape aspect/.initial=1,% but this is consistent with other pgfset stuff. + shape aspect/.code={% + \pgfkeys{/pgf/aspect=#1}% + \pgfkeyssetvalue{/pgf/shape aspect}{#1} + }% } \def\pgfsetshapeaspect#1{% @@ -568,717 +610,717 @@ % Shape cloud. % \pgfdeclareshape{cloud}{% - \savedmacro\getradii{% - \pgfmathtruncatemacro\puffs{\pgfkeysvalueof{/pgf/cloud puffs}}% - \addtosavedmacro\puffs% - \pgfmathdivide{360}{\pgfkeysvalueof{/pgf/cloud puffs}}% - \let\anglestep\pgfmathresult% - \addtosavedmacro\anglestep% - \pgfmathsetmacro\arc{\pgfkeysvalueof{/pgf/cloud puff arc}}% - \addtosavedmacro\arc% - % - % x radius. - % - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% - \advance\pgf@x.5\wd\pgfnodeparttextbox% - \pgf@x1.4142135\pgf@x% - % - % y radius. - % - \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% - \advance\pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y.5\dp\pgfnodeparttextbox% - \pgf@y1.4142135\pgf@y% - % - % Adjust for shape aspect. - % - \ifpgfcloudignoresaspect% - \pgf@xc\pgf@x% - \pgf@yc\pgf@y% - \else% - \pgf@xc\pgfshapeaspect\pgf@y% - \ifdim\pgf@xc<\pgf@x% - \pgf@xc\pgf@x% - \fi% - \pgf@yc\pgfshapeaspectinverse\pgf@xc% - \ifdim\pgf@yc<\pgf@y% - \pgf@yc\pgf@y% - \pgf@xc\pgfshapeaspect\pgf@y% - \fi% - \fi% - % - \edef\xinnerradius{\the\pgf@xc}% - \edef\yinnerradius{\the\pgf@yc}% - % - % Get the larger of the outer sep. - % - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}% - \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}% - \ifdim\pgf@x<\pgf@y% - \pgf@x\pgf@y% - \fi% - \edef\outersep{\the\pgf@x}% - \addtosavedmacro\outersep% - % - % For a given cloud, with puff arc length a, the quotient of the - % distance between the start and end point of a puffs circular arc - % and the radius of that arc, is constant: - % - % g = .5 * sec((180-a)/2) - % - \pgfmathsubtract{180}{\arc}% - \pgfmathdivide@{\pgfmathresult}{2}% - \let\tempangle\pgfmathresult% - \pgfmathsec@{\pgfmathresult}% - \pgfmathdivide@{\pgfmathresult}{2}% - \let\arcradiusquotient\pgfmathresult% - \addtosavedmacro\arcradiusquotient% - % - % In addition, the quotient of the distance between the start and - % end point of a puffs circular arc and the height of that arc - % (ignoring rotation), is also constant: - % - % h = .5 * (1-sin((180-a)/2))/cos((180-a)/2) - % = g * (1 - sin((180-a)/2)) - \pgfmathsin@{\tempangle}% - \pgfmathsubtract@{1}{\pgfmathresult}% - \pgfmathmultiply@{\pgfmathresult}{\arcradiusquotient}% - \let\archeightquotient\pgfmathresult% - \addtosavedmacro\archeightquotient% - % - % Minimum size is applied to the circum-ellipse (i.e. the ellipse - % that passes through the extremeties of each puff). Thus, the - % relationship between the radii of the elliptical incircle ("inellipse"?) - % of the cloud (x and y) and the radii of the circum-ellispe (X and Y), - % is given by - % - % X = 2(x*cos(p/2) + ky) - % Y = 2(y*cos(p/2) + kx) - % - % where: - % k = sin(p/2)*((1-cos(a/2))/sin(a/2)) - % p = the angle between each puff (i.e. 360/<puffs>) - % a = the length of arc of the puff. - % - \pgfmathdivide{\arc}{2}% - \let\halfarcangle\pgfmathresult% - \pgfmathcos@{\pgfmathresult}% - \pgfmathsubtract@{1}{\pgfmathresult}% - \let\pgf@temp\pgfmathresult% - \pgfmathsin@{\halfarcangle}% - \pgfmathdivide@{\pgf@temp}{\pgfmathresult}% - \let\pgf@temp\pgfmathresult% - \pgfmathdivide@{\anglestep}{2}% - \pgfmathsin@{\pgfmathresult}% - \pgfmathmultiply@{\pgfmathresult}{\pgf@temp}% - \let\k\pgfmathresult% - % - \pgfmathdivide@{\anglestep}{2}% - \pgfmathcos@{\pgfmathresult}% - \let\coshalfanglestep\pgfmathresult% - % - % Calculate the actual radii of the circum-ellipse. - % - \pgf@x\xinnerradius\relax% - \pgf@y\yinnerradius\relax% - \pgf@xa\coshalfanglestep\pgf@x% - \advance\pgf@xa\k\pgf@y% - \pgf@ya\coshalfanglestep\pgf@y% - \advance\pgf@ya\k\pgf@x% - % - % Adjust for minimum height (Y'). - % - \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}% - \ifdim\pgf@ya<.5\pgf@yb% - \pgf@ya.5\pgf@yb% - \fi% - % - % Adjust for minimum width (X'). - % - \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}% - \ifdim\pgf@xa<.5\pgf@xb% - \pgf@xa.5\pgf@xb% - \fi% - % - \edef\xouterradius{\the\pgf@xa}% - \addtosavedmacro\xouterradius% - \edef\youterradius{\the\pgf@ya}% - \addtosavedmacro\youterradius% - % - % Now recalculate `in-ellispe' radii: - % - % x = (X'cos(p/2)-kY')/cos^2(p/2)-k^2, - % y = (Y'cos(p/2)-kX')/cos^2(p/2)-k^2, - % - \pgf@xc\k pt\relax% - \pgf@xc-\k\pgf@xc% - \pgf@yc\coshalfanglestep pt\relax% - \pgf@yc\coshalfanglestep\pgf@yc% - \advance\pgf@xc\pgf@yc\relax% - \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@xc}}% cos^2(p/2)-k^2 - % - \pgf@x\coshalfanglestep\pgf@xa% - \advance\pgf@x-\k\pgf@ya% - \pgf@x\pgfmathresult\pgf@x% - \pgf@y\coshalfanglestep\pgf@ya% - \advance\pgf@y-\k\pgf@xa% - \pgf@y\pgfmathresult\pgf@y% - % - \edef\xinnerradius{\the\pgf@x}% - \edef\yinnerradius{\the\pgf@y}% - \addtosavedmacro\xinnerradius% - \addtosavedmacro\yinnerradius% - % - % Get some useful trig. constants. - % - \pgfmathdivide@{\arc}{4}% - \let\quarterarc\pgfmathresult% - \pgfmathsubtract@{180}{\arc}% - \pgfmathdivide@{\pgfmathresult}{2}% - \let\halfcomplementarc\pgfmathresult% - % - \addtosavedmacro\arc% - \addtosavedmacro\quarterarc% - \addtosavedmacro\halfcomplementarc% - % - \pgfmathsec@{\halfcomplementarc}% 1/cos((180-a)/2) - \let\sechalfcomplementarc\pgfmathresult% - \pgfmathsin@{\halfcomplementarc}% sin((180-a)/2) - \let\sinhalfcomplementarc\pgfmathresult% - % - \addtosavedmacro\sechalfcomplementarc% - \addtosavedmacro\sinhalfcomplementarc% - % - \pgfmathsin@{\quarterarc}% sin(a/4) - \let\sinquarterarc\pgfmathresult% - \pgfmathcos@{\quarterarc}% cos(a/4) - \let\cosquarterarc\pgfmathresult% - \pgfmathreciprocal@{\cosquarterarc}% - \pgfmathmultiply@{\pgfmathresult}{\sinquarterarc}% tan(a/4) - \let\tanquarterarc\pgfmathresult% - % - \addtosavedmacro\sinquarterarc% - \addtosavedmacro\cosquarterarc% - \addtosavedmacro\tanquarterarc% - % - } - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+.5ex}% - } - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \anchor{center}{\centerpoint} - \anchor{mid}{\midpoint} - \anchor{base}{\basepoint} - \anchor{north}{% - \getradii% - \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{0pt}{\youterradius}}% - }% - \anchor{south}{% - \getradii% - \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{0pt}{-\youterradius}}% - }% - \anchor{east}{% - \getradii% - \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{\xouterradius}{0pt}}% - }% - \anchor{west}{% - \getradii% - \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{-\xouterradius}{0pt}}% - }% - \anchor{north west}{% - \getradii% - \pgfextract@process\pgf@sh{% - \pgf@x\xouterradius\relax% - \pgf@x-0.707106\pgf@x% - \pgf@y\youterradius\relax% - \pgf@y0.707106\pgf@y% - }% - \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}% - }% - \anchor{north east}{% - \getradii% - \pgfextract@process\pgf@sh{% - \pgf@x\xouterradius\relax% - \pgf@x0.707106\pgf@x% - \pgf@y\youterradius\relax% - \pgf@y0.707106\pgf@y% - }% - \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}% - }% - \anchor{south west}{% - \getradii% - \pgfextract@process\pgf@sh{% - \pgf@x\xouterradius\relax% - \pgf@x-0.707106\pgf@x% - \pgf@y\youterradius\relax% - \pgf@y-0.707106\pgf@y% - }% - \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}% - }% - \anchor{south east}{% - \getradii% - \pgfextract@process\pgf@sh{% - \pgf@x\xouterradius\relax% - \pgf@x0.707106\pgf@x% - \pgf@y\youterradius\relax% - \pgf@y-0.707106\pgf@y% - }% - \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}% - }% - % - % Each `puff' is a circular arc of length a, drawn using two a/2 - % arcs (a < 180), approximated by Bezier curves. - % Due to TeX rounding errors, it is sometimes necessary to `force' - % the arc to end at a specific point. So... - % - % @article{riskus2006, - % author = {Aleskus Ri\v{s}kus}, - % title = {Approximation of a cubic Bezier curve by circular arcs and vice versa}, - % journal = {Information Technology and Control}, - % year = {2006}, - % volume = {35}, - % number = {4} - % } - % - \backgroundpath{% - {% - \getradii% - % - % Get the start angle. - % - \pgfmathdivide@{\anglestep}{2}% - \pgfmathsubtract@{90}{\pgfmathresult}% - \let\angle\pgfmathresult% - % - % Calculate the first arc point. - % - \pgfextract@process\arcfirstpoint{% - \pgfpointadd{\centerpoint}{% - \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}% - }% - }% - \pgfpathmoveto{\arcfirstpoint}% - \let\arcendpoint\arcfirstpoint% - % - \pgfmathloop% - \ifnum\pgfmathcounter>\puffs\relax% - \else - \let\arcstartpoint\arcendpoint% - % - % Make sure beginning and end of path are exactly the same. - % - \ifnum\pgfmathcounter=\puffs\relax% - \let\arcendpoint\arcfirstpoint% - \else% - \pgfmathadd@{\angle}{\anglestep}% - \let\angle\pgfmathresult% - \pgfextract@process\arcendpoint{% - \pgfpointadd{\centerpoint}{% - \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}% - }% - }% - \fi% - % - % Get some useful cloud parameters from \arcstartpoint and \arcendpoint. - % - \pgf@sh@getcloudpuffparameters% - % - % Get the rotation for the Bezier curve. - % - \pgfmathsubtract@{90}{\quarterarc}% - \pgfmathadd@{\pgfmathresult}{\arcslope}% - \let\arcrotate\pgfmathresult% - \pgfmathsin@{\arcrotate}% - \let\sinarcrotate\pgfmathresult% - \pgfmathcos@{\arcrotate}% - \let\cosarcrotate\pgfmathresult% - % - % Calculate the amount by which to scale the control - % points, in order to approximate an a/2 arc with radius x. - % - \pgf@x\arcradius\relax% - \pgf@x\tanquarterarc\pgf@x% tan(a/4) - \edef\controlscale{\pgfmath@tonumber{\pgf@x}}% - % - % Get the first control point for the first arc (length a/2)... - % - \pgfextract@process\controlone{% - % - % k = 0.552284745 (a `magic' number)... - % - \pgf@x0.55228475pt\relax% - \pgf@x\sinquarterarc\pgf@x% k * sin(a/2) - \pgf@y0.55228475pt\relax% - \pgf@y\cosquarterarc\pgf@y% k * cos(a/2) - % - % ...scale the control points up... - % - \pgf@x\controlscale\pgf@x% - \pgf@y\controlscale\pgf@y% - % - % ...rotate... - % - \pgf@xa\cosarcrotate\pgf@x% - \advance\pgf@xa-\sinarcrotate\pgf@y% - \pgf@ya\cosarcrotate\pgf@y% - \advance\pgf@ya\sinarcrotate\pgf@x% - % - % ...and shift. - % - \arcstartpoint% - \advance\pgf@x\pgf@xa% - \advance\pgf@y\pgf@ya% - }% - % - % Get the midpoint of the 150° arc. - % - \pgfextract@process\arcmidpoint{% - \pgfextract@process\arcmidpoint{% - \pgf@x-\halfchordlength\relax% - \pgf@y\segmentheight\relax% - }% - \pgfpointadd{\arcstartpoint}{% - \pgfmathrotatepointaround{\arcmidpoint}{\pgfpointorigin}{\arcslope}% - }% - }% - % - % Get the second control point for the first arc (length a/2)... - % - \pgfextract@process\controltwo{% - \pgf@x0.55228475pt\relax% - \pgf@x\sinquarterarc\pgf@x% k * sin(a/2) - \pgf@y-0.55228475pt\relax% - \pgf@y\cosquarterarc\pgf@y% -k * cos(a/2) - % - % ...scale, rotate and shift. - % - \pgf@x\controlscale\pgf@x% - \pgf@y\controlscale\pgf@y% - % - \pgf@xa\cosarcrotate\pgf@x% - \advance\pgf@xa-\sinarcrotate\pgf@y% - \pgf@ya\cosarcrotate\pgf@y% - \advance\pgf@ya\sinarcrotate\pgf@x% - % - \arcmidpoint% - \advance\pgf@x\pgf@xa% - \advance\pgf@y\pgf@ya% - }% - {% - \pgfsetcornersarced{\pgfpointorigin}% - \pgfpathcurveto{\controlone}{\controltwo}{\arcmidpoint}% - }% - % - % Do the same for the second arc... - % - \pgfmathadd@{\quarterarc}{90}% - \pgfmathadd@{\pgfmathresult}{\arcslope}% - \let\arcrotate\pgfmathresult% - \pgfmathsin@{\arcrotate}% - \let\sinarcrotate\pgfmathresult% - \pgfmathcos@{\arcrotate}% - \let\cosarcrotate\pgfmathresult% - % - % First control point for the second arc... - % - \pgfextract@process\controlone{% - \pgf@x0.55228475pt\relax% - \pgf@x\sinquarterarc\pgf@x% k * sin(a/2) - \pgf@y0.55228475pt\relax% - \pgf@y\cosquarterarc\pgf@y% k * cos(a/2) - % - % ...scale, rotate and shift. - % - \pgf@x\controlscale\pgf@x% - \pgf@y\controlscale\pgf@y% - % - \pgf@xa\cosarcrotate\pgf@x% - \advance\pgf@xa-\sinarcrotate\pgf@y% - \pgf@ya\cosarcrotate\pgf@y% - \advance\pgf@ya\sinarcrotate\pgf@x% - % - \arcmidpoint% - \advance\pgf@x\pgf@xa% - \advance\pgf@y\pgf@ya% - }% - % - % Second control point for the second arc. - % - \pgfextract@process\controltwo{% - \pgf@x0.55228475pt\relax% - \pgf@x\sinquarterarc\pgf@x% k * sin(a/2) - \pgf@y-0.55228475pt\relax% - \pgf@y\cosquarterarc\pgf@y% -k * cos(a/2) - % - % ...scale, rotate and shift. - % - \pgf@x\controlscale\pgf@x% - \pgf@y\controlscale\pgf@y% - % - \pgf@xa\cosarcrotate\pgf@x% - \advance\pgf@xa-\sinarcrotate\pgf@y% - \pgf@ya\cosarcrotate\pgf@y% - \advance\pgf@ya\sinarcrotate\pgf@x% - % - \arcendpoint% - \advance\pgf@x\pgf@xa% - \advance\pgf@y\pgf@ya% - }% - \pgfpathcurveto{\controlone}{\controltwo}{\arcendpoint}% - \repeatpgfmathloop% - \pgfpathclose% Phew! - }% - }% - % - % Calculate a point on the border of the cloud. This is a two-stage process: - % - % 1. Locate the correct puff. - % 2. Locate the angle on the circular arc which forms the puff. - % - \anchorborder{% - % - % Save x and y. - % - \edef\externalx{\the\pgf@x}% - \edef\externaly{\the\pgf@y}% - % - % Get the inner radii and trig. constants. - % - \getradii% - % - % - % - \ifpgfcloudanchorsuseellipse% - \pgfpointadd{\centerpoint}{% - \pgfpointborderellipse{% - \pgfpoint{\externalx}{\externaly} - }{% - \pgfpoint{\xouterradius}{\youterradius} - }% - }% - \else% - \pgfextract@process\externalpoint{% - \centerpoint% - \advance\pgf@x\externalx\relax% - \advance\pgf@y\externaly\relax% - }% - \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}% - \let\externalangle\pgfmathresult% - % - % 1. Locate the correct puff: - % - % Get end angle of the relavent puff arc. - % - \pgfmathdivide@{\anglestep}{2}% - \let\halfanglestep\pgfmathresult% - \pgfmathsubtract@{90}{\halfanglestep}% - \let\endangle\pgfmathresult% - \pgfmathloop% - \pgfmathsubtract@{\endangle}{\anglestep}% - \ifdim\pgfmathresult pt<-\anglestep pt\relax% - \else% - \let\endangle\pgfmathresult% - \repeatpgfmathloop% - \def\angle{0}% - \let\lastangle\angle% - \pgfmathloop% - \pgfmathadd@{\endangle}{\anglestep}% - \let\endangle\pgfmathresult% - % - % Calculate the `miter point'. This is the point between - % each puff, and takes into account the outer sep. - % - \pgfextract@process\miterpoint{% - % - \pgfextract@process\secondpoint{% - \pgfpointpolar{+\endangle}{+\xinnerradius and +\yinnerradius}% - }% - % - \pgfmathadd@{\endangle}{\anglestep}% - \let\angletemp\pgfmathresult% - \pgfextract@process\thirdpoint{% - \pgfpointpolar{+\angletemp}{+\xinnerradius and +\yinnerradius}% - }% - % - \pgfmathsubtract@{\endangle}{\anglestep}% - \let\angletemp\pgfmathresult% - \pgfextract@process\firstpoint{% - \pgfpointpolar{+\angletemp}{+\xinnerradius and +\yinnerradius}% - }% - % - \pgfmathanglebetweenpoints{\firstpoint}{\secondpoint}% - \let\anglealpha\pgfmathresult% - \pgfmathanglebetweenpoints{\secondpoint}{\thirdpoint}% - \let\anglebeta\pgfmathresult% - % - \pgfmathsubtract@{\anglebeta}{\anglealpha}% - \pgfmathdivide@{\pgfmathresult}{2}% - \pgfmathadd@{\pgfmathresult}{\halfcomplementarc}% - \pgfmathcosec@{\pgfmathresult}% - \pgf@x\outersep\relax% - \pgf@x\pgfmathresult\pgf@x% - \edef\miterradius{\the\pgf@x}% - % - \pgfmathadd@{\anglealpha}{\anglebeta}% - \pgfmathsubtract@{\pgfmathresult}{180}% - \pgfmathdivide@{\pgfmathresult}{2}% - \let\miterangle\pgfmathresult% - \pgfpointadd{\secondpoint}{% - \pgfqpointpolar{\miterangle}{\miterradius}% - }% - }% - % - % Get the angle of the miter point... - % - \pgfmathanglebetweenpoints{\pgfpointorigin}{\miterpoint}% - \let\angle\pgfmathresult% - \ifdim\angle pt<\lastangle pt\relax% Guard against 360° = 0° - \pgfmathadd@{\angle}{360}% - \let\angle\pgfmathresult% - \fi% - \let\lastangle\angle% - % - % ...and see if it is greater than the external point. - % - \ifdim\externalangle pt>\angle pt\relax% - \repeatpgfmathloop% - % - % Get the start angle of the relevant arc and ensure angles are in the range. - % - \pgfmathmod@{\endangle}{360}% - \let\endangle\pgfmathresult% - \pgfmathsubtract@{\endangle}{\anglestep}% - \ifdim\pgfmathresult pt<0pt\relax% - \pgfmathadd@{\pgfmathresult}{360}% - \fi% - \let\startangle\pgfmathresult% - % - % Now, get the start and end points of the arc. - % - \pgfextract@process\arcstartpoint{% - \pgfpointadd{\centerpoint}{% - \pgfpointpolar{+\startangle}{+\xinnerradius and +\yinnerradius}% - }% - }% - \pgfextract@process\arcendpoint{% - \pgfpointadd{\centerpoint}{% - \pgfpointpolar{+\endangle}{+\xinnerradius and +\yinnerradius}% - }% - }% - % - % Get some useful cloud parameters from \arcstartpoint and \arcendpoint. - % - \pgf@sh@getcloudpuffparameters% - % - % Hackery, for when an arc straddles 0°. - % - \ifdim\endangle pt<\startangle pt\relax% - \pgfmathadd@{\externalangle}{180}% - \pgfmathmod@{\pgfmathresult}{360}% - \let\x\pgfmathresult% - \else% - \let\x\externalangle% - \fi% - % - % 2. Locate the angle on the circular arc which forms the puff. - % - % Essentially a binary search to find the angle on the circular - % arc, which provides the nearset estimate to the border point. - % - \let\s\halfcomplementarc% The start of the arc. - \pgfmathadd@{\s}{\arc}% - \let\e\pgfmathresult% The end of the arc. - \pgfmathadd@{\e}{\s}% - \pgfmathdivide@{\pgfmathresult}{2}% - \let\n\pgfmathresult% The nearest estimate (default to middle of arc). - \def\m{360}% Measure of `nearness'. - \pgfmathloop% - \pgfmathadd@{\e}{\s}% - \pgfmathdivide@{\pgfmathresult}{2}% - \let\p\pgfmathresult% The point halfway between \s and \e. - \ifdim\p pt=\s pt\relax% - \else% - % - % Get the point on the circular arc. - % - \pgfmathadd@{\p}{\arcslope}% - \let\a\pgfmathresult% - \pgfextract@process\arcpoint{% - \pgfpointadd{\circlecenterpoint}{% - \pgfqpointpolar{\a}{\outerarcradius}% - }% - }% - % - % Find the angle between the node centre and the point on the arc. - % - \pgfmathanglebetweenpoints{\centerpoint}{\arcpoint}% - % - % Hackery, for when an arc straddles 0°. - % - \ifdim\endangle pt<\startangle pt\relax% - \pgfmathadd@{\pgfmathresult}{180}% - \pgfmathmod@{\pgfmathresult}{360}% - \fi% - \let\q\pgfmathresult% - \ifdim\x pt=\q pt% Found it! - \pgfmathbreakloop% Breaks after current iteration is complete. - \else - \ifdim\x pt<\q pt\relax% - \let\e\p% - \else% - \let\s\p% - \fi% - \fi% - \pgfmathsubtract@{\x}{\q}% - \pgfmathabs@{\pgfmathresult}% - % - % Save the estimate if it is better than any previous estimate. - % - \ifdim\pgfmathresult pt<\m pt\relax% - \let\m\pgfmathresult% - \let\n\p% - \fi% - \repeatpgfmathloop% - % - % Use the nearest estimate as the anchor angle. - % - \pgfmathadd@{\n}{\arcslope}% - \let\anchorangle\pgfmathresult% - % - % Finally, the required point. - % - \pgfpointadd{\circlecenterpoint}{% - \pgfqpointpolar{\anchorangle}{\outerarcradius}% - }% - \fi% - }% Again, Phew! - % - % Now, a sneaky hack. This means an arbitrary `puff' anchors - % can be used for positiong the cloud shape. This is needed - % if a cloud is positioned using the `puff <n+1>' anchor, where - % n is the number of puffs of any previously drawn cloud. - % - \pgfutil@g@addto@macro\pgf@sh@s@cloud{% - \c@pgf@counta\puffs\relax% - \pgfmathloop% - \ifnum\c@pgf@counta>0\relax% - \pgfutil@ifundefined{pgf@anchor@cloud@puff\space\the\c@pgf@counta}{% - \expandafter\xdef\csname pgf@anchor@cloud@puff\space\the\c@pgf@counta\endcsname{% - \noexpand\pgf@sh@@cloudpuffanchor{\the\c@pgf@counta}% - }% - }{\c@pgf@counta0\relax}% - \advance\c@pgf@counta-1\relax% - \repeatpgfmathloop% - }% + \savedmacro\getradii{% + \pgfmathtruncatemacro\puffs{\pgfkeysvalueof{/pgf/cloud puffs}}% + \addtosavedmacro\puffs% + \pgfmathdivide{360}{\pgfkeysvalueof{/pgf/cloud puffs}}% + \let\anglestep\pgfmathresult% + \addtosavedmacro\anglestep% + \pgfmathsetmacro\arc{\pgfkeysvalueof{/pgf/cloud puff arc}}% + \addtosavedmacro\arc% + % + % x radius. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% + \advance\pgf@x.5\wd\pgfnodeparttextbox% + \pgf@x1.4142135\pgf@x% + % + % y radius. + % + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% + \advance\pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y.5\dp\pgfnodeparttextbox% + \pgf@y1.4142135\pgf@y% + % + % Adjust for shape aspect. + % + \ifpgfcloudignoresaspect% + \pgf@xc\pgf@x% + \pgf@yc\pgf@y% + \else% + \pgf@xc\pgfshapeaspect\pgf@y% + \ifdim\pgf@xc<\pgf@x% + \pgf@xc\pgf@x% + \fi% + \pgf@yc\pgfshapeaspectinverse\pgf@xc% + \ifdim\pgf@yc<\pgf@y% + \pgf@yc\pgf@y% + \pgf@xc\pgfshapeaspect\pgf@y% + \fi% + \fi% + % + \edef\xinnerradius{\the\pgf@xc}% + \edef\yinnerradius{\the\pgf@yc}% + % + % Get the larger of the outer sep. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@x<\pgf@y% + \pgf@x\pgf@y% + \fi% + \edef\outersep{\the\pgf@x}% + \addtosavedmacro\outersep% + % + % For a given cloud, with puff arc length a, the quotient of the + % distance between the start and end point of a puffs circular arc + % and the radius of that arc, is constant: + % + % g = .5 * sec((180-a)/2) + % + \pgfmathsubtract{180}{\arc}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\tempangle\pgfmathresult% + \pgfmathsec@{\pgfmathresult}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\arcradiusquotient\pgfmathresult% + \addtosavedmacro\arcradiusquotient% + % + % In addition, the quotient of the distance between the start and + % end point of a puffs circular arc and the height of that arc + % (ignoring rotation), is also constant: + % + % h = .5 * (1-sin((180-a)/2))/cos((180-a)/2) + % = g * (1 - sin((180-a)/2)) + \pgfmathsin@{\tempangle}% + \pgfmathsubtract@{1}{\pgfmathresult}% + \pgfmathmultiply@{\pgfmathresult}{\arcradiusquotient}% + \let\archeightquotient\pgfmathresult% + \addtosavedmacro\archeightquotient% + % + % Minimum size is applied to the circum-ellipse (i.e. the ellipse + % that passes through the extremeties of each puff). Thus, the + % relationship between the radii of the elliptical incircle ("inellipse"?) + % of the cloud (x and y) and the radii of the circum-ellispe (X and Y), + % is given by + % + % X = 2(x*cos(p/2) + ky) + % Y = 2(y*cos(p/2) + kx) + % + % where: + % k = sin(p/2)*((1-cos(a/2))/sin(a/2)) + % p = the angle between each puff (i.e. 360/<puffs>) + % a = the length of arc of the puff. + % + \pgfmathdivide{\arc}{2}% + \let\halfarcangle\pgfmathresult% + \pgfmathcos@{\pgfmathresult}% + \pgfmathsubtract@{1}{\pgfmathresult}% + \let\pgf@temp\pgfmathresult% + \pgfmathsin@{\halfarcangle}% + \pgfmathdivide@{\pgf@temp}{\pgfmathresult}% + \let\pgf@temp\pgfmathresult% + \pgfmathdivide@{\anglestep}{2}% + \pgfmathsin@{\pgfmathresult}% + \pgfmathmultiply@{\pgfmathresult}{\pgf@temp}% + \let\k\pgfmathresult% + % + \pgfmathdivide@{\anglestep}{2}% + \pgfmathcos@{\pgfmathresult}% + \let\coshalfanglestep\pgfmathresult% + % + % Calculate the actual radii of the circum-ellipse. + % + \pgf@x\xinnerradius\relax% + \pgf@y\yinnerradius\relax% + \pgf@xa\coshalfanglestep\pgf@x% + \advance\pgf@xa\k\pgf@y% + \pgf@ya\coshalfanglestep\pgf@y% + \advance\pgf@ya\k\pgf@x% + % + % Adjust for minimum height (Y'). + % + \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgf@ya<.5\pgf@yb% + \pgf@ya.5\pgf@yb% + \fi% + % + % Adjust for minimum width (X'). + % + \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}% + \ifdim\pgf@xa<.5\pgf@xb% + \pgf@xa.5\pgf@xb% + \fi% + % + \edef\xouterradius{\the\pgf@xa}% + \addtosavedmacro\xouterradius% + \edef\youterradius{\the\pgf@ya}% + \addtosavedmacro\youterradius% + % + % Now recalculate `in-ellispe' radii: + % + % x = (X'cos(p/2)-kY')/cos^2(p/2)-k^2, + % y = (Y'cos(p/2)-kX')/cos^2(p/2)-k^2, + % + \pgf@xc\k pt\relax% + \pgf@xc-\k\pgf@xc% + \pgf@yc\coshalfanglestep pt\relax% + \pgf@yc\coshalfanglestep\pgf@yc% + \advance\pgf@xc\pgf@yc\relax% + \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@xc}}% cos^2(p/2)-k^2 + % + \pgf@x\coshalfanglestep\pgf@xa% + \advance\pgf@x-\k\pgf@ya% + \pgf@x\pgfmathresult\pgf@x% + \pgf@y\coshalfanglestep\pgf@ya% + \advance\pgf@y-\k\pgf@xa% + \pgf@y\pgfmathresult\pgf@y% + % + \edef\xinnerradius{\the\pgf@x}% + \edef\yinnerradius{\the\pgf@y}% + \addtosavedmacro\xinnerradius% + \addtosavedmacro\yinnerradius% + % + % Get some useful trig. constants. + % + \pgfmathdivide@{\arc}{4}% + \let\quarterarc\pgfmathresult% + \pgfmathsubtract@{180}{\arc}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\halfcomplementarc\pgfmathresult% + % + \addtosavedmacro\arc% + \addtosavedmacro\quarterarc% + \addtosavedmacro\halfcomplementarc% + % + \pgfmathsec@{\halfcomplementarc}% 1/cos((180-a)/2) + \let\sechalfcomplementarc\pgfmathresult% + \pgfmathsin@{\halfcomplementarc}% sin((180-a)/2) + \let\sinhalfcomplementarc\pgfmathresult% + % + \addtosavedmacro\sechalfcomplementarc% + \addtosavedmacro\sinhalfcomplementarc% + % + \pgfmathsin@{\quarterarc}% sin(a/4) + \let\sinquarterarc\pgfmathresult% + \pgfmathcos@{\quarterarc}% cos(a/4) + \let\cosquarterarc\pgfmathresult% + \pgfmathreciprocal@{\cosquarterarc}% + \pgfmathmultiply@{\pgfmathresult}{\sinquarterarc}% tan(a/4) + \let\tanquarterarc\pgfmathresult% + % + \addtosavedmacro\sinquarterarc% + \addtosavedmacro\cosquarterarc% + \addtosavedmacro\tanquarterarc% + % + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+.5ex}% + } + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \anchor{center}{\centerpoint} + \anchor{mid}{\midpoint} + \anchor{base}{\basepoint} + \anchor{north}{% + \getradii% + \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{0pt}{\youterradius}}% + }% + \anchor{south}{% + \getradii% + \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{0pt}{-\youterradius}}% + }% + \anchor{east}{% + \getradii% + \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{\xouterradius}{0pt}}% + }% + \anchor{west}{% + \getradii% + \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{-\xouterradius}{0pt}}% + }% + \anchor{north west}{% + \getradii% + \pgfextract@process\pgf@sh{% + \pgf@x\xouterradius\relax% + \pgf@x-0.707106\pgf@x% + \pgf@y\youterradius\relax% + \pgf@y0.707106\pgf@y% + }% + \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}% + }% + \anchor{north east}{% + \getradii% + \pgfextract@process\pgf@sh{% + \pgf@x\xouterradius\relax% + \pgf@x0.707106\pgf@x% + \pgf@y\youterradius\relax% + \pgf@y0.707106\pgf@y% + }% + \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}% + }% + \anchor{south west}{% + \getradii% + \pgfextract@process\pgf@sh{% + \pgf@x\xouterradius\relax% + \pgf@x-0.707106\pgf@x% + \pgf@y\youterradius\relax% + \pgf@y-0.707106\pgf@y% + }% + \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}% + }% + \anchor{south east}{% + \getradii% + \pgfextract@process\pgf@sh{% + \pgf@x\xouterradius\relax% + \pgf@x0.707106\pgf@x% + \pgf@y\youterradius\relax% + \pgf@y-0.707106\pgf@y% + }% + \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}% + }% + % + % Each `puff' is a circular arc of length a, drawn using two a/2 + % arcs (a < 180), approximated by Bezier curves. + % Due to TeX rounding errors, it is sometimes necessary to `force' + % the arc to end at a specific point. So... + % + % @article{riskus2006, + % author = {Aleskus Ri\v{s}kus}, + % title = {Approximation of a cubic Bezier curve by circular arcs and vice versa}, + % journal = {Information Technology and Control}, + % year = {2006}, + % volume = {35}, + % number = {4} + % } + % + \backgroundpath{% + {% + \getradii% + % + % Get the start angle. + % + \pgfmathdivide@{\anglestep}{2}% + \pgfmathsubtract@{90}{\pgfmathresult}% + \let\angle\pgfmathresult% + % + % Calculate the first arc point. + % + \pgfextract@process\arcfirstpoint{% + \pgfpointadd{\centerpoint}{% + \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}% + }% + }% + \pgfpathmoveto{\arcfirstpoint}% + \let\arcendpoint\arcfirstpoint% + % + \pgfmathloop% + \ifnum\pgfmathcounter>\puffs\relax% + \else + \let\arcstartpoint\arcendpoint% + % + % Make sure beginning and end of path are exactly the same. + % + \ifnum\pgfmathcounter=\puffs\relax% + \let\arcendpoint\arcfirstpoint% + \else% + \pgfmathadd@{\angle}{\anglestep}% + \let\angle\pgfmathresult% + \pgfextract@process\arcendpoint{% + \pgfpointadd{\centerpoint}{% + \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}% + }% + }% + \fi% + % + % Get some useful cloud parameters from \arcstartpoint and \arcendpoint. + % + \pgf@sh@getcloudpuffparameters% + % + % Get the rotation for the Bezier curve. + % + \pgfmathsubtract@{90}{\quarterarc}% + \pgfmathadd@{\pgfmathresult}{\arcslope}% + \let\arcrotate\pgfmathresult% + \pgfmathsin@{\arcrotate}% + \let\sinarcrotate\pgfmathresult% + \pgfmathcos@{\arcrotate}% + \let\cosarcrotate\pgfmathresult% + % + % Calculate the amount by which to scale the control + % points, in order to approximate an a/2 arc with radius x. + % + \pgf@x\arcradius\relax% + \pgf@x\tanquarterarc\pgf@x% tan(a/4) + \edef\controlscale{\pgfmath@tonumber{\pgf@x}}% + % + % Get the first control point for the first arc (length a/2)... + % + \pgfextract@process\controlone{% + % + % k = 0.552284745 (a `magic' number)... + % + \pgf@x0.55228475pt\relax% + \pgf@x\sinquarterarc\pgf@x% k * sin(a/2) + \pgf@y0.55228475pt\relax% + \pgf@y\cosquarterarc\pgf@y% k * cos(a/2) + % + % ...scale the control points up... + % + \pgf@x\controlscale\pgf@x% + \pgf@y\controlscale\pgf@y% + % + % ...rotate... + % + \pgf@xa\cosarcrotate\pgf@x% + \advance\pgf@xa-\sinarcrotate\pgf@y% + \pgf@ya\cosarcrotate\pgf@y% + \advance\pgf@ya\sinarcrotate\pgf@x% + % + % ...and shift. + % + \arcstartpoint% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + % + % Get the midpoint of the 150� arc. + % + \pgfextract@process\arcmidpoint{% + \pgfextract@process\arcmidpoint{% + \pgf@x-\halfchordlength\relax% + \pgf@y\segmentheight\relax% + }% + \pgfpointadd{\arcstartpoint}{% + \pgfmathrotatepointaround{\arcmidpoint}{\pgfpointorigin}{\arcslope}% + }% + }% + % + % Get the second control point for the first arc (length a/2)... + % + \pgfextract@process\controltwo{% + \pgf@x0.55228475pt\relax% + \pgf@x\sinquarterarc\pgf@x% k * sin(a/2) + \pgf@y-0.55228475pt\relax% + \pgf@y\cosquarterarc\pgf@y% -k * cos(a/2) + % + % ...scale, rotate and shift. + % + \pgf@x\controlscale\pgf@x% + \pgf@y\controlscale\pgf@y% + % + \pgf@xa\cosarcrotate\pgf@x% + \advance\pgf@xa-\sinarcrotate\pgf@y% + \pgf@ya\cosarcrotate\pgf@y% + \advance\pgf@ya\sinarcrotate\pgf@x% + % + \arcmidpoint% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + {% + \pgfsetcornersarced{\pgfpointorigin}% + \pgfpathcurveto{\controlone}{\controltwo}{\arcmidpoint}% + }% + % + % Do the same for the second arc... + % + \pgfmathadd@{\quarterarc}{90}% + \pgfmathadd@{\pgfmathresult}{\arcslope}% + \let\arcrotate\pgfmathresult% + \pgfmathsin@{\arcrotate}% + \let\sinarcrotate\pgfmathresult% + \pgfmathcos@{\arcrotate}% + \let\cosarcrotate\pgfmathresult% + % + % First control point for the second arc... + % + \pgfextract@process\controlone{% + \pgf@x0.55228475pt\relax% + \pgf@x\sinquarterarc\pgf@x% k * sin(a/2) + \pgf@y0.55228475pt\relax% + \pgf@y\cosquarterarc\pgf@y% k * cos(a/2) + % + % ...scale, rotate and shift. + % + \pgf@x\controlscale\pgf@x% + \pgf@y\controlscale\pgf@y% + % + \pgf@xa\cosarcrotate\pgf@x% + \advance\pgf@xa-\sinarcrotate\pgf@y% + \pgf@ya\cosarcrotate\pgf@y% + \advance\pgf@ya\sinarcrotate\pgf@x% + % + \arcmidpoint% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + % + % Second control point for the second arc. + % + \pgfextract@process\controltwo{% + \pgf@x0.55228475pt\relax% + \pgf@x\sinquarterarc\pgf@x% k * sin(a/2) + \pgf@y-0.55228475pt\relax% + \pgf@y\cosquarterarc\pgf@y% -k * cos(a/2) + % + % ...scale, rotate and shift. + % + \pgf@x\controlscale\pgf@x% + \pgf@y\controlscale\pgf@y% + % + \pgf@xa\cosarcrotate\pgf@x% + \advance\pgf@xa-\sinarcrotate\pgf@y% + \pgf@ya\cosarcrotate\pgf@y% + \advance\pgf@ya\sinarcrotate\pgf@x% + % + \arcendpoint% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + \pgfpathcurveto{\controlone}{\controltwo}{\arcendpoint}% + \repeatpgfmathloop% + \pgfpathclose% Phew! + }% + }% + % + % Calculate a point on the border of the cloud. This is a two-stage process: + % + % 1. Locate the correct puff. + % 2. Locate the angle on the circular arc which forms the puff. + % + \anchorborder{% + % + % Save x and y. + % + \edef\externalx{\the\pgf@x}% + \edef\externaly{\the\pgf@y}% + % + % Get the inner radii and trig. constants. + % + \getradii% + % + % + % + \ifpgfcloudanchorsuseellipse% + \pgfpointadd{\centerpoint}{% + \pgfpointborderellipse{% + \pgfpoint{\externalx}{\externaly} + }{% + \pgfpoint{\xouterradius}{\youterradius} + }% + }% + \else% + \pgfextract@process\externalpoint{% + \centerpoint% + \advance\pgf@x\externalx\relax% + \advance\pgf@y\externaly\relax% + }% + \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}% + \let\externalangle\pgfmathresult% + % + % 1. Locate the correct puff: + % + % Get end angle of the relavent puff arc. + % + \pgfmathdivide@{\anglestep}{2}% + \let\halfanglestep\pgfmathresult% + \pgfmathsubtract@{90}{\halfanglestep}% + \let\endangle\pgfmathresult% + \pgfmathloop% + \pgfmathsubtract@{\endangle}{\anglestep}% + \ifdim\pgfmathresult pt<-\anglestep pt\relax% + \else% + \let\endangle\pgfmathresult% + \repeatpgfmathloop% + \def\angle{0}% + \let\lastangle\angle% + \pgfmathloop% + \pgfmathadd@{\endangle}{\anglestep}% + \let\endangle\pgfmathresult% + % + % Calculate the `miter point'. This is the point between + % each puff, and takes into account the outer sep. + % + \pgfextract@process\miterpoint{% + % + \pgfextract@process\secondpoint{% + \pgfpointpolar{+\endangle}{+\xinnerradius and +\yinnerradius}% + }% + % + \pgfmathadd@{\endangle}{\anglestep}% + \let\angletemp\pgfmathresult% + \pgfextract@process\thirdpoint{% + \pgfpointpolar{+\angletemp}{+\xinnerradius and +\yinnerradius}% + }% + % + \pgfmathsubtract@{\endangle}{\anglestep}% + \let\angletemp\pgfmathresult% + \pgfextract@process\firstpoint{% + \pgfpointpolar{+\angletemp}{+\xinnerradius and +\yinnerradius}% + }% + % + \pgfmathanglebetweenpoints{\firstpoint}{\secondpoint}% + \let\anglealpha\pgfmathresult% + \pgfmathanglebetweenpoints{\secondpoint}{\thirdpoint}% + \let\anglebeta\pgfmathresult% + % + \pgfmathsubtract@{\anglebeta}{\anglealpha}% + \pgfmathdivide@{\pgfmathresult}{2}% + \pgfmathadd@{\pgfmathresult}{\halfcomplementarc}% + \pgfmathcosec@{\pgfmathresult}% + \pgf@x\outersep\relax% + \pgf@x\pgfmathresult\pgf@x% + \edef\miterradius{\the\pgf@x}% + % + \pgfmathadd@{\anglealpha}{\anglebeta}% + \pgfmathsubtract@{\pgfmathresult}{180}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\miterangle\pgfmathresult% + \pgfpointadd{\secondpoint}{% + \pgfqpointpolar{\miterangle}{\miterradius}% + }% + }% + % + % Get the angle of the miter point... + % + \pgfmathanglebetweenpoints{\pgfpointorigin}{\miterpoint}% + \let\angle\pgfmathresult% + \ifdim\angle pt<\lastangle pt\relax% Guard against 360� = 0� + \pgfmathadd@{\angle}{360}% + \let\angle\pgfmathresult% + \fi% + \let\lastangle\angle% + % + % ...and see if it is greater than the external point. + % + \ifdim\externalangle pt>\angle pt\relax% + \repeatpgfmathloop% + % + % Get the start angle of the relevant arc and ensure angles are in the range. + % + \pgfmathmod@{\endangle}{360}% + \let\endangle\pgfmathresult% + \pgfmathsubtract@{\endangle}{\anglestep}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\startangle\pgfmathresult% + % + % Now, get the start and end points of the arc. + % + \pgfextract@process\arcstartpoint{% + \pgfpointadd{\centerpoint}{% + \pgfpointpolar{+\startangle}{+\xinnerradius and +\yinnerradius}% + }% + }% + \pgfextract@process\arcendpoint{% + \pgfpointadd{\centerpoint}{% + \pgfpointpolar{+\endangle}{+\xinnerradius and +\yinnerradius}% + }% + }% + % + % Get some useful cloud parameters from \arcstartpoint and \arcendpoint. + % + \pgf@sh@getcloudpuffparameters% + % + % Hackery, for when an arc straddles 0�. + % + \ifdim\endangle pt<\startangle pt\relax% + \pgfmathadd@{\externalangle}{180}% + \pgfmathmod@{\pgfmathresult}{360}% + \let\x\pgfmathresult% + \else% + \let\x\externalangle% + \fi% + % + % 2. Locate the angle on the circular arc which forms the puff. + % + % Essentially a binary search to find the angle on the circular + % arc, which provides the nearset estimate to the border point. + % + \let\s\halfcomplementarc% The start of the arc. + \pgfmathadd@{\s}{\arc}% + \let\e\pgfmathresult% The end of the arc. + \pgfmathadd@{\e}{\s}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\n\pgfmathresult% The nearest estimate (default to middle of arc). + \def\m{360}% Measure of `nearness'. + \pgfmathloop% + \pgfmathadd@{\e}{\s}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\p\pgfmathresult% The point halfway between \s and \e. + \ifdim\p pt=\s pt\relax% + \else% + % + % Get the point on the circular arc. + % + \pgfmathadd@{\p}{\arcslope}% + \let\a\pgfmathresult% + \pgfextract@process\arcpoint{% + \pgfpointadd{\circlecenterpoint}{% + \pgfqpointpolar{\a}{\outerarcradius}% + }% + }% + % + % Find the angle between the node centre and the point on the arc. + % + \pgfmathanglebetweenpoints{\centerpoint}{\arcpoint}% + % + % Hackery, for when an arc straddles 0�. + % + \ifdim\endangle pt<\startangle pt\relax% + \pgfmathadd@{\pgfmathresult}{180}% + \pgfmathmod@{\pgfmathresult}{360}% + \fi% + \let\q\pgfmathresult% + \ifdim\x pt=\q pt% Found it! + \pgfmathbreakloop% Breaks after current iteration is complete. + \else + \ifdim\x pt<\q pt\relax% + \let\e\p% + \else% + \let\s\p% + \fi% + \fi% + \pgfmathsubtract@{\x}{\q}% + \pgfmathabs@{\pgfmathresult}% + % + % Save the estimate if it is better than any previous estimate. + % + \ifdim\pgfmathresult pt<\m pt\relax% + \let\m\pgfmathresult% + \let\n\p% + \fi% + \repeatpgfmathloop% + % + % Use the nearest estimate as the anchor angle. + % + \pgfmathadd@{\n}{\arcslope}% + \let\anchorangle\pgfmathresult% + % + % Finally, the required point. + % + \pgfpointadd{\circlecenterpoint}{% + \pgfqpointpolar{\anchorangle}{\outerarcradius}% + }% + \fi% + }% Again, Phew! + % + % Now, a sneaky hack. This means an arbitrary `puff' anchors + % can be used for positiong the cloud shape. This is needed + % if a cloud is positioned using the `puff <n+1>' anchor, where + % n is the number of puffs of any previously drawn cloud. + % + \pgfutil@g@addto@macro\pgf@sh@s@cloud{% + \c@pgf@counta\puffs\relax% + \pgfmathloop% + \ifnum\c@pgf@counta>0\relax% + \pgfutil@ifundefined{pgf@anchor@cloud@puff\space\the\c@pgf@counta}{% + \expandafter\xdef\csname pgf@anchor@cloud@puff\space\the\c@pgf@counta\endcsname{% + \noexpand\pgf@sh@@cloudpuffanchor{\the\c@pgf@counta}% + }% + }{\c@pgf@counta0\relax}% + \advance\c@pgf@counta-1\relax% + \repeatpgfmathloop% + }% } % \pgf@sh@@cloudpuffanchor @@ -1286,43 +1328,43 @@ % Internal macro for calculating the anchors puff 1, puff 2, ... etc. % \def\pgf@sh@@cloudpuffanchor#1{% - \getradii% - \pgfmathdivide@{\anglestep}{2}% - \let\halfanglestep\pgfmathresult% - \c@pgf@counta#1\relax% - \advance\c@pgf@counta-1\relax% - \pgfmathmultiply@{\anglestep}{\the\c@pgf@counta}% - \pgfmathadd@{\pgfmathresult}{90}% - \pgfmathsubtract@{\pgfmathresult}{\halfanglestep}% - \let\angle\pgfmathresult% - % - % Calculate the first arc point. - % - \pgfextract@process\arcstartpoint{% - \pgfpointadd{\centerpoint}{% - \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}% - }% - }% - % - \pgfmathadd@{\angle}{\anglestep}% - \let\angle\pgfmathresult% - \pgfextract@process\arcendpoint{% - \pgfpointadd{\centerpoint}{% - \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}% - }% - }% - % - % Get some useful cloud parameters from \arcstartpoint and \arcendpoint. - % - \pgf@sh@getcloudpuffparameters% - % - % Calculate the point. - % - \pgfmathadd@{\arcslope}{90}% - \let\anchorangle\pgfmathresult% - \pgfpointadd{\circlecenterpoint}{% - \pgfqpointpolar{\anchorangle}{\outerarcradius}% - }% + \getradii% + \pgfmathdivide@{\anglestep}{2}% + \let\halfanglestep\pgfmathresult% + \c@pgf@counta#1\relax% + \advance\c@pgf@counta-1\relax% + \pgfmathmultiply@{\anglestep}{\the\c@pgf@counta}% + \pgfmathadd@{\pgfmathresult}{90}% + \pgfmathsubtract@{\pgfmathresult}{\halfanglestep}% + \let\angle\pgfmathresult% + % + % Calculate the first arc point. + % + \pgfextract@process\arcstartpoint{% + \pgfpointadd{\centerpoint}{% + \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}% + }% + }% + % + \pgfmathadd@{\angle}{\anglestep}% + \let\angle\pgfmathresult% + \pgfextract@process\arcendpoint{% + \pgfpointadd{\centerpoint}{% + \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}% + }% + }% + % + % Get some useful cloud parameters from \arcstartpoint and \arcendpoint. + % + \pgf@sh@getcloudpuffparameters% + % + % Calculate the point. + % + \pgfmathadd@{\arcslope}{90}% + \let\anchorangle\pgfmathresult% + \pgfpointadd{\circlecenterpoint}{% + \pgfqpointpolar{\anchorangle}{\outerarcradius}% + }% } % \pgf@sh@cloudpuffparameters @@ -1333,11 +1375,11 @@ % \def\pgf@sh@getcloudpuffparameters{% % - % Calculate the angle to which the entire arc is sloped. - % - \pgfmathanglebetweenpoints{\arcendpoint}{\arcstartpoint}% - \let\arcslope\pgfmathresult% - % + % Calculate the angle to which the entire arc is sloped. + % + \pgfmathanglebetweenpoints{\arcendpoint}{\arcstartpoint}% + \let\arcslope\pgfmathresult% + % % Calculate the chord length and arc radius. % \pgfpointdiff{\arcendpoint}{\arcstartpoint}% @@ -1345,7 +1387,7 @@ \pgf@x\pgfmathresult pt\relax% \pgf@xa.5\pgf@x% \edef\halfchordlength{\the\pgf@xa}% - \pgf@x\arcradiusquotient\pgf@x% + \pgf@x\arcradiusquotient\pgf@x% \edef\arcradius{\the\pgf@x}% \pgf@xa\outersep\relax% \advance\pgf@xa\pgf@x% @@ -1382,671 +1424,671 @@ \def\pgf@lib@sh@signal@to{to}% \def\pgf@lib@sh@signal@parsedirection#1#2{% - % - \let\pgf@lib@sh@signal@direction=#2% - \edef\pgf@lib@sh@temp{#1}% - \expandafter\pgf@lib@sh@signal@@parsedirection\pgf@lib@sh@temp\pgf@stop} + % + \let\pgf@lib@sh@signal@direction=#2% + \edef\pgf@lib@sh@temp{#1}% + \expandafter\pgf@lib@sh@signal@@parsedirection\pgf@lib@sh@temp\pgf@stop} \def\pgf@lib@sh@signal@@parsedirection#1\pgf@stop{% - \pgfutil@in@{and}{#1}% - \ifpgfutil@in@% - \pgf@lib@sh@signal@@@parsedirection#1\pgf@lib% - \else% - \pgf@lib@sh@signal@@@parsedirection#1 and #1\pgf@lib% - \fi + \pgfutil@in@{and}{#1}% + \ifpgfutil@in@% + \pgf@lib@sh@signal@@@parsedirection#1\pgf@lib% + \else% + \pgf@lib@sh@signal@@@parsedirection#1 and #1\pgf@lib% + \fi } \def\pgf@lib@sh@signal@@@parsedirection#1 and #2\pgf@lib{% - \pgfutil@in@{nowhere}{#1}% - \ifpgfutil@in@ - \else% - \pgf@lib@sh@signal@@@@parsedirection{#1}% - \pgf@lib@sh@signal@@@@parsedirection{#2}% - \fi% + \pgfutil@in@{nowhere}{#1}% + \ifpgfutil@in@ + \else% + \pgf@lib@sh@signal@@@@parsedirection{#1}% + \pgf@lib@sh@signal@@@@parsedirection{#2}% + \fi% } \def\pgf@lib@sh@signal@@@@parsedirection#1{% - \pgfutil@in@{ #1 }{ east right }% - \ifpgfutil@in@% - \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@direction% - \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@nowhere% - \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@nowhere% - \fi% - \pgfutil@in@{ #1 }{ left west }% - \ifpgfutil@in@% - \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@direction% - \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@nowhere% - \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@nowhere% - \fi% - \pgfutil@in@{ #1 }{ above up north }% - \ifpgfutil@in@% - \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@direction% - \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@nowhere% - \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@nowhere% - \fi% - \pgfutil@in@{ #1 }{ below down south }% - \ifpgfutil@in@% - \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@direction% - \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@nowhere% - \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@nowhere% - \fi% + \pgfutil@in@{ #1 }{ east right }% + \ifpgfutil@in@% + \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@direction% + \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@nowhere% + \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@nowhere% + \fi% + \pgfutil@in@{ #1 }{ left west }% + \ifpgfutil@in@% + \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@direction% + \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@nowhere% + \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@nowhere% + \fi% + \pgfutil@in@{ #1 }{ above up north }% + \ifpgfutil@in@% + \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@direction% + \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@nowhere% + \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@nowhere% + \fi% + \pgfutil@in@{ #1 }{ below down south }% + \ifpgfutil@in@% + \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@direction% + \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@nowhere% + \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@nowhere% + \fi% } % Keys for signal shape: % \pgfkeys{/pgf/.cd, - signal pointer angle/.initial=90, - signal to/.initial=east, - signal from/.initial=nowhere + signal pointer angle/.initial=90, + signal to/.initial=east, + signal from/.initial=nowhere } \pgfdeclareshape{signal}{% - \savedmacro\installsignalparameters{% - % - \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@nowhere% - \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@nowhere% - \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@nowhere% - \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@nowhere% - % - \pgf@lib@sh@signal@parsedirection{\pgfkeysvalueof{/pgf/signal from}}{\pgf@lib@sh@signal@from}% - \pgf@lib@sh@signal@parsedirection{\pgfkeysvalueof{/pgf/signal to}}{\pgf@lib@sh@signal@to}% - % - % Define a centerpoint. - % - \pgfextract@process\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - }% - % - % Get some useful trig. stuff - % - \pgfmathsetmacro\pointerangle{\pgfkeysvalueof{/pgf/signal pointer angle}}% - % - \pgfmathdivide@{\pointerangle}{2}% - \let\halfpointerangle=\pgfmathresult% - % - \pgfmathcosec@{\halfpointerangle}% - \let\cosechalfpointerangle=\pgfmathresult% - % - \pgfmathdivide@{\halfpointerangle}{2}% - \let\quarterpointerangle=\pgfmathresult% - % - \pgfmathcosec@{\quarterpointerangle}% - \let\cosecquarterpointerangle=\pgfmathresult% - % - \pgfmathsec@{\quarterpointerangle}% - \let\secquarterpointerangle=\pgfmathresult% - % - \pgfmathsubtract@{90}{\quarterpointerangle}% - \let\complementquarterpointerangle\pgfmathresult% - % - % Get the larger of the outer sep. - % - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}% - \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}% - \ifdim\pgf@x>\pgf@y% - \pgf@y\pgf@x% - \fi% - \pgf@yc=\pgf@y% - % - % Calculate the miter due to the line width, at the pointer apex... - % - \pgf@x=\cosechalfpointerangle\pgf@y% - \edef\pointerapexmiter{\the\pgf@x}% - % - % ...at a corner by a `to' pointer (i.e. sticks out)... - % - \pgf@x=\secquarterpointerangle\pgf@y% - \edef\tocornermiter{\the\pgf@x}% - % - % ...at a corner by a `from' pointer (i.e. sticks in). - % - \pgf@x=\cosecquarterpointerangle\pgf@y - \edef\fromcornermiter{\the\pgf@x}% - % - % Get the (half) dimensions of the node. - % - \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}% - \advance\pgf@xa.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}% - \advance\pgf@ya.5\ht\pgfnodeparttextbox% - \advance\pgf@ya.5\dp\pgfnodeparttextbox% - % - % Get the distance a pointer sticks out to the side... - % - \pgfmathsubtract@{90}{\halfpointerangle}% - \pgfmathtan@{\pgfmathresult}% - \pgf@xb=\pgfmathresult\pgf@ya% - % - % ...and up. - % - \pgf@yb=\pgfmathresult\pgf@xa% - % - % Adjust for minimum height. - % - \pgfutil@tempdima=2.0\pgf@ya% - \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@nowhere% - \else% - \advance\pgfutil@tempdima by\pgf@yb% - \fi% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@nowhere% - \else% - \advance\pgfutil@tempdima by\pgf@yb% - \fi% - \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/minimum height}}% - \ifdim\pgfutil@tempdima<\pgf@y% - \pgfutil@tempdima=\pgf@y% - % - \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@nowhere% - \else% - \advance\pgfutil@tempdima by-\pgf@yb% - \fi% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@nowhere% - \else% - \advance\pgfutil@tempdima by-\pgf@yb% - \fi% - \pgf@ya=0.5\pgfutil@tempdima% - \pgfmathsubtract@{90}{\halfpointerangle}% - \pgfmathtan@{\pgfmathresult}% - \pgf@xb=\pgfmathresult\pgf@ya% - \fi% - % - % Adjust for minimum width. - % - \pgfutil@tempdima=2.0\pgf@xa% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% - \else% - \advance\pgfutil@tempdima by\pgf@xb% - \fi% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% - \else% - \advance\pgfutil@tempdima by\pgf@xb% - \fi% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/minimum width}}% - \ifdim\pgfutil@tempdima<\pgf@x% - \pgfutil@tempdima=\pgf@x% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% - \else% - \advance\pgfutil@tempdima by-\pgf@xb% - \fi% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% - \else% - \advance\pgfutil@tempdima by-\pgf@xb% - \fi% - \pgf@xa=0.5\pgfutil@tempdima% - \pgfmathsubtract@{90}{\halfpointerangle}% - \pgfmathtan@{\pgfmathresult}% - \pgf@yb=\pgfmathresult\pgf@xa% - \fi% - % - % So, define the points for the background path. - % - \pgfextract@process\north{% - \centerpoint% - \advance\pgf@y\pgf@ya% - \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@to% - \advance\pgf@y\pgf@yb% - \fi% - }% - \pgfextract@process\south{% - \centerpoint% - \advance\pgf@y-\pgf@ya% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@to% - \advance\pgf@y-\pgf@yb% - \fi% - }% - \pgfextract@process\east{% - \centerpoint% - \advance\pgf@x\pgf@xa% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@to% - \advance\pgf@x\pgf@xb% - \fi% - }% - \pgfextract@process\west{% - \centerpoint% - \advance\pgf@x-\pgf@xa% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to% - \advance\pgf@x-\pgf@xb% - \fi% - }% - \pgfextract@process\northeast{% - \centerpoint% - \advance\pgf@y\pgf@ya% - \advance\pgf@x\pgf@xa% - \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from% - \advance\pgf@y\pgf@yb% - \fi% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from% - \advance\pgf@x\pgf@xb% - \fi% - }% - \pgfextract@process\southeast{% - \centerpoint% - \advance\pgf@y-\pgf@ya% - \advance\pgf@x\pgf@xa% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from% - \advance\pgf@y-\pgf@yb% - \fi% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from% - \advance\pgf@x\pgf@xb% - \fi% - }% - \pgfextract@process\southwest{% - \centerpoint% - \advance\pgf@y-\pgf@ya% - \advance\pgf@x-\pgf@xa% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from% - \advance\pgf@y-\pgf@yb% - \fi% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from% - \advance\pgf@x-\pgf@xb% - \fi% - }% - \pgfextract@process\northwest{% - \centerpoint% - \advance\pgf@y\pgf@ya% - \advance\pgf@x-\pgf@xa% - \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from% - \advance\pgf@y\pgf@yb% - \fi% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from% - \advance\pgf@x-\pgf@xb% - \fi% - }% - \addtosavedmacro{\north}% - \addtosavedmacro{\south}% - \addtosavedmacro{\east}% - \addtosavedmacro{\west}% - \addtosavedmacro{\northeast}% - \addtosavedmacro{\southwest}% - \addtosavedmacro{\southeast}% - \addtosavedmacro{\northwest}% - % - % Calculate the `miter vectors' (i.e. +outer sep). - % - \pgfextract@process\northmiter{% - \pgf@x0pt% - \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@nowhere% - \pgf@y\pgf@yc% - \else% - \pgf@y\pointerapexmiter\relax% - \fi% - }% - \pgfextract@process\southmiter{% - \pgf@x0pt% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@nowhere% - \pgf@y-\pgf@yc% - \else% - \pgf@y-\pointerapexmiter\relax% - \fi% - }% - \pgfextract@process\eastmiter{% - \pgf@y0pt% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% - \pgf@x\pgf@yc% - \else% - \pgf@x\pointerapexmiter\relax% - \fi% - }% - \pgfextract@process\westmiter{% - \pgf@y0pt% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% - \pgf@x-\pgf@yc% - \else% - \pgf@x-\pointerapexmiter\relax% - \fi% - }% - \pgfextract@process\northeastmiter{% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% - \pgf@x\pgf@yc - \pgf@y\pgf@yc% - \else - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from% - \pgfqpointpolar{\quarterpointerangle}{\fromcornermiter} - \else% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@to% - \pgfqpointpolar{\complementquarterpointerangle}{\tocornermiter}% - \fi% - \fi% - \fi% - \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from% - \pgfqpointpolar{\complementquarterpointerangle}{\fromcornermiter}% - \else% - \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@to% - \pgfqpointpolar{\quarterpointerangle}{\tocornermiter}% - \fi% - \fi% - }% - \pgfextract@process\southeastmiter{% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% - \pgf@x\pgf@yc% - \pgf@y\pgf@yc% - \else - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from% - \pgfqpointpolar{-\quarterpointerangle}{\fromcornermiter} - \else% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@to% - \pgfqpointpolar{-\complementquarterpointerangle}{\tocornermiter}% - \fi% - \fi% - \fi% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from% - \pgfqpointpolar{-\complementquarterpointerangle}{\fromcornermiter} - \else% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@to% - \pgfqpointpolar{-\quarterpointerangle}{\tocornermiter}% - \fi% - \fi% - }% - \pgfextract@process\southwestmiter{% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% - \pgf@x-\pgf@yc - \pgf@y-\pgf@yc% - \else - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from% - \pgfmathadd@{\quarterpointerangle}{180}% - \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter} - \else% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to% - \pgfmathadd@{\complementquarterpointerangle}{180}% - \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}% - \fi% - \fi% - \fi% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from% - \pgfmathadd@{\complementquarterpointerangle}{180}% - \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter}% - \else% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@to% - \pgfmathadd@{\quarterpointerangle}{180}% - \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}% - \fi% - \fi% - }% - \pgfextract@process\northwestmiter{% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% - \pgf@x-\pgf@yc% - \pgf@y\pgf@yc% - \else - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from% - \pgfmathsubtract@{180}{\quarterpointerangle}% - \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter} - \else% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to% - \pgfmathsubtract@{180}{\complementquarterpointerangle}% - \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}% - \fi% - \fi% - \fi% - \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from% - \pgfmathsubtract@{180}{\complementquarterpointerangle}% - \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter}% - \else% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to% - \pgfmathsubtract@{180}{\quarterpointerangle}% - \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}% - \fi% - \fi% - }% - \addtosavedmacro{\northmiter}% - \addtosavedmacro{\southmiter}% - \addtosavedmacro{\eastmiter}% - \addtosavedmacro{\westmiter}% - \addtosavedmacro{\northeastmiter}% - \addtosavedmacro{\southeastmiter}% - \addtosavedmacro{\southwestmiter}% - \addtosavedmacro{\northwestmiter}% - % - % Now calculate the anchor points - % - \pgfextract@process\anchornorth{% - \pgfpointadd{\north}{\northmiter}% - }% - \pgfextract@process\anchorsouth{% - \pgfpointadd{\south}{\southmiter}% - }% - \pgfextract@process\anchoreast{% - \pgfpointadd{\east}{\eastmiter}% - }% - \pgfextract@process\anchorwest{% - \pgfpointadd{\west}{\westmiter}% - }% - \pgfextract@process\anchornortheast{% - \pgfpointadd{\northeast}{\northeastmiter}% - }% - \pgfextract@process\anchorsoutheast{% - \pgfpointadd{\southeast}{\southeastmiter}% - }% - \pgfextract@process\anchorsouthwest{% - \pgfpointadd{\southwest}{\southwestmiter}% - }% - \pgfextract@process\anchornorthwest{% - \pgfpointadd{\northwest}{\northwestmiter}% - }% - \addtosavedmacro{\anchornorth}% - \addtosavedmacro{\anchorsouth}% - \addtosavedmacro{\anchoreast}% - \addtosavedmacro{\anchorwest}% - \addtosavedmacro{\anchornortheast}% - \addtosavedmacro{\anchorsouthwest}% - \addtosavedmacro{\anchorsoutheast}% - \addtosavedmacro{\anchornorthwest}% - }% - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - }% - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - }% - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+.5ex}% - }% - \anchor{center}{\centerpoint}% - \anchor{base}{\basepoint}% - \anchor{base east}{% - \installsignalparameters% - \anchoreast% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \anchorsoutheast% - \ifdim\pgf@xa>\pgf@x% - \pgfutil@tempdima\pgf@xa% - \else% - \pgfutil@tempdima\pgf@x% - \fi% - \pgfextract@process\externalpoint{% - \basepoint% - \pgf@x\pgfutil@tempdima% - } - \basepoint% - \let\firstpoint\anchoreast% - \ifdim\pgf@y<\pgf@ya% - \let\secondpoint\anchorsoutheast% - \else% - \let\secondpoint\anchornortheast% - \fi% - \pgfpointintersectionoflines{\basepoint}{\externalpoint}% - {\firstpoint}{\secondpoint}% - }% - \anchor{base west}{% - \installsignalparameters% - \anchorwest% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \anchorsouthwest% - \ifdim\pgf@xa<\pgf@x% - \pgfutil@tempdima\pgf@xa% - \else% - \pgfutil@tempdima\pgf@x% - \fi% - \pgfextract@process\externalpoint{% - \basepoint% - \pgf@x\pgfutil@tempdima% - } - \basepoint% - \let\firstpoint\anchorwest% - \ifdim\pgf@y<\pgf@ya% - \let\secondpoint\anchorsouthwest% - \else% - \let\secondpoint\anchornorthwest% - \fi% - \pgfpointintersectionoflines{\basepoint}{\externalpoint}% - {\firstpoint}{\secondpoint}% - }% - \anchor{mid}{\midpoint}% - \anchor{mid east}{% - \installsignalparameters% - \anchoreast% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \anchorsoutheast% - \ifdim\pgf@xa>\pgf@x% - \pgfutil@tempdima\pgf@xa% - \else% - \pgfutil@tempdima\pgf@x% - \fi% - \pgfextract@process\externalpoint{% - \midpoint% - \pgf@x\pgfutil@tempdima% - } - \midpoint% - \let\firstpoint\anchoreast% - \ifdim\pgf@y<\pgf@ya% - \let\secondpoint\anchorsoutheast% - \else% - \let\secondpoint\anchornortheast% - \fi% - \pgfpointintersectionoflines{\midpoint}{\externalpoint}% - {\firstpoint}{\secondpoint}% - }% - \anchor{mid west}{% - \installsignalparameters% - \anchorwest% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \anchorsouthwest% - \ifdim\pgf@xa<\pgf@x% - \pgfutil@tempdima\pgf@xa% - \else% - \pgfutil@tempdima\pgf@x% - \fi% - \pgfextract@process\externalpoint{% - \midpoint% - \pgf@x\pgfutil@tempdima% - } - \midpoint% - \let\firstpoint\anchorwest% - \ifdim\pgf@y<\pgf@ya% - \let\secondpoint\anchorsouthwest% - \else% - \let\secondpoint\anchornorthwest% - \fi% - \pgfpointintersectionoflines{\midpoint}{\externalpoint}% - {\firstpoint}{\secondpoint}% - }% - \anchor{north}{\installsignalparameters\anchornorth}% - \anchor{south}{\installsignalparameters\anchorsouth}% - \anchor{east}{\installsignalparameters\anchoreast}% - \anchor{west}{\installsignalparameters\anchorwest}% - \anchor{north east}{\installsignalparameters\anchornortheast}% - \anchor{south east}{\installsignalparameters\anchorsoutheast}% - \anchor{south west}{\installsignalparameters\anchorsouthwest}% - \anchor{north west}{\installsignalparameters\anchornorthwest}% - \backgroundpath{% - \installsignalparameters% - \pgfpathmoveto{\north}% - \pgfpathlineto{\northeast}% - \pgfpathlineto{\east}% - \pgfpathlineto{\southeast}% - \pgfpathlineto{\south}% - \pgfpathlineto{\southwest}% - \pgfpathlineto{\west}% - \pgfpathlineto{\northwest}% - \pgfpathclose% - } - \anchorborder{% - % - % Save x and y. - % - \edef\externalx{\the\pgf@x}% - \edef\externaly{\the\pgf@y}% - % - % Adjust the location of the external - % point relative to \centerpoint. - % - \centerpoint% - \pgf@xa\externalx\relax% - \pgf@ya\externaly\relax% - \advance\pgf@xa\pgf@x% - \advance\pgf@ya\pgf@y% - \edef\externalx{\the\pgf@xa}% - \edef\externaly{\the\pgf@ya}% - % - % Get the shape parameters. - % - \installsignalparameters% - % - % Get the angle of the external point to the \centerpoint. - % - \pgfmathanglebetweenpoints{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% - \let\externalangle\pgfmathresult% - % - % - % - \pgfmathanglebetweenpoints{\centerpoint}{\anchorwest}% - \ifdim\externalangle pt<\pgfmathresult pt\relax% - \pgfmathanglebetweenpoints{\centerpoint}{\anchornorth}% - \ifdim\externalangle pt<\pgfmathresult pt\relax% - \pgfmathanglebetweenpoints{\centerpoint}{\anchornortheast}% - \ifdim\externalangle pt<\pgfmathresult pt\relax% - \let\firstpoint\anchoreast% - \let\secondpoint\anchornortheast% - \else% - \let\secondpoint\anchornortheast% - \let\firstpoint\anchornorth% - \fi% - \else% - \pgfmathanglebetweenpoints{\centerpoint}{\anchornorthwest}% - \ifdim\externalangle pt<\pgfmathresult pt\relax% - \let\firstpoint\anchornorth% - \let\secondpoint\anchornorthwest% - \else% - \let\secondpoint\anchornorthwest% - \let\firstpoint\anchorwest% - \fi% - \fi% - \else% - \pgfmathanglebetweenpoints{\centerpoint}{\anchorsouth}% - \ifdim\externalangle pt<\pgfmathresult pt\relax% - \pgfmathanglebetweenpoints{\centerpoint}{\anchorsouthwest}% - \ifdim\externalangle pt<\pgfmathresult pt\relax% - \let\firstpoint\anchorwest% - \let\secondpoint\anchorsouthwest% - \else% - \let\secondpoint\anchorsouthwest% - \let\firstpoint\anchorsouth% - \fi% - \else% - \pgfmathanglebetweenpoints{\centerpoint}{\anchorsoutheast}% - \ifdim\externalangle pt<\pgfmathresult pt\relax% - \let\firstpoint\anchorsouth% - \let\secondpoint\anchorsoutheast% - \else% - \let\secondpoint\anchorsoutheast% - \let\firstpoint\anchoreast% - \fi% - \fi% - \fi% - % - % Now locate the point. - % - \pgfpointintersectionoflines{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% - {\firstpoint}{\secondpoint}% - }% + \savedmacro\installsignalparameters{% + % + \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@nowhere% + \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@nowhere% + \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@nowhere% + \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@nowhere% + % + \pgf@lib@sh@signal@parsedirection{\pgfkeysvalueof{/pgf/signal from}}{\pgf@lib@sh@signal@from}% + \pgf@lib@sh@signal@parsedirection{\pgfkeysvalueof{/pgf/signal to}}{\pgf@lib@sh@signal@to}% + % + % Define a centerpoint. + % + \pgfextract@process\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + }% + % + % Get some useful trig. stuff + % + \pgfmathsetmacro\pointerangle{\pgfkeysvalueof{/pgf/signal pointer angle}}% + % + \pgfmathdivide@{\pointerangle}{2}% + \let\halfpointerangle=\pgfmathresult% + % + \pgfmathcosec@{\halfpointerangle}% + \let\cosechalfpointerangle=\pgfmathresult% + % + \pgfmathdivide@{\halfpointerangle}{2}% + \let\quarterpointerangle=\pgfmathresult% + % + \pgfmathcosec@{\quarterpointerangle}% + \let\cosecquarterpointerangle=\pgfmathresult% + % + \pgfmathsec@{\quarterpointerangle}% + \let\secquarterpointerangle=\pgfmathresult% + % + \pgfmathsubtract@{90}{\quarterpointerangle}% + \let\complementquarterpointerangle\pgfmathresult% + % + % Get the larger of the outer sep. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@x>\pgf@y% + \pgf@y\pgf@x% + \fi% + \pgf@yc=\pgf@y% + % + % Calculate the miter due to the line width, at the pointer apex... + % + \pgf@x=\cosechalfpointerangle\pgf@y% + \edef\pointerapexmiter{\the\pgf@x}% + % + % ...at a corner by a `to' pointer (i.e. sticks out)... + % + \pgf@x=\secquarterpointerangle\pgf@y% + \edef\tocornermiter{\the\pgf@x}% + % + % ...at a corner by a `from' pointer (i.e. sticks in). + % + \pgf@x=\cosecquarterpointerangle\pgf@y + \edef\fromcornermiter{\the\pgf@x}% + % + % Get the (half) dimensions of the node. + % + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}% + \advance\pgf@xa.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}% + \advance\pgf@ya.5\ht\pgfnodeparttextbox% + \advance\pgf@ya.5\dp\pgfnodeparttextbox% + % + % Get the distance a pointer sticks out to the side... + % + \pgfmathsubtract@{90}{\halfpointerangle}% + \pgfmathtan@{\pgfmathresult}% + \pgf@xb=\pgfmathresult\pgf@ya% + % + % ...and up. + % + \pgf@yb=\pgfmathresult\pgf@xa% + % + % Adjust for minimum height. + % + \pgfutil@tempdima=2.0\pgf@ya% + \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@nowhere% + \else% + \advance\pgfutil@tempdima by\pgf@yb% + \fi% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@nowhere% + \else% + \advance\pgfutil@tempdima by\pgf@yb% + \fi% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgfutil@tempdima<\pgf@y% + \pgfutil@tempdima=\pgf@y% + % + \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@nowhere% + \else% + \advance\pgfutil@tempdima by-\pgf@yb% + \fi% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@nowhere% + \else% + \advance\pgfutil@tempdima by-\pgf@yb% + \fi% + \pgf@ya=0.5\pgfutil@tempdima% + \pgfmathsubtract@{90}{\halfpointerangle}% + \pgfmathtan@{\pgfmathresult}% + \pgf@xb=\pgfmathresult\pgf@ya% + \fi% + % + % Adjust for minimum width. + % + \pgfutil@tempdima=2.0\pgf@xa% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% + \else% + \advance\pgfutil@tempdima by\pgf@xb% + \fi% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% + \else% + \advance\pgfutil@tempdima by\pgf@xb% + \fi% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/minimum width}}% + \ifdim\pgfutil@tempdima<\pgf@x% + \pgfutil@tempdima=\pgf@x% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% + \else% + \advance\pgfutil@tempdima by-\pgf@xb% + \fi% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% + \else% + \advance\pgfutil@tempdima by-\pgf@xb% + \fi% + \pgf@xa=0.5\pgfutil@tempdima% + \pgfmathsubtract@{90}{\halfpointerangle}% + \pgfmathtan@{\pgfmathresult}% + \pgf@yb=\pgfmathresult\pgf@xa% + \fi% + % + % So, define the points for the background path. + % + \pgfextract@process\north{% + \centerpoint% + \advance\pgf@y\pgf@ya% + \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@to% + \advance\pgf@y\pgf@yb% + \fi% + }% + \pgfextract@process\south{% + \centerpoint% + \advance\pgf@y-\pgf@ya% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@to% + \advance\pgf@y-\pgf@yb% + \fi% + }% + \pgfextract@process\east{% + \centerpoint% + \advance\pgf@x\pgf@xa% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@to% + \advance\pgf@x\pgf@xb% + \fi% + }% + \pgfextract@process\west{% + \centerpoint% + \advance\pgf@x-\pgf@xa% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to% + \advance\pgf@x-\pgf@xb% + \fi% + }% + \pgfextract@process\northeast{% + \centerpoint% + \advance\pgf@y\pgf@ya% + \advance\pgf@x\pgf@xa% + \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from% + \advance\pgf@y\pgf@yb% + \fi% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from% + \advance\pgf@x\pgf@xb% + \fi% + }% + \pgfextract@process\southeast{% + \centerpoint% + \advance\pgf@y-\pgf@ya% + \advance\pgf@x\pgf@xa% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from% + \advance\pgf@y-\pgf@yb% + \fi% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from% + \advance\pgf@x\pgf@xb% + \fi% + }% + \pgfextract@process\southwest{% + \centerpoint% + \advance\pgf@y-\pgf@ya% + \advance\pgf@x-\pgf@xa% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from% + \advance\pgf@y-\pgf@yb% + \fi% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from% + \advance\pgf@x-\pgf@xb% + \fi% + }% + \pgfextract@process\northwest{% + \centerpoint% + \advance\pgf@y\pgf@ya% + \advance\pgf@x-\pgf@xa% + \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from% + \advance\pgf@y\pgf@yb% + \fi% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from% + \advance\pgf@x-\pgf@xb% + \fi% + }% + \addtosavedmacro{\north}% + \addtosavedmacro{\south}% + \addtosavedmacro{\east}% + \addtosavedmacro{\west}% + \addtosavedmacro{\northeast}% + \addtosavedmacro{\southwest}% + \addtosavedmacro{\southeast}% + \addtosavedmacro{\northwest}% + % + % Calculate the `miter vectors' (i.e. +outer sep). + % + \pgfextract@process\northmiter{% + \pgf@x0pt% + \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@nowhere% + \pgf@y\pgf@yc% + \else% + \pgf@y\pointerapexmiter\relax% + \fi% + }% + \pgfextract@process\southmiter{% + \pgf@x0pt% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@nowhere% + \pgf@y-\pgf@yc% + \else% + \pgf@y-\pointerapexmiter\relax% + \fi% + }% + \pgfextract@process\eastmiter{% + \pgf@y0pt% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% + \pgf@x\pgf@yc% + \else% + \pgf@x\pointerapexmiter\relax% + \fi% + }% + \pgfextract@process\westmiter{% + \pgf@y0pt% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% + \pgf@x-\pgf@yc% + \else% + \pgf@x-\pointerapexmiter\relax% + \fi% + }% + \pgfextract@process\northeastmiter{% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% + \pgf@x\pgf@yc + \pgf@y\pgf@yc% + \else + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from% + \pgfqpointpolar{\quarterpointerangle}{\fromcornermiter} + \else% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@to% + \pgfqpointpolar{\complementquarterpointerangle}{\tocornermiter}% + \fi% + \fi% + \fi% + \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from% + \pgfqpointpolar{\complementquarterpointerangle}{\fromcornermiter}% + \else% + \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@to% + \pgfqpointpolar{\quarterpointerangle}{\tocornermiter}% + \fi% + \fi% + }% + \pgfextract@process\southeastmiter{% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% + \pgf@x\pgf@yc% + \pgf@y\pgf@yc% + \else + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from% + \pgfqpointpolar{-\quarterpointerangle}{\fromcornermiter} + \else% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@to% + \pgfqpointpolar{-\complementquarterpointerangle}{\tocornermiter}% + \fi% + \fi% + \fi% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from% + \pgfqpointpolar{-\complementquarterpointerangle}{\fromcornermiter} + \else% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@to% + \pgfqpointpolar{-\quarterpointerangle}{\tocornermiter}% + \fi% + \fi% + }% + \pgfextract@process\southwestmiter{% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% + \pgf@x-\pgf@yc + \pgf@y-\pgf@yc% + \else + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from% + \pgfmathadd@{\quarterpointerangle}{180}% + \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter} + \else% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to% + \pgfmathadd@{\complementquarterpointerangle}{180}% + \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}% + \fi% + \fi% + \fi% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from% + \pgfmathadd@{\complementquarterpointerangle}{180}% + \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter}% + \else% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@to% + \pgfmathadd@{\quarterpointerangle}{180}% + \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}% + \fi% + \fi% + }% + \pgfextract@process\northwestmiter{% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% + \pgf@x-\pgf@yc% + \pgf@y\pgf@yc% + \else + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from% + \pgfmathsubtract@{180}{\quarterpointerangle}% + \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter} + \else% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to% + \pgfmathsubtract@{180}{\complementquarterpointerangle}% + \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}% + \fi% + \fi% + \fi% + \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from% + \pgfmathsubtract@{180}{\complementquarterpointerangle}% + \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter}% + \else% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to% + \pgfmathsubtract@{180}{\quarterpointerangle}% + \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}% + \fi% + \fi% + }% + \addtosavedmacro{\northmiter}% + \addtosavedmacro{\southmiter}% + \addtosavedmacro{\eastmiter}% + \addtosavedmacro{\westmiter}% + \addtosavedmacro{\northeastmiter}% + \addtosavedmacro{\southeastmiter}% + \addtosavedmacro{\southwestmiter}% + \addtosavedmacro{\northwestmiter}% + % + % Now calculate the anchor points + % + \pgfextract@process\anchornorth{% + \pgfpointadd{\north}{\northmiter}% + }% + \pgfextract@process\anchorsouth{% + \pgfpointadd{\south}{\southmiter}% + }% + \pgfextract@process\anchoreast{% + \pgfpointadd{\east}{\eastmiter}% + }% + \pgfextract@process\anchorwest{% + \pgfpointadd{\west}{\westmiter}% + }% + \pgfextract@process\anchornortheast{% + \pgfpointadd{\northeast}{\northeastmiter}% + }% + \pgfextract@process\anchorsoutheast{% + \pgfpointadd{\southeast}{\southeastmiter}% + }% + \pgfextract@process\anchorsouthwest{% + \pgfpointadd{\southwest}{\southwestmiter}% + }% + \pgfextract@process\anchornorthwest{% + \pgfpointadd{\northwest}{\northwestmiter}% + }% + \addtosavedmacro{\anchornorth}% + \addtosavedmacro{\anchorsouth}% + \addtosavedmacro{\anchoreast}% + \addtosavedmacro{\anchorwest}% + \addtosavedmacro{\anchornortheast}% + \addtosavedmacro{\anchorsouthwest}% + \addtosavedmacro{\anchorsoutheast}% + \addtosavedmacro{\anchornorthwest}% + }% + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + }% + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + }% + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+.5ex}% + }% + \anchor{center}{\centerpoint}% + \anchor{base}{\basepoint}% + \anchor{base east}{% + \installsignalparameters% + \anchoreast% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \anchorsoutheast% + \ifdim\pgf@xa>\pgf@x% + \pgfutil@tempdima\pgf@xa% + \else% + \pgfutil@tempdima\pgf@x% + \fi% + \pgfextract@process\externalpoint{% + \basepoint% + \pgf@x\pgfutil@tempdima% + } + \basepoint% + \let\firstpoint\anchoreast% + \ifdim\pgf@y<\pgf@ya% + \let\secondpoint\anchorsoutheast% + \else% + \let\secondpoint\anchornortheast% + \fi% + \pgfpointintersectionoflines{\basepoint}{\externalpoint}% + {\firstpoint}{\secondpoint}% + }% + \anchor{base west}{% + \installsignalparameters% + \anchorwest% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \anchorsouthwest% + \ifdim\pgf@xa<\pgf@x% + \pgfutil@tempdima\pgf@xa% + \else% + \pgfutil@tempdima\pgf@x% + \fi% + \pgfextract@process\externalpoint{% + \basepoint% + \pgf@x\pgfutil@tempdima% + } + \basepoint% + \let\firstpoint\anchorwest% + \ifdim\pgf@y<\pgf@ya% + \let\secondpoint\anchorsouthwest% + \else% + \let\secondpoint\anchornorthwest% + \fi% + \pgfpointintersectionoflines{\basepoint}{\externalpoint}% + {\firstpoint}{\secondpoint}% + }% + \anchor{mid}{\midpoint}% + \anchor{mid east}{% + \installsignalparameters% + \anchoreast% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \anchorsoutheast% + \ifdim\pgf@xa>\pgf@x% + \pgfutil@tempdima\pgf@xa% + \else% + \pgfutil@tempdima\pgf@x% + \fi% + \pgfextract@process\externalpoint{% + \midpoint% + \pgf@x\pgfutil@tempdima% + } + \midpoint% + \let\firstpoint\anchoreast% + \ifdim\pgf@y<\pgf@ya% + \let\secondpoint\anchorsoutheast% + \else% + \let\secondpoint\anchornortheast% + \fi% + \pgfpointintersectionoflines{\midpoint}{\externalpoint}% + {\firstpoint}{\secondpoint}% + }% + \anchor{mid west}{% + \installsignalparameters% + \anchorwest% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \anchorsouthwest% + \ifdim\pgf@xa<\pgf@x% + \pgfutil@tempdima\pgf@xa% + \else% + \pgfutil@tempdima\pgf@x% + \fi% + \pgfextract@process\externalpoint{% + \midpoint% + \pgf@x\pgfutil@tempdima% + } + \midpoint% + \let\firstpoint\anchorwest% + \ifdim\pgf@y<\pgf@ya% + \let\secondpoint\anchorsouthwest% + \else% + \let\secondpoint\anchornorthwest% + \fi% + \pgfpointintersectionoflines{\midpoint}{\externalpoint}% + {\firstpoint}{\secondpoint}% + }% + \anchor{north}{\installsignalparameters\anchornorth}% + \anchor{south}{\installsignalparameters\anchorsouth}% + \anchor{east}{\installsignalparameters\anchoreast}% + \anchor{west}{\installsignalparameters\anchorwest}% + \anchor{north east}{\installsignalparameters\anchornortheast}% + \anchor{south east}{\installsignalparameters\anchorsoutheast}% + \anchor{south west}{\installsignalparameters\anchorsouthwest}% + \anchor{north west}{\installsignalparameters\anchornorthwest}% + \backgroundpath{% + \installsignalparameters% + \pgfpathmoveto{\north}% + \pgfpathlineto{\northeast}% + \pgfpathlineto{\east}% + \pgfpathlineto{\southeast}% + \pgfpathlineto{\south}% + \pgfpathlineto{\southwest}% + \pgfpathlineto{\west}% + \pgfpathlineto{\northwest}% + \pgfpathclose% + } + \anchorborder{% + % + % Save x and y. + % + \edef\externalx{\the\pgf@x}% + \edef\externaly{\the\pgf@y}% + % + % Adjust the location of the external + % point relative to \centerpoint. + % + \centerpoint% + \pgf@xa\externalx\relax% + \pgf@ya\externaly\relax% + \advance\pgf@xa\pgf@x% + \advance\pgf@ya\pgf@y% + \edef\externalx{\the\pgf@xa}% + \edef\externaly{\the\pgf@ya}% + % + % Get the shape parameters. + % + \installsignalparameters% + % + % Get the angle of the external point to the \centerpoint. + % + \pgfmathanglebetweenpoints{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% + \let\externalangle\pgfmathresult% + % + % + % + \pgfmathanglebetweenpoints{\centerpoint}{\anchorwest}% + \ifdim\externalangle pt<\pgfmathresult pt\relax% + \pgfmathanglebetweenpoints{\centerpoint}{\anchornorth}% + \ifdim\externalangle pt<\pgfmathresult pt\relax% + \pgfmathanglebetweenpoints{\centerpoint}{\anchornortheast}% + \ifdim\externalangle pt<\pgfmathresult pt\relax% + \let\firstpoint\anchoreast% + \let\secondpoint\anchornortheast% + \else% + \let\secondpoint\anchornortheast% + \let\firstpoint\anchornorth% + \fi% + \else% + \pgfmathanglebetweenpoints{\centerpoint}{\anchornorthwest}% + \ifdim\externalangle pt<\pgfmathresult pt\relax% + \let\firstpoint\anchornorth% + \let\secondpoint\anchornorthwest% + \else% + \let\secondpoint\anchornorthwest% + \let\firstpoint\anchorwest% + \fi% + \fi% + \else% + \pgfmathanglebetweenpoints{\centerpoint}{\anchorsouth}% + \ifdim\externalangle pt<\pgfmathresult pt\relax% + \pgfmathanglebetweenpoints{\centerpoint}{\anchorsouthwest}% + \ifdim\externalangle pt<\pgfmathresult pt\relax% + \let\firstpoint\anchorwest% + \let\secondpoint\anchorsouthwest% + \else% + \let\secondpoint\anchorsouthwest% + \let\firstpoint\anchorsouth% + \fi% + \else% + \pgfmathanglebetweenpoints{\centerpoint}{\anchorsoutheast}% + \ifdim\externalangle pt<\pgfmathresult pt\relax% + \let\firstpoint\anchorsouth% + \let\secondpoint\anchorsoutheast% + \else% + \let\secondpoint\anchorsoutheast% + \let\firstpoint\anchoreast% + \fi% + \fi% + \fi% + % + % Now locate the point. + % + \pgfpointintersectionoflines{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% + {\firstpoint}{\secondpoint}% + }% }% @@ -2060,10 +2102,10 @@ % /pgf/tape bend bottom : Type of bend for south side. % /pgf/tape bend height : The height of the bends. \pgfkeys{/pgf/.cd, - tape bend top/.initial=in and out, - tape bend bottom/.initial=in and out, - tape bend/.style={/pgf/tape bend top=#1, /pgf/tape bend bottom=#1}, - tape bend height/.initial=5pt + tape bend top/.initial=in and out, + tape bend bottom/.initial=in and out, + tape bend/.style={/pgf/tape bend top=#1, /pgf/tape bend bottom=#1}, + tape bend height/.initial=5pt } \def\pgf@lib@sh@inandouttext{in and out} @@ -2071,447 +2113,447 @@ \def\pgf@lib@sh@nonetext{none} \pgfdeclareshape{tape}{ - \savedmacro\tapedimensions{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% - \advance\pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% - \advance\pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y.5\dp\pgfnodeparttextbox% - % - \pgfmathsetlengthmacro\outerxsep{\pgfkeysvalueof{/pgf/outer xsep}}% - \pgfmathsetlengthmacro\outerysep{\pgfkeysvalueof{/pgf/outer ysep}}% - \addtosavedmacro\outerxsep% - \addtosavedmacro\outerysep% - % - \pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/tape bend height}}% - \pgfutil@tempdima.5\pgfutil@tempdima% - \edef\halfbendheight{\the\pgfutil@tempdima}% - \addtosavedmacro\halfbendheight% - % - \pgfkeysgetvalue{/pgf/tape bend top}{\topbendstyle}% - \pgfkeysgetvalue{/pgf/tape bend bottom}{\bottombendstyle}% - \addtosavedmacro\topbendstyle% - \addtosavedmacro\bottombendstyle% - % - \ifx\topbendstyle\pgf@lib@sh@nonetext% - \else% - \advance\pgf@y\pgfutil@tempdima% - \fi% - \ifx\bottombendstyle\pgf@lib@sh@none% - \else% - \advance\pgf@y\pgfutil@tempdima% - \fi% - % - \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}% - \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}% - \ifdim\pgf@x<.5\pgf@xa% - \pgf@x.5\pgf@xa% - \fi% - \ifdim\pgf@y<.5\pgf@ya% - \pgf@y.5\pgf@ya% - \fi% - \ifx\topbendstyle\pgf@lib@sh@nonetext% - \else% - \advance\pgf@y-\pgfutil@tempdima% - \fi% - \ifx\bottombendstyle\pgf@lib@sh@nonetext% - \else% - \advance\pgf@y-\pgfutil@tempdima% - \fi% - % - \pgfutil@tempdima3.414213\pgfutil@tempdima% 1 / (1-sin(45)) - \edef\bendyradius{\the\pgfutil@tempdima}% - \addtosavedmacro\bendyradius% - \advance\pgfutil@tempdima\outerysep% - \edef\outerbendyradius{\the\pgfutil@tempdima}% - \addtosavedmacro\outerbendyradius% - \advance\pgfutil@tempdima-\outerysep% - \advance\pgfutil@tempdima-\outerysep% - \edef\innerbendyradius{\the\pgfutil@tempdima}% - \addtosavedmacro\innerbendyradius% - % - \pgfutil@tempdima0.707106\pgf@x% cos(45) - \edef\bendxradius{\the\pgfutil@tempdima}% - \addtosavedmacro\bendxradius% - \advance\pgfutil@tempdima\outerxsep% - \edef\outerbendxradius{\the\pgfutil@tempdima}% - \addtosavedmacro\outerbendxradius% - \advance\pgfutil@tempdima-\outerxsep% - \advance\pgfutil@tempdima-\outerxsep% - \edef\innerbendxradius{\the\pgfutil@tempdima}% - \addtosavedmacro\innerbendxradius% - % - \edef\halfwidth{\the\pgf@x}% - \edef\halfheight{\the\pgf@y}% - \addtosavedmacro\halfwidth% - \addtosavedmacro\halfheight% - % - \advance\pgf@x\outerxsep% - \edef\outerhalfwidth{\the\pgf@x}% - \addtosavedmacro\outerhalfwidth% - % - \pgf@xc\bendxradius% - \pgf@yc\bendyradius% - \pgfmathdivide@{\pgfmath@tonumber{\pgf@yc}}{\pgfmath@tonumber{\pgf@xc}}% - \pgfmathatan{\pgfmathresult}% - \pgf@xc\pgfmathresult pt\relax% - \pgf@xc.5\pgf@xc% - \edef\halfangle{\pgfmath@tonumber{\pgf@xc}}% - \addtosavedmacro\halfangle% - % - \pgf@xc45pt\relax% - \advance\pgf@xc-\halfangle pt% - \pgfmathcot@{\pgfmath@tonumber{\pgf@xc}}% - \let\cothalfanglein\pgfmathresult% - \addtosavedmacro\cothalfanglein% - % - \pgf@xc90pt\relax% - \advance\pgf@xc-\halfangle pt% - \pgfmathcot@{\pgfmath@tonumber{\pgf@xc}}% - \let\cothalfangleout\pgfmathresult% - \addtosavedmacro\cothalfangleout% - % - } - \savedanchor{\centerpoint}{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor{\midpoint}{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+0.5ex}% - } - \savedanchor{\basepoint}{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \anchor{center}{\centerpoint}% - \anchor{mid}{\midpoint}% - \anchor{mid east}{\tapedimensions\midpoint\advance\pgf@x\outerhalfwidth}% - \anchor{mid west}{\tapedimensions\midpoint\advance\pgf@x-\outerhalfwidth}% - \anchor{base}{\basepoint}% - \anchor{base east}{\tapedimensions\basepoint\advance\pgf@x\outerhalfwidth}% - \anchor{base west}{\tapedimensions\basepoint\advance\pgf@x-\outerhalfwidth}% - \anchor{north}{% - \csname pgf@anchor@tape@north east\endcsname% - \pgf@ya\pgf@y% - \csname pgf@anchor@tape@north west\endcsname% - \advance\pgf@ya\pgf@y% - \centerpoint% - \pgf@y.5\pgf@ya% - } - \anchor{south}{% - \csname pgf@anchor@tape@south east\endcsname% - \pgf@ya\pgf@y% - \csname pgf@anchor@tape@south west\endcsname% - \advance\pgf@ya\pgf@y% - \centerpoint% - \pgf@y.5\pgf@ya% - } - \anchor{east}{% - \tapedimensions% - \centerpoint% - \advance\pgf@x\outerhalfwidth% - } - \anchor{west}{% - \tapedimensions% - \centerpoint% - \advance\pgf@x-\outerhalfwidth% - } - \anchor{north east}{% - \tapedimensions% - \centerpoint% - \advance\pgf@x\outerhalfwidth% - \advance\pgf@y\halfheight% - \pgf@yc\outerysep% - \ifx\topbendstyle\pgf@lib@sh@inandouttext% - \advance\pgf@y\halfbendheight% - \advance\pgf@y\cothalfangleout\pgf@yc% - \else% - \ifx\topbendstyle\pgf@lib@sh@outandintext% - \advance\pgf@y\halfbendheight% - \advance\pgf@y\cothalfanglein\pgf@yc% - \else% - \advance\pgf@y\pgf@yc% - \fi% - \fi% - }% - \anchor{north west}{% - \tapedimensions% - \centerpoint% - \advance\pgf@x-\outerhalfwidth% - \advance\pgf@y\halfheight% - \pgf@yc\outerysep% - \ifx\topbendstyle\pgf@lib@sh@inandouttext% - \advance\pgf@y\halfbendheight% - \advance\pgf@y\cothalfanglein\pgf@yc% - \else% - \ifx\topbendstyle\pgf@lib@sh@outandintext% - \advance\pgf@y\halfbendheight% - \advance\pgf@y\cothalfangleout\pgf@yc% - \else% - \advance\pgf@y\pgf@yc% - \fi% - \fi% - }% - \anchor{south east}{% - \tapedimensions% - \centerpoint% - \advance\pgf@x\outerhalfwidth% - \advance\pgf@y-\halfheight% - \pgf@yc\outerysep% - \ifx\topbendstyle\pgf@lib@sh@outandintext% - \advance\pgf@y-\halfbendheight% - \advance\pgf@y-\cothalfangleout\pgf@yc% - \else% - \ifx\topbendstyle\pgf@lib@sh@inandouttext% - \advance\pgf@y-\halfbendheight% - \advance\pgf@y-\cothalfanglein\pgf@yc% - \else% - \advance\pgf@y-\pgf@yc% - \fi% - \fi% - }% - \anchor{south west}{% - \tapedimensions% - \centerpoint% - \advance\pgf@x-\outerhalfwidth% - \advance\pgf@y-\halfheight% - \pgf@yc\outerysep% - \ifx\topbendstyle\pgf@lib@sh@outandintext% - \advance\pgf@y-\halfbendheight% - \advance\pgf@y-\cothalfanglein\pgf@yc% - \else% - \ifx\topbendstyle\pgf@lib@sh@inandouttext% - \advance\pgf@y-\halfbendheight% - \advance\pgf@y-\cothalfangleout\pgf@yc% - \else% - \advance\pgf@y-\pgf@yc% - \fi% - \fi% - }% - \backgroundpath{% - \tapedimensions% - % - \pgf@xc\halfwidth% - \pgf@yc\halfheight% - % - \pgf@xc\bendxradius% - \pgf@yc\bendyradius% - {% - \pgftransformshift{\centerpoint}% - \pgfpathmoveto{\pgfqpoint{-\halfwidth}{0pt}}% - \pgfpathlineto{\pgfqpoint{-\halfwidth}{\halfheight}}% - \ifx\topbendstyle\pgf@lib@sh@inandouttext% - \pgfpathlineto{\pgf@x-\halfwidth\pgf@y\halfheight\advance\pgf@y\halfbendheight}% - \pgfpatharc{225}{315}{\bendxradius and \bendyradius}% - \pgfpatharc{135}{45}{\bendxradius and \bendyradius}% - \else% - \ifx\topbendstyle\pgf@lib@sh@outandintext% - \pgfpathlineto{\pgf@x-\halfwidth\pgf@y\halfheight\advance\pgf@y\halfbendheight}% - \pgfpatharc{135}{45}{\bendxradius and \bendyradius}% - \pgfpatharc{225}{315}{\bendxradius and \bendyradius}% - \else% - \pgfpathlineto{\pgfqpoint{\halfwidth}{\halfheight}}% - \fi% - \fi% - \pgfpathlineto{\pgfqpoint{\halfwidth}{-\halfheight}}% - \ifx\bottombendstyle\pgf@lib@sh@inandouttext% - \pgfpathlineto{\pgf@x\halfwidth\pgf@y-\halfheight\advance\pgf@y-\halfbendheight}% - \pgfpatharc{45}{135}{\bendxradius and \bendyradius}% - \pgfpatharc{315}{225}{\bendxradius and \bendyradius}% - \else% - \ifx\bottombendstyle\pgf@lib@sh@outandintext% - \pgfpathlineto{\pgf@x\halfwidth\pgf@y-\halfheight\advance\pgf@y-\halfbendheight}% - \pgfpatharc{315}{225}{\bendxradius and \bendyradius}% - \pgfpatharc{45}{135}{\bendxradius and \bendyradius}% - \else% - \pgfpathlineto{\pgfqpoint{-\halfwidth}{-\halfheight}}% - \fi% - \fi% - \pgfpathclose% - }% - } - \anchorborder{% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \pgfextract@process\externalpoint{% - \centerpoint% - \advance\pgf@x\pgf@xa% - \advance\pgf@y\pgf@ya% - }% - \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}% - \let\externalangle\pgfmathresult% - \tapedimensions% - % - \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@north west\endcsname}% - \ifdim\externalangle pt<\pgfmathresult pt% - \ifdim\externalangle pt<90pt% - \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@north east\endcsname}% - \ifdim\externalangle pt<\pgfmathresult pt% - \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% - {\csname pgf@anchor@tape@north east\endcsname}% - {\csname pgf@anchor@tape@south east\endcsname}% - \else% - % Between north and north east. - \ifx\topbendstyle\pgf@lib@sh@inandouttext% - % in and out. - \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}% - {% - \centerpoint% - \pgf@xc\halfwidth% - \advance\pgf@x.5\pgf@xc% - \advance\pgf@y\halfheight% - \advance\pgf@y\halfbendheight% - \pgf@yc\bendyradius% - \advance\pgf@y-.707106\pgf@yc% - }% - {5}{175}{\outerbendxradius and \outerbendyradius}% - \else% - \ifx\topbendstyle\pgf@lib@sh@outandintext% - % out and in. - \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}% - {% - \centerpoint% - \pgf@xc\halfwidth% - \advance\pgf@x.5\pgf@xc% - \advance\pgf@y\halfheight% - \advance\pgf@y\halfbendheight% - \pgf@yc\bendyradius% - \advance\pgf@y.707106\pgf@yc% - }% - {185}{355}{\innerbendxradius and \innerbendyradius}% - \else% - \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% - {\csname pgf@anchor@tape@north east\endcsname}% - {\csname pgf@anchor@tape@north west\endcsname}% - \fi% - \fi% - \fi% - \else% - % Between north and north west. - \ifx\topbendstyle\pgf@lib@sh@inandouttext% - % in and out. - \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}% - {% - \centerpoint% - \pgf@xc\halfwidth% - \advance\pgf@x-.5\pgf@xc% - \advance\pgf@y\halfheight% - \advance\pgf@y\halfbendheight% - \pgf@yc\bendyradius% - \advance\pgf@y.707106\pgf@yc% - }% - {185}{355}{\innerbendxradius and \innerbendyradius}% - \else% - \ifx\topbendstyle\pgf@lib@sh@outandintext% - % out and in. - \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}% - {% - \centerpoint% - \pgf@xc\halfwidth% - \advance\pgf@x-.5\pgf@xc% - \advance\pgf@y\halfheight% - \advance\pgf@y\halfbendheight% - \pgf@yc\bendyradius% - \advance\pgf@y-.707106\pgf@yc% - }% - {5}{175}{\outerbendxradius and \outerbendyradius}% - \else% - \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% - {\csname pgf@anchor@tape@north east\endcsname}% - {\csname pgf@anchor@tape@north west\endcsname}% - \fi% - \fi% - \fi% - \else% - \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@south west\endcsname}% - \ifdim\externalangle pt>\pgfmathresult pt% - \ifdim\externalangle pt>270pt% - \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@south east\endcsname}% - \ifdim\externalangle pt>\pgfmathresult pt% - \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% - {\csname pgf@anchor@tape@north east\endcsname}% - {\csname pgf@anchor@tape@south east\endcsname}% - \else% - % Between south and south east. - \ifx\bottombendstyle\pgf@lib@sh@inandouttext% - % in and out. - \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}% - {% - \centerpoint% - \pgf@xc\halfwidth% - \advance\pgf@x.5\pgf@xc% - \advance\pgf@y-\halfheight% - \advance\pgf@y-\halfbendheight% - \pgf@yc\bendyradius% - \advance\pgf@y-.707106\pgf@yc% - }% - {5}{175}{\innerbendxradius and \innerbendyradius}% - \else% - \ifx\bottombendstyle\pgf@lib@sh@outandintext% - % out and in. - \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}% - {% - \centerpoint% - \pgf@xc\halfwidth% - \advance\pgf@x.5\pgf@xc% - \advance\pgf@y-\halfheight% - \advance\pgf@y-\halfbendheight% - \pgf@yc\bendyradius% - \advance\pgf@y.707106\pgf@yc% - }% - {185}{355}{\outerbendxradius and \outerbendyradius}% - \else% - \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% - {\csname pgf@anchor@tape@south east\endcsname}% - {\csname pgf@anchor@tape@south west\endcsname}% - \fi% - \fi% - \fi% - \else% - % Between south and south west. - \ifx\bottombendstyle\pgf@lib@sh@inandouttext% - % in and out. - \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}% - {% - \centerpoint% - \pgf@xc\halfwidth% - \advance\pgf@x-.5\pgf@xc% - \advance\pgf@y-\halfheight% - \advance\pgf@y-\halfbendheight% - \pgf@yc\bendyradius% - \advance\pgf@y.707106\pgf@yc% - }% - {185}{355}{\outerbendxradius and \outerbendyradius}% - \else% - \ifx\bottombendstyle\pgf@lib@sh@outandintext% - % out and in. - \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}% - {% - \centerpoint% - \pgf@xc\halfwidth% - \advance\pgf@x-.5\pgf@xc% - \advance\pgf@y-\halfheight% - \advance\pgf@y-\halfbendheight% - \pgf@yc\bendyradius% - \advance\pgf@y-.707106\pgf@yc% - }% - {5}{175}{\innerbendxradius and \innerbendyradius}% - \else% - \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% - {\csname pgf@anchor@tape@south east\endcsname}% - {\csname pgf@anchor@tape@south west\endcsname}% - \fi% - \fi% - \fi% - \else% - \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% - {\csname pgf@anchor@tape@north west\endcsname}% - {\csname pgf@anchor@tape@south west\endcsname}% - \fi% - \fi% - }% + \savedmacro\tapedimensions{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% + \advance\pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% + \advance\pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y.5\dp\pgfnodeparttextbox% + % + \pgfmathsetlengthmacro\outerxsep{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlengthmacro\outerysep{\pgfkeysvalueof{/pgf/outer ysep}}% + \addtosavedmacro\outerxsep% + \addtosavedmacro\outerysep% + % + \pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/tape bend height}}% + \pgfutil@tempdima.5\pgfutil@tempdima% + \edef\halfbendheight{\the\pgfutil@tempdima}% + \addtosavedmacro\halfbendheight% + % + \pgfkeysgetvalue{/pgf/tape bend top}{\topbendstyle}% + \pgfkeysgetvalue{/pgf/tape bend bottom}{\bottombendstyle}% + \addtosavedmacro\topbendstyle% + \addtosavedmacro\bottombendstyle% + % + \ifx\topbendstyle\pgf@lib@sh@nonetext% + \else% + \advance\pgf@y\pgfutil@tempdima% + \fi% + \ifx\bottombendstyle\pgf@lib@sh@none% + \else% + \advance\pgf@y\pgfutil@tempdima% + \fi% + % + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgf@x<.5\pgf@xa% + \pgf@x.5\pgf@xa% + \fi% + \ifdim\pgf@y<.5\pgf@ya% + \pgf@y.5\pgf@ya% + \fi% + \ifx\topbendstyle\pgf@lib@sh@nonetext% + \else% + \advance\pgf@y-\pgfutil@tempdima% + \fi% + \ifx\bottombendstyle\pgf@lib@sh@nonetext% + \else% + \advance\pgf@y-\pgfutil@tempdima% + \fi% + % + \pgfutil@tempdima3.414213\pgfutil@tempdima% 1 / (1-sin(45)) + \edef\bendyradius{\the\pgfutil@tempdima}% + \addtosavedmacro\bendyradius% + \advance\pgfutil@tempdima\outerysep% + \edef\outerbendyradius{\the\pgfutil@tempdima}% + \addtosavedmacro\outerbendyradius% + \advance\pgfutil@tempdima-\outerysep% + \advance\pgfutil@tempdima-\outerysep% + \edef\innerbendyradius{\the\pgfutil@tempdima}% + \addtosavedmacro\innerbendyradius% + % + \pgfutil@tempdima0.707106\pgf@x% cos(45) + \edef\bendxradius{\the\pgfutil@tempdima}% + \addtosavedmacro\bendxradius% + \advance\pgfutil@tempdima\outerxsep% + \edef\outerbendxradius{\the\pgfutil@tempdima}% + \addtosavedmacro\outerbendxradius% + \advance\pgfutil@tempdima-\outerxsep% + \advance\pgfutil@tempdima-\outerxsep% + \edef\innerbendxradius{\the\pgfutil@tempdima}% + \addtosavedmacro\innerbendxradius% + % + \edef\halfwidth{\the\pgf@x}% + \edef\halfheight{\the\pgf@y}% + \addtosavedmacro\halfwidth% + \addtosavedmacro\halfheight% + % + \advance\pgf@x\outerxsep% + \edef\outerhalfwidth{\the\pgf@x}% + \addtosavedmacro\outerhalfwidth% + % + \pgf@xc\bendxradius% + \pgf@yc\bendyradius% + \pgfmathdivide@{\pgfmath@tonumber{\pgf@yc}}{\pgfmath@tonumber{\pgf@xc}}% + \pgfmathatan{\pgfmathresult}% + \pgf@xc\pgfmathresult pt\relax% + \pgf@xc.5\pgf@xc% + \edef\halfangle{\pgfmath@tonumber{\pgf@xc}}% + \addtosavedmacro\halfangle% + % + \pgf@xc45pt\relax% + \advance\pgf@xc-\halfangle pt% + \pgfmathcot@{\pgfmath@tonumber{\pgf@xc}}% + \let\cothalfanglein\pgfmathresult% + \addtosavedmacro\cothalfanglein% + % + \pgf@xc90pt\relax% + \advance\pgf@xc-\halfangle pt% + \pgfmathcot@{\pgfmath@tonumber{\pgf@xc}}% + \let\cothalfangleout\pgfmathresult% + \addtosavedmacro\cothalfangleout% + % + } + \savedanchor{\centerpoint}{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor{\midpoint}{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + } + \savedanchor{\basepoint}{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \anchor{center}{\centerpoint}% + \anchor{mid}{\midpoint}% + \anchor{mid east}{\tapedimensions\midpoint\advance\pgf@x\outerhalfwidth}% + \anchor{mid west}{\tapedimensions\midpoint\advance\pgf@x-\outerhalfwidth}% + \anchor{base}{\basepoint}% + \anchor{base east}{\tapedimensions\basepoint\advance\pgf@x\outerhalfwidth}% + \anchor{base west}{\tapedimensions\basepoint\advance\pgf@x-\outerhalfwidth}% + \anchor{north}{% + \csname pgf@anchor@tape@north east\endcsname% + \pgf@ya\pgf@y% + \csname pgf@anchor@tape@north west\endcsname% + \advance\pgf@ya\pgf@y% + \centerpoint% + \pgf@y.5\pgf@ya% + } + \anchor{south}{% + \csname pgf@anchor@tape@south east\endcsname% + \pgf@ya\pgf@y% + \csname pgf@anchor@tape@south west\endcsname% + \advance\pgf@ya\pgf@y% + \centerpoint% + \pgf@y.5\pgf@ya% + } + \anchor{east}{% + \tapedimensions% + \centerpoint% + \advance\pgf@x\outerhalfwidth% + } + \anchor{west}{% + \tapedimensions% + \centerpoint% + \advance\pgf@x-\outerhalfwidth% + } + \anchor{north east}{% + \tapedimensions% + \centerpoint% + \advance\pgf@x\outerhalfwidth% + \advance\pgf@y\halfheight% + \pgf@yc\outerysep% + \ifx\topbendstyle\pgf@lib@sh@inandouttext% + \advance\pgf@y\halfbendheight% + \advance\pgf@y\cothalfangleout\pgf@yc% + \else% + \ifx\topbendstyle\pgf@lib@sh@outandintext% + \advance\pgf@y\halfbendheight% + \advance\pgf@y\cothalfanglein\pgf@yc% + \else% + \advance\pgf@y\pgf@yc% + \fi% + \fi% + }% + \anchor{north west}{% + \tapedimensions% + \centerpoint% + \advance\pgf@x-\outerhalfwidth% + \advance\pgf@y\halfheight% + \pgf@yc\outerysep% + \ifx\topbendstyle\pgf@lib@sh@inandouttext% + \advance\pgf@y\halfbendheight% + \advance\pgf@y\cothalfanglein\pgf@yc% + \else% + \ifx\topbendstyle\pgf@lib@sh@outandintext% + \advance\pgf@y\halfbendheight% + \advance\pgf@y\cothalfangleout\pgf@yc% + \else% + \advance\pgf@y\pgf@yc% + \fi% + \fi% + }% + \anchor{south east}{% + \tapedimensions% + \centerpoint% + \advance\pgf@x\outerhalfwidth% + \advance\pgf@y-\halfheight% + \pgf@yc\outerysep% + \ifx\topbendstyle\pgf@lib@sh@outandintext% + \advance\pgf@y-\halfbendheight% + \advance\pgf@y-\cothalfangleout\pgf@yc% + \else% + \ifx\topbendstyle\pgf@lib@sh@inandouttext% + \advance\pgf@y-\halfbendheight% + \advance\pgf@y-\cothalfanglein\pgf@yc% + \else% + \advance\pgf@y-\pgf@yc% + \fi% + \fi% + }% + \anchor{south west}{% + \tapedimensions% + \centerpoint% + \advance\pgf@x-\outerhalfwidth% + \advance\pgf@y-\halfheight% + \pgf@yc\outerysep% + \ifx\topbendstyle\pgf@lib@sh@outandintext% + \advance\pgf@y-\halfbendheight% + \advance\pgf@y-\cothalfanglein\pgf@yc% + \else% + \ifx\topbendstyle\pgf@lib@sh@inandouttext% + \advance\pgf@y-\halfbendheight% + \advance\pgf@y-\cothalfangleout\pgf@yc% + \else% + \advance\pgf@y-\pgf@yc% + \fi% + \fi% + }% + \backgroundpath{% + \tapedimensions% + % + \pgf@xc\halfwidth% + \pgf@yc\halfheight% + % + \pgf@xc\bendxradius% + \pgf@yc\bendyradius% + {% + \pgftransformshift{\centerpoint}% + \pgfpathmoveto{\pgfqpoint{-\halfwidth}{0pt}}% + \pgfpathlineto{\pgfqpoint{-\halfwidth}{\halfheight}}% + \ifx\topbendstyle\pgf@lib@sh@inandouttext% + \pgfpathlineto{\pgf@x-\halfwidth\pgf@y\halfheight\advance\pgf@y\halfbendheight}% + \pgfpatharc{225}{315}{\bendxradius and \bendyradius}% + \pgfpatharc{135}{45}{\bendxradius and \bendyradius}% + \else% + \ifx\topbendstyle\pgf@lib@sh@outandintext% + \pgfpathlineto{\pgf@x-\halfwidth\pgf@y\halfheight\advance\pgf@y\halfbendheight}% + \pgfpatharc{135}{45}{\bendxradius and \bendyradius}% + \pgfpatharc{225}{315}{\bendxradius and \bendyradius}% + \else% + \pgfpathlineto{\pgfqpoint{\halfwidth}{\halfheight}}% + \fi% + \fi% + \pgfpathlineto{\pgfqpoint{\halfwidth}{-\halfheight}}% + \ifx\bottombendstyle\pgf@lib@sh@inandouttext% + \pgfpathlineto{\pgf@x\halfwidth\pgf@y-\halfheight\advance\pgf@y-\halfbendheight}% + \pgfpatharc{45}{135}{\bendxradius and \bendyradius}% + \pgfpatharc{315}{225}{\bendxradius and \bendyradius}% + \else% + \ifx\bottombendstyle\pgf@lib@sh@outandintext% + \pgfpathlineto{\pgf@x\halfwidth\pgf@y-\halfheight\advance\pgf@y-\halfbendheight}% + \pgfpatharc{315}{225}{\bendxradius and \bendyradius}% + \pgfpatharc{45}{135}{\bendxradius and \bendyradius}% + \else% + \pgfpathlineto{\pgfqpoint{-\halfwidth}{-\halfheight}}% + \fi% + \fi% + \pgfpathclose% + }% + } + \anchorborder{% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgfextract@process\externalpoint{% + \centerpoint% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}% + \let\externalangle\pgfmathresult% + \tapedimensions% + % + \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@north west\endcsname}% + \ifdim\externalangle pt<\pgfmathresult pt% + \ifdim\externalangle pt<90pt% + \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@north east\endcsname}% + \ifdim\externalangle pt<\pgfmathresult pt% + \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% + {\csname pgf@anchor@tape@north east\endcsname}% + {\csname pgf@anchor@tape@south east\endcsname}% + \else% + % Between north and north east. + \ifx\topbendstyle\pgf@lib@sh@inandouttext% + % in and out. + \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}% + {% + \centerpoint% + \pgf@xc\halfwidth% + \advance\pgf@x.5\pgf@xc% + \advance\pgf@y\halfheight% + \advance\pgf@y\halfbendheight% + \pgf@yc\bendyradius% + \advance\pgf@y-.707106\pgf@yc% + }% + {5}{175}{\outerbendxradius and \outerbendyradius}% + \else% + \ifx\topbendstyle\pgf@lib@sh@outandintext% + % out and in. + \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}% + {% + \centerpoint% + \pgf@xc\halfwidth% + \advance\pgf@x.5\pgf@xc% + \advance\pgf@y\halfheight% + \advance\pgf@y\halfbendheight% + \pgf@yc\bendyradius% + \advance\pgf@y.707106\pgf@yc% + }% + {185}{355}{\innerbendxradius and \innerbendyradius}% + \else% + \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% + {\csname pgf@anchor@tape@north east\endcsname}% + {\csname pgf@anchor@tape@north west\endcsname}% + \fi% + \fi% + \fi% + \else% + % Between north and north west. + \ifx\topbendstyle\pgf@lib@sh@inandouttext% + % in and out. + \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}% + {% + \centerpoint% + \pgf@xc\halfwidth% + \advance\pgf@x-.5\pgf@xc% + \advance\pgf@y\halfheight% + \advance\pgf@y\halfbendheight% + \pgf@yc\bendyradius% + \advance\pgf@y.707106\pgf@yc% + }% + {185}{355}{\innerbendxradius and \innerbendyradius}% + \else% + \ifx\topbendstyle\pgf@lib@sh@outandintext% + % out and in. + \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}% + {% + \centerpoint% + \pgf@xc\halfwidth% + \advance\pgf@x-.5\pgf@xc% + \advance\pgf@y\halfheight% + \advance\pgf@y\halfbendheight% + \pgf@yc\bendyradius% + \advance\pgf@y-.707106\pgf@yc% + }% + {5}{175}{\outerbendxradius and \outerbendyradius}% + \else% + \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% + {\csname pgf@anchor@tape@north east\endcsname}% + {\csname pgf@anchor@tape@north west\endcsname}% + \fi% + \fi% + \fi% + \else% + \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@south west\endcsname}% + \ifdim\externalangle pt>\pgfmathresult pt% + \ifdim\externalangle pt>270pt% + \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@south east\endcsname}% + \ifdim\externalangle pt>\pgfmathresult pt% + \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% + {\csname pgf@anchor@tape@north east\endcsname}% + {\csname pgf@anchor@tape@south east\endcsname}% + \else% + % Between south and south east. + \ifx\bottombendstyle\pgf@lib@sh@inandouttext% + % in and out. + \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}% + {% + \centerpoint% + \pgf@xc\halfwidth% + \advance\pgf@x.5\pgf@xc% + \advance\pgf@y-\halfheight% + \advance\pgf@y-\halfbendheight% + \pgf@yc\bendyradius% + \advance\pgf@y-.707106\pgf@yc% + }% + {5}{175}{\innerbendxradius and \innerbendyradius}% + \else% + \ifx\bottombendstyle\pgf@lib@sh@outandintext% + % out and in. + \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}% + {% + \centerpoint% + \pgf@xc\halfwidth% + \advance\pgf@x.5\pgf@xc% + \advance\pgf@y-\halfheight% + \advance\pgf@y-\halfbendheight% + \pgf@yc\bendyradius% + \advance\pgf@y.707106\pgf@yc% + }% + {185}{355}{\outerbendxradius and \outerbendyradius}% + \else% + \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% + {\csname pgf@anchor@tape@south east\endcsname}% + {\csname pgf@anchor@tape@south west\endcsname}% + \fi% + \fi% + \fi% + \else% + % Between south and south west. + \ifx\bottombendstyle\pgf@lib@sh@inandouttext% + % in and out. + \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}% + {% + \centerpoint% + \pgf@xc\halfwidth% + \advance\pgf@x-.5\pgf@xc% + \advance\pgf@y-\halfheight% + \advance\pgf@y-\halfbendheight% + \pgf@yc\bendyradius% + \advance\pgf@y.707106\pgf@yc% + }% + {185}{355}{\outerbendxradius and \outerbendyradius}% + \else% + \ifx\bottombendstyle\pgf@lib@sh@outandintext% + % out and in. + \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}% + {% + \centerpoint% + \pgf@xc\halfwidth% + \advance\pgf@x-.5\pgf@xc% + \advance\pgf@y-\halfheight% + \advance\pgf@y-\halfbendheight% + \pgf@yc\bendyradius% + \advance\pgf@y-.707106\pgf@yc% + }% + {5}{175}{\innerbendxradius and \innerbendyradius}% + \else% + \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% + {\csname pgf@anchor@tape@south east\endcsname}% + {\csname pgf@anchor@tape@south west\endcsname}% + \fi% + \fi% + \fi% + \else% + \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% + {\csname pgf@anchor@tape@north west\endcsname}% + {\csname pgf@anchor@tape@south west\endcsname}% + \fi% + \fi% + }% } @@ -2565,7 +2607,169 @@ {\pgfpointpolar{\pgfkeysvalueof{/pgf/magnifying glass handle angle}}{\pgfutil@tempdima}}} \pgfpathlineto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}} {\pgfpointpolar{\pgfkeysvalueof{/pgf/magnifying glass handle angle}}{\pgfutil@tempdima+\pgfutil@tempdima*(\pgfkeysvalueof{/pgf/magnifying glass handle aspect})}}} + \pgfsetarrowsstart{} + \pgfsetarrowsend{} } } +\pgfkeys{% + /pgf/magnetic tape tail/.initial=0.15, + /pgf/magnetic tape tail extend/.initial=0cm, +} +\pgfdeclareshape{magnetic tape}{ + \nodeparts{text} + \savedmacro\installparameters{% + % + \pgf@x=0.5\wd\pgfnodeparttextbox% + \pgf@y=0.5\ht\pgfnodeparttextbox% + \advance\pgf@y by-0.5\dp\pgfnodeparttextbox% + \edef\centerpoint{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + % + \pgf@x=\wd\pgfnodeparttextbox% + \pgf@y=\ht\pgfnodeparttextbox% + \advance\pgf@y by\dp\pgfnodeparttextbox% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}% + \advance\pgf@x by2.0\pgf@xa% + \advance\pgf@y by2.0\pgf@ya% + \ifdim\pgf@y>\pgf@x% + \pgf@x=\pgf@y% + \fi% + \pgf@x=1.414213\pgf@x% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgf@x<\pgf@xa% + \pgf@x=\pgf@xa% + \fi% + \ifdim\pgf@x<\pgf@ya% + \pgf@x=\pgf@ya% + \fi% + \pgf@x=0.5\pgf@x% + \edef\radius{\the\pgf@x}% + % + \pgfmathparse{max(\pgfkeysvalueof{/pgf/magnetic tape tail extend},0)}% + \edef\tailextend{\pgfmathresult pt}% + % + \pgfmathparse{min(max(\pgfkeysvalueof{/pgf/magnetic tape tail},0),1)}% + \pgf@xa=\pgfmathresult\pgf@x% + \edef\tailheight{\the\pgf@xa}% + % + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@xa<\pgf@ya% + \pgf@xa=\pgf@ya% + \fi% + \edef\outersep{\the\pgf@xa}% + % + \pgfmathparse{\outersep+\radius}% + \edef\outerradius{\pgfmathresult pt}% + % + \pgfmathparse{(\radius-\tailheight)/\radius}% + \pgfmathasin@{\pgfmathresult}% + \pgfmathadd@{-\pgfmathresult}{360}% + \let\tailangle=\pgfmathresult% + % + \pgfmathparse{\outerradius/(\outerradius+\tailextend)}% + \pgfmathatan@{\pgfmathresult}% + \pgfmathadd@{-\pgfmathresult}{360}% + \let\tailbottomangle=\pgfmathresult% + % + \pgfmathparse{(\outerradius-\outersep-\tailheight-\outersep)/(\outerradius+\tailextend)}% + \pgfmathatan@{\pgfmathresult}% + \pgfmathadd@{-\pgfmathresult}{360}% + \let\tailtopangle=\pgfmathresult% + % + \addtosavedmacro\radius% + \addtosavedmacro\outerradius% + \addtosavedmacro\outersep% + \addtosavedmacro\tailheight% + \addtosavedmacro\tailextend + \addtosavedmacro\tailangle% + \addtosavedmacro\tailtopangle% + \addtosavedmacro\tailbottomangle% + \addtosavedmacro\centerpoint% + } + \savedanchor{\base}{\pgfqpoint{0.5\wd\pgfnodeparttextbox}{0pt}} + \savedanchor{\mid}{\pgfqpoint{0.5\wd\pgfnodeparttextbox}{0pt}\pgfmathsetlength\pgf@y{.5ex}} + \anchor{center}{\installparameters\centerpoint}% \addtosavedmacro\outerradius% + \anchor{base}{\base} + \anchor{mid}{\mid} + \anchor{base west}{\installparameters\pgfpointadd{\base}{\pgfqpoint{-\outerradius}{0pt}}} + \anchor{base east}{\installparameters\pgfpointadd{\base}{\pgfqpoint{\outerradius}{0pt}}} + \anchor{mid west}{\installparameters\pgfpointadd{\mid}{\pgfqpoint{-\outerradius}{0pt}}} + \anchor{mid east}{\installparameters\pgfpointadd{\mid}{\pgfqpoint{\outerradius}{0pt}}} + \anchor{north}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfqpoint{0pt}{\outerradius}}} + \anchor{north east}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfqpointpolar{45}{\outerradius}}} + \anchor{south}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfqpoint{0pt}{-\outerradius}}} + \anchor{south east}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfqpoint{\outerradius}{-\outerradius}}} + \anchor{east}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfqpoint{\outerradius}{0pt}}} + \anchor{south west}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfqpointpolar{225}{\outerradius}}} + \anchor{west}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfqpoint{-\outerradius}{0pt}}} + \anchor{north west}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfqpointpolar{135}{\outerradius}}} + \anchor{tail east}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfpoint{\radius+\tailextend+\outersep}{-\outerradius+\outersep+\tailheight/2}}} + \anchor{tail south east}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfpoint{\radius+\tailextend+\outersep}{-\outerradius}}} + \anchor{tail north east}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfpoint{\radius+\tailextend+\outersep}{-\outerradius+\outersep+\tailheight+\outersep}}} + \backgroundpath{ + % + \installparameters% + {% + \pgftransformshift{\centerpoint}% + \pgfpathmoveto{\pgfpointpolar{\tailangle}{\radius}}% + \pgfpatharc{\tailangle}{360}{\radius}% + \pgfpatharc{0}{270}{\radius}% + \pgfpathlineto{\pgfpoint{\radius+\tailextend}{-\radius}}% + \pgfpathlineto{\pgfpoint{\radius+\tailextend}{-\radius+\tailheight}}% + \pgfpathclose% + }% + } + \anchorborder{% + \pgfextract@process\externalpoint{}% + \installparameters% + \pgfmathanglebetweenpoints{\pgfpointorigin}{\externalpoint} + \ifdim\pgfmathresult pt<270pt\relax% + \pgfpointadd{\centerpoint}{% + \pgfpointborderellipse% + {\externalpoint}% + {\pgfqpoint{\outerradius}{\outerradius}}% + }% + \else% + \ifdim\pgfmathresult pt<\tailbottomangle pt\relax% + \pgfpointadd{\centerpoint}{% + \pgfpointintersectionoflines% + {\externalpoint}{\pgfpointorigin}% + {\pgfqpoint{0pt}{-\outerradius}}{\pgfqpoint{\outerradius}{-\outerradius}}% + }% + \else% + \ifdim\pgfmathresult pt<\tailtopangle pt\relax% + \pgfpointadd{\centerpoint}{% + \pgfpointintersectionoflines% + {\externalpoint}{\pgfpointorigin}% + {\pgfqpoint{\outerradius}{\outerradius}}{\pgfqpoint{\outerradius}{-\outerradius}}% + }% + \else% + \pgfpointadd{\centerpoint}{% + \pgfpointborderellipse% + {\externalpoint}% + {\pgfqpoint{\outerradius}{\outerradius}}% + }% + \fi% + \fi% + \fi% + } +} + +% Local Variables: +% tab-width: 2 +% End:
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/lua/pgf/manual.lua b/Master/texmf-dist/tex/generic/pgf/lua/pgf/manual.lua new file mode 100644 index 00000000000..583777075df --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/lua/pgf/manual.lua @@ -0,0 +1,18 @@ +-- Copyright 2013 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/lua/pgf/manual.lua,v 1.1 2013/05/23 20:01:29 tantau Exp $ + + + +local manual = {} + +require 'pgf'.manual = manual + +return manual diff --git a/Master/texmf-dist/tex/generic/pgf/lua/pgf/manual/DocumentParser.lua b/Master/texmf-dist/tex/generic/pgf/lua/pgf/manual/DocumentParser.lua new file mode 100644 index 00000000000..3905f348358 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/lua/pgf/manual/DocumentParser.lua @@ -0,0 +1,596 @@ +-- Copyright 2013 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/lua/pgf/manual/DocumentParser.lua,v 1.2 2013/08/01 16:02:22 tantau Exp $ + + + +--- +-- This class offers functions for converting the documentation of Lua +-- and other code into \TeX. +-- +-- @field renderers This array must consist of tables having two +-- fields: |test| and |renderer|. The first must be set to a function +-- that is called with an information table as parameter and must +-- return |true| if the funciton stored in the |renderer| should be +-- called. (Typically, the |test| will test whether the ``head line'' +-- following a documentation block has a special form.) + +local DocumentParser = { + renderers = {} +} + +-- Namespace: +require 'pgf.manual'.DocumentParser = DocumentParser + +-- Imports +local keys = require 'pgf.gd.interface.InterfaceCore'.keys + +-- Forwards: + +local collect_infos, render_infos + + +--- +-- Includes the documentation stored in some file in the manual. +-- +-- @param filename The file from which the documentation is to be read +-- @param type The type of the file. + +function DocumentParser.include(filename, typ) + + local fullname = assert(kpse.find_file(filename:gsub("%.", "/"), typ or "lua") + or kpse.find_file(filename:gsub("%.", "\\"), typ or "lua"), + "file " .. filename .. " not found") + + local file, error = io.open(fullname) + + -- First, let us read the file into a table to make handling easier: + local lines = {} + + for line in file:lines() do + lines [#lines + 1] = line + end + + -- A table storing the current output. The array part contains TeX + -- lines, the table part contains information about special table.s + local output = {} + + -- Now, start the main parser loop. + local i = 1 + while i <= #lines do + + if lines[i]:match("^%-%-%-") then + local infos = collect_infos (lines, i) + + infos.filename = filename + + render_infos(infos, output) + + i = infos.last_line + end + + i = i + 1 + end + + -- Render output: + for _,l in ipairs(output) do + if type(l) == "string" then + tex.print(l) + else + l() + end + end + +end + + + +--- +-- Add a test and a renderer to the array of renderers. +-- +-- @param test A test function (see |DocumentParser.renderers|). +-- @param renderer A rendering function. + +function DocumentParser.addRenderer (test, renderer) + DocumentParser.renderers [#DocumentParser.renderers + 1] = + { test = test, renderer = renderer } +end + + +-- Forwards: +local print_on_output, print_on_output_escape, print_docline_on_output, open_mode, close_mode, print_lines_on_output + + + +local function strip_quotes(s) + if s then return string.gsub(s, '^"(.*)"$', "%1") end +end + +local function split(s) + local t = {} + for line in string.gmatch(s, ".-\n") do + t[#t+1] = line + end + for i=#t,1,-1 do + if t[i]:match("^%s*$") then + t[i] = nil + else + return t + end + end + return t +end + + +local function process_string(s) + if s then + local t = split(s.."\n") + -- Compute min spaces + local min = math.huge + for _,l in ipairs(t) do + min = math.min(min, string.find(l, "%S") or math.huge) + end + if min < math.huge then + -- Now, trim 'em all! + for i=1,#t do + t[i] = string.sub(t[i],min,-2) + end + end + return t + end +end + + +local function process_examples(t) + if not t then + return nil + end + + if type(t) == "string" then + t = {t} + end + + local n = {} + for i=1,#t do + n[i] = process_string(strip_quotes(t[i])) + end + return n +end + + + +-- The standard renderers: + + +-- The function renderer +DocumentParser.addRenderer ( + function (infos) + -- The test + return + infos.keywords["function"] or + infos.head_line:match("^%s*function%s+") or + infos.head_line:match("^%s*local%s+function%s+") + end, + function (infos, output) + -- The renderer + + if infos.keywords["function"] then + local k = infos.keywords["function"][1] + infos.head_line = k:match("^%s*@(.*)") + end + + local rest = infos.head_line:match("function%s+(.*)") + local tab = rest:match("([^(]*[%.%:]).*") + local fun = rest:match("[^(]*[%.%:](.-)%s*%(") or rest:match("(.-)%s*%(") + local pars = rest:match(".-%((.*)%)") + + -- Render the head + print_on_output_escape(output, [[\begin{luacommand}]]) + output[#output+1] = "{" .. (tab or "") .. fun .. "}" + print_on_output_escape(output, + "{", tab or "", "}", + "{", fun, "}", + "{", pars, "}") + + if tab then + local table_name = tab:sub(1,-2) + local t = output[table_name] or {} + t[#t+1] = { + link = "pgf/lua/" .. tab .. fun, + text = "function " .. tab .. "\\declare{" .. fun .. "} (" .. pars .. ")" + } + output[table_name] = t + end + + local mode = "text" + for _,l in ipairs(infos.doc_lines) do + if mode ~= "done" then + mode = print_docline_on_output(output, l, mode) + end + end + close_mode(output, mode) + + print_on_output(output, [[\end{luacommand}]]) + + end +) + + +-- The table renderer +DocumentParser.addRenderer ( + function (infos) + -- The test + return + infos.keywords["table"] or + infos.head_line:match("=%s*{") + end, + function (infos, output) + -- The renderer + + if infos.keywords["table"] then + local k = infos.keywords["table"][1] + infos.head_line = k:match("^%s*@table(.*)") .. "=" + end + + local name = + infos.head_line:match("^%s*local%s+(.-)%s*=") or + infos.head_line:match("^%s*(.*)%s*=") + + -- Render the head + print_on_output_escape(output, + [[\begin{luatable}]], + "{", name:match("(.*[%.%:]).*") or "", "}", + "{", name:match(".*[%.%:](*-)") or name,"}", + "{", infos.filename, "}") + + local mode = "text" + for _,l in ipairs(infos.doc_lines) do + mode = print_docline_on_output(output, l, mode) + end + close_mode(output, mode) + + output[#output+1] = + function () + if output[name] then + tex.print("\\par\\emph{Alphabetical method summary:}\\par{\\small") + table.sort(output[name], function (a,b) return a.text < b.text end) + for _,l in ipairs(output[name]) do + tex.print("\\texttt{\\hyperlink{" .. l.link .. "}{" .. l.text:gsub("_", "\\_") .. "}}\\par") + end + tex.print("}") + end + end + + print_on_output(output, [[\end{luatable}]]) + + end +) + + + +-- The library renderer +DocumentParser.addRenderer ( + function (infos) + -- The test + return infos.keywords["library"] + end, + function (infos, output) + -- The renderer + + local name = infos.filename:gsub("%.library$",""):gsub("^pgf%.gd%.","") + + -- Render the head + print_on_output_escape(output, "\\begin{lualibrary}{", name, "}") + + local mode = "text" + for _,l in ipairs(infos.doc_lines) do + mode = print_docline_on_output(output, l, mode) + end + close_mode(output, mode) + + print_on_output(output, "\\end{lualibrary}") + + end +) + + +-- The section renderer +DocumentParser.addRenderer ( + function (infos) + -- The test + return infos.keywords["section"] + end, + function (infos, output) + -- The renderer + local mode = "text" + for _,l in ipairs(infos.doc_lines) do + mode = print_docline_on_output(output, l, mode) + end + close_mode(output, mode) + end +) + + +-- The documentation (plain text) renderer +DocumentParser.addRenderer ( + function (infos) + -- The test + return infos.keywords["documentation"] + end, + function (infos, output) + -- The renderer + local mode = "text" + for _,l in ipairs(infos.doc_lines) do + mode = print_docline_on_output(output, l, mode) + end + close_mode(output, mode) + end +) + + +-- The declare renderer +DocumentParser.addRenderer ( + function (infos) + -- The test + return + infos.keywords["declare"] or + infos.head_line:match("declare%s*{") or + infos.head_line:match("^%s*key%s*") + end, + function (infos, output) + -- The renderer + + local key_name + + if infos.keywords["declare"] then + local k = infos.keywords["declare"][1] + key_name = k:match("^%s*@declare%s*(.*)") + elseif infos.head_line:match("^%s*key%s*") then + key_name = infos.head_line:match('^%s*key%s*"(.*)"') or + infos.head_line:match("^%s*key%s*'(.*)'") + else + local l = infos.lines [infos.last_line + 1] + key_name = l:match('key%s*=%s*"(.*)"') or l:match("key%s*=%s*'(.*)'") + end + + assert (key_name, "could not determine key") + local key = assert (keys[key_name], "unknown key '" .. key_name .. "'") + + -- Render the head + if key.type then + print_on_output_escape(output, + "\\begin{luadeclare}", + "{", key.key, "}", + "{\\meta{", key.type, "}}", + "{", key.default or "", "}", + "{", key.initial or "", "}") + else + print_on_output_escape(output, + "\\begin{luadeclarestyle}", + "{", key.key, "}", + "{}", + "{", key.default or "", "}", + "{", key.initial or "", "}") + end + + + local mode = "text" + + print_lines_on_output(output, process_string(strip_quotes(key.summary))) + print_lines_on_output(output, process_string(strip_quotes(key.documentation))) + + if key.examples then + local e = process_examples(key.examples) + print_on_output(output, + "\\par\\smallskip\\emph{Example" .. (((#e>1) and "s") or "") .. "}\\par") + for _,example in ipairs(e) do + print_on_output(output, "\\begin{codeexample}[]") + print_lines_on_output(output, example) + print_on_output(output, "\\end{codeexample}") + end + end + + print_on_output(output, key.type and "\\end{luadeclare}" or "\\end{luadeclarestyle}") + end +) + + + +-- The empty line +DocumentParser.addRenderer ( + function (infos) + -- The test + return + #infos.doc_lines == 1 and + infos.doc_lines[1]:match("^%-*%s*$") + end, + function (infos, output) + end +) + + +function print_lines_on_output(output, lines) + for _,l in ipairs(lines or {}) do + output[#output+1] = l + end +end + +function print_on_output(output, ...) + local args = {...} + if #args > 0 then + for i = 1, #args do + args[i] = tostring(args[i]) + end + output[#output+1] = table.concat(args) + end +end + +function print_on_output_escape(output, ...) + local args = {...} + if #args > 0 then + for i = 1, #args do + args[i] = tostring(args[i]):gsub("_", "\\_") + end + output[#output+1] = table.concat(args) + end +end + + +function print_docline_on_output(output, l, mode) + + if l:match("^%s*@section") then + print_on_output(output, "\\", l:match("%s*@section%s*(.*)")) + elseif l:match("^%s*@param%s+") then + if mode ~= "param" then + close_mode (output, mode) + mode = open_mode (output, "param") + end + print_on_output(output, "\\item[\\texttt{", + l:match("%s@param%s+(.-)%s"):gsub("_", "\\_"), + "}] ", + l:match("%s@param%s+.-%s+(.*)")) + elseif l:match("^%s*@return%s+") then + if mode ~= "return" then + close_mode (output, mode) + mode = open_mode (output, "returns") + end + print_on_output(output, "\\item[]", l:match("%s@return%s+(.*)")) + elseif l:match("^%s*@see%s+") then + if mode ~= "text" then + close_mode (output, mode) + mode = open_mode (output, "text") + end + print_on_output(output, "\\par\\emph{See also:} \\texttt{", + l:match("%s@see%s+(.*)"):gsub("_", "\\_"), + "}") + elseif l:match("^%s*@usage%s+") then + if mode ~= "text" then + close_mode (output, mode) + mode = open_mode (output, "text") + end + print_on_output(output, "\\par\\emph{Usage:} ", + l:match("%s@usage%s+(.*)")) + elseif l:match("^%s*@field+") then + close_mode (output, mode) + mode = open_mode (output, "field") + print_on_output(output, "{", + (l:match("%s@field%s+(.-)%s") or l:match("%s@field%s+(.*)")):gsub("_", "\\_"), + "}", + l:match("%s@field%s+.-%s+(.*)")) + elseif l:match("^%s*@done") or l:match("^%s*@text") then + close_mode(output, mode) + print_on_output(output, l) + + mode = "text" + elseif l:match("^%s*@library") then + -- do nothing + elseif l:match("^%s*@end") then + close_mode(output, mode) + mode = "done" + elseif l:match("^%s*@") then + error("Unknown mark " .. l) + else + print_on_output(output, l) + end + + return mode +end + +function open_mode (output, mode) + if mode == "param" then + print_on_output(output, "\\begin{luaparameters}") + elseif mode == "field" then + print_on_output(output, "\\begin{luafield}") + elseif mode == "returns" then + print_on_output(output, "\\begin{luareturns}") + end + return mode +end + +function close_mode (output, mode) + if mode == "param" then + print_on_output(output, "\\end{luaparameters}") + elseif mode == "field" then + print_on_output(output, "\\end{luafield}") + elseif mode == "returns" then + print_on_output(output, "\\end{luareturns}") + end + return mode +end + + +function collect_infos (lines, i, state) + + local doc_lines = {} + + local keywords = {} + + local function find_keywords(line) + local keyword = line:match("^%s*@([^%s]*)") + if keyword then + local t = keywords[keyword] or {} + t[#t+1] = line + keywords[keyword] = t + end + return line + end + + -- Copy triple matches: + while lines[i] and lines[i]:match("^%-%-%-") do + doc_lines [#doc_lines + 1] = find_keywords(lines[i]:sub(4)) + i = i + 1 + end + + -- Continue with double matches: + while lines[i] and lines[i]:match("^%-%-") do + doc_lines [#doc_lines + 1] = find_keywords(lines[i]:sub(3)) + i = i + 1 + end + + local head_line = "" + + if not keywords["end"] then + -- Skip empty lines + while lines[i] and lines[i]:match("^%s*$") do + i = i + 1 + end + head_line = lines[i] or "" + if lines[i] and lines[i]:match("^%-%-%-") then + i = i - 1 + end + end + + return { + lines = lines, + last_line = i, + doc_lines = doc_lines, + keywords = keywords, + head_line = head_line + } + +end + + + +function render_infos(infos, state) + + for _,renderer in ipairs(DocumentParser.renderers) do + if renderer.test (infos, state) then + renderer.renderer (infos, state) + return + end + end + + pgf.debug(infos) + error("Unkown documentation type") +end + + +return DocumentParser diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex index 9c51dc46117..0c11f544594 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex @@ -7,6 +7,11 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. +\ifx\pgfmathsetlength\undefined +\else + \expandafter\endinput +\fi + \input pgfmathcalc.code.tex \ifx\pgfkeysloaded\undefined @@ -15,3 +20,4 @@ \expandafter\input pgfmathfloat.code.tex \fi +\endinput
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathcalc.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathcalc.code.tex index c1f099ce160..5cc58e62e5d 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathcalc.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathcalc.code.tex @@ -33,21 +33,24 @@ % parsed assignment. \def\pgfmathsetlength#1#2{% - \expandafter\pgfmath@onquick#2\pgfmath@% - {% - % Ok, quick version: - \begingroup% - \pgfmath@selectfont% - \pgfmath@x#2\unskip% - \pgfmath@returnone\pgfmath@x% - \endgroup% - #1\pgfmathresult pt\relax% - }% - {% - \pgfmathparse{#2}% - #1\pgfmathresult pt\relax% - }% - \ignorespaces% + \expandafter\pgfmath@onquick#2\pgfmath@% + {% + % Ok, quick version: + \begingroup% + \pgfmath@selectfont% + #1#2\unskip% + \expandafter\endgroup% + \expandafter#1\the#1\relax% + }% + {% + \pgfmathparse{#2}% + \ifpgfmathmathunitsdeclared% + #1\pgfmathresult mu\relax% + \else% + #1\pgfmathresult pt\relax% + \fi% + }% + \ignorespaces% } % \pgfmathaddtolength @@ -58,19 +61,22 @@ % #2 - an expression % \def\pgfmathaddtolength#1#2{% - \expandafter\pgfmath@onquick#2\pgfmath@% + \expandafter\pgfmath@onquick#2\pgfmath@% {% - \begingroup% - \pgfmath@selectfont% - \pgfmath@x#1\relax% - \advance\pgfmath@x#2\unskip% - \pgfmath@returnone\pgfmath@x% + \begingroup% + \pgfmath@selectfont% + \advance#1#2\unskip% + \expandafter% \endgroup% - #1\pgfmathresult pt\relax% + \expandafter#1\the#1\relax% }% {% - \pgfmathparse{#2}% - \advance#1\pgfmathresult pt\relax% + \pgfmathparse{#2}% + \ifpgfmathmathunitsdeclared% + \advance#1\pgfmathresult mu\relax% + \else% + \advance#1\pgfmathresult pt\relax% + \fi% }% \ignorespaces% } @@ -135,11 +141,11 @@ % \thecounter (same as \the\c@counter) % \def\pgfmathnewcounter#1{% - \expandafter\ifx\csname c@#1\endcsname\relax% - \def\pgfmath@marshal{\csname newcount\endcsname}% Ha! Who cares about \outer? - \expandafter\pgfmath@marshal\csname c@#1\endcsname% - \expandafter\def\csname the#1\endcsname{\expandafter\the\csname c@#1\endcsname}% - \fi% + \expandafter\ifx\csname c@#1\endcsname\relax% + \def\pgfmath@marshal{\csname newcount\endcsname}% Ha! Who cares about \outer? + \expandafter\pgfmath@marshal\csname c@#1\endcsname% + \expandafter\def\csname the#1\endcsname{\expandafter\the\csname c@#1\endcsname}% + \fi% } % \pgfmathsetcounter @@ -150,7 +156,7 @@ % #2 - an expression % \def\pgfmathsetcounter#1#2{% - \expandafter\pgfmathsetcount\csname c@#1\endcsname{#2}% + \expandafter\pgfmathsetcount\csname c@#1\endcsname{#2}% } % \pgfmathaddtocounter @@ -173,17 +179,17 @@ \def\pgfmath@pgftext{pgf} \def\pgfmath@tikztext{tikz} \def\pgfmathmakecounterglobal#1{% - \pgfmath@ifundefined{c@#1}{}{% - \expandafter\pgfmath@in@\expandafter{\pgfmath@pgftext}{#1}% - \ifpgfmath@in@% - \else% - \expandafter\pgfmath@in@\expandafter{\pgfmath@tikztext}{#1}% - \ifpgfmath@in@% - \else% - \expandafter\global\csname c@#1\endcsname\csname c@#1\endcsname\relax% - \fi% - \fi% - }% + \pgfmath@ifundefined{c@#1}{}{% + \expandafter\pgfmath@in@\expandafter{\pgfmath@pgftext}{#1}% + \ifpgfmath@in@% + \else% + \expandafter\pgfmath@in@\expandafter{\pgfmath@tikztext}{#1}% + \ifpgfmath@in@% + \else% + \expandafter\global\csname c@#1\endcsname\csname c@#1\endcsname\relax% + \fi% + \fi% + }% } % \pgfmathsetmacro @@ -194,11 +200,11 @@ % #2 - an expression % \def\pgfmathsetmacro#1#2{% - \begingroup% - \pgfmathsetlength\pgfmath@x{#2}% - \edef#1{\pgfmath@tonumber{\pgfmath@x}}% - \pgfmath@smuggleone{#1}% - \endgroup% + \begingroup% + \pgfmathparse{#2}% + \let#1=\pgfmathresult + \pgfmath@smuggleone{#1}% + \endgroup% } % \pgfmathsetlengthmacro @@ -209,11 +215,11 @@ % #2 - an expression % \def\pgfmathsetlengthmacro#1#2{% - \begingroup% - \pgfmathsetlength\pgfmath@x{#2}% - \edef#1{\the\pgfmath@x}% - \pgfmath@smuggleone{#1}% - \endgroup% + \begingroup% + \pgfmathsetlength\pgfmath@x{#2}% + \edef#1{\the\pgfmath@x}% + \pgfmath@smuggleone{#1}% + \endgroup% } % \pgfmathtruncatemacro @@ -224,11 +230,11 @@ % #2 - an expression % \def\pgfmathtruncatemacro#1#2{% - \begingroup% - \pgfmathsetcount\c@pgfmath@counta{#2}% - \edef#1{\the\c@pgfmath@counta}% - \pgfmath@smuggleone{#1}% - \endgroup% + \begingroup% + \pgfmathsetcount\c@pgfmath@counta{#2}% + \edef#1{\the\c@pgfmath@counta}% + \pgfmath@smuggleone{#1}% + \endgroup% } % Check whether a given parameter starts with quick. @@ -247,72 +253,33 @@ \futurelet\pgfmath@next% \pgfmath@@onquick} \def\pgfmath@@onquick#1\pgfmath@{% - \ifx\pgfmath@next+% - \let\pgfmath@next=\pgfmath@firstoftwo% - \else% - \let\pgfmath@next=\pgfmath@secondoftwo% - \fi% - \pgfmath@next% + \ifx\pgfmath@next+% + \let\pgfmath@next=\pgfmath@firstoftwo% + \else% + \let\pgfmath@next=\pgfmath@secondoftwo% + \fi% + \pgfmath@next% } % *** The following commands DO NOT WORK without the rest of PGF *** % % (a dumping ground for stuff that doesn't really belong anywhere else) - + % \pgfmathanglebetweenpoints % % Define \pgfmathresult as the angle between points #1 and #2 % Should get the quadrants right as well. % \def\pgfmathanglebetweenpoints#1#2{% - \begingroup% - \pgf@process{\pgfpointdiff{#1}{#2}}% - % - % First approximate the angle of the external point... - % - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \pgf@xb\pgf@x% - \pgf@yb\pgf@y% - \ifdim\pgf@xa<0pt\relax% - \pgf@xa-\pgf@xa% - \fi% - \ifdim\pgf@ya<0pt\relax% - \pgf@ya-\pgf@ya% - \fi% - \ifdim\pgf@ya>\pgf@xa% - \pgf@x\pgf@xa% - \pgf@y\pgf@ya% - \else% - \pgf@x\pgf@ya% - \pgf@y\pgf@xa% - \fi% - \ifdim\pgf@y=0pt\relax% - \pgf@x0pt% - \else% - \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@y}}% - \pgf@x\pgfmathresult\pgf@x% - \fi% - \multiply\pgf@x1000\relax% - \afterassignment\pgfmath@gobbletilpgfmath@% - \expandafter\c@pgf@counta\the\pgf@x\relax\pgfmath@% - \expandafter\pgf@x\csname pgfmath@atan@\the\c@pgf@counta\endcsname pt\relax% - \ifdim\pgfmath@ya>\pgfmath@xa\relax% - \pgf@x-\pgf@x% - \advance\pgf@x90pt% - \fi% - \ifdim\pgf@xb<0pt% - \ifdim\pgf@yb>0pt% - \pgf@x-\pgf@x% - \fi% - \advance\pgf@x180pt\relax% - \else% - \ifdim\pgf@yb<0pt% - \pgf@x-\pgf@x% - \advance\pgf@x360pt\relax% - \fi\fi% - \pgfmath@returnone\pgf@x% - \endgroup% + \begingroup% + \pgf@process{\pgfpointdiff{#1}{#2}}% + \edef\pgf@marshall{\expandafter\noexpand\csname pgfmathatan2@\endcsname{\expandafter\Pgf@geT\the\pgf@y}{\expandafter\Pgf@geT\the\pgf@x}}% + \pgf@marshall% + \ifdim\pgfmathresult pt<0pt% + \pgfmathparse{\pgfmathresult+360}% + \fi% + \expandafter% + \endgroup\expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult}% } % @@ -321,33 +288,33 @@ % Rotate point #1 about point #2 by #3 degrees. % \def\pgfmathrotatepointaround#1#2#3{% - \pgf@process{% - \pgf@process{#1}% - \pgf@xc=\pgf@x% - \pgf@yc=\pgf@y% - \pgf@process{#2}% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \pgf@xb\pgf@x% - \pgf@yb\pgf@y% - \pgf@x=\pgf@xc% - \pgf@y=\pgf@yc% - \advance\pgf@x-\pgf@xa% - \advance\pgf@y-\pgf@ya% - \pgfmathsetmacro\angle{#3}% - \pgfmathsin@{\angle}% - \let\sineangle\pgfmathresult% - \pgfmathcos@{\angle}% - \let\cosineangle\pgfmathresult% - \pgf@xa\cosineangle\pgf@x% - \advance\pgf@xa-\sineangle\pgf@y% - \pgf@ya\sineangle\pgf@x% - \advance\pgf@ya\cosineangle\pgf@y% - \pgf@x\pgf@xb% - \pgf@y\pgf@yb% - \advance\pgf@x\pgf@xa% - \advance\pgf@y\pgf@ya% - }% + \pgf@process{% + \pgf@process{#1}% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \pgf@process{#2}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgf@xb\pgf@x% + \pgf@yb\pgf@y% + \pgf@x=\pgf@xc% + \pgf@y=\pgf@yc% + \advance\pgf@x-\pgf@xa% + \advance\pgf@y-\pgf@ya% + \pgfmathsetmacro\angle{#3}% + \pgfmathsin@{\angle}% + \let\sineangle\pgfmathresult% + \pgfmathcos@{\angle}% + \let\cosineangle\pgfmathresult% + \pgf@xa\cosineangle\pgf@x% + \advance\pgf@xa-\sineangle\pgf@y% + \pgf@ya\sineangle\pgf@x% + \advance\pgf@ya\cosineangle\pgf@y% + \pgf@x\pgf@xb% + \pgf@y\pgf@yb% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% } % \pgfmathanglebetweenlines @@ -356,18 +323,18 @@ % to point #2 and a line from #3 to point #4. % \def\pgfmathanglebetweenlines#1#2#3#4{% - \begingroup% - \pgfmathanglebetweenpoints{#1}{#2}% - \let\firstangle\pgfmathresult% - \pgfmathanglebetweenpoints{#3}{#4}% - \let\secondangle\pgfmathresult% - \ifdim\firstangle pt>\secondangle pt\relax% - \pgfmathadd@{\secondangle}{360}% - \let\secondangle\pgfmathresult% - \fi% - \pgfmathsubtract@{\secondangle}{\firstangle}% - \pgfmath@smuggleone\pgfmathresult% - \endgroup% + \begingroup% + \pgfmathanglebetweenpoints{#1}{#2}% + \let\firstangle\pgfmathresult% + \pgfmathanglebetweenpoints{#3}{#4}% + \let\secondangle\pgfmathresult% + \ifdim\firstangle pt>\secondangle pt\relax% + \pgfmathadd@{\secondangle}{360}% + \let\secondangle\pgfmathresult% + \fi% + \pgfmathsubtract@{\secondangle}{\firstangle}% + \pgfmath@smuggleone\pgfmathresult% + \endgroup% } % \pgfmathpointreflectalongaxis @@ -375,14 +342,14 @@ % Reflects point #2 around an axis centered on #2 at an angle #3. % \def\pgfmathreflectpointalongaxis#1#2#3{% - \pgf@process{% - \pgfmathanglebetweenpoints{#2}{#1}% - \pgfmath@tempdima\pgfmathresult pt\relax% - \pgfmathparse{#3}% - \advance\pgfmath@tempdima-\pgfmathresult pt\relax% - \pgfmath@tempdima-2.0\pgfmath@tempdima% - \pgfmathrotatepointaround{#1}{#2}{\pgfmath@tonumber{\pgfmath@tempdima}}% - }% + \pgf@process{% + \pgfmathanglebetweenpoints{#2}{#1}% + \pgfmath@tempdima\pgfmathresult pt\relax% + \pgfmathparse{#3}% + \advance\pgfmath@tempdima-\pgfmathresult pt\relax% + \pgfmath@tempdima-2.0\pgfmath@tempdima% + \pgfmathrotatepointaround{#1}{#2}{\pgfmath@tonumber{\pgfmath@tempdima}}% + }% } @@ -402,107 +369,107 @@ % #6 radii of the arc. % \def\pgfmathpointintersectionoflineandarc#1#2#3#4#5#6{% - \pgf@process{% - % - % Get the required angle. - % - \pgfmathanglebetweenpoints{#2}{#1}% - \let\x\pgfmathresult% - % - % Get the radii of the arc. - % - \pgfmath@in@{and }{#6}% - \ifpgfmath@in@% - \pgf@polar@#6\@@% - \else% - \pgf@polar@#6 and #6\@@% - \fi% - \edef\xarcradius{\the\pgf@x}% - \edef\yarcradius{\the\pgf@y}% - % - % Get the start and end angles of the arc... - % - \pgfmathsetmacro\s{#4}% - \pgfmathsetmacro\e{#5}% - % - % ...and also with rounding. - % - \pgfmathmod@{\s}{360}% - \ifdim\pgfmathresult pt<0pt\relax% - \pgfmathadd@{\pgfmathresult}{360}% - \fi% - \let\ss\pgfmathresult% - \pgfmathmod@{\e}{360}% - \ifdim\pgfmathresult pt<0pt\relax% - \pgfmathadd@{\pgfmathresult}{360}% - \fi% - \let\ee\pgfmathresult% - % - % Hackery for when arc straddles zero. - % - \ifdim\ee pt<\ss pt\relax% - \pgfmathadd@{\x}{180}% - \pgfmathmod@{\pgfmathresult}{360}% - \let\x\pgfmathresult% - \fi% - \def\m{360}% Measure of nearness. - \pgfmathadd@{\s}{\e}% - \pgfmathdivide@{\pgfmathresult}{2}% - \let\n\pgfmathresult% The best estimate (default to middle of arc). - \pgfmathloop% - \pgfmathadd@{\s}{\e}% - \pgfmathdivide@{\pgfmathresult}{2}% - \let\p\pgfmathresult% - \ifdim\p pt=\s pt\relax% - \else% - \pgfmathanglebetweenpoints{#2}{% - \pgfpointadd{#3}{% - \pgf@x\xarcradius\relax% - \pgfmathcos@{\p}% - \pgf@x\pgfmathresult\pgf@x% - \pgf@y\yarcradius\relax% - \pgfmathsin@{\p}% - \pgf@y\pgfmathresult\pgf@y% - }% - }% - % - % Hackery for when arc straddles zero. - % - \ifdim\ee pt<\ss pt\relax% - \pgfmathadd@{\pgfmathresult}{180}% - \pgfmathmod@{\pgfmathresult}{360}% - \fi% - \let\q\pgfmathresult% - % - % More hackery... - % - \ifdim\x pt>335pt\relax% - \ifdim\q pt<45pt\relax% - \pgfmathadd@{\q}{360}% - \let\q\pgfmathresult% - \fi% - \fi% - \ifdim\x pt=\q pt% Found it! - \pgfmathbreakloop% Breaks after current iteration is complete. - \else - \ifdim\x pt<\q pt\relax% - \let\e\p% - \else% - \let\s\p% - \fi% - \fi% - \pgfmathsubtract@{\x}{\q}% - \pgfmathabs@{\pgfmathresult}% - % - % Save the estimate if it is better than any previous estimate. - % - \ifdim\pgfmathresult pt<\m pt\relax% - \let\m\pgfmathresult% - \let\n\p% - \fi% - \repeatpgfmathloop% - \pgfpointadd{#3}{\pgfpointpolar{\n}{\xarcradius and \yarcradius}}% - }% + \pgf@process{% + % + % Get the required angle. + % + \pgfmathanglebetweenpoints{#2}{#1}% + \let\x\pgfmathresult% + % + % Get the radii of the arc. + % + \pgfmath@in@{and }{#6}% + \ifpgfmath@in@% + \pgf@polar@#6\@@% + \else% + \pgf@polar@#6 and #6\@@% + \fi% + \edef\xarcradius{\the\pgf@x}% + \edef\yarcradius{\the\pgf@y}% + % + % Get the start and end angles of the arc... + % + \pgfmathsetmacro\s{#4}% + \pgfmathsetmacro\e{#5}% + % + % ...and also with rounding. + % + \pgfmathmod@{\s}{360}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\ss\pgfmathresult% + \pgfmathmod@{\e}{360}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\ee\pgfmathresult% + % + % Hackery for when arc straddles zero. + % + \ifdim\ee pt<\ss pt\relax% + \pgfmathadd@{\x}{180}% + \pgfmathmod@{\pgfmathresult}{360}% + \let\x\pgfmathresult% + \fi% + \def\m{360}% Measure of nearness. + \pgfmathadd@{\s}{\e}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\n\pgfmathresult% The best estimate (default to middle of arc). + \pgfmathloop% + \pgfmathadd@{\s}{\e}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\p\pgfmathresult% + \ifdim\p pt=\s pt\relax% + \else% + \pgfmathanglebetweenpoints{#2}{% + \pgfpointadd{#3}{% + \pgf@x\xarcradius\relax% + \pgfmathcos@{\p}% + \pgf@x\pgfmathresult\pgf@x% + \pgf@y\yarcradius\relax% + \pgfmathsin@{\p}% + \pgf@y\pgfmathresult\pgf@y% + }% + }% + % + % Hackery for when arc straddles zero. + % + \ifdim\ee pt<\ss pt\relax% + \pgfmathadd@{\pgfmathresult}{180}% + \pgfmathmod@{\pgfmathresult}{360}% + \fi% + \let\q\pgfmathresult% + % + % More hackery... + % + \ifdim\x pt>335pt\relax% + \ifdim\q pt<45pt\relax% + \pgfmathadd@{\q}{360}% + \let\q\pgfmathresult% + \fi% + \fi% + \ifdim\x pt=\q pt% Found it! + \pgfmathbreakloop% Breaks after current iteration is complete. + \else + \ifdim\x pt<\q pt\relax% + \let\e\p% + \else% + \let\s\p% + \fi% + \fi% + \pgfmathsubtract@{\x}{\q}% + \pgfmathabs@{\pgfmathresult}% + % + % Save the estimate if it is better than any previous estimate. + % + \ifdim\pgfmathresult pt<\m pt\relax% + \let\m\pgfmathresult% + \let\n\p% + \fi% + \repeatpgfmathloop% + \pgfpointadd{#3}{\pgfpointpolar{\n}{\xarcradius and \yarcradius}}% + }% } % \pgfmathangleonellipse @@ -513,58 +480,63 @@ % #2 - the radii of the ellipse. % \def\pgfmathangleonellipse#1#2{% - \begingroup% - \pgfmath@in@{and }{#2}% - \ifpgfmath@in@% - \pgf@polar@#2\@@% - \else% - \pgf@polar@#2 and #2\@@% - \fi% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \pgf@process{#1}% - \ifdim\pgf@x=0pt\relax% - \pgfutil@tempdima1pt\relax% - \else% - \pgfutil@tempdima\pgf@x% - \pgfmathdivide@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgfutil@tempdima}}% - \pgfutil@tempdima\pgfmathresult pt\relax% - \fi% - \ifdim\pgf@y=0pt\relax% - \pgfutil@tempdima1pt\relax% - \else% - \pgfmathdivide@{\pgfmath@tonumber{\pgf@y}}{\pgfmath@tonumber{\pgf@ya}}% - \pgfutil@tempdima\pgfmathresult\pgfutil@tempdima% - \pgfmathatan@{\pgfmath@tonumber{\pgfutil@tempdima}}% - \fi% - % - \pgfutil@tempdima\pgfmathresult pt\relax% - \ifdim\pgfutil@tempdima<0pt\relax% - \advance\pgfutil@tempdima360pt\relax% - \fi% - \ifdim\pgf@x<0pt\relax% - \ifdim\pgf@y=0pt\relax% - \pgfutil@tempdima180pt\relax% - \else% - \ifdim\pgf@y<0pt\relax% - \advance\pgfutil@tempdima180pt\relax% - \else% - \advance\pgfutil@tempdima-180pt\relax% - \fi% - \fi% - \else% - \ifdim\pgf@x=0pt\relax% - \ifdim\pgf@y<0pt\relax% - \pgfutil@tempdima270pt\relax% - \else% - \pgfutil@tempdima90pt\relax% - \fi% - \else% - \ifdim\pgf@y=0pt\relax% - \pgfutil@tempdima0pt\relax% - \fi% - \fi% - \fi% - \pgfmath@returnone\pgfutil@tempdima% - \endgroup% + \begingroup% + \pgfmath@in@{and }{#2}% + \ifpgfmath@in@% + \pgf@polar@#2\@@% + \else% + \pgf@polar@#2 and #2\@@% + \fi% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgf@process{#1}% + \ifdim\pgf@x=0pt\relax% + \pgfutil@tempdima1pt\relax% + \else% + \pgfutil@tempdima\pgf@x% + \pgfmathdivide@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgfutil@tempdima}}% + \pgfutil@tempdima\pgfmathresult pt\relax% + \fi% + \ifdim\pgf@y=0pt\relax% + \pgfutil@tempdima1pt\relax% + \else% + \pgfmathdivide@{\pgfmath@tonumber{\pgf@y}}{\pgfmath@tonumber{\pgf@ya}}% + \pgfutil@tempdima\pgfmathresult\pgfutil@tempdima% + \pgfmathatan@{\pgfmath@tonumber{\pgfutil@tempdima}}% + \fi% + % + \pgfutil@tempdima\pgfmathresult pt\relax% + \ifdim\pgfutil@tempdima<0pt\relax% + \advance\pgfutil@tempdima360pt\relax% + \fi% + \ifdim\pgf@x<0pt\relax% + \ifdim\pgf@y=0pt\relax% + \pgfutil@tempdima180pt\relax% + \else% + \ifdim\pgf@y<0pt\relax% + \advance\pgfutil@tempdima180pt\relax% + \else% + \advance\pgfutil@tempdima-180pt\relax% + \fi% + \fi% + \else% + \ifdim\pgf@x=0pt\relax% + \ifdim\pgf@y<0pt\relax% + \pgfutil@tempdima270pt\relax% + \else% + \pgfutil@tempdima90pt\relax% + \fi% + \else% + \ifdim\pgf@y=0pt\relax% + \pgfutil@tempdima0pt\relax% + \fi% + \fi% + \fi% + \pgfmath@returnone\pgfutil@tempdima% + \endgroup% } + + +% Local Variables: +% tab-width: 2 +% End: diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfloat.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfloat.code.tex index 722856f3628..727af976f8d 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfloat.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfloat.code.tex @@ -10,7 +10,28 @@ % This file contains methods for basic floating point arithmetics, rounding % to arbitrary precision and number pretty printing. % -% Version 1.0 2008/09/17 + + +\pgfkeys{ + % The bug 3430171 (wrong minus sign spacing in pgfmathprintnumber) + % has been fixed in 2.10 CVS. Since it changes the spacing, its + % effects can be undone with this compatibility switch. + /pgf/compat/number printer/.is choice, + /pgf/compat/number printer/2.10/.code={% + \def\pgfmathprintnumber@begingroup{\bgroup}% + \def\pgfmathprintnumber@endgroup{\egroup}% + }, + % I do not know the version number of the next release at this + % time. Please be so kind and KEEP THIS NAME INTACT. Add an alias + % if needed. + /pgf/compat/number printer/next after 2.10/.code={% + \def\pgfmathprintnumber@begingroup{\begingroup}% + \def\pgfmathprintnumber@endgroup{\endgroup}% + }, + % activate the fix by default. + /pgf/compat/number printer/next after 2.10,% +} + \global\newif\ifpgfmathfloatcomparison \newif\ifpgfmathfloatroundhasperiod @@ -34,6 +55,13 @@ % can be changed with options. \def\pgfmathfloat@round@precision{2} +% I introduced this to acces the "original" precision in case a +% formatted changes it locally... in this case, the formatter may +% overwrite \pgfmathfloat@round@precision@orig to provide the original +% one. +% The default implementation here does nothing: +\def\pgfmathfloat@round@precision@orig{\pgfmathfloat@round@precision}% + \gdef\pgfmathfloat@glob@TMP{} @@ -472,7 +500,7 @@ \pgfkeysgetvalue{/pgf/number format/set decimal separator}\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP \pgfkeysgetvalue{/pgf/number format/@dec sep mark}\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP@MARK \pgfkeysgetvalue{/pgf/number format/set thousands separator}\pgfmathprintnumber@fixed@styleDEFAULT@THOUSAND@SEP - \c@pgf@counta=#4\relax + \c@pgf@counta=#4\relax % it is the exponent here. \ifnum#2=0 \c@pgf@counta=0 \fi @@ -511,20 +539,30 @@ \else \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod#1\pgfmathfloat@EOI\pgfmathfloat@EOI\pgfmathfloat@EOI \fi + \ifpgfmathprintnumber@thousand@sep@in@fractional + \let\pgfmathresultfractional\pgfutil@empty% + \pgfmathprintnumber@thousand@sep@in@fractional#2MMMM\@@ + \else + \def\pgfmathresultfractional{#2}% + \fi \begingroup \toks0=\expandafter{\pgfmathresult}% \toks1=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP@MARK}% - \toks2=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP #2}% - \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 \the\toks2 }% + \toks2=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP}% + \toks3=\expandafter{\pgfmathresultfractional}% + \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 \the\toks2 \the\toks3 }% \endgroup \let\pgfmathresult=\pgfmathfloat@glob@TMP }% + +% assigns \pgfmathresult such that it contains the formatted result. +% It assumes that none of the following tokens contains a period. \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod{% \ifx\pgfmathprintnumber@fixed@styleDEFAULT@THOUSAND@SEP\pgfutil@empty \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{% \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printall}% \else - \ifnum\c@pgf@counta<0\relax + \ifnum\c@pgf@counta<0\relax % exponent of the number in this context \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{% \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printall}% \else @@ -561,7 +599,7 @@ \fi \fi \fi - \ifnum\c@pgf@counta>0 + \ifnum\c@pgf@counta>0 % \c@pgf@counta = N MOD 3 in this context \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{% \expandafter\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printtrailingdigits\pgfmathfloat@loc@TMPb }% @@ -573,7 +611,8 @@ \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT } \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printtrailingdigits#1#2{% - \ifcase\c@pgf@counta + \ifcase\c@pgf@counta % = N MOD 3 in this context + % does not happen per construction \or \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult #1}% \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{% @@ -585,7 +624,7 @@ \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@counteverythird% }% \fi - \ifnum\c@pgf@countb>0\relax + \ifnum\c@pgf@countb>0\relax % \c@pgf@countb = N DIV 3 in this context \begingroup \toks0=\expandafter{\pgfmathresult}% \toks1=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@THOUSAND@SEP}% @@ -625,6 +664,32 @@ \fi \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT } + +% \pgfmathprintnumber@thousand@sep@in@fractional 01234525MMMM\@@ +% -> +% 012<sep>345<sep>25 +\def\pgfmathprintnumber@thousand@sep@in@fractional#1#2#3#4{% + \if#4M% + % Ok, no further separator + \def\pgfmathprint@next{\pgfmathprintnumber@thousand@sep@in@fractional@finish#1#2#3#4}% + \else + \begingroup + \toks0=\expandafter{\pgfmathresultfractional}% + \toks1={#1#2#3}% + \toks2=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@THOUSAND@SEP}% + \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 \the\toks2 }% + \endgroup + \let\pgfmathresultfractional=\pgfmathfloat@glob@TMP + \def\pgfmathprint@next{\pgfmathprintnumber@thousand@sep@in@fractional#4}% + \fi + \pgfmathprint@next +}% +\def\pgfmathprintnumber@thousand@sep@in@fractional@finish#1M{% + \expandafter\def\expandafter\pgfmathresultfractional\expandafter{\pgfmathresultfractional #1}% + \pgfmathprintnumber@thousand@sep@in@fractional@finish@ +}% +\def\pgfmathprintnumber@thousand@sep@in@fractional@finish@#1\@@{}% + \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printall#1{% \def\pgfmathfloat@loc@TMPb{#1}% \let\pgfmathfloat@loc@TMPc=\pgfutil@empty @@ -662,7 +727,7 @@ % The default style to display fixed point numbers. % -% It does not apply numerics, but it is responsable to typeset the +% It does not apply numerics, but it is responsable for typesetting the % rounded number. % It can access the \ifpgfmathfloatroundhasperiod boolean. % @@ -753,21 +818,23 @@ % #1: the part before the exponent code % #2: the part for the exponent code. \def\pgfmathfloatrounddisplaystyle@shared@impl@#1#2{% - {\toks0={#1}% + \pgfmathprintnumber@begingroup + \toks0={#1}% \toks1=\expandafter{\pgfmathfloatrounddisplaystyle@e@mark #2}% \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 }% - }% + \pgfmathprintnumber@endgroup \let\pgfmathresult=\pgfmathfloat@glob@TMP }% % Same as \pgfmathfloatrounddisplaystyle@shared@impl@, but it also % inserts the '@dec sep mark' at the end. \def\pgfmathfloatrounddisplaystyle@shared@impl@@#1#2{% - {\toks0={#1}% + \pgfmathprintnumber@begingroup + \toks0={#1}% \toks1=\expandafter{\pgfmathfloatrounddisplaystyle@e@mark #2}% \pgfkeysgetvalue{/pgf/number format/@dec sep mark}\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP@MARK \toks2=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP@MARK}% \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 \the\toks2 }% - }% + \pgfmathprintnumber@endgroup \let\pgfmathresult=\pgfmathfloat@glob@TMP } @@ -782,10 +849,11 @@ } \def\pgfmathfloatrounddisplaystyle@e#1#2e#3\relax{% \ifnum#3<0\relax - {\count0=#3\relax + \pgfmathprintnumber@begingroup + \count0=#3\relax \multiply\count0 by-1 \xdef\pgfmathfloat@glob@TMP{e{-}\the\count0}% - }% + \pgfmathprintnumber@endgroup% \let\pgfmathresult=\pgfmathfloat@glob@TMP \else \def\pgfmathresult{e{+}#3}% @@ -795,10 +863,11 @@ } \def\pgfmathfloatrounddisplaystyle@E#1#2e#3\relax{% \ifnum#3<0\relax - {\count0=#3\relax + \pgfmathprintnumber@begingroup + \count0=#3\relax \multiply\count0 by-1 \xdef\pgfmathfloat@glob@TMP{E{-}\the\count0}% - }% + \pgfmathprintnumber@endgroup% \let\pgfmathresult=\pgfmathfloat@glob@TMP \else \def\pgfmathresult{E{+}#3}% @@ -841,6 +910,14 @@ \long\def\pgfmathfloatfrac@verbatim#1#2{#1/#2}% +\let\pgfmathround@@orig=\pgfmathround@ + +% 2 = compatible +% 0 = no +% 1 = yes +\def\pgfmathprintnumber@RELATIVE@choice@roundtofixed{2}% + +\newif\ifpgfmathprintnumber@thousand@sep@in@fractional \pgfkeys{% /pgf/number format/.is family, /pgf/number format, @@ -848,6 +925,22 @@ sci/.code= \pgfmath@set@number@printer{pgfmathprintnumber@SCI}, std/.code= {\pgfmath@set@number@printer{pgfmathprintnumber@STD}\pgfmathprintnumber@STD@setparam{#1}}, std/.default=,% + relative round mode/.is choice, + relative round mode/fixed/.code={\def\pgfmathprintnumber@RELATIVE@choice@roundtofixed{1}}, + relative round mode/mantissa/.code={\def\pgfmathprintnumber@RELATIVE@choice@roundtofixed{0}}, + relative round mode/compatible/.code={\def\pgfmathprintnumber@RELATIVE@choice@roundtofixed{2}}, + % relative={<exponent base 10>} + relative/.code= {% + \pgfmath@set@number@printer{pgfmathprintnumber@RELATIVE}% + \pgfmathround@@orig{#1}% + \expandafter\pgfmathfloattoint@@\pgfmathresult\relax + \let\pgfmathprintnumber@RELATIVE@param=\pgfmathresult + },% + relative/.value required, + relative*/.style={/pgf/number format/relative={#1},/pgf/number format/relative round mode=fixed}, + every relative/.style=std, + relative style/.style={/pgf/number format/every relative/.append style={#1}}, + fixed relative/.code= \pgfmath@set@number@printer{pgfmathprintnumber@FIXED@RELATIVE}, int detect/.code= \pgfmath@set@number@printer{pgfmathprintnumber@INT@DETECT}, int trunc/.code= \pgfmath@set@number@printer{pgfmathprintnumber@INT@TRUNC}, frac/.code= \pgfmath@set@number@printer{pgfmathprintnumber@frac},% @@ -880,11 +973,13 @@ sci precision=, fixed default/.code= {\let\pgfmathprintnumber@fixed@style=\pgfmathprintnumber@fixed@styleDEFAULT}, set decimal separator/.initial=, - dec sep/.style={/pgf/number format/set decimal separator=#1}, + dec sep/.style={/pgf/number format/set decimal separator={#1}}, @dec sep mark/.initial=, @sci exponent mark/.initial=, set thousands separator/.initial=, - 1000 sep/.style={/pgf/number format/set thousands separator=#1}, + 1000 sep in fractionals/.is if=pgfmathprintnumber@thousand@sep@in@fractional, + 1000 sep in fractionals/.default=true, + 1000 sep/.style={/pgf/number format/set thousands separator={#1}}, min exponent for 1000 sep/.initial=0, use period/.style= {/pgf/number format/set decimal separator={.},/pgf/number format/set thousands separator={{{,}}}}, use comma/.style= {/pgf/number format/set decimal separator={{{,}}},/pgf/number format/set thousands separator={.}}, @@ -946,7 +1041,7 @@ \ifx\pgfmathfloat@loc@TMPb\pgfutil@empty % DEFAULT for lower and upper bound. \def\pgfmathprintnumber@STD@getlowerbound{% - \c@pgf@counta=\pgfmathfloat@round@precision\relax + \c@pgf@counta=\pgfmathfloat@round@precision@orig\relax \divide\c@pgf@counta by-2\relax }% \def\pgfmathprintnumber@STD@upperbound{4}% @@ -992,6 +1087,114 @@ \fi } +\def\pgfmathprintnumber@RELATIVE#1{% + % parse the input: + \pgfmathfloatparsenumber{#1}% + \pgfmathfloat@to@FMeE@style\pgfmathresult + \expandafter\pgfmathprintnumber@RELATIVE@issci\pgfmathresult\relax +} + +\def\pgfmathprintnumber@RELATIVE@choice@roundtofixed@warn{% + \immediate\write16{! Package pgf warning: the use of /pgf/number format/relative is discouraged (buggy). Please use 'relative*' instead or type \string\pgfkeys{/pgf/number format/relative round mode=fixed} into your preamble.}% + \global\let\pgfmathprintnumber@RELATIVE@choice@roundtofixed@warn=\relax +} + +\def\pgfmathprintnumber@RELATIVE@issci#1#2e#3\relax{% + \begingroup + % format X / 10^{relative}: + \c@pgf@counta=#3\relax + \advance\c@pgf@counta by-\pgfmathprintnumber@RELATIVE@param\relax + \pgfmathfloatcreate{#1}{#2}{\the\c@pgf@counta}% + % OK, round it to the desired precision: + \if0\pgfmathprintnumber@RELATIVE@choice@roundtofixed + % relative round mode=mantissa + \def\b@round@fixed{0}% + \else + \if1\pgfmathprintnumber@RELATIVE@choice@roundtofixed + % relative round mode=fixed + \def\b@round@fixed{1}% + \else + \pgfmathprintnumber@RELATIVE@choice@roundtofixed@warn + % relative round mode=compatible + \ifnum\c@pgf@counta>0 + % hm. for positive exponents, we should round the + % mantissa rather than only the fractional part. + \def\b@round@fixed{0}% + \else + % negative exponent -> round fixed representation: + \def\b@round@fixed{1}% + \fi + \fi + \fi + \if1\b@round@fixed + % round fixed representation: + \pgfmathfloattofixed\pgfmathresult + \expandafter\pgfmathroundto\expandafter{\pgfmathresult}% + \pgfmathfloatparsenumber{\pgfmathresult}% + \pgfmathfloatroundhasperiodtrue% make sure the code below works: + \else + % round the mantissa: + \expandafter\pgfmathfloatround\expandafter{\pgfmathresult}% + \fi + % Now, compute result * 10^{relative} and format the result: + \pgfmathfloattoregisterstok\pgfmathresult\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E + \ifnum\pgfmathfloat@a@S=0 + \pgfmathfloat@a@E=\pgfmathfloat@a@S % avoid 0 * 10^8 + \else + \advance\pgfmathfloat@a@E by+\pgfmathprintnumber@RELATIVE@param\relax + \fi + \edef\pgfmathresultX{% + \the\pgfmathfloat@a@S + \the\pgfmathfloat@a@Mtok + \ifpgfmathfloatroundhasperiod\else.0\fi + e\the\pgfmathfloat@a@E}% + % call another formatter for the result (but avoid rounding inside of it): + \pgfqkeys{/pgf/number format}{/pgf/number format/every relative, + fixed zerofill=false,% useless here! + sci zerofill=false}% + \ifx\pgfmathprintnumber@issci\pgfmathprintnumber@RELATIVE@issci + \pgfmath@error{The '/pgf/number format/every relative' style should set a valid display style}% + \fi + \let\pgfmathfloat@round@precision@orig=\pgfmathfloat@round@precision + \def\pgfmathfloat@round@precision{9999}% + \expandafter\pgfmathprintnumber@issci\pgfmathresultX\relax% + \pgfmath@smuggleone\pgfmathresult + \endgroup +} + +\def\pgfmathprintnumber@FIXED@RELATIVE#1{% + % parse the input: + \pgfmathfloatparsenumber{#1}% + \pgfmathfloat@to@FMeE@style\pgfmathresult + \expandafter\pgfmathprintnumber@FIXED@RELATIVE@issci\pgfmathresult\relax +} + +\def\pgfmathprintnumber@FIXED@RELATIVE@issci#1#2e#3\relax{% + \begingroup + \pgfmathfloatcreate{#1}{#2}{#3}% + % we want the first <precision> digits - not the first + % <precision>+1 digits: + \c@pgf@counta=\pgfmathfloat@round@precision\relax + \advance\c@pgf@counta by-1 + \edef\pgfmathfloat@round@precision{\the\c@pgf@counta}% + \pgfmathfloatround{\pgfmathresult}% + \pgfmathfloattoregisterstok\pgfmathresult\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E + \ifnum\pgfmathfloat@a@S=0 + \pgfmathfloat@a@E=\pgfmathfloat@a@S % avoid 0 * 10^8 + \fi + \edef\pgfmathresultX{% + \the\pgfmathfloat@a@S + \the\pgfmathfloat@a@Mtok + \ifpgfmathfloatroundhasperiod\else.0\fi + e\the\pgfmathfloat@a@E}% + \let\pgfmathfloat@round@precision@orig=\pgfmathfloat@round@precision + \pgfmathfloat@usezerofill@fixedfalse + \def\pgfmathfloat@round@precision{9999}% typeset all remaining digits! + \expandafter\pgfmathprintnumber@FIXED@issci\pgfmathresultX\relax% + \pgfmath@smuggleone\pgfmathresult + \endgroup +} + \def\pgfmathprintnumber@frac#1{% % parse the input: \pgfmathfloatparsenumber{#1}% @@ -1048,7 +1251,7 @@ % The numerator and denominator is always a number (not empty) \def\pgfmathfloatgetfrac#1{% \pgfutil@ifundefined{pgfmathfloatmultiply@}{% - \PackageError{tikz}{Sorry, the number format 'frac' requires '\string\usetikzlibrary{fpu}' (and, optionally, \string\usepackage{fp}) in order to work correctly}{}% + \pgfmath@PackageError{Sorry, the number format 'frac' requires '\string\usetikzlibrary{fpu}' (and, optionally, \string\usepackage{fp}) in order to work correctly}% \edef\pgfmathresult{{#1}{0}{1}}% }{% \pgfmathfloatgetfrac@{#1}% diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.base.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.base.code.tex index a4e510d4dc8..581cdaade5f 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.base.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.base.code.tex @@ -301,3 +301,31 @@ \def\pgfmathsetbasenumberlength#1{\def\pgfmath@basenumberlength{#1}} \pgfmathsetbasenumberlength{1}% + +% \pgfmathtodigitlist\marg{macro}\marg{number}} +% +% This command converts \meta{number} into a comma-separated +% list of digits and stores the result in \meta{macro}. +% The \marg{number} is \emph{not} parsed before processing. +% +\def\pgfmathtodigitlist#1#2{% + \def\pgfmath@temp{#1}% + \let\pgfmath@digitlist=\pgfutil@empty% + \edef\pgfmath@@tmp{#2}% + \expandafter\pgfmath@todigitlist\pgfmath@@tmp @% +} +\def\pgfmath@base@atchar{@} +\def\pgfmath@todigitlist#1{% + \def\pgfmath@digit{#1}% + \ifx\pgfmath@digit\pgfmath@base@atchar% + \expandafter\let\pgfmath@temp=\pgfmath@digitlist% + \else% + \ifx\pgfmath@digitlist\pgfutil@empty% + \edef\pgfmath@digitlist{#1}% + \else% + \edef\pgfmath@digitlist{\pgfmath@digitlist,#1}% + \fi% + \expandafter\pgfmath@todigitlist% + \fi% +} + diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.basic.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.basic.code.tex index ca741fa7adc..99f8ccbb2c0 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.basic.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.basic.code.tex @@ -121,9 +121,24 @@ \divide\c@pgfmath@counta by\c@pgfmath@countb% \pgfmath@ya=\c@pgfmath@counta\pgfmath@y% \advance\pgfmath@x by-\pgfmath@ya% - \expandafter\expandafter\expandafter\def% - \expandafter\expandafter\expandafter\pgfmathresult - \expandafter\expandafter\expandafter{\expandafter\pgfmathresult\the\c@pgfmath@counta}% + \def\pgfmath@next{% + \toks0=\expandafter{\pgfmathresult}% + \edef\pgfmathresult{\the\toks0 \the\c@pgfmath@counta}% + }% + \ifpgfmath@divide@period + \else + % we are behind the period. It may happen that the + % result is more than one digit - in that case, + % introduce special handling: + \ifnum\c@pgfmath@counta>9 % + \expandafter\pgfmathdivide@advance@last@digit\pgfmathresult CCCCC\@@ + \advance\c@pgfmath@counta by-10 % + \ifnum\c@pgfmath@counta=0 + \let\pgfmath@next=\relax + \fi + \fi + \fi + \pgfmath@next \fi% \let\pgfmath@next=\pgfmathdivide@@% \fi% @@ -131,6 +146,46 @@ \pgfmath@next% } +% advances the last digit found in the number. Any missing digits are +% supposed to be filled with 'C'. +\def\pgfmathdivide@advance@last@digit#1.#2#3#4#5#6#7\@@{% + \pgfmath@ya=\pgfmathresult pt % + \if#2C% + \pgfmath@xa=1pt % + \else + \if#3C% + \pgfmath@xa=0.1pt % + \else + \if#4C% + \pgfmath@xa=0.01pt % + \else + \if#5C% + \pgfmath@xa=0.001pt % + \else + \if#6C% + \pgfmath@xa=0.0001pt % + \else + \pgfmath@xa=0.00001pt % + \fi + \fi + \fi + \fi + \fi + \advance\pgfmath@ya by\pgfmath@xa + \edef\pgfmathresult{\pgfmath@tonumber@notrailingzero\pgfmath@ya}% +}% + +{ +\catcode`\p=12 +\catcode`\t=12 +\gdef\Pgf@geT@NO@TRAILING@ZERO#1.#2pt{% + #1.% + \ifnum#2=0 \else #2\fi +} +} +\def\pgfmath@tonumber@notrailingzero#1{\expandafter\Pgf@geT@NO@TRAILING@ZERO\the#1} + + \def\pgfmathdivide@dimenbyten#1{% \edef\pgfmath@temp{\pgfmath@tonumber{#1}}% \expandafter\pgfmathdivide@@dimenbyten\pgfmath@temp\@@#1\@@} @@ -451,32 +506,33 @@ % exp function. % \pgfmathdeclarefunction{exp}{1}{% - \begingroup% - \pgfmath@xc=#1pt\relax% - \ifdim\pgfmath@xc<-9pt% - \pgfmath@x=1sp\relax% - \else% - \ifdim\pgfmath@xc<0pt% - \pgfmath@xc=-\pgfmath@xc% - \fi% - \pgfmath@x=1pt\relax% - \pgfmath@xa=1pt\relax% - \pgfmath@xb=\pgfmath@x% + \begingroup + \pgfmath@xc=#1pt\relax + \pgfmath@yc=#1pt\relax + \ifdim\pgfmath@xc<-9pt + \pgfmath@x=1sp\relax + \else + \ifdim\pgfmath@xc<0pt + \pgfmath@xc=-\pgfmath@xc + \fi + \pgfmath@x=1pt\relax + \pgfmath@xa=1pt\relax + \pgfmath@xb=\pgfmath@x \pgfmathloop% - \divide\pgfmath@xa by\pgfmathcounter% + \divide\pgfmath@xa by\pgfmathcounter \pgfmath@xa=\pgfmath@tonumber\pgfmath@xc\pgfmath@xa% - \advance\pgfmath@x by\pgfmath@xa% - \ifdim\pgfmath@x=\pgfmath@xb% - \else% - \pgfmath@xb=\pgfmath@x% + \advance\pgfmath@x by\pgfmath@xa + \ifdim\pgfmath@x=\pgfmath@xb + \else + \pgfmath@xb=\pgfmath@x \repeatpgfmathloop% - \ifdim#1pt<0pt% + \ifdim\pgfmath@yc<0pt \pgfmathreciprocal@{\pgfmath@tonumber\pgfmath@x}% - \pgfmath@x=\pgfmathresult pt\relax% - \fi% - \fi% + \pgfmath@x=\pgfmathresult pt\relax + \fi + \fi \pgfmath@returnone\pgfmath@x% - \endgroup% + \endgroup } % sqrt function. @@ -664,34 +720,42 @@ \begingroup% \pgfmath@xa=#1pt% \pgfmath@xb=#2pt% - \afterassignment\pgfmath@x% - \expandafter\c@pgfmath@counta\the\pgfmath@xb\relax% - \ifnum\c@pgfmath@counta<0\relax% - \c@pgfmath@counta=-\c@pgfmath@counta% - \pgfmathreciprocal@{#1}% - \pgfmath@xa=\pgfmathresult pt\relax% - \fi - \ifdim\pgfmath@x=0pt\relax% - \pgfmath@x=1pt\relax% - \pgfmathloop% - \ifnum\c@pgfmath@counta>0\relax% - \ifodd\c@pgfmath@counta% - \pgfmath@x=\pgfmath@tonumber{\pgfmath@x}\pgfmath@xa% - \fi - \ifnum\c@pgfmath@counta>1\relax% - \pgfmath@xa=\pgfmath@tonumber{\pgfmath@xa}\pgfmath@xa% - \fi% - \divide\c@pgfmath@counta by2\relax% - \repeatpgfmathloop% - \else% - \pgfmathln@{#1}% - \pgfmath@x=\pgfmathresult pt\relax% - \pgfmath@x=\pgfmath@tonumber{\pgfmath@xb}\pgfmath@x% - \pgfmathexp@{\pgfmath@tonumber{\pgfmath@x}}% - \pgfmath@x=\pgfmathresult pt\relax% - \fi% - \pgfmath@returnone\pgf@x% - \endgroup% + \ifdim\pgfmath@xa=0pt\relax% + \ifdim\pgfmath@xb=0pt\relax% + \pgfmath@x=1pt\relax% + \else% + \pgfmath@x=0pt\relax% + \fi% + \else% + \afterassignment\pgfmath@x% + \expandafter\c@pgfmath@counta\the\pgfmath@xb\relax% + \ifnum\c@pgfmath@counta<0\relax% + \c@pgfmath@counta=-\c@pgfmath@counta% + \pgfmathreciprocal@{#1}% + \pgfmath@xa=\pgfmathresult pt\relax% + \fi + \ifdim\pgfmath@x=0pt\relax% + \pgfmath@x=1pt\relax% + \pgfmathloop% + \ifnum\c@pgfmath@counta>0\relax% + \ifodd\c@pgfmath@counta% + \pgfmath@x=\pgfmath@tonumber{\pgfmath@x}\pgfmath@xa% + \fi + \ifnum\c@pgfmath@counta>1\relax% + \pgfmath@xa=\pgfmath@tonumber{\pgfmath@xa}\pgfmath@xa% + \fi% + \divide\c@pgfmath@counta by2\relax% + \repeatpgfmathloop% + \else% + \pgfmathln@{#1}% + \pgfmath@x=\pgfmathresult pt\relax% + \pgfmath@x=\pgfmath@tonumber{\pgfmath@xb}\pgfmath@x% + \pgfmathexp@{\pgfmath@tonumber{\pgfmath@x}}% + \pgfmath@x=\pgfmathresult pt\relax% + \fi% + \fi + \pgfmath@returnone\pgf@x% + \endgroup% } % factorial function. @@ -711,3 +775,7 @@ \pgfmath@smuggleone\pgfmathresult% \endgroup% } + +% Local Variables: +% coding: undecided-unix +% End: diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.code.tex index a493b6c6b62..55ef700c14d 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.code.tex @@ -238,3 +238,10 @@ \input pgfmathfunctions.base.code.tex \input pgfmathfunctions.round.code.tex \input pgfmathfunctions.misc.code.tex +\input pgfmathfunctions.integerarithmetics.code.tex + + + +% Local Variables: +% tab-width: 2 +% End: diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.integerarithmetics.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.integerarithmetics.code.tex new file mode 100644 index 00000000000..f11704c94c2 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.integerarithmetics.code.tex @@ -0,0 +1,124 @@ +% This file may be distributed and/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 details. + +% Macros contributed by Alain Matthes and adapted by CJ +\pgfmathdeclarefunction{gcd}{2}{% + \begingroup + \pgfmathcontinuelooptrue + \pgfmath@xa=#1pt + \pgfmath@xb=#2pt + \ifdim\pgfmath@xa=0pt + \pgfmathcontinueloopfalse + \pgfmath@xa=\pgfmath@xb + \fi + \ifdim\pgfmath@xb=0pt + \pgfmathcontinueloopfalse + \pgfmath@xb=\pgfmath@xa + \fi + \ifdim\pgfmath@xa<0pt + \pgfmath@xa=-\pgfmath@xa + \fi + \ifdim\pgfmath@xb<0pt + \pgfmath@xb=-\pgfmath@xb + \fi + \loop + \ifpgfmathcontinueloop + \ifdim\pgfmath@xa=\pgfmath@xb + \pgfmathcontinueloopfalse + \else + \ifdim\pgfmath@xa>\pgfmath@xb + \advance\pgfmath@xa by-\pgfmath@xb + \else + \advance\pgfmath@xb by-\pgfmath@xa + \fi + \fi + \repeat + \pgfmathparse{int(\pgfmath@xa)}% + \pgfmath@smuggleone\pgfmathresult + \endgroup} + +\newif\ifpgfmath@isprime@unknown +\newif\ifpgfmath@isprime + +\pgfmathdeclarefunction{isprime}{1}{% + \begingroup + \pgfmath@isprime@unknowntrue + \pgfmathsetcount\c@pgfmath@counta{abs(int(#1))}% + \ifcase\c@pgfmath@counta\relax + % |#1| = 0 + \pgfmath@isprimefalse + \pgfmath@isprime@unknownfalse + \or + % |#1| = 1 + \pgfmath@isprimefalse + \pgfmath@isprime@unknownfalse + \or + % |#1| = 2 + \pgfmath@isprimetrue + \pgfmath@isprime@unknownfalse + \or + % |#1| = 3 + \pgfmath@isprimetrue + \pgfmath@isprime@unknownfalse + \else + % |#1| > 3 + \ifodd\c@pgfmath@counta\relax + \else + \pgfmath@isprimefalse + \pgfmath@isprime@unknownfalse + \fi + \fi + \ifpgfmath@isprime@unknown + \c@pgfmath@countd=3 + \pgfmath@isprimetrue + \pgfmathloop + \c@pgfmath@countb=\c@pgfmath@counta + \divide\c@pgfmath@countb by\c@pgfmath@countd + \ifnum\c@pgfmath@countb>\c@pgfmath@countd + \pgfmath@isprime@unknowntrue + \else + \pgfmath@isprime@unknownfalse + \fi + \multiply\c@pgfmath@countb by\c@pgfmath@countd + \ifnum\c@pgfmath@countb=\c@pgfmath@counta + \global\pgfmath@isprimefalse + \pgfmath@isprime@unknownfalse + \fi + \ifpgfmath@isprime@unknown\advance\c@pgfmath@countd by 2 + \repeatpgfmathloop + \fi + \ifpgfmath@isprime + \def\pgfmathresult{1}% + \else + \def\pgfmathresult{0}% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup} + +\pgfmathdeclarefunction{isodd}{1}{% + \begingroup + \pgfmathsetcount\c@pgfmath@counta{abs(int(#1))}% + \ifodd\c@pgfmath@counta + \def\pgfmathresult{1}% + \else + \def\pgfmathresult{0}% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup} + +\pgfmathdeclarefunction{iseven}{1}{% + \begingroup + \pgfmathsetcount\c@pgfmath@counta{abs(int(#1))}% + \ifodd\c@pgfmath@counta + \def\pgfmathresult{0}% + \else + \def\pgfmathresult{1}% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup} + +\endinput
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.misc.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.misc.code.tex index 65460e4b3cc..e00786d7a37 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.misc.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.misc.code.tex @@ -160,6 +160,9 @@ \def\pgfmath@scientific@@@#1#2#3#4#5#6\pgfmath@{% \edef\pgfmath@sci@mantissaB{#1#2#3#4#5}% \c@pgfmath@counta\pgfmath@sci@exponent\relax% + \ifnum\c@pgfmath@counta<-4\relax% + \pgfmath@x0pt\relax% + \else% \c@pgfmath@countb\c@pgfmath@counta% \ifnum\c@pgfmath@counta<0\relax% \c@pgfmath@counta-\c@pgfmath@counta% @@ -191,7 +194,7 @@ \advance\c@pgfmath@countc100000\relax% \edef\pgfmath@sci@result{\pgfmath@sci@sign\the\c@pgfmath@counta.\expandafter\pgfmath@gobbleone\the\c@pgfmath@countc pt}% \pgfmath@x\pgfmath@sci@result\relax% - \fi% + \fi\fi% \pgfmath@returnone\pgfmath@x% \endgroup} @@ -263,6 +266,24 @@ \pgfmath@smuggleone\pgfmathresult\endgroup% } +% dim function: return dimension of an array +% dim({1,2,3}) return 3 +% dim({{1,2,3},{4,5,6}}) return 2 +\pgfmathdeclarefunction{dim}{1}{% + \begingroup + \pgfmath@count=0\relax + \expandafter\pgfmath@dim@i\pgfutil@firstofone#1\pgfmath@token@stop + \edef\pgfmathresult{\the\pgfmath@count}% + \pgfmath@smuggleone\pgfmathresult% + \endgroup} + +\def\pgfmath@dim@i#1{% + \ifx\pgfmath@token@stop#1% + \else + \advance\pgfmath@count by 1\relax + \expandafter\pgfmath@dim@i + \fi} + % max function. % @@ -287,7 +308,7 @@ % For compatability with old code. \def\pgfmathmax#1#2{% - \pgfmathparse{getargs(#1,#2)}% + \pgfmathparse{#1,#2}% \expandafter\pgfmathmax@\expandafter{\pgfmathresult}% } @@ -314,7 +335,7 @@ % For compatability with old code. \def\pgfmathmin#1#2{% - \pgfmathparse{getargs(#1,#2)}% + \pgfmathparse{#1,#2}% \expandafter\pgfmathmin@\expandafter{\pgfmathresult}% } diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.trigonometric.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.trigonometric.code.tex index 6b60eb7ec16..02726731357 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.trigonometric.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.trigonometric.code.tex @@ -24,36 +24,36 @@ % Convert #1 from radians to degrees (accurate to 1 deg). % \pgfmathdeclarefunction{radians}{1}{% - \begingroup% - \expandafter\pgfmath@x#1pt\relax% - \pgfmath@x57.29577\pgfmath@x\relax% 57.29577 = 360/(2*pi) - \pgfmath@returnone\pgfmath@x% - \endgroup% + \begingroup% + \expandafter\pgfmath@x#1pt\relax% + \pgfmath@x57.29577\pgfmath@x\relax% 57.29577 = 360/(2*pi) + \pgfmath@returnone\pgfmath@x% + \endgroup% }% % \pgfmathdeg % % Convert #1 from radians to degrees. % -\pgfmathdeclarefunction{deg}{1}{% - \begingroup% - \expandafter\pgfmath@x#1pt\relax% - \pgfmath@x57.29577\pgfmath@x\relax% 57.29577 = 360/(2*pi) - \pgfmath@returnone\pgfmath@x% - \endgroup% +\pgfmathdeclarefunction{deg}{1}{% + \begingroup% + \expandafter\pgfmath@x#1pt\relax% + \pgfmath@x57.29577\pgfmath@x\relax% 57.29577 = 360/(2*pi) + \pgfmath@returnone\pgfmath@x% + \endgroup% }% % \pgfmathrad % % Convert #1 from degrees to radians. % -\pgfmathdeclarefunction{rad}{1}{% - \begingroup% - \expandafter\pgfmath@x#1pt\relax% - \pgfmath@x3.14159\pgfmath@x% - \divide\pgfmath@x180\relax% - \pgfmath@returnone\pgfmath@x% - \endgroup% +\pgfmathdeclarefunction{rad}{1}{% + \begingroup% + \expandafter\pgfmath@x#1pt\relax% + \pgfmath@x3.14159\pgfmath@x% + \divide\pgfmath@x180\relax% + \pgfmath@returnone\pgfmath@x% + \endgroup% }% % \pgfmathsin @@ -61,40 +61,41 @@ % Calculate the sine of #1 (in degrees). % \pgfmathdeclarefunction{sin}{1}{% - % Let #1 = a.b - % Then sin(#1) \approx (1-b)*sin(a) + b*sin(a+1) - % - \begingroup% - \expandafter\pgfmath@x#1pt\relax% - \advance\pgfmath@x-90pt\relax% - \afterassignment\pgfmath@gobbletilpgfmath@ - \expandafter\c@pgfmath@counta\the\pgfmath@x\relax\pgfmath@ - \divide\c@pgfmath@counta360\relax% - \multiply\c@pgfmath@counta-360\relax% - \advance\pgfmath@x\c@pgfmath@counta pt\relax% - \ifdim\pgfmath@x<0pt\relax\pgfmath@x-\pgfmath@x\fi% - \ifdim\pgfmath@x<180pt\relax% - \else - \pgfmath@x-\pgfmath@x% - \advance\pgfmath@x360pt\relax% - \fi% - % Now 0 <= x < 179. So split x into integer and decimal... - % - \afterassignment\pgfmath@xa% - \expandafter\c@pgfmath@counta\the\pgfmath@x\relax% - % - % ...if #1 is an integer, don't do anything fancy. - \ifdim\pgfmath@xa=0pt% - \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname pt\relax% - \else% - \pgfmath@x-\pgfmath@xa% - \advance\pgfmath@x1pt\relax% - \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@x% - \advance\c@pgfmath@counta1\relax% - \expandafter\advance\expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@xa% - \fi% - \pgfmath@returnone\pgfmath@x% - \endgroup + % Let #1 = a.b + % Then sin(#1) \approx (1-b)*sin(a) + b*sin(a+1) + % + \begingroup% + \expandafter\pgfmath@x#1pt\relax% + \advance\pgfmath@x-90pt\relax% + \afterassignment\pgfmath@gobbletilpgfmath@ + \expandafter\c@pgfmath@counta\the\pgfmath@x\relax\pgfmath@ + \divide\c@pgfmath@counta360\relax% + \multiply\c@pgfmath@counta-360\relax% + \advance\pgfmath@x\c@pgfmath@counta pt\relax% + \ifdim\pgfmath@x<0pt\relax\pgfmath@x-\pgfmath@x\fi% + \ifdim\pgfmath@x<180pt\relax% + \else + \pgfmath@x-\pgfmath@x% + \advance\pgfmath@x360pt\relax% + \fi% + % Now 0 <= x < 179. So split x into integer and decimal... + % + \afterassignment\pgfmath@xa% + \expandafter\c@pgfmath@counta\the\pgfmath@x\relax% + % + % ...if #1 is an integer, don't do anything fancy. + \ifdim\pgfmath@xa=0pt% + \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname pt\relax% + \else% + \pgfmath@x-\pgfmath@xa% + \advance\pgfmath@x1pt\relax% + \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@x% + \advance\c@pgfmath@counta1\relax% + \ifnum\c@pgfmath@counta=181\relax\c@pgfmath@counta179\relax\fi% + \expandafter\advance\expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@xa% + \fi% + \pgfmath@returnone\pgfmath@x% + \endgroup } % \pgfmathcos @@ -102,40 +103,40 @@ % Calculate the cosine of #1 (in degrees). % \pgfmathdeclarefunction{cos}{1}{% - % Let x = a.b - % Then cos(x) \approx (1-b)*cos(a) + b*cos(a+1) - % - \begingroup% - \expandafter\pgfmath@x#1pt\relax% - \afterassignment\pgfmath@gobbletilpgfmath@% - \expandafter\c@pgfmath@counta\the\pgfmath@x\relax\pgfmath@% - \divide\c@pgfmath@counta360\relax% - \multiply\c@pgfmath@counta-360\relax% - \advance\pgfmath@x\c@pgfmath@counta pt\relax% - \ifdim\pgfmath@x<0pt\relax\pgfmath@x-\pgfmath@x\fi% - \ifdim\pgfmath@x<180pt\relax% - \else% - \pgfmath@x-\pgfmath@x% - \advance\pgfmath@x360pt\relax% - \fi% - % Now 0 <= x < 179. So split x into integer and decimal... - % - \afterassignment\pgfmath@xa% - \expandafter\c@pgfmath@counta\the\pgfmath@x\relax% - % - % ...if #1 is an integer, don't do anything fancy. - \ifdim\pgfmath@xa=0pt% - \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname pt% - \else% - \pgfmath@x-\pgfmath@xa% - \advance\pgfmath@x1pt\relax% - \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@x% - \advance\c@pgfmath@counta1\relax% - \ifnum\c@pgfmath@counta=181\relax\c@pgfmath@counta179\relax\fi% - \expandafter\advance\expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@xa% - \fi% - \pgfmath@returnone\pgfmath@x% - \endgroup% + % Let x = a.b + % Then cos(x) \approx (1-b)*cos(a) + b*cos(a+1) + % + \begingroup% + \expandafter\pgfmath@x#1pt\relax% + \afterassignment\pgfmath@gobbletilpgfmath@% + \expandafter\c@pgfmath@counta\the\pgfmath@x\relax\pgfmath@% + \divide\c@pgfmath@counta360\relax% + \multiply\c@pgfmath@counta-360\relax% + \advance\pgfmath@x\c@pgfmath@counta pt\relax% + \ifdim\pgfmath@x<0pt\relax\pgfmath@x-\pgfmath@x\fi% + \ifdim\pgfmath@x<180pt\relax% + \else% + \pgfmath@x-\pgfmath@x% + \advance\pgfmath@x360pt\relax% + \fi% + % Now 0 <= x < 179. So split x into integer and decimal... + % + \afterassignment\pgfmath@xa% + \expandafter\c@pgfmath@counta\the\pgfmath@x\relax% + % + % ...if #1 is an integer, don't do anything fancy. + \ifdim\pgfmath@xa=0pt% + \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname pt% + \else% + \pgfmath@x-\pgfmath@xa% + \advance\pgfmath@x1pt\relax% + \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@x% + \advance\c@pgfmath@counta1\relax% + \ifnum\c@pgfmath@counta=181\relax\c@pgfmath@counta179\relax\fi% + \expandafter\advance\expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@xa% + \fi% + \pgfmath@returnone\pgfmath@x% + \endgroup% } % \pgfmathsincos @@ -143,12 +144,12 @@ % Calculate the sin and cosine of #1 (in degrees). % \def\pgfmathsincos#1{% - \pgfmathparse{#1}% - \expandafter\pgfmathsincos@\expandafter{\pgfmathresult}} + \pgfmathparse{#1}% + \expandafter\pgfmathsincos@\expandafter{\pgfmathresult}} \def\pgfmathsincos@#1{% - \edef\pgfmath@temparg{#1}% - \pgfmathsin@{\pgfmath@temparg}\edef\pgfmathresulty{\pgfmathresult}% - \pgfmathcos@{\pgfmath@temparg}\edef\pgfmathresultx{\pgfmathresult}% + \edef\pgfmath@temparg{#1}% + \pgfmathsin@{\pgfmath@temparg}\edef\pgfmathresulty{\pgfmathresult}% + \pgfmathcos@{\pgfmath@temparg}\edef\pgfmathresultx{\pgfmathresult}% } % \pgfmathtan @@ -156,25 +157,25 @@ % Calculate the tangent of #1 (in degrees). % \pgfmathdeclarefunction{tan}{1}{% - \begingroup% - \edef\pgfmath@temparg{#1}% - \pgfmathcos@{\pgfmath@temparg}% - \expandafter\pgfmathreciprocal@\expandafter{\pgfmathresult}% - \edef\pgfmath@tantemp{\pgfmathresult}% - \pgfmathsin@{\pgfmath@temparg}% - \pgfmath@x\pgfmathresult pt\relax% - \pgfmath@x\pgfmath@tantemp\pgfmath@x% - \pgfmath@returnone\pgfmath@x% - \endgroup% + \begingroup% + \edef\pgfmath@temparg{#1}% + \pgfmathcos@{\pgfmath@temparg}% + \expandafter\pgfmathreciprocal@\expandafter{\pgfmathresult}% + \edef\pgfmath@tantemp{\pgfmathresult}% + \pgfmathsin@{\pgfmath@temparg}% + \pgfmath@x\pgfmathresult pt\relax% + \pgfmath@x\pgfmath@tantemp\pgfmath@x% + \pgfmath@returnone\pgfmath@x% + \endgroup% } % \pgfmathcosec % % Calculate the cosec of #1 (in degrees). % -\pgfmathdeclarefunction{cosec}{1}{% - \expandafter\pgfmathsin@\expandafter{#1}% - \pgfmathreciprocal@{\pgfmathresult}% +\pgfmathdeclarefunction{cosec}{1}{% + \expandafter\pgfmathsin@\expandafter{#1}% + \pgfmathreciprocal@{\pgfmathresult}% } % \pgfmathsec @@ -182,1282 +183,1338 @@ % Calculate the sec of #1 (in degrees). % \pgfmathdeclarefunction{sec}{1}{% - \expandafter\pgfmathcos@\expandafter{#1}% - \pgfmathreciprocal@{\pgfmathresult}% + \expandafter\pgfmathcos@\expandafter{#1}% + \pgfmathreciprocal@{\pgfmathresult}% } % \pgfmathcot % % Calculate the cotangent of #1 (in degrees). % -\pgfmathdeclarefunction{cot}{1}{% - \begingroup% - \edef\pgfmath@temparg{#1}% - \pgfmathsin@{\pgfmath@temparg}% - \expandafter\pgfmathreciprocal@\expandafter{\pgfmathresult}% - \edef\pgfmath@tantemp{\pgfmathresult}% - \pgfmathcos@{\pgfmath@temparg}% - \pgfmath@x\pgfmathresult pt\relax% - \pgfmath@x\pgfmath@tantemp\pgfmath@x% - \pgfmath@returnone\pgfmath@x% - \endgroup% +\pgfmathdeclarefunction{cot}{1}{% + \begingroup% + \edef\pgfmath@temparg{#1}% + \pgfmathsin@{\pgfmath@temparg}% + \expandafter\pgfmathreciprocal@\expandafter{\pgfmathresult}% + \edef\pgfmath@tantemp{\pgfmathresult}% + \pgfmathcos@{\pgfmath@temparg}% + \pgfmath@x\pgfmathresult pt\relax% + \pgfmath@x\pgfmath@tantemp\pgfmath@x% + \pgfmath@returnone\pgfmath@x% + \endgroup% } +\def\pgfmath@multiply@thousand#1.#2#3#4#5\relax{% + \edef\pgfmathresult{#1#2#3#4.#5}% +}% + % \pgfmathasin % % The asin of #1 % \pgfmathdeclarefunction{asin}{1}{% - \begingroup% - \expandafter\pgfmath@x#1pt\relax% - \pgfmath@xa\pgfmath@x% - \ifdim\pgfmath@x<0pt\relax% - \pgfmath@x-\pgfmath@x% - \fi% - \pgfmath@x1000\pgfmath@x% - \afterassignment\pgfmath@gobbletilpgfmath@% - \expandafter\c@pgfmath@counta\the\pgfmath@x\relax\pgfmath@% - \pgfmath@x-\csname pgfmath@acos@\the\c@pgfmath@counta\endcsname pt\relax% - \advance\pgfmath@x90pt\relax% - \ifdim\pgfmath@xa<0pt\relax% - \pgfmath@x-\pgfmath@x% - \fi% - \pgfmath@returnone\pgfmath@x% - \endgroup% + \begingroup% + \pgfmath@x=#1pt % + \pgfmath@xa\pgfmath@x% + \edef\pgf@temp{\pgf@sys@tonumber\pgfmath@x}% + % compute lossless '*1000' operation: + \expandafter\pgfmath@multiply@thousand\pgf@temp 000\relax + \pgfmath@x=\pgfmathresult pt % + \ifdim\pgfmath@x<0pt\relax% + \pgfmath@x-\pgfmath@x% + \fi% + \pgfmath@table@lookup{\pgfmath@x}{pgfmath@acos@}{1001}% + \pgfmath@x=-\pgfmath@x + \advance\pgfmath@x90pt\relax% + \ifdim\pgfmath@xa<0pt\relax% + \pgfmath@x-\pgfmath@x% + \fi% + \pgfmath@returnone\pgfmath@x% + \endgroup% +} + +% Defines \pgfmath@x to be the result of the table lookup for value +% '#1' in table '#2' +% +% #1: a value for which lookup should be performed +% #2: the table's prefix name +% #3: the table's size +\def\pgfmath@table@lookup#1#2#3{% + \pgfmath@x=#1\relax + \expandafter\pgfmath@table@lookup@\the\pgfmath@x\relax{#2}{#3}% } +\def\pgfmath@table@lookup@#1.#2\relax#3#4{% + \edef\pgf@temp{\Pgf@geT#2}% strip 'pt' suffix. + % + % prepare constant interpolant (i.e. the value at node '#1'): + \pgfmath@x=\csname #3#1\endcsname pt % + % + \c@pgfmath@countc=#1 % + \advance\c@pgfmath@countc by1 % + \ifnum\c@pgfmath@countc<#4 % + % Ah - we have enough elements in the table. + % + % perform linear interpolation: + \pgfmath@ya=\csname #3\the\c@pgfmath@countc\endcsname pt % + \advance\pgfmath@ya by-\pgfmath@x % + \advance\pgfmath@x by0.\pgf@temp\pgfmath@ya + \fi +}% % \pgfmathacos % % The acos of #1 -% +% \pgfmathdeclarefunction{acos}{1}{% - \begingroup% - \expandafter\pgfmath@x#1pt\relax% - \pgfmath@xa\pgfmath@x% - \ifdim\pgfmath@x<0pt\relax% - \pgfmath@x-\pgfmath@x% - \fi% - \pgfmath@x1000\pgfmath@x% - \afterassignment\pgfmath@gobbletilpgfmath@% - \expandafter\c@pgfmath@counta\the\pgfmath@x\relax\pgfmath@% - \expandafter\pgfmath@x\csname pgfmath@acos@\the\c@pgfmath@counta\endcsname pt\relax% - \ifdim\pgfmath@xa<0pt\relax% - \pgfmath@x-\pgfmath@x% - \advance\pgfmath@x by180pt\relax% - \fi% - \pgfmath@returnone\pgfmath@x% - \endgroup% + \begingroup% + \pgfmath@x#1pt\relax% + \pgfmath@xa\pgfmath@x% + \edef\pgf@temp{\pgf@sys@tonumber\pgfmath@x}% + % compute lossless '*1000' operation: + \expandafter\pgfmath@multiply@thousand\pgf@temp 000\relax + \pgfmath@x=\pgfmathresult pt % + \ifdim\pgfmath@x<0pt\relax% + \pgfmath@x-\pgfmath@x% + \fi% + \pgfmath@table@lookup{\pgfmath@x}{pgfmath@acos@}{1001}% + \ifdim\pgfmath@xa<0pt\relax% + \pgfmath@x-\pgfmath@x% + \advance\pgfmath@x by180pt\relax% + \fi% + \pgfmath@returnone\pgfmath@x% + \endgroup% } \pgfmathdeclarefunction{atan}{1}{% - \begingroup% - \expandafter\pgfmath@x#1pt\relax% - \pgfmath@xa\pgfmath@x% - \ifdim\pgfmath@x<0pt\relax% - \pgfmath@x-\pgfmath@x% - \fi% - \pgfmath@xb\pgfmath@x% - \ifdim\pgfmath@x>1pt\relax% - \edef\pgfmath@temp{\pgfmath@tonumber{\pgfmath@x}}% - \pgfmathreciprocal@{\pgfmath@temp}% - \pgfmath@x\pgfmathresult pt\relax% - \fi% - \pgfmath@x1000\pgfmath@x% - \afterassignment\pgfmath@gobbletilpgfmath@% - \expandafter\c@pgfmath@counta\the\pgfmath@x\relax\pgfmath@% - \ifdim\pgfmath@xb>1pt\relax% - \expandafter\pgfmath@x\expandafter-\csname pgfmath@atan@\the\c@pgfmath@counta\endcsname pt\relax% - \advance\pgfmath@x90pt% - \else% - \expandafter\pgfmath@x\csname pgfmath@atan@\the\c@pgfmath@counta\endcsname pt\relax% - \fi% - \ifdim\pgfmath@xa<0pt\relax% - \pgfmath@x-\pgfmath@x% - \fi% - \pgfmath@returnone\pgfmath@x% - \endgroup% + \begingroup% + \expandafter\pgfmath@x#1pt\relax% + \pgfmath@xa\pgfmath@x% + \ifdim\pgfmath@x<0pt\relax% + \pgfmath@x-\pgfmath@x% + \fi% + \pgfmath@xb\pgfmath@x% + \ifdim\pgfmath@x>1pt\relax% + \edef\pgfmath@temp{\pgfmath@tonumber{\pgfmath@x}}% + \pgfmathreciprocal@{\pgfmath@temp}% + \pgfmath@x\pgfmathresult pt\relax% + \fi% + % compute lossless '*1000' operation: + \edef\pgf@temp{\pgf@sys@tonumber\pgfmath@x}% + \expandafter\pgfmath@multiply@thousand\pgf@temp 000\relax + \pgfmath@x=\pgfmathresult pt % + \pgfmath@table@lookup{\pgfmath@x}{pgfmath@atan@}{1001}%xxx + \ifdim\pgfmath@xb>1pt\relax% + \pgfmath@x=-\pgfmath@x% + \advance\pgfmath@x90pt% + \fi% + \ifdim\pgfmath@xa<0pt\relax% + \pgfmath@x-\pgfmath@x% + \fi% + \pgfmath@returnone\pgfmath@x% + \endgroup% } \pgfmathdeclarefunction{atan2}{2}{% - \begingroup% - \pgfmath@x=#1pt\relax% - \ifdim\pgfmath@x<0pt\relax% - \pgfmath@x=-\pgfmath@x% - \fi% - \ifdim\pgfmath@x<0.001pt\relax% - \ifdim#2pt<0pt\relax% - \pgfmath@x=-90pt\relax% - \else% - \ifdim#2pt>0pt\relax% - \pgfmath@x=90pt\relax% - \else% - \pgfmath@x=0pt\relax% - \fi% - \fi% - \else% - \pgfmathdivide@{#2}{#1}% - \expandafter\pgfmathatan@\expandafter{\pgfmathresult}% - \pgfmath@x=\pgfmathresult pt\relax% - \ifdim#2pt<0pt\relax% - \ifdim#1pt<0pt\relax% - \advance\pgfmath@x by-180pt\relax% - \fi% - \else% - \ifdim#1pt<0pt\relax% - \advance\pgfmath@x by180pt\relax% - \fi% - \fi% - \fi% - \pgfmath@returnone\pgfmath@x% - \endgroup% + % Note: first parameter is y (!), second is x (!) + \begingroup% + \pgfmath@y=#1pt\relax% + \ifdim\pgfmath@y<0pt\relax% + \pgfmath@y=-\pgfmath@y% + \fi% + \ifdim\pgfmath@y<0.001pt\relax% + \ifdim#2pt<0pt\relax% + \pgfmath@x=-180pt\relax% + \else% + \ifdim#2pt>0pt\relax% + \pgfmath@x=0pt\relax% + \else% + \ifdim#1pt<0pt% + \pgfmath@x=-90pt\relax% + \else% + \pgfmath@x=90pt\relax% + \fi% + \fi% + \fi% + \else% + \pgfmathabs@{#1}\let\pgfmath@tempa\pgfmathresult% + \pgfmathabs@{#2}\let\pgfmath@tempb\pgfmathresult% + \ifdim\pgfmath@tempa pt>\pgfmath@tempb pt% + \pgfmathdivide@{#2}{\pgfmath@tempa}% + \expandafter\pgfmathatan@\expandafter{\pgfmathresult}% + \pgfmath@x=90pt% + \advance\pgfmath@x by-\pgfmathresult pt\relax% + \else% + \pgfmathdivide@{\pgfmath@tempa}{#2}% + \expandafter\pgfmathatan@\expandafter{\pgfmathresult}% + \pgfmath@x=\pgfmathresult pt\relax% + \ifdim#2pt<0pt% + \advance\pgfmath@x by180pt\relax% + \fi% + \fi% + \ifdim#1pt<0pt\relax% + \pgfmath@x=-\pgfmath@x% + \fi% + \fi% + \pgfmath@returnone\pgfmath@x% + \endgroup% } +% This is needed since \pgfmathatan2 is not a legal macro name +\expandafter\let\expandafter\pgfmathatantwo\csname pgfmathatan2\endcsname +\expandafter\let\expandafter\pgfmathatantwo@\csname pgfmathatan2@\endcsname + \def\pgfmath@def#1#2#3{\expandafter\def\csname pgfmath@#1@#2\endcsname{#3}} -\pgfmath@def{cos}{0}{1.00000} \pgfmath@def{cos}{1}{0.99985} -\pgfmath@def{cos}{2}{0.99939} \pgfmath@def{cos}{3}{0.99863} -\pgfmath@def{cos}{4}{0.99756} \pgfmath@def{cos}{5}{0.99619} -\pgfmath@def{cos}{6}{0.99452} \pgfmath@def{cos}{7}{0.99255} -\pgfmath@def{cos}{8}{0.99027} \pgfmath@def{cos}{9}{0.98769} -\pgfmath@def{cos}{10}{0.98481} \pgfmath@def{cos}{11}{0.98163} -\pgfmath@def{cos}{12}{0.97815} \pgfmath@def{cos}{13}{0.97437} -\pgfmath@def{cos}{14}{0.97030} \pgfmath@def{cos}{15}{0.96593} -\pgfmath@def{cos}{16}{0.96126} \pgfmath@def{cos}{17}{0.95630} -\pgfmath@def{cos}{18}{0.95106} \pgfmath@def{cos}{19}{0.94552} -\pgfmath@def{cos}{20}{0.93969} \pgfmath@def{cos}{21}{0.93358} -\pgfmath@def{cos}{22}{0.92718} \pgfmath@def{cos}{23}{0.92050} -\pgfmath@def{cos}{24}{0.91355} \pgfmath@def{cos}{25}{0.90631} -\pgfmath@def{cos}{26}{0.89879} \pgfmath@def{cos}{27}{0.89101} -\pgfmath@def{cos}{28}{0.88295} \pgfmath@def{cos}{29}{0.87462} -\pgfmath@def{cos}{30}{0.86603} \pgfmath@def{cos}{31}{0.85717} -\pgfmath@def{cos}{32}{0.84805} \pgfmath@def{cos}{33}{0.83867} -\pgfmath@def{cos}{34}{0.82904} \pgfmath@def{cos}{35}{0.81915} -\pgfmath@def{cos}{36}{0.80902} \pgfmath@def{cos}{37}{0.79864} -\pgfmath@def{cos}{38}{0.78801} \pgfmath@def{cos}{39}{0.77715} -\pgfmath@def{cos}{40}{0.76604} \pgfmath@def{cos}{41}{0.75471} -\pgfmath@def{cos}{42}{0.74314} \pgfmath@def{cos}{43}{0.73135} -\pgfmath@def{cos}{44}{0.71934} \pgfmath@def{cos}{45}{0.70711} -\pgfmath@def{cos}{46}{0.69466} \pgfmath@def{cos}{47}{0.68200} -\pgfmath@def{cos}{48}{0.66913} \pgfmath@def{cos}{49}{0.65606} -\pgfmath@def{cos}{50}{0.64279} \pgfmath@def{cos}{51}{0.62932} -\pgfmath@def{cos}{52}{0.61566} \pgfmath@def{cos}{53}{0.60182} -\pgfmath@def{cos}{54}{0.58779} \pgfmath@def{cos}{55}{0.57358} -\pgfmath@def{cos}{56}{0.55919} \pgfmath@def{cos}{57}{0.54464} -\pgfmath@def{cos}{58}{0.52992} \pgfmath@def{cos}{59}{0.51504} -\pgfmath@def{cos}{60}{0.50000} \pgfmath@def{cos}{61}{0.48481} -\pgfmath@def{cos}{62}{0.46947} \pgfmath@def{cos}{63}{0.45399} -\pgfmath@def{cos}{64}{0.43837} \pgfmath@def{cos}{65}{0.42262} -\pgfmath@def{cos}{66}{0.40674} \pgfmath@def{cos}{67}{0.39073} -\pgfmath@def{cos}{68}{0.37461} \pgfmath@def{cos}{69}{0.35837} -\pgfmath@def{cos}{70}{0.34202} \pgfmath@def{cos}{71}{0.32557} -\pgfmath@def{cos}{72}{0.30902} \pgfmath@def{cos}{73}{0.29237} -\pgfmath@def{cos}{74}{0.27564} \pgfmath@def{cos}{75}{0.25882} -\pgfmath@def{cos}{76}{0.24192} \pgfmath@def{cos}{77}{0.22495} -\pgfmath@def{cos}{78}{0.20791} \pgfmath@def{cos}{79}{0.19081} -\pgfmath@def{cos}{80}{0.17365} \pgfmath@def{cos}{81}{0.15643} -\pgfmath@def{cos}{82}{0.13917} \pgfmath@def{cos}{83}{0.12187} -\pgfmath@def{cos}{84}{0.10453} \pgfmath@def{cos}{85}{0.08716} -\pgfmath@def{cos}{86}{0.06976} \pgfmath@def{cos}{87}{0.05234} -\pgfmath@def{cos}{88}{0.03490} \pgfmath@def{cos}{89}{0.01745} -\pgfmath@def{cos}{90}{0.00000} \pgfmath@def{cos}{91}{-0.01745} -\pgfmath@def{cos}{92}{-0.03490} \pgfmath@def{cos}{93}{-0.05234} -\pgfmath@def{cos}{94}{-0.06976} \pgfmath@def{cos}{95}{-0.08716} -\pgfmath@def{cos}{96}{-0.10453} \pgfmath@def{cos}{97}{-0.12187} -\pgfmath@def{cos}{98}{-0.13917} \pgfmath@def{cos}{99}{-0.15643} -\pgfmath@def{cos}{100}{-0.17365} \pgfmath@def{cos}{101}{-0.19081} -\pgfmath@def{cos}{102}{-0.20791} \pgfmath@def{cos}{103}{-0.22495} -\pgfmath@def{cos}{104}{-0.24192} \pgfmath@def{cos}{105}{-0.25882} -\pgfmath@def{cos}{106}{-0.27564} \pgfmath@def{cos}{107}{-0.29237} -\pgfmath@def{cos}{108}{-0.30902} \pgfmath@def{cos}{109}{-0.32557} -\pgfmath@def{cos}{110}{-0.34202} \pgfmath@def{cos}{111}{-0.35837} -\pgfmath@def{cos}{112}{-0.37461} \pgfmath@def{cos}{113}{-0.39073} -\pgfmath@def{cos}{114}{-0.40674} \pgfmath@def{cos}{115}{-0.42262} -\pgfmath@def{cos}{116}{-0.43837} \pgfmath@def{cos}{117}{-0.45399} -\pgfmath@def{cos}{118}{-0.46947} \pgfmath@def{cos}{119}{-0.48481} -\pgfmath@def{cos}{120}{-0.50000} \pgfmath@def{cos}{121}{-0.51504} -\pgfmath@def{cos}{122}{-0.52992} \pgfmath@def{cos}{123}{-0.54464} -\pgfmath@def{cos}{124}{-0.55919} \pgfmath@def{cos}{125}{-0.57358} -\pgfmath@def{cos}{126}{-0.58779} \pgfmath@def{cos}{127}{-0.60182} -\pgfmath@def{cos}{128}{-0.61566} \pgfmath@def{cos}{129}{-0.62932} -\pgfmath@def{cos}{130}{-0.64279} \pgfmath@def{cos}{131}{-0.65606} -\pgfmath@def{cos}{132}{-0.66913} \pgfmath@def{cos}{133}{-0.68200} -\pgfmath@def{cos}{134}{-0.69466} \pgfmath@def{cos}{135}{-0.70711} -\pgfmath@def{cos}{136}{-0.71934} \pgfmath@def{cos}{137}{-0.73135} -\pgfmath@def{cos}{138}{-0.74314} \pgfmath@def{cos}{139}{-0.75471} -\pgfmath@def{cos}{140}{-0.76604} \pgfmath@def{cos}{141}{-0.77715} -\pgfmath@def{cos}{142}{-0.78801} \pgfmath@def{cos}{143}{-0.79864} -\pgfmath@def{cos}{144}{-0.80902} \pgfmath@def{cos}{145}{-0.81915} -\pgfmath@def{cos}{146}{-0.82904} \pgfmath@def{cos}{147}{-0.83867} -\pgfmath@def{cos}{148}{-0.84805} \pgfmath@def{cos}{149}{-0.85717} -\pgfmath@def{cos}{150}{-0.86603} \pgfmath@def{cos}{151}{-0.87462} -\pgfmath@def{cos}{152}{-0.88295} \pgfmath@def{cos}{153}{-0.89101} -\pgfmath@def{cos}{154}{-0.89879} \pgfmath@def{cos}{155}{-0.90631} -\pgfmath@def{cos}{156}{-0.91355} \pgfmath@def{cos}{157}{-0.92050} -\pgfmath@def{cos}{158}{-0.92718} \pgfmath@def{cos}{159}{-0.93358} -\pgfmath@def{cos}{160}{-0.93969} \pgfmath@def{cos}{161}{-0.94552} -\pgfmath@def{cos}{162}{-0.95106} \pgfmath@def{cos}{163}{-0.95630} -\pgfmath@def{cos}{164}{-0.96126} \pgfmath@def{cos}{165}{-0.96593} -\pgfmath@def{cos}{166}{-0.97030} \pgfmath@def{cos}{167}{-0.97437} -\pgfmath@def{cos}{168}{-0.97815} \pgfmath@def{cos}{169}{-0.98163} -\pgfmath@def{cos}{170}{-0.98481} \pgfmath@def{cos}{171}{-0.98769} -\pgfmath@def{cos}{172}{-0.99027} \pgfmath@def{cos}{173}{-0.99255} -\pgfmath@def{cos}{174}{-0.99452} \pgfmath@def{cos}{175}{-0.99619} -\pgfmath@def{cos}{176}{-0.99756} \pgfmath@def{cos}{177}{-0.99863} -\pgfmath@def{cos}{178}{-0.99939} \pgfmath@def{cos}{179}{-0.99985} -\pgfmath@def{cos}{180}{-1.00000} \pgfmath@def{cos}{181}{-0.99985} +\pgfmath@def{cos}{0}{1.00000} \pgfmath@def{cos}{1}{0.99985} +\pgfmath@def{cos}{2}{0.99939} \pgfmath@def{cos}{3}{0.99863} +\pgfmath@def{cos}{4}{0.99756} \pgfmath@def{cos}{5}{0.99619} +\pgfmath@def{cos}{6}{0.99452} \pgfmath@def{cos}{7}{0.99255} +\pgfmath@def{cos}{8}{0.99027} \pgfmath@def{cos}{9}{0.98769} +\pgfmath@def{cos}{10}{0.98481} \pgfmath@def{cos}{11}{0.98163} +\pgfmath@def{cos}{12}{0.97815} \pgfmath@def{cos}{13}{0.97437} +\pgfmath@def{cos}{14}{0.97030} \pgfmath@def{cos}{15}{0.96593} +\pgfmath@def{cos}{16}{0.96126} \pgfmath@def{cos}{17}{0.95630} +\pgfmath@def{cos}{18}{0.95106} \pgfmath@def{cos}{19}{0.94552} +\pgfmath@def{cos}{20}{0.93969} \pgfmath@def{cos}{21}{0.93358} +\pgfmath@def{cos}{22}{0.92718} \pgfmath@def{cos}{23}{0.92050} +\pgfmath@def{cos}{24}{0.91355} \pgfmath@def{cos}{25}{0.90631} +\pgfmath@def{cos}{26}{0.89879} \pgfmath@def{cos}{27}{0.89101} +\pgfmath@def{cos}{28}{0.88295} \pgfmath@def{cos}{29}{0.87462} +\pgfmath@def{cos}{30}{0.86603} \pgfmath@def{cos}{31}{0.85717} +\pgfmath@def{cos}{32}{0.84805} \pgfmath@def{cos}{33}{0.83867} +\pgfmath@def{cos}{34}{0.82904} \pgfmath@def{cos}{35}{0.81915} +\pgfmath@def{cos}{36}{0.80902} \pgfmath@def{cos}{37}{0.79864} +\pgfmath@def{cos}{38}{0.78801} \pgfmath@def{cos}{39}{0.77715} +\pgfmath@def{cos}{40}{0.76604} \pgfmath@def{cos}{41}{0.75471} +\pgfmath@def{cos}{42}{0.74314} \pgfmath@def{cos}{43}{0.73135} +\pgfmath@def{cos}{44}{0.71934} \pgfmath@def{cos}{45}{0.70711} +\pgfmath@def{cos}{46}{0.69466} \pgfmath@def{cos}{47}{0.68200} +\pgfmath@def{cos}{48}{0.66913} \pgfmath@def{cos}{49}{0.65606} +\pgfmath@def{cos}{50}{0.64279} \pgfmath@def{cos}{51}{0.62932} +\pgfmath@def{cos}{52}{0.61566} \pgfmath@def{cos}{53}{0.60182} +\pgfmath@def{cos}{54}{0.58779} \pgfmath@def{cos}{55}{0.57358} +\pgfmath@def{cos}{56}{0.55919} \pgfmath@def{cos}{57}{0.54464} +\pgfmath@def{cos}{58}{0.52992} \pgfmath@def{cos}{59}{0.51504} +\pgfmath@def{cos}{60}{0.50000} \pgfmath@def{cos}{61}{0.48481} +\pgfmath@def{cos}{62}{0.46947} \pgfmath@def{cos}{63}{0.45399} +\pgfmath@def{cos}{64}{0.43837} \pgfmath@def{cos}{65}{0.42262} +\pgfmath@def{cos}{66}{0.40674} \pgfmath@def{cos}{67}{0.39073} +\pgfmath@def{cos}{68}{0.37461} \pgfmath@def{cos}{69}{0.35837} +\pgfmath@def{cos}{70}{0.34202} \pgfmath@def{cos}{71}{0.32557} +\pgfmath@def{cos}{72}{0.30902} \pgfmath@def{cos}{73}{0.29237} +\pgfmath@def{cos}{74}{0.27564} \pgfmath@def{cos}{75}{0.25882} +\pgfmath@def{cos}{76}{0.24192} \pgfmath@def{cos}{77}{0.22495} +\pgfmath@def{cos}{78}{0.20791} \pgfmath@def{cos}{79}{0.19081} +\pgfmath@def{cos}{80}{0.17365} \pgfmath@def{cos}{81}{0.15643} +\pgfmath@def{cos}{82}{0.13917} \pgfmath@def{cos}{83}{0.12187} +\pgfmath@def{cos}{84}{0.10453} \pgfmath@def{cos}{85}{0.08716} +\pgfmath@def{cos}{86}{0.06976} \pgfmath@def{cos}{87}{0.05234} +\pgfmath@def{cos}{88}{0.03490} \pgfmath@def{cos}{89}{0.01745} +\pgfmath@def{cos}{90}{0.00000} \pgfmath@def{cos}{91}{-0.01745} +\pgfmath@def{cos}{92}{-0.03490} \pgfmath@def{cos}{93}{-0.05234} +\pgfmath@def{cos}{94}{-0.06976} \pgfmath@def{cos}{95}{-0.08716} +\pgfmath@def{cos}{96}{-0.10453} \pgfmath@def{cos}{97}{-0.12187} +\pgfmath@def{cos}{98}{-0.13917} \pgfmath@def{cos}{99}{-0.15643} +\pgfmath@def{cos}{100}{-0.17365} \pgfmath@def{cos}{101}{-0.19081} +\pgfmath@def{cos}{102}{-0.20791} \pgfmath@def{cos}{103}{-0.22495} +\pgfmath@def{cos}{104}{-0.24192} \pgfmath@def{cos}{105}{-0.25882} +\pgfmath@def{cos}{106}{-0.27564} \pgfmath@def{cos}{107}{-0.29237} +\pgfmath@def{cos}{108}{-0.30902} \pgfmath@def{cos}{109}{-0.32557} +\pgfmath@def{cos}{110}{-0.34202} \pgfmath@def{cos}{111}{-0.35837} +\pgfmath@def{cos}{112}{-0.37461} \pgfmath@def{cos}{113}{-0.39073} +\pgfmath@def{cos}{114}{-0.40674} \pgfmath@def{cos}{115}{-0.42262} +\pgfmath@def{cos}{116}{-0.43837} \pgfmath@def{cos}{117}{-0.45399} +\pgfmath@def{cos}{118}{-0.46947} \pgfmath@def{cos}{119}{-0.48481} +\pgfmath@def{cos}{120}{-0.50000} \pgfmath@def{cos}{121}{-0.51504} +\pgfmath@def{cos}{122}{-0.52992} \pgfmath@def{cos}{123}{-0.54464} +\pgfmath@def{cos}{124}{-0.55919} \pgfmath@def{cos}{125}{-0.57358} +\pgfmath@def{cos}{126}{-0.58779} \pgfmath@def{cos}{127}{-0.60182} +\pgfmath@def{cos}{128}{-0.61566} \pgfmath@def{cos}{129}{-0.62932} +\pgfmath@def{cos}{130}{-0.64279} \pgfmath@def{cos}{131}{-0.65606} +\pgfmath@def{cos}{132}{-0.66913} \pgfmath@def{cos}{133}{-0.68200} +\pgfmath@def{cos}{134}{-0.69466} \pgfmath@def{cos}{135}{-0.70711} +\pgfmath@def{cos}{136}{-0.71934} \pgfmath@def{cos}{137}{-0.73135} +\pgfmath@def{cos}{138}{-0.74314} \pgfmath@def{cos}{139}{-0.75471} +\pgfmath@def{cos}{140}{-0.76604} \pgfmath@def{cos}{141}{-0.77715} +\pgfmath@def{cos}{142}{-0.78801} \pgfmath@def{cos}{143}{-0.79864} +\pgfmath@def{cos}{144}{-0.80902} \pgfmath@def{cos}{145}{-0.81915} +\pgfmath@def{cos}{146}{-0.82904} \pgfmath@def{cos}{147}{-0.83867} +\pgfmath@def{cos}{148}{-0.84805} \pgfmath@def{cos}{149}{-0.85717} +\pgfmath@def{cos}{150}{-0.86603} \pgfmath@def{cos}{151}{-0.87462} +\pgfmath@def{cos}{152}{-0.88295} \pgfmath@def{cos}{153}{-0.89101} +\pgfmath@def{cos}{154}{-0.89879} \pgfmath@def{cos}{155}{-0.90631} +\pgfmath@def{cos}{156}{-0.91355} \pgfmath@def{cos}{157}{-0.92050} +\pgfmath@def{cos}{158}{-0.92718} \pgfmath@def{cos}{159}{-0.93358} +\pgfmath@def{cos}{160}{-0.93969} \pgfmath@def{cos}{161}{-0.94552} +\pgfmath@def{cos}{162}{-0.95106} \pgfmath@def{cos}{163}{-0.95630} +\pgfmath@def{cos}{164}{-0.96126} \pgfmath@def{cos}{165}{-0.96593} +\pgfmath@def{cos}{166}{-0.97030} \pgfmath@def{cos}{167}{-0.97437} +\pgfmath@def{cos}{168}{-0.97815} \pgfmath@def{cos}{169}{-0.98163} +\pgfmath@def{cos}{170}{-0.98481} \pgfmath@def{cos}{171}{-0.98769} +\pgfmath@def{cos}{172}{-0.99027} \pgfmath@def{cos}{173}{-0.99255} +\pgfmath@def{cos}{174}{-0.99452} \pgfmath@def{cos}{175}{-0.99619} +\pgfmath@def{cos}{176}{-0.99756} \pgfmath@def{cos}{177}{-0.99863} +\pgfmath@def{cos}{178}{-0.99939} \pgfmath@def{cos}{179}{-0.99985} +\pgfmath@def{cos}{180}{-1.00000} \pgfmath@def{cos}{181}{-0.99985} -\pgfmath@def{cosfrac}{0}{1.00000} \pgfmath@def{cosfrac}{1}{0.99995} -\pgfmath@def{cosfrac}{2}{0.99980} \pgfmath@def{cosfrac}{3}{0.99955} -\pgfmath@def{cosfrac}{4}{0.99920} \pgfmath@def{cosfrac}{5}{0.99875} -\pgfmath@def{cosfrac}{6}{0.99820} \pgfmath@def{cosfrac}{7}{0.99755} -\pgfmath@def{cosfrac}{8}{0.99681} \pgfmath@def{cosfrac}{9}{0.99597} -\pgfmath@def{cosfrac}{10}{0.99503} \pgfmath@def{cosfrac}{11}{0.99400} -\pgfmath@def{cosfrac}{12}{0.99287} \pgfmath@def{cosfrac}{13}{0.99165} -\pgfmath@def{cosfrac}{14}{0.99034} \pgfmath@def{cosfrac}{15}{0.98893} -\pgfmath@def{cosfrac}{16}{0.98744} \pgfmath@def{cosfrac}{17}{0.98585} -\pgfmath@def{cosfrac}{18}{0.98418} \pgfmath@def{cosfrac}{19}{0.98242} -\pgfmath@def{cosfrac}{20}{0.98058} \pgfmath@def{cosfrac}{21}{0.97865} -\pgfmath@def{cosfrac}{22}{0.97664} \pgfmath@def{cosfrac}{23}{0.97455} -\pgfmath@def{cosfrac}{24}{0.97238} \pgfmath@def{cosfrac}{25}{0.97014} -\pgfmath@def{cosfrac}{26}{0.96782} \pgfmath@def{cosfrac}{27}{0.96542} -\pgfmath@def{cosfrac}{28}{0.96296} \pgfmath@def{cosfrac}{29}{0.96042} -\pgfmath@def{cosfrac}{30}{0.95782} \pgfmath@def{cosfrac}{31}{0.95515} -\pgfmath@def{cosfrac}{32}{0.95242} \pgfmath@def{cosfrac}{33}{0.94962} -\pgfmath@def{cosfrac}{34}{0.94677} \pgfmath@def{cosfrac}{35}{0.94385} -\pgfmath@def{cosfrac}{36}{0.94088} \pgfmath@def{cosfrac}{37}{0.93786} -\pgfmath@def{cosfrac}{38}{0.93478} \pgfmath@def{cosfrac}{39}{0.93165} -\pgfmath@def{cosfrac}{40}{0.92847} \pgfmath@def{cosfrac}{41}{0.92525} -\pgfmath@def{cosfrac}{42}{0.92198} \pgfmath@def{cosfrac}{43}{0.91866} -\pgfmath@def{cosfrac}{44}{0.91531} \pgfmath@def{cosfrac}{45}{0.91192} -\pgfmath@def{cosfrac}{46}{0.90849} \pgfmath@def{cosfrac}{47}{0.90502} -\pgfmath@def{cosfrac}{48}{0.90152} \pgfmath@def{cosfrac}{49}{0.89799} -\pgfmath@def{cosfrac}{50}{0.89442} \pgfmath@def{cosfrac}{51}{0.89083} -\pgfmath@def{cosfrac}{52}{0.88721} \pgfmath@def{cosfrac}{53}{0.88357} -\pgfmath@def{cosfrac}{54}{0.87990} \pgfmath@def{cosfrac}{55}{0.87621} -\pgfmath@def{cosfrac}{56}{0.87250} \pgfmath@def{cosfrac}{57}{0.86877} -\pgfmath@def{cosfrac}{58}{0.86503} \pgfmath@def{cosfrac}{59}{0.86126} -\pgfmath@def{cosfrac}{60}{0.85749} \pgfmath@def{cosfrac}{61}{0.85370} -\pgfmath@def{cosfrac}{62}{0.84990} \pgfmath@def{cosfrac}{63}{0.84609} -\pgfmath@def{cosfrac}{64}{0.84227} \pgfmath@def{cosfrac}{65}{0.83844} -\pgfmath@def{cosfrac}{66}{0.83460} \pgfmath@def{cosfrac}{67}{0.83077} -\pgfmath@def{cosfrac}{68}{0.82692} \pgfmath@def{cosfrac}{69}{0.82308} -\pgfmath@def{cosfrac}{70}{0.81923} \pgfmath@def{cosfrac}{71}{0.81538} -\pgfmath@def{cosfrac}{72}{0.81153} \pgfmath@def{cosfrac}{73}{0.80768} -\pgfmath@def{cosfrac}{74}{0.80384} \pgfmath@def{cosfrac}{75}{0.80000} -\pgfmath@def{cosfrac}{76}{0.79616} \pgfmath@def{cosfrac}{77}{0.79232} -\pgfmath@def{cosfrac}{78}{0.78850} \pgfmath@def{cosfrac}{79}{0.78468} -\pgfmath@def{cosfrac}{80}{0.78086} \pgfmath@def{cosfrac}{81}{0.77706} -\pgfmath@def{cosfrac}{82}{0.77326} \pgfmath@def{cosfrac}{83}{0.76948} -\pgfmath@def{cosfrac}{84}{0.76570} \pgfmath@def{cosfrac}{85}{0.76193} -\pgfmath@def{cosfrac}{86}{0.75818} \pgfmath@def{cosfrac}{87}{0.75444} -\pgfmath@def{cosfrac}{88}{0.75071} \pgfmath@def{cosfrac}{89}{0.74699} -\pgfmath@def{cosfrac}{90}{0.74329} \pgfmath@def{cosfrac}{91}{0.73960} -\pgfmath@def{cosfrac}{92}{0.73593} \pgfmath@def{cosfrac}{93}{0.73227} -\pgfmath@def{cosfrac}{94}{0.72862} \pgfmath@def{cosfrac}{95}{0.72499} -\pgfmath@def{cosfrac}{96}{0.72138} \pgfmath@def{cosfrac}{97}{0.71779} -\pgfmath@def{cosfrac}{98}{0.71421} \pgfmath@def{cosfrac}{99}{0.71065} -\pgfmath@def{cosfrac}{100}{0.70710} +\pgfmath@def{cosfrac}{0}{1.00000} \pgfmath@def{cosfrac}{1}{0.99995} +\pgfmath@def{cosfrac}{2}{0.99980} \pgfmath@def{cosfrac}{3}{0.99955} +\pgfmath@def{cosfrac}{4}{0.99920} \pgfmath@def{cosfrac}{5}{0.99875} +\pgfmath@def{cosfrac}{6}{0.99820} \pgfmath@def{cosfrac}{7}{0.99755} +\pgfmath@def{cosfrac}{8}{0.99681} \pgfmath@def{cosfrac}{9}{0.99597} +\pgfmath@def{cosfrac}{10}{0.99503} \pgfmath@def{cosfrac}{11}{0.99400} +\pgfmath@def{cosfrac}{12}{0.99287} \pgfmath@def{cosfrac}{13}{0.99165} +\pgfmath@def{cosfrac}{14}{0.99034} \pgfmath@def{cosfrac}{15}{0.98893} +\pgfmath@def{cosfrac}{16}{0.98744} \pgfmath@def{cosfrac}{17}{0.98585} +\pgfmath@def{cosfrac}{18}{0.98418} \pgfmath@def{cosfrac}{19}{0.98242} +\pgfmath@def{cosfrac}{20}{0.98058} \pgfmath@def{cosfrac}{21}{0.97865} +\pgfmath@def{cosfrac}{22}{0.97664} \pgfmath@def{cosfrac}{23}{0.97455} +\pgfmath@def{cosfrac}{24}{0.97238} \pgfmath@def{cosfrac}{25}{0.97014} +\pgfmath@def{cosfrac}{26}{0.96782} \pgfmath@def{cosfrac}{27}{0.96542} +\pgfmath@def{cosfrac}{28}{0.96296} \pgfmath@def{cosfrac}{29}{0.96042} +\pgfmath@def{cosfrac}{30}{0.95782} \pgfmath@def{cosfrac}{31}{0.95515} +\pgfmath@def{cosfrac}{32}{0.95242} \pgfmath@def{cosfrac}{33}{0.94962} +\pgfmath@def{cosfrac}{34}{0.94677} \pgfmath@def{cosfrac}{35}{0.94385} +\pgfmath@def{cosfrac}{36}{0.94088} \pgfmath@def{cosfrac}{37}{0.93786} +\pgfmath@def{cosfrac}{38}{0.93478} \pgfmath@def{cosfrac}{39}{0.93165} +\pgfmath@def{cosfrac}{40}{0.92847} \pgfmath@def{cosfrac}{41}{0.92525} +\pgfmath@def{cosfrac}{42}{0.92198} \pgfmath@def{cosfrac}{43}{0.91866} +\pgfmath@def{cosfrac}{44}{0.91531} \pgfmath@def{cosfrac}{45}{0.91192} +\pgfmath@def{cosfrac}{46}{0.90849} \pgfmath@def{cosfrac}{47}{0.90502} +\pgfmath@def{cosfrac}{48}{0.90152} \pgfmath@def{cosfrac}{49}{0.89799} +\pgfmath@def{cosfrac}{50}{0.89442} \pgfmath@def{cosfrac}{51}{0.89083} +\pgfmath@def{cosfrac}{52}{0.88721} \pgfmath@def{cosfrac}{53}{0.88357} +\pgfmath@def{cosfrac}{54}{0.87990} \pgfmath@def{cosfrac}{55}{0.87621} +\pgfmath@def{cosfrac}{56}{0.87250} \pgfmath@def{cosfrac}{57}{0.86877} +\pgfmath@def{cosfrac}{58}{0.86503} \pgfmath@def{cosfrac}{59}{0.86126} +\pgfmath@def{cosfrac}{60}{0.85749} \pgfmath@def{cosfrac}{61}{0.85370} +\pgfmath@def{cosfrac}{62}{0.84990} \pgfmath@def{cosfrac}{63}{0.84609} +\pgfmath@def{cosfrac}{64}{0.84227} \pgfmath@def{cosfrac}{65}{0.83844} +\pgfmath@def{cosfrac}{66}{0.83460} \pgfmath@def{cosfrac}{67}{0.83077} +\pgfmath@def{cosfrac}{68}{0.82692} \pgfmath@def{cosfrac}{69}{0.82308} +\pgfmath@def{cosfrac}{70}{0.81923} \pgfmath@def{cosfrac}{71}{0.81538} +\pgfmath@def{cosfrac}{72}{0.81153} \pgfmath@def{cosfrac}{73}{0.80768} +\pgfmath@def{cosfrac}{74}{0.80384} \pgfmath@def{cosfrac}{75}{0.80000} +\pgfmath@def{cosfrac}{76}{0.79616} \pgfmath@def{cosfrac}{77}{0.79232} +\pgfmath@def{cosfrac}{78}{0.78850} \pgfmath@def{cosfrac}{79}{0.78468} +\pgfmath@def{cosfrac}{80}{0.78086} \pgfmath@def{cosfrac}{81}{0.77706} +\pgfmath@def{cosfrac}{82}{0.77326} \pgfmath@def{cosfrac}{83}{0.76948} +\pgfmath@def{cosfrac}{84}{0.76570} \pgfmath@def{cosfrac}{85}{0.76193} +\pgfmath@def{cosfrac}{86}{0.75818} \pgfmath@def{cosfrac}{87}{0.75444} +\pgfmath@def{cosfrac}{88}{0.75071} \pgfmath@def{cosfrac}{89}{0.74699} +\pgfmath@def{cosfrac}{90}{0.74329} \pgfmath@def{cosfrac}{91}{0.73960} +\pgfmath@def{cosfrac}{92}{0.73593} \pgfmath@def{cosfrac}{93}{0.73227} +\pgfmath@def{cosfrac}{94}{0.72862} \pgfmath@def{cosfrac}{95}{0.72499} +\pgfmath@def{cosfrac}{96}{0.72138} \pgfmath@def{cosfrac}{97}{0.71779} +\pgfmath@def{cosfrac}{98}{0.71421} \pgfmath@def{cosfrac}{99}{0.71065} +\pgfmath@def{cosfrac}{100}{0.70710} % Oh No! Some really loooooong tables. -\pgfmath@def{atan}{0}{0.00000} \pgfmath@def{atan}{1}{0.05729} -\pgfmath@def{atan}{2}{0.11459} \pgfmath@def{atan}{3}{0.17188} -\pgfmath@def{atan}{4}{0.22918} \pgfmath@def{atan}{5}{0.28647} -\pgfmath@def{atan}{6}{0.34377} \pgfmath@def{atan}{7}{0.40106} -\pgfmath@def{atan}{8}{0.45835} \pgfmath@def{atan}{9}{0.51564} -\pgfmath@def{atan}{10}{0.57293} \pgfmath@def{atan}{11}{0.63022} -\pgfmath@def{atan}{12}{0.68751} \pgfmath@def{atan}{13}{0.74480} -\pgfmath@def{atan}{14}{0.80208} \pgfmath@def{atan}{15}{0.85937} -\pgfmath@def{atan}{16}{0.91665} \pgfmath@def{atan}{17}{0.97393} -\pgfmath@def{atan}{18}{1.03121} \pgfmath@def{atan}{19}{1.08848} -\pgfmath@def{atan}{20}{1.14576} \pgfmath@def{atan}{21}{1.20303} -\pgfmath@def{atan}{22}{1.26030} \pgfmath@def{atan}{23}{1.31757} -\pgfmath@def{atan}{24}{1.37483} \pgfmath@def{atan}{25}{1.43209} -\pgfmath@def{atan}{26}{1.48935} \pgfmath@def{atan}{27}{1.54661} -\pgfmath@def{atan}{28}{1.60386} \pgfmath@def{atan}{29}{1.66111} -\pgfmath@def{atan}{30}{1.71835} \pgfmath@def{atan}{31}{1.77560} -\pgfmath@def{atan}{32}{1.83284} \pgfmath@def{atan}{33}{1.89007} -\pgfmath@def{atan}{34}{1.94730} \pgfmath@def{atan}{35}{2.00453} -\pgfmath@def{atan}{36}{2.06175} \pgfmath@def{atan}{37}{2.11897} -\pgfmath@def{atan}{38}{2.17619} \pgfmath@def{atan}{39}{2.23340} -\pgfmath@def{atan}{40}{2.29061} \pgfmath@def{atan}{41}{2.34781} -\pgfmath@def{atan}{42}{2.40500} \pgfmath@def{atan}{43}{2.46220} -\pgfmath@def{atan}{44}{2.51938} \pgfmath@def{atan}{45}{2.57657} -\pgfmath@def{atan}{46}{2.63374} \pgfmath@def{atan}{47}{2.69092} -\pgfmath@def{atan}{48}{2.74808} \pgfmath@def{atan}{49}{2.80524} -\pgfmath@def{atan}{50}{2.86240} \pgfmath@def{atan}{51}{2.91955} -\pgfmath@def{atan}{52}{2.97669} \pgfmath@def{atan}{53}{3.03383} -\pgfmath@def{atan}{54}{3.09097} \pgfmath@def{atan}{55}{3.14809} -\pgfmath@def{atan}{56}{3.20521} \pgfmath@def{atan}{57}{3.26232} -\pgfmath@def{atan}{58}{3.31943} \pgfmath@def{atan}{59}{3.37653} -\pgfmath@def{atan}{60}{3.43363} \pgfmath@def{atan}{61}{3.49071} -\pgfmath@def{atan}{62}{3.54779} \pgfmath@def{atan}{63}{3.60487} -\pgfmath@def{atan}{64}{3.66193} \pgfmath@def{atan}{65}{3.71899} -\pgfmath@def{atan}{66}{3.77604} \pgfmath@def{atan}{67}{3.83308} -\pgfmath@def{atan}{68}{3.89012} \pgfmath@def{atan}{69}{3.94715} -\pgfmath@def{atan}{70}{4.00417} \pgfmath@def{atan}{71}{4.06118} -\pgfmath@def{atan}{72}{4.11819} \pgfmath@def{atan}{73}{4.17518} -\pgfmath@def{atan}{74}{4.23217} \pgfmath@def{atan}{75}{4.28915} -\pgfmath@def{atan}{76}{4.34612} \pgfmath@def{atan}{77}{4.40308} -\pgfmath@def{atan}{78}{4.46004} \pgfmath@def{atan}{79}{4.51698} -\pgfmath@def{atan}{80}{4.57392} \pgfmath@def{atan}{81}{4.63084} -\pgfmath@def{atan}{82}{4.68776} \pgfmath@def{atan}{83}{4.74467} -\pgfmath@def{atan}{84}{4.80157} \pgfmath@def{atan}{85}{4.85846} -\pgfmath@def{atan}{86}{4.91534} \pgfmath@def{atan}{87}{4.97221} -\pgfmath@def{atan}{88}{5.02907} \pgfmath@def{atan}{89}{5.08592} -\pgfmath@def{atan}{90}{5.14276} \pgfmath@def{atan}{91}{5.19959} -\pgfmath@def{atan}{92}{5.25641} \pgfmath@def{atan}{93}{5.31322} -\pgfmath@def{atan}{94}{5.37002} \pgfmath@def{atan}{95}{5.42681} -\pgfmath@def{atan}{96}{5.48359} \pgfmath@def{atan}{97}{5.54035} -\pgfmath@def{atan}{98}{5.59711} \pgfmath@def{atan}{99}{5.65385} -\pgfmath@def{atan}{100}{5.71059} \pgfmath@def{atan}{101}{5.76731} -\pgfmath@def{atan}{102}{5.82402} \pgfmath@def{atan}{103}{5.88072} -\pgfmath@def{atan}{104}{5.93741} \pgfmath@def{atan}{105}{5.99409} -\pgfmath@def{atan}{106}{6.05075} \pgfmath@def{atan}{107}{6.10741} -\pgfmath@def{atan}{108}{6.16405} \pgfmath@def{atan}{109}{6.22068} -\pgfmath@def{atan}{110}{6.27729} \pgfmath@def{atan}{111}{6.33390} -\pgfmath@def{atan}{112}{6.39049} \pgfmath@def{atan}{113}{6.44707} -\pgfmath@def{atan}{114}{6.50364} \pgfmath@def{atan}{115}{6.56019} -\pgfmath@def{atan}{116}{6.61673} \pgfmath@def{atan}{117}{6.67326} -\pgfmath@def{atan}{118}{6.72978} \pgfmath@def{atan}{119}{6.78628} -\pgfmath@def{atan}{120}{6.84277} \pgfmath@def{atan}{121}{6.89924} -\pgfmath@def{atan}{122}{6.95571} \pgfmath@def{atan}{123}{7.01216} -\pgfmath@def{atan}{124}{7.06859} \pgfmath@def{atan}{125}{7.12501} -\pgfmath@def{atan}{126}{7.18142} \pgfmath@def{atan}{127}{7.23781} -\pgfmath@def{atan}{128}{7.29419} \pgfmath@def{atan}{129}{7.35056} -\pgfmath@def{atan}{130}{7.40691} \pgfmath@def{atan}{131}{7.46324} -\pgfmath@def{atan}{132}{7.51957} \pgfmath@def{atan}{133}{7.57587} -\pgfmath@def{atan}{134}{7.63217} \pgfmath@def{atan}{135}{7.68844} -\pgfmath@def{atan}{136}{7.74471} \pgfmath@def{atan}{137}{7.80095} -\pgfmath@def{atan}{138}{7.85719} \pgfmath@def{atan}{139}{7.91340} -\pgfmath@def{atan}{140}{7.96961} \pgfmath@def{atan}{141}{8.02579} -\pgfmath@def{atan}{142}{8.08196} \pgfmath@def{atan}{143}{8.13812} -\pgfmath@def{atan}{144}{8.19426} \pgfmath@def{atan}{145}{8.25038} -\pgfmath@def{atan}{146}{8.30649} \pgfmath@def{atan}{147}{8.36258} -\pgfmath@def{atan}{148}{8.41866} \pgfmath@def{atan}{149}{8.47472} -\pgfmath@def{atan}{150}{8.53076} \pgfmath@def{atan}{151}{8.58679} -\pgfmath@def{atan}{152}{8.64280} \pgfmath@def{atan}{153}{8.69879} -\pgfmath@def{atan}{154}{8.75477} \pgfmath@def{atan}{155}{8.81073} -\pgfmath@def{atan}{156}{8.86667} \pgfmath@def{atan}{157}{8.92260} -\pgfmath@def{atan}{158}{8.97851} \pgfmath@def{atan}{159}{9.03440} -\pgfmath@def{atan}{160}{9.09027} \pgfmath@def{atan}{161}{9.14613} -\pgfmath@def{atan}{162}{9.20197} \pgfmath@def{atan}{163}{9.25779} -\pgfmath@def{atan}{164}{9.31359} \pgfmath@def{atan}{165}{9.36938} -\pgfmath@def{atan}{166}{9.42515} \pgfmath@def{atan}{167}{9.48090} -\pgfmath@def{atan}{168}{9.53663} \pgfmath@def{atan}{169}{9.59235} -\pgfmath@def{atan}{170}{9.64804} \pgfmath@def{atan}{171}{9.70372} -\pgfmath@def{atan}{172}{9.75938} \pgfmath@def{atan}{173}{9.81502} -\pgfmath@def{atan}{174}{9.87064} \pgfmath@def{atan}{175}{9.92624} -\pgfmath@def{atan}{176}{9.98182} \pgfmath@def{atan}{177}{10.03739} -\pgfmath@def{atan}{178}{10.09294} \pgfmath@def{atan}{179}{10.14846} -\pgfmath@def{atan}{180}{10.20397} \pgfmath@def{atan}{181}{10.25946} -\pgfmath@def{atan}{182}{10.31493} \pgfmath@def{atan}{183}{10.37037} -\pgfmath@def{atan}{184}{10.42580} \pgfmath@def{atan}{185}{10.48121} -\pgfmath@def{atan}{186}{10.53660} \pgfmath@def{atan}{187}{10.59197} -\pgfmath@def{atan}{188}{10.64732} \pgfmath@def{atan}{189}{10.70265} -\pgfmath@def{atan}{190}{10.75796} \pgfmath@def{atan}{191}{10.81325} -\pgfmath@def{atan}{192}{10.86852} \pgfmath@def{atan}{193}{10.92377} -\pgfmath@def{atan}{194}{10.97900} \pgfmath@def{atan}{195}{11.03420} -\pgfmath@def{atan}{196}{11.08939} \pgfmath@def{atan}{197}{11.14456} -\pgfmath@def{atan}{198}{11.19970} \pgfmath@def{atan}{199}{11.25483} -\pgfmath@def{atan}{200}{11.30993} \pgfmath@def{atan}{201}{11.36501} -\pgfmath@def{atan}{202}{11.42007} \pgfmath@def{atan}{203}{11.47511} -\pgfmath@def{atan}{204}{11.53013} \pgfmath@def{atan}{205}{11.58512} -\pgfmath@def{atan}{206}{11.64010} \pgfmath@def{atan}{207}{11.69505} -\pgfmath@def{atan}{208}{11.74998} \pgfmath@def{atan}{209}{11.80489} -\pgfmath@def{atan}{210}{11.85977} \pgfmath@def{atan}{211}{11.91464} -\pgfmath@def{atan}{212}{11.96948} \pgfmath@def{atan}{213}{12.02430} -\pgfmath@def{atan}{214}{12.07910} \pgfmath@def{atan}{215}{12.13388} -\pgfmath@def{atan}{216}{12.18863} \pgfmath@def{atan}{217}{12.24336} -\pgfmath@def{atan}{218}{12.29807} \pgfmath@def{atan}{219}{12.35275} -\pgfmath@def{atan}{220}{12.40741} \pgfmath@def{atan}{221}{12.46205} -\pgfmath@def{atan}{222}{12.51667} \pgfmath@def{atan}{223}{12.57126} -\pgfmath@def{atan}{224}{12.62583} \pgfmath@def{atan}{225}{12.68038} -\pgfmath@def{atan}{226}{12.73490} \pgfmath@def{atan}{227}{12.78940} -\pgfmath@def{atan}{228}{12.84388} \pgfmath@def{atan}{229}{12.89833} -\pgfmath@def{atan}{230}{12.95276} \pgfmath@def{atan}{231}{13.00717} -\pgfmath@def{atan}{232}{13.06155} \pgfmath@def{atan}{233}{13.11590} -\pgfmath@def{atan}{234}{13.17024} \pgfmath@def{atan}{235}{13.22455} -\pgfmath@def{atan}{236}{13.27883} \pgfmath@def{atan}{237}{13.33309} -\pgfmath@def{atan}{238}{13.38733} \pgfmath@def{atan}{239}{13.44154} -\pgfmath@def{atan}{240}{13.49573} \pgfmath@def{atan}{241}{13.54989} -\pgfmath@def{atan}{242}{13.60403} \pgfmath@def{atan}{243}{13.65814} -\pgfmath@def{atan}{244}{13.71223} \pgfmath@def{atan}{245}{13.76630} -\pgfmath@def{atan}{246}{13.82034} \pgfmath@def{atan}{247}{13.87435} -\pgfmath@def{atan}{248}{13.92834} \pgfmath@def{atan}{249}{13.98230} -\pgfmath@def{atan}{250}{14.03624} \pgfmath@def{atan}{251}{14.09015} -\pgfmath@def{atan}{252}{14.14404} \pgfmath@def{atan}{253}{14.19790} -\pgfmath@def{atan}{254}{14.25174} \pgfmath@def{atan}{255}{14.30555} -\pgfmath@def{atan}{256}{14.35933} \pgfmath@def{atan}{257}{14.41309} -\pgfmath@def{atan}{258}{14.46682} \pgfmath@def{atan}{259}{14.52053} -\pgfmath@def{atan}{260}{14.57421} \pgfmath@def{atan}{261}{14.62787} -\pgfmath@def{atan}{262}{14.68149} \pgfmath@def{atan}{263}{14.73510} -\pgfmath@def{atan}{264}{14.78867} \pgfmath@def{atan}{265}{14.84222} -\pgfmath@def{atan}{266}{14.89575} \pgfmath@def{atan}{267}{14.94924} -\pgfmath@def{atan}{268}{15.00271} \pgfmath@def{atan}{269}{15.05615} -\pgfmath@def{atan}{270}{15.10957} \pgfmath@def{atan}{271}{15.16296} -\pgfmath@def{atan}{272}{15.21632} \pgfmath@def{atan}{273}{15.26966} -\pgfmath@def{atan}{274}{15.32297} \pgfmath@def{atan}{275}{15.37625} -\pgfmath@def{atan}{276}{15.42950} \pgfmath@def{atan}{277}{15.48273} -\pgfmath@def{atan}{278}{15.53593} \pgfmath@def{atan}{279}{15.58910} -\pgfmath@def{atan}{280}{15.64224} \pgfmath@def{atan}{281}{15.69536} -\pgfmath@def{atan}{282}{15.74845} \pgfmath@def{atan}{283}{15.80151} -\pgfmath@def{atan}{284}{15.85454} \pgfmath@def{atan}{285}{15.90755} -\pgfmath@def{atan}{286}{15.96052} \pgfmath@def{atan}{287}{16.01347} -\pgfmath@def{atan}{288}{16.06640} \pgfmath@def{atan}{289}{16.11929} -\pgfmath@def{atan}{290}{16.17215} \pgfmath@def{atan}{291}{16.22499} -\pgfmath@def{atan}{292}{16.27780} \pgfmath@def{atan}{293}{16.33058} -\pgfmath@def{atan}{294}{16.38333} \pgfmath@def{atan}{295}{16.43605} -\pgfmath@def{atan}{296}{16.48875} \pgfmath@def{atan}{297}{16.54142} -\pgfmath@def{atan}{298}{16.59405} \pgfmath@def{atan}{299}{16.64666} -\pgfmath@def{atan}{300}{16.69924} \pgfmath@def{atan}{301}{16.75179} -\pgfmath@def{atan}{302}{16.80431} \pgfmath@def{atan}{303}{16.85680} -\pgfmath@def{atan}{304}{16.90927} \pgfmath@def{atan}{305}{16.96170} -\pgfmath@def{atan}{306}{17.01411} \pgfmath@def{atan}{307}{17.06648} -\pgfmath@def{atan}{308}{17.11883} \pgfmath@def{atan}{309}{17.17114} -\pgfmath@def{atan}{310}{17.22343} \pgfmath@def{atan}{311}{17.27569} -\pgfmath@def{atan}{312}{17.32792} \pgfmath@def{atan}{313}{17.38012} -\pgfmath@def{atan}{314}{17.43228} \pgfmath@def{atan}{315}{17.48442} -\pgfmath@def{atan}{316}{17.53653} \pgfmath@def{atan}{317}{17.58861} -\pgfmath@def{atan}{318}{17.64066} \pgfmath@def{atan}{319}{17.69268} -\pgfmath@def{atan}{320}{17.74467} \pgfmath@def{atan}{321}{17.79663} -\pgfmath@def{atan}{322}{17.84855} \pgfmath@def{atan}{323}{17.90045} -\pgfmath@def{atan}{324}{17.95232} \pgfmath@def{atan}{325}{18.00416} -\pgfmath@def{atan}{326}{18.05596} \pgfmath@def{atan}{327}{18.10774} -\pgfmath@def{atan}{328}{18.15949} \pgfmath@def{atan}{329}{18.21120} -\pgfmath@def{atan}{330}{18.26289} \pgfmath@def{atan}{331}{18.31454} -\pgfmath@def{atan}{332}{18.36616} \pgfmath@def{atan}{333}{18.41775} -\pgfmath@def{atan}{334}{18.46931} \pgfmath@def{atan}{335}{18.52084} -\pgfmath@def{atan}{336}{18.57234} \pgfmath@def{atan}{337}{18.62381} -\pgfmath@def{atan}{338}{18.67525} \pgfmath@def{atan}{339}{18.72665} -\pgfmath@def{atan}{340}{18.77803} \pgfmath@def{atan}{341}{18.82937} -\pgfmath@def{atan}{342}{18.88068} \pgfmath@def{atan}{343}{18.93196} -\pgfmath@def{atan}{344}{18.98321} \pgfmath@def{atan}{345}{19.03443} -\pgfmath@def{atan}{346}{19.08562} \pgfmath@def{atan}{347}{19.13677} -\pgfmath@def{atan}{348}{19.18789} \pgfmath@def{atan}{349}{19.23898} -\pgfmath@def{atan}{350}{19.29004} \pgfmath@def{atan}{351}{19.34107} -\pgfmath@def{atan}{352}{19.39206} \pgfmath@def{atan}{353}{19.44303} -\pgfmath@def{atan}{354}{19.49396} \pgfmath@def{atan}{355}{19.54486} -\pgfmath@def{atan}{356}{19.59572} \pgfmath@def{atan}{357}{19.64656} -\pgfmath@def{atan}{358}{19.69736} \pgfmath@def{atan}{359}{19.74813} -\pgfmath@def{atan}{360}{19.79887} \pgfmath@def{atan}{361}{19.84958} -\pgfmath@def{atan}{362}{19.90025} \pgfmath@def{atan}{363}{19.95089} -\pgfmath@def{atan}{364}{20.00150} \pgfmath@def{atan}{365}{20.05208} -\pgfmath@def{atan}{366}{20.10262} \pgfmath@def{atan}{367}{20.15313} -\pgfmath@def{atan}{368}{20.20361} \pgfmath@def{atan}{369}{20.25406} -\pgfmath@def{atan}{370}{20.30447} \pgfmath@def{atan}{371}{20.35485} -\pgfmath@def{atan}{372}{20.40520} \pgfmath@def{atan}{373}{20.45551} -\pgfmath@def{atan}{374}{20.50579} \pgfmath@def{atan}{375}{20.55604} -\pgfmath@def{atan}{376}{20.60626} \pgfmath@def{atan}{377}{20.65644} -\pgfmath@def{atan}{378}{20.70659} \pgfmath@def{atan}{379}{20.75670} -\pgfmath@def{atan}{380}{20.80679} \pgfmath@def{atan}{381}{20.85684} -\pgfmath@def{atan}{382}{20.90685} \pgfmath@def{atan}{383}{20.95684} -\pgfmath@def{atan}{384}{21.00678} \pgfmath@def{atan}{385}{21.05670} -\pgfmath@def{atan}{386}{21.10658} \pgfmath@def{atan}{387}{21.15643} -\pgfmath@def{atan}{388}{21.20625} \pgfmath@def{atan}{389}{21.25603} -\pgfmath@def{atan}{390}{21.30578} \pgfmath@def{atan}{391}{21.35549} -\pgfmath@def{atan}{392}{21.40517} \pgfmath@def{atan}{393}{21.45482} -\pgfmath@def{atan}{394}{21.50444} \pgfmath@def{atan}{395}{21.55402} -\pgfmath@def{atan}{396}{21.60356} \pgfmath@def{atan}{397}{21.65307} -\pgfmath@def{atan}{398}{21.70255} \pgfmath@def{atan}{399}{21.75200} -\pgfmath@def{atan}{400}{21.80140} \pgfmath@def{atan}{401}{21.85078} -\pgfmath@def{atan}{402}{21.90012} \pgfmath@def{atan}{403}{21.94943} -\pgfmath@def{atan}{404}{21.99870} \pgfmath@def{atan}{405}{22.04794} -\pgfmath@def{atan}{406}{22.09715} \pgfmath@def{atan}{407}{22.14632} -\pgfmath@def{atan}{408}{22.19546} \pgfmath@def{atan}{409}{22.24456} -\pgfmath@def{atan}{410}{22.29362} \pgfmath@def{atan}{411}{22.34266} -\pgfmath@def{atan}{412}{22.39166} \pgfmath@def{atan}{413}{22.44062} -\pgfmath@def{atan}{414}{22.48955} \pgfmath@def{atan}{415}{22.53845} -\pgfmath@def{atan}{416}{22.58731} \pgfmath@def{atan}{417}{22.63613} -\pgfmath@def{atan}{418}{22.68492} \pgfmath@def{atan}{419}{22.73368} -\pgfmath@def{atan}{420}{22.78240} \pgfmath@def{atan}{421}{22.83109} -\pgfmath@def{atan}{422}{22.87974} \pgfmath@def{atan}{423}{22.92836} -\pgfmath@def{atan}{424}{22.97694} \pgfmath@def{atan}{425}{23.02549} -\pgfmath@def{atan}{426}{23.07400} \pgfmath@def{atan}{427}{23.12248} -\pgfmath@def{atan}{428}{23.17092} \pgfmath@def{atan}{429}{23.21933} -\pgfmath@def{atan}{430}{23.26770} \pgfmath@def{atan}{431}{23.31604} -\pgfmath@def{atan}{432}{23.36434} \pgfmath@def{atan}{433}{23.41261} -\pgfmath@def{atan}{434}{23.46084} \pgfmath@def{atan}{435}{23.50904} -\pgfmath@def{atan}{436}{23.55720} \pgfmath@def{atan}{437}{23.60532} -\pgfmath@def{atan}{438}{23.65341} \pgfmath@def{atan}{439}{23.70147} -\pgfmath@def{atan}{440}{23.74949} \pgfmath@def{atan}{441}{23.79747} -\pgfmath@def{atan}{442}{23.84542} \pgfmath@def{atan}{443}{23.89334} -\pgfmath@def{atan}{444}{23.94122} \pgfmath@def{atan}{445}{23.98906} -\pgfmath@def{atan}{446}{24.03687} \pgfmath@def{atan}{447}{24.08464} -\pgfmath@def{atan}{448}{24.13238} \pgfmath@def{atan}{449}{24.18008} -\pgfmath@def{atan}{450}{24.22774} \pgfmath@def{atan}{451}{24.27537} -\pgfmath@def{atan}{452}{24.32296} \pgfmath@def{atan}{453}{24.37052} -\pgfmath@def{atan}{454}{24.41804} \pgfmath@def{atan}{455}{24.46553} -\pgfmath@def{atan}{456}{24.51298} \pgfmath@def{atan}{457}{24.56040} -\pgfmath@def{atan}{458}{24.60778} \pgfmath@def{atan}{459}{24.65512} -\pgfmath@def{atan}{460}{24.70243} \pgfmath@def{atan}{461}{24.74970} -\pgfmath@def{atan}{462}{24.79693} \pgfmath@def{atan}{463}{24.84413} -\pgfmath@def{atan}{464}{24.89130} \pgfmath@def{atan}{465}{24.93842} -\pgfmath@def{atan}{466}{24.98551} \pgfmath@def{atan}{467}{25.03257} -\pgfmath@def{atan}{468}{25.07959} \pgfmath@def{atan}{469}{25.12657} -\pgfmath@def{atan}{470}{25.17352} \pgfmath@def{atan}{471}{25.22043} -\pgfmath@def{atan}{472}{25.26731} \pgfmath@def{atan}{473}{25.31414} -\pgfmath@def{atan}{474}{25.36095} \pgfmath@def{atan}{475}{25.40771} -\pgfmath@def{atan}{476}{25.45444} \pgfmath@def{atan}{477}{25.50114} -\pgfmath@def{atan}{478}{25.54780} \pgfmath@def{atan}{479}{25.59442} -\pgfmath@def{atan}{480}{25.64100} \pgfmath@def{atan}{481}{25.68755} -\pgfmath@def{atan}{482}{25.73406} \pgfmath@def{atan}{483}{25.78054} -\pgfmath@def{atan}{484}{25.82698} \pgfmath@def{atan}{485}{25.87338} -\pgfmath@def{atan}{486}{25.91975} \pgfmath@def{atan}{487}{25.96608} -\pgfmath@def{atan}{488}{26.01237} \pgfmath@def{atan}{489}{26.05863} -\pgfmath@def{atan}{490}{26.10485} \pgfmath@def{atan}{491}{26.15103} -\pgfmath@def{atan}{492}{26.19718} \pgfmath@def{atan}{493}{26.24329} -\pgfmath@def{atan}{494}{26.28937} \pgfmath@def{atan}{495}{26.33541} -\pgfmath@def{atan}{496}{26.38141} \pgfmath@def{atan}{497}{26.42737} -\pgfmath@def{atan}{498}{26.47330} \pgfmath@def{atan}{499}{26.51919} -\pgfmath@def{atan}{500}{26.56505} \pgfmath@def{atan}{501}{26.61086} -\pgfmath@def{atan}{502}{26.65665} \pgfmath@def{atan}{503}{26.70239} -\pgfmath@def{atan}{504}{26.74810} \pgfmath@def{atan}{505}{26.79377} -\pgfmath@def{atan}{506}{26.83941} \pgfmath@def{atan}{507}{26.88500} -\pgfmath@def{atan}{508}{26.93057} \pgfmath@def{atan}{509}{26.97609} -\pgfmath@def{atan}{510}{27.02158} \pgfmath@def{atan}{511}{27.06703} -\pgfmath@def{atan}{512}{27.11244} \pgfmath@def{atan}{513}{27.15782} -\pgfmath@def{atan}{514}{27.20316} \pgfmath@def{atan}{515}{27.24846} -\pgfmath@def{atan}{516}{27.29373} \pgfmath@def{atan}{517}{27.33896} -\pgfmath@def{atan}{518}{27.38415} \pgfmath@def{atan}{519}{27.42931} -\pgfmath@def{atan}{520}{27.47443} \pgfmath@def{atan}{521}{27.51951} -\pgfmath@def{atan}{522}{27.56455} \pgfmath@def{atan}{523}{27.60956} -\pgfmath@def{atan}{524}{27.65453} \pgfmath@def{atan}{525}{27.69947} -\pgfmath@def{atan}{526}{27.74437} \pgfmath@def{atan}{527}{27.78923} -\pgfmath@def{atan}{528}{27.83405} \pgfmath@def{atan}{529}{27.87884} -\pgfmath@def{atan}{530}{27.92359} \pgfmath@def{atan}{531}{27.96830} -\pgfmath@def{atan}{532}{28.01297} \pgfmath@def{atan}{533}{28.05761} -\pgfmath@def{atan}{534}{28.10221} \pgfmath@def{atan}{535}{28.14678} -\pgfmath@def{atan}{536}{28.19130} \pgfmath@def{atan}{537}{28.23579} -\pgfmath@def{atan}{538}{28.28025} \pgfmath@def{atan}{539}{28.32466} -\pgfmath@def{atan}{540}{28.36904} \pgfmath@def{atan}{541}{28.41338} -\pgfmath@def{atan}{542}{28.45769} \pgfmath@def{atan}{543}{28.50196} -\pgfmath@def{atan}{544}{28.54619} \pgfmath@def{atan}{545}{28.59038} -\pgfmath@def{atan}{546}{28.63454} \pgfmath@def{atan}{547}{28.67865} -\pgfmath@def{atan}{548}{28.72274} \pgfmath@def{atan}{549}{28.76678} -\pgfmath@def{atan}{550}{28.81079} \pgfmath@def{atan}{551}{28.85476} -\pgfmath@def{atan}{552}{28.89869} \pgfmath@def{atan}{553}{28.94259} -\pgfmath@def{atan}{554}{28.98645} \pgfmath@def{atan}{555}{29.03027} -\pgfmath@def{atan}{556}{29.07405} \pgfmath@def{atan}{557}{29.11780} -\pgfmath@def{atan}{558}{29.16151} \pgfmath@def{atan}{559}{29.20519} -\pgfmath@def{atan}{560}{29.24882} \pgfmath@def{atan}{561}{29.29242} -\pgfmath@def{atan}{562}{29.33598} \pgfmath@def{atan}{563}{29.37951} -\pgfmath@def{atan}{564}{29.42299} \pgfmath@def{atan}{565}{29.46644} -\pgfmath@def{atan}{566}{29.50986} \pgfmath@def{atan}{567}{29.55323} -\pgfmath@def{atan}{568}{29.59657} \pgfmath@def{atan}{569}{29.63987} -\pgfmath@def{atan}{570}{29.68314} \pgfmath@def{atan}{571}{29.72636} -\pgfmath@def{atan}{572}{29.76955} \pgfmath@def{atan}{573}{29.81270} -\pgfmath@def{atan}{574}{29.85582} \pgfmath@def{atan}{575}{29.89890} -\pgfmath@def{atan}{576}{29.94194} \pgfmath@def{atan}{577}{29.98494} -\pgfmath@def{atan}{578}{30.02791} \pgfmath@def{atan}{579}{30.07084} -\pgfmath@def{atan}{580}{30.11373} \pgfmath@def{atan}{581}{30.15658} -\pgfmath@def{atan}{582}{30.19940} \pgfmath@def{atan}{583}{30.24218} -\pgfmath@def{atan}{584}{30.28492} \pgfmath@def{atan}{585}{30.32763} -\pgfmath@def{atan}{586}{30.37030} \pgfmath@def{atan}{587}{30.41293} -\pgfmath@def{atan}{588}{30.45552} \pgfmath@def{atan}{589}{30.49808} -\pgfmath@def{atan}{590}{30.54060} \pgfmath@def{atan}{591}{30.58308} -\pgfmath@def{atan}{592}{30.62553} \pgfmath@def{atan}{593}{30.66794} -\pgfmath@def{atan}{594}{30.71031} \pgfmath@def{atan}{595}{30.75264} -\pgfmath@def{atan}{596}{30.79494} \pgfmath@def{atan}{597}{30.83720} -\pgfmath@def{atan}{598}{30.87942} \pgfmath@def{atan}{599}{30.92160} -\pgfmath@def{atan}{600}{30.96375} \pgfmath@def{atan}{601}{31.00586} -\pgfmath@def{atan}{602}{31.04794} \pgfmath@def{atan}{603}{31.08997} -\pgfmath@def{atan}{604}{31.13197} \pgfmath@def{atan}{605}{31.17393} -\pgfmath@def{atan}{606}{31.21586} \pgfmath@def{atan}{607}{31.25775} -\pgfmath@def{atan}{608}{31.29960} \pgfmath@def{atan}{609}{31.34141} -\pgfmath@def{atan}{610}{31.38319} \pgfmath@def{atan}{611}{31.42493} -\pgfmath@def{atan}{612}{31.46663} \pgfmath@def{atan}{613}{31.50829} -\pgfmath@def{atan}{614}{31.54992} \pgfmath@def{atan}{615}{31.59151} -\pgfmath@def{atan}{616}{31.63306} \pgfmath@def{atan}{617}{31.67458} -\pgfmath@def{atan}{618}{31.71606} \pgfmath@def{atan}{619}{31.75750} -\pgfmath@def{atan}{620}{31.79891} \pgfmath@def{atan}{621}{31.84028} -\pgfmath@def{atan}{622}{31.88161} \pgfmath@def{atan}{623}{31.92290} -\pgfmath@def{atan}{624}{31.96416} \pgfmath@def{atan}{625}{32.00538} -\pgfmath@def{atan}{626}{32.04656} \pgfmath@def{atan}{627}{32.08771} -\pgfmath@def{atan}{628}{32.12882} \pgfmath@def{atan}{629}{32.16989} -\pgfmath@def{atan}{630}{32.21092} \pgfmath@def{atan}{631}{32.25192} -\pgfmath@def{atan}{632}{32.29288} \pgfmath@def{atan}{633}{32.33381} -\pgfmath@def{atan}{634}{32.37469} \pgfmath@def{atan}{635}{32.41554} -\pgfmath@def{atan}{636}{32.45636} \pgfmath@def{atan}{637}{32.49713} -\pgfmath@def{atan}{638}{32.53787} \pgfmath@def{atan}{639}{32.57857} -\pgfmath@def{atan}{640}{32.61924} \pgfmath@def{atan}{641}{32.65987} -\pgfmath@def{atan}{642}{32.70046} \pgfmath@def{atan}{643}{32.74101} -\pgfmath@def{atan}{644}{32.78153} \pgfmath@def{atan}{645}{32.82201} -\pgfmath@def{atan}{646}{32.86246} \pgfmath@def{atan}{647}{32.90286} -\pgfmath@def{atan}{648}{32.94323} \pgfmath@def{atan}{649}{32.98357} -\pgfmath@def{atan}{650}{33.02386} \pgfmath@def{atan}{651}{33.06412} -\pgfmath@def{atan}{652}{33.10435} \pgfmath@def{atan}{653}{33.14453} -\pgfmath@def{atan}{654}{33.18468} \pgfmath@def{atan}{655}{33.22479} -\pgfmath@def{atan}{656}{33.26487} \pgfmath@def{atan}{657}{33.30491} -\pgfmath@def{atan}{658}{33.34491} \pgfmath@def{atan}{659}{33.38488} -\pgfmath@def{atan}{660}{33.42481} \pgfmath@def{atan}{661}{33.46470} -\pgfmath@def{atan}{662}{33.50455} \pgfmath@def{atan}{663}{33.54437} -\pgfmath@def{atan}{664}{33.58416} \pgfmath@def{atan}{665}{33.62390} -\pgfmath@def{atan}{666}{33.66361} \pgfmath@def{atan}{667}{33.70328} -\pgfmath@def{atan}{668}{33.74292} \pgfmath@def{atan}{669}{33.78252} -\pgfmath@def{atan}{670}{33.82208} \pgfmath@def{atan}{671}{33.86161} -\pgfmath@def{atan}{672}{33.90110} \pgfmath@def{atan}{673}{33.94055} -\pgfmath@def{atan}{674}{33.97997} \pgfmath@def{atan}{675}{34.01935} -\pgfmath@def{atan}{676}{34.05869} \pgfmath@def{atan}{677}{34.09800} -\pgfmath@def{atan}{678}{34.13727} \pgfmath@def{atan}{679}{34.17650} -\pgfmath@def{atan}{680}{34.21570} \pgfmath@def{atan}{681}{34.25486} -\pgfmath@def{atan}{682}{34.29398} \pgfmath@def{atan}{683}{34.33307} -\pgfmath@def{atan}{684}{34.37212} \pgfmath@def{atan}{685}{34.41114} -\pgfmath@def{atan}{686}{34.45012} \pgfmath@def{atan}{687}{34.48906} -\pgfmath@def{atan}{688}{34.52797} \pgfmath@def{atan}{689}{34.56684} -\pgfmath@def{atan}{690}{34.60567} \pgfmath@def{atan}{691}{34.64447} -\pgfmath@def{atan}{692}{34.68323} \pgfmath@def{atan}{693}{34.72195} -\pgfmath@def{atan}{694}{34.76064} \pgfmath@def{atan}{695}{34.79930} -\pgfmath@def{atan}{696}{34.83791} \pgfmath@def{atan}{697}{34.87649} -\pgfmath@def{atan}{698}{34.91504} \pgfmath@def{atan}{699}{34.95354} -\pgfmath@def{atan}{700}{34.99202} \pgfmath@def{atan}{701}{35.03045} -\pgfmath@def{atan}{702}{35.06885} \pgfmath@def{atan}{703}{35.10721} -\pgfmath@def{atan}{704}{35.14554} \pgfmath@def{atan}{705}{35.18383} -\pgfmath@def{atan}{706}{35.22209} \pgfmath@def{atan}{707}{35.26031} -\pgfmath@def{atan}{708}{35.29849} \pgfmath@def{atan}{709}{35.33664} -\pgfmath@def{atan}{710}{35.37475} \pgfmath@def{atan}{711}{35.41282} -\pgfmath@def{atan}{712}{35.45086} \pgfmath@def{atan}{713}{35.48886} -\pgfmath@def{atan}{714}{35.52683} \pgfmath@def{atan}{715}{35.56476} -\pgfmath@def{atan}{716}{35.60266} \pgfmath@def{atan}{717}{35.64052} -\pgfmath@def{atan}{718}{35.67834} \pgfmath@def{atan}{719}{35.71613} -\pgfmath@def{atan}{720}{35.75388} \pgfmath@def{atan}{721}{35.79160} -\pgfmath@def{atan}{722}{35.82928} \pgfmath@def{atan}{723}{35.86692} -\pgfmath@def{atan}{724}{35.90453} \pgfmath@def{atan}{725}{35.94211} -\pgfmath@def{atan}{726}{35.97965} \pgfmath@def{atan}{727}{36.01715} -\pgfmath@def{atan}{728}{36.05461} \pgfmath@def{atan}{729}{36.09204} -\pgfmath@def{atan}{730}{36.12944} \pgfmath@def{atan}{731}{36.16680} -\pgfmath@def{atan}{732}{36.20412} \pgfmath@def{atan}{733}{36.24141} -\pgfmath@def{atan}{734}{36.27866} \pgfmath@def{atan}{735}{36.31588} -\pgfmath@def{atan}{736}{36.35306} \pgfmath@def{atan}{737}{36.39021} -\pgfmath@def{atan}{738}{36.42732} \pgfmath@def{atan}{739}{36.46440} -\pgfmath@def{atan}{740}{36.50144} \pgfmath@def{atan}{741}{36.53844} -\pgfmath@def{atan}{742}{36.57541} \pgfmath@def{atan}{743}{36.61234} -\pgfmath@def{atan}{744}{36.64924} \pgfmath@def{atan}{745}{36.68611} -\pgfmath@def{atan}{746}{36.72293} \pgfmath@def{atan}{747}{36.75973} -\pgfmath@def{atan}{748}{36.79648} \pgfmath@def{atan}{749}{36.83321} -\pgfmath@def{atan}{750}{36.86989} \pgfmath@def{atan}{751}{36.90654} -\pgfmath@def{atan}{752}{36.94316} \pgfmath@def{atan}{753}{36.97974} -\pgfmath@def{atan}{754}{37.01629} \pgfmath@def{atan}{755}{37.05280} -\pgfmath@def{atan}{756}{37.08928} \pgfmath@def{atan}{757}{37.12572} -\pgfmath@def{atan}{758}{37.16212} \pgfmath@def{atan}{759}{37.19849} -\pgfmath@def{atan}{760}{37.23483} \pgfmath@def{atan}{761}{37.27113} -\pgfmath@def{atan}{762}{37.30740} \pgfmath@def{atan}{763}{37.34363} -\pgfmath@def{atan}{764}{37.37982} \pgfmath@def{atan}{765}{37.41598} -\pgfmath@def{atan}{766}{37.45211} \pgfmath@def{atan}{767}{37.48820} -\pgfmath@def{atan}{768}{37.52426} \pgfmath@def{atan}{769}{37.56028} -\pgfmath@def{atan}{770}{37.59627} \pgfmath@def{atan}{771}{37.63222} -\pgfmath@def{atan}{772}{37.66814} \pgfmath@def{atan}{773}{37.70402} -\pgfmath@def{atan}{774}{37.73987} \pgfmath@def{atan}{775}{37.77568} -\pgfmath@def{atan}{776}{37.81146} \pgfmath@def{atan}{777}{37.84720} -\pgfmath@def{atan}{778}{37.88291} \pgfmath@def{atan}{779}{37.91859} -\pgfmath@def{atan}{780}{37.95423} \pgfmath@def{atan}{781}{37.98983} -\pgfmath@def{atan}{782}{38.02540} \pgfmath@def{atan}{783}{38.06094} -\pgfmath@def{atan}{784}{38.09644} \pgfmath@def{atan}{785}{38.13191} -\pgfmath@def{atan}{786}{38.16734} \pgfmath@def{atan}{787}{38.20274} -\pgfmath@def{atan}{788}{38.23811} \pgfmath@def{atan}{789}{38.27344} -\pgfmath@def{atan}{790}{38.30873} \pgfmath@def{atan}{791}{38.34399} -\pgfmath@def{atan}{792}{38.37922} \pgfmath@def{atan}{793}{38.41441} -\pgfmath@def{atan}{794}{38.44957} \pgfmath@def{atan}{795}{38.48469} -\pgfmath@def{atan}{796}{38.51979} \pgfmath@def{atan}{797}{38.55484} -\pgfmath@def{atan}{798}{38.58986} \pgfmath@def{atan}{799}{38.62485} -\pgfmath@def{atan}{800}{38.65980} \pgfmath@def{atan}{801}{38.69472} -\pgfmath@def{atan}{802}{38.72961} \pgfmath@def{atan}{803}{38.76446} -\pgfmath@def{atan}{804}{38.79928} \pgfmath@def{atan}{805}{38.83406} -\pgfmath@def{atan}{806}{38.86881} \pgfmath@def{atan}{807}{38.90353} -\pgfmath@def{atan}{808}{38.93821} \pgfmath@def{atan}{809}{38.97285} -\pgfmath@def{atan}{810}{39.00747} \pgfmath@def{atan}{811}{39.04205} -\pgfmath@def{atan}{812}{39.07659} \pgfmath@def{atan}{813}{39.11111} -\pgfmath@def{atan}{814}{39.14558} \pgfmath@def{atan}{815}{39.18003} -\pgfmath@def{atan}{816}{39.21444} \pgfmath@def{atan}{817}{39.24882} -\pgfmath@def{atan}{818}{39.28316} \pgfmath@def{atan}{819}{39.31747} -\pgfmath@def{atan}{820}{39.35175} \pgfmath@def{atan}{821}{39.38599} -\pgfmath@def{atan}{822}{39.42020} \pgfmath@def{atan}{823}{39.45438} -\pgfmath@def{atan}{824}{39.48852} \pgfmath@def{atan}{825}{39.52263} -\pgfmath@def{atan}{826}{39.55670} \pgfmath@def{atan}{827}{39.59074} -\pgfmath@def{atan}{828}{39.62475} \pgfmath@def{atan}{829}{39.65873} -\pgfmath@def{atan}{830}{39.69267} \pgfmath@def{atan}{831}{39.72658} -\pgfmath@def{atan}{832}{39.76045} \pgfmath@def{atan}{833}{39.79429} -\pgfmath@def{atan}{834}{39.82810} \pgfmath@def{atan}{835}{39.86188} -\pgfmath@def{atan}{836}{39.89562} \pgfmath@def{atan}{837}{39.92933} -\pgfmath@def{atan}{838}{39.96300} \pgfmath@def{atan}{839}{39.99665} -\pgfmath@def{atan}{840}{40.03025} \pgfmath@def{atan}{841}{40.06383} -\pgfmath@def{atan}{842}{40.09737} \pgfmath@def{atan}{843}{40.13088} -\pgfmath@def{atan}{844}{40.16436} \pgfmath@def{atan}{845}{40.19781} -\pgfmath@def{atan}{846}{40.23122} \pgfmath@def{atan}{847}{40.26459} -\pgfmath@def{atan}{848}{40.29794} \pgfmath@def{atan}{849}{40.33125} -\pgfmath@def{atan}{850}{40.36453} \pgfmath@def{atan}{851}{40.39778} -\pgfmath@def{atan}{852}{40.43099} \pgfmath@def{atan}{853}{40.46417} -\pgfmath@def{atan}{854}{40.49732} \pgfmath@def{atan}{855}{40.53044} -\pgfmath@def{atan}{856}{40.56352} \pgfmath@def{atan}{857}{40.59657} -\pgfmath@def{atan}{858}{40.62959} \pgfmath@def{atan}{859}{40.66257} -\pgfmath@def{atan}{860}{40.69553} \pgfmath@def{atan}{861}{40.72845} -\pgfmath@def{atan}{862}{40.76133} \pgfmath@def{atan}{863}{40.79419} -\pgfmath@def{atan}{864}{40.82701} \pgfmath@def{atan}{865}{40.85980} -\pgfmath@def{atan}{866}{40.89256} \pgfmath@def{atan}{867}{40.92528} -\pgfmath@def{atan}{868}{40.95798} \pgfmath@def{atan}{869}{40.99064} -\pgfmath@def{atan}{870}{41.02326} \pgfmath@def{atan}{871}{41.05586} -\pgfmath@def{atan}{872}{41.08842} \pgfmath@def{atan}{873}{41.12095} -\pgfmath@def{atan}{874}{41.15345} \pgfmath@def{atan}{875}{41.18592} -\pgfmath@def{atan}{876}{41.21836} \pgfmath@def{atan}{877}{41.25076} -\pgfmath@def{atan}{878}{41.28313} \pgfmath@def{atan}{879}{41.31547} -\pgfmath@def{atan}{880}{41.34777} \pgfmath@def{atan}{881}{41.38005} -\pgfmath@def{atan}{882}{41.41229} \pgfmath@def{atan}{883}{41.44450} -\pgfmath@def{atan}{884}{41.47668} \pgfmath@def{atan}{885}{41.50882} -\pgfmath@def{atan}{886}{41.54094} \pgfmath@def{atan}{887}{41.57302} -\pgfmath@def{atan}{888}{41.60507} \pgfmath@def{atan}{889}{41.63709} -\pgfmath@def{atan}{890}{41.66908} \pgfmath@def{atan}{891}{41.70103} -\pgfmath@def{atan}{892}{41.73296} \pgfmath@def{atan}{893}{41.76485} -\pgfmath@def{atan}{894}{41.79671} \pgfmath@def{atan}{895}{41.82854} -\pgfmath@def{atan}{896}{41.86034} \pgfmath@def{atan}{897}{41.89210} -\pgfmath@def{atan}{898}{41.92383} \pgfmath@def{atan}{899}{41.95554} -\pgfmath@def{atan}{900}{41.98721} \pgfmath@def{atan}{901}{42.01885} -\pgfmath@def{atan}{902}{42.05046} \pgfmath@def{atan}{903}{42.08203} -\pgfmath@def{atan}{904}{42.11358} \pgfmath@def{atan}{905}{42.14509} -\pgfmath@def{atan}{906}{42.17657} \pgfmath@def{atan}{907}{42.20802} -\pgfmath@def{atan}{908}{42.23944} \pgfmath@def{atan}{909}{42.27083} -\pgfmath@def{atan}{910}{42.30219} \pgfmath@def{atan}{911}{42.33352} -\pgfmath@def{atan}{912}{42.36481} \pgfmath@def{atan}{913}{42.39607} -\pgfmath@def{atan}{914}{42.42731} \pgfmath@def{atan}{915}{42.45851} -\pgfmath@def{atan}{916}{42.48968} \pgfmath@def{atan}{917}{42.52082} -\pgfmath@def{atan}{918}{42.55193} \pgfmath@def{atan}{919}{42.58300} -\pgfmath@def{atan}{920}{42.61405} \pgfmath@def{atan}{921}{42.64507} -\pgfmath@def{atan}{922}{42.67605} \pgfmath@def{atan}{923}{42.70701} -\pgfmath@def{atan}{924}{42.73793} \pgfmath@def{atan}{925}{42.76882} -\pgfmath@def{atan}{926}{42.79968} \pgfmath@def{atan}{927}{42.83051} -\pgfmath@def{atan}{928}{42.86131} \pgfmath@def{atan}{929}{42.89208} -\pgfmath@def{atan}{930}{42.92282} \pgfmath@def{atan}{931}{42.95353} -\pgfmath@def{atan}{932}{42.98421} \pgfmath@def{atan}{933}{43.01485} -\pgfmath@def{atan}{934}{43.04547} \pgfmath@def{atan}{935}{43.07605} -\pgfmath@def{atan}{936}{43.10661} \pgfmath@def{atan}{937}{43.13713} -\pgfmath@def{atan}{938}{43.16763} \pgfmath@def{atan}{939}{43.19809} -\pgfmath@def{atan}{940}{43.22853} \pgfmath@def{atan}{941}{43.25893} -\pgfmath@def{atan}{942}{43.28930} \pgfmath@def{atan}{943}{43.31964} -\pgfmath@def{atan}{944}{43.34996} \pgfmath@def{atan}{945}{43.38024} -\pgfmath@def{atan}{946}{43.41049} \pgfmath@def{atan}{947}{43.44071} -\pgfmath@def{atan}{948}{43.47090} \pgfmath@def{atan}{949}{43.50106} -\pgfmath@def{atan}{950}{43.53119} \pgfmath@def{atan}{951}{43.56130} -\pgfmath@def{atan}{952}{43.59137} \pgfmath@def{atan}{953}{43.62141} -\pgfmath@def{atan}{954}{43.65142} \pgfmath@def{atan}{955}{43.68140} -\pgfmath@def{atan}{956}{43.71135} \pgfmath@def{atan}{957}{43.74127} -\pgfmath@def{atan}{958}{43.77116} \pgfmath@def{atan}{959}{43.80102} -\pgfmath@def{atan}{960}{43.83086} \pgfmath@def{atan}{961}{43.86066} -\pgfmath@def{atan}{962}{43.89043} \pgfmath@def{atan}{963}{43.92017} -\pgfmath@def{atan}{964}{43.94988} \pgfmath@def{atan}{965}{43.97957} -\pgfmath@def{atan}{966}{44.00922} \pgfmath@def{atan}{967}{44.03884} -\pgfmath@def{atan}{968}{44.06844} \pgfmath@def{atan}{969}{44.09800} -\pgfmath@def{atan}{970}{44.12754} \pgfmath@def{atan}{971}{44.15704} -\pgfmath@def{atan}{972}{44.18652} \pgfmath@def{atan}{973}{44.21597} -\pgfmath@def{atan}{974}{44.24538} \pgfmath@def{atan}{975}{44.27477} -\pgfmath@def{atan}{976}{44.30413} \pgfmath@def{atan}{977}{44.33346} -\pgfmath@def{atan}{978}{44.36276} \pgfmath@def{atan}{979}{44.39203} -\pgfmath@def{atan}{980}{44.42127} \pgfmath@def{atan}{981}{44.45048} -\pgfmath@def{atan}{982}{44.47966} \pgfmath@def{atan}{983}{44.50882} -\pgfmath@def{atan}{984}{44.53794} \pgfmath@def{atan}{985}{44.56704} -\pgfmath@def{atan}{986}{44.59610} \pgfmath@def{atan}{987}{44.62514} -\pgfmath@def{atan}{988}{44.65415} \pgfmath@def{atan}{989}{44.68313} -\pgfmath@def{atan}{990}{44.71208} \pgfmath@def{atan}{991}{44.74100} -\pgfmath@def{atan}{992}{44.76989} \pgfmath@def{atan}{993}{44.79876} -\pgfmath@def{atan}{994}{44.82759} \pgfmath@def{atan}{995}{44.85640} -\pgfmath@def{atan}{996}{44.88517} \pgfmath@def{atan}{997}{44.91392} -\pgfmath@def{atan}{998}{44.94264} \pgfmath@def{atan}{999}{44.97133} -\pgfmath@def{atan}{1000}{45.00000} - -\pgfmath@def{acos}{0}{90.00000} \pgfmath@def{acos}{1}{89.94270} -\pgfmath@def{acos}{2}{89.88540} \pgfmath@def{acos}{3}{89.82811} -\pgfmath@def{acos}{4}{89.77081} \pgfmath@def{acos}{5}{89.71352} -\pgfmath@def{acos}{6}{89.65622} \pgfmath@def{acos}{7}{89.59892} -\pgfmath@def{acos}{8}{89.54162} \pgfmath@def{acos}{9}{89.48433} -\pgfmath@def{acos}{10}{89.42703} \pgfmath@def{acos}{11}{89.36973} -\pgfmath@def{acos}{12}{89.31243} \pgfmath@def{acos}{13}{89.25513} -\pgfmath@def{acos}{14}{89.19783} \pgfmath@def{acos}{15}{89.14053} -\pgfmath@def{acos}{16}{89.08322} \pgfmath@def{acos}{17}{89.02592} -\pgfmath@def{acos}{18}{88.96862} \pgfmath@def{acos}{19}{88.91131} -\pgfmath@def{acos}{20}{88.85400} \pgfmath@def{acos}{21}{88.79670} -\pgfmath@def{acos}{22}{88.73939} \pgfmath@def{acos}{23}{88.68208} -\pgfmath@def{acos}{24}{88.62476} \pgfmath@def{acos}{25}{88.56745} -\pgfmath@def{acos}{26}{88.51014} \pgfmath@def{acos}{27}{88.45282} -\pgfmath@def{acos}{28}{88.39550} \pgfmath@def{acos}{29}{88.33818} -\pgfmath@def{acos}{30}{88.28086} \pgfmath@def{acos}{31}{88.22354} -\pgfmath@def{acos}{32}{88.16622} \pgfmath@def{acos}{33}{88.10889} -\pgfmath@def{acos}{34}{88.05156} \pgfmath@def{acos}{35}{87.99423} -\pgfmath@def{acos}{36}{87.93690} \pgfmath@def{acos}{37}{87.87957} -\pgfmath@def{acos}{38}{87.82223} \pgfmath@def{acos}{39}{87.76489} -\pgfmath@def{acos}{40}{87.70755} \pgfmath@def{acos}{41}{87.65021} -\pgfmath@def{acos}{42}{87.59286} \pgfmath@def{acos}{43}{87.53552} -\pgfmath@def{acos}{44}{87.47817} \pgfmath@def{acos}{45}{87.42081} -\pgfmath@def{acos}{46}{87.36346} \pgfmath@def{acos}{47}{87.30610} -\pgfmath@def{acos}{48}{87.24874} \pgfmath@def{acos}{49}{87.19138} -\pgfmath@def{acos}{50}{87.13401} \pgfmath@def{acos}{51}{87.07664} -\pgfmath@def{acos}{52}{87.01927} \pgfmath@def{acos}{53}{86.96190} -\pgfmath@def{acos}{54}{86.90452} \pgfmath@def{acos}{55}{86.84714} -\pgfmath@def{acos}{56}{86.78975} \pgfmath@def{acos}{57}{86.73237} -\pgfmath@def{acos}{58}{86.67497} \pgfmath@def{acos}{59}{86.61758} -\pgfmath@def{acos}{60}{86.56018} \pgfmath@def{acos}{61}{86.50278} -\pgfmath@def{acos}{62}{86.44538} \pgfmath@def{acos}{63}{86.38797} -\pgfmath@def{acos}{64}{86.33056} \pgfmath@def{acos}{65}{86.27314} -\pgfmath@def{acos}{66}{86.21572} \pgfmath@def{acos}{67}{86.15830} -\pgfmath@def{acos}{68}{86.10087} \pgfmath@def{acos}{69}{86.04344} -\pgfmath@def{acos}{70}{85.98601} \pgfmath@def{acos}{71}{85.92857} -\pgfmath@def{acos}{72}{85.87113} \pgfmath@def{acos}{73}{85.81368} -\pgfmath@def{acos}{74}{85.75623} \pgfmath@def{acos}{75}{85.69877} -\pgfmath@def{acos}{76}{85.64131} \pgfmath@def{acos}{77}{85.58385} -\pgfmath@def{acos}{78}{85.52638} \pgfmath@def{acos}{79}{85.46891} -\pgfmath@def{acos}{80}{85.41143} \pgfmath@def{acos}{81}{85.35395} -\pgfmath@def{acos}{82}{85.29646} \pgfmath@def{acos}{83}{85.23897} -\pgfmath@def{acos}{84}{85.18147} \pgfmath@def{acos}{85}{85.12397} -\pgfmath@def{acos}{86}{85.06646} \pgfmath@def{acos}{87}{85.00895} -\pgfmath@def{acos}{88}{84.95144} \pgfmath@def{acos}{89}{84.89392} -\pgfmath@def{acos}{90}{84.83639} \pgfmath@def{acos}{91}{84.77886} -\pgfmath@def{acos}{92}{84.72132} \pgfmath@def{acos}{93}{84.66378} -\pgfmath@def{acos}{94}{84.60623} \pgfmath@def{acos}{95}{84.54868} -\pgfmath@def{acos}{96}{84.49112} \pgfmath@def{acos}{97}{84.43355} -\pgfmath@def{acos}{98}{84.37598} \pgfmath@def{acos}{99}{84.31841} -\pgfmath@def{acos}{100}{84.26083} \pgfmath@def{acos}{101}{84.20324} -\pgfmath@def{acos}{102}{84.14564} \pgfmath@def{acos}{103}{84.08805} -\pgfmath@def{acos}{104}{84.03044} \pgfmath@def{acos}{105}{83.97283} -\pgfmath@def{acos}{106}{83.91521} \pgfmath@def{acos}{107}{83.85759} -\pgfmath@def{acos}{108}{83.79996} \pgfmath@def{acos}{109}{83.74232} -\pgfmath@def{acos}{110}{83.68468} \pgfmath@def{acos}{111}{83.62703} -\pgfmath@def{acos}{112}{83.56938} \pgfmath@def{acos}{113}{83.51171} -\pgfmath@def{acos}{114}{83.45405} \pgfmath@def{acos}{115}{83.39637} -\pgfmath@def{acos}{116}{83.33869} \pgfmath@def{acos}{117}{83.28100} -\pgfmath@def{acos}{118}{83.22330} \pgfmath@def{acos}{119}{83.16560} -\pgfmath@def{acos}{120}{83.10789} \pgfmath@def{acos}{121}{83.05018} -\pgfmath@def{acos}{122}{82.99245} \pgfmath@def{acos}{123}{82.93472} -\pgfmath@def{acos}{124}{82.87698} \pgfmath@def{acos}{125}{82.81924} -\pgfmath@def{acos}{126}{82.76149} \pgfmath@def{acos}{127}{82.70373} -\pgfmath@def{acos}{128}{82.64596} \pgfmath@def{acos}{129}{82.58819} -\pgfmath@def{acos}{130}{82.53040} \pgfmath@def{acos}{131}{82.47261} -\pgfmath@def{acos}{132}{82.41482} \pgfmath@def{acos}{133}{82.35701} -\pgfmath@def{acos}{134}{82.29920} \pgfmath@def{acos}{135}{82.24138} -\pgfmath@def{acos}{136}{82.18355} \pgfmath@def{acos}{137}{82.12571} -\pgfmath@def{acos}{138}{82.06786} \pgfmath@def{acos}{139}{82.01001} -\pgfmath@def{acos}{140}{81.95215} \pgfmath@def{acos}{141}{81.89428} -\pgfmath@def{acos}{142}{81.83640} \pgfmath@def{acos}{143}{81.77851} -\pgfmath@def{acos}{144}{81.72062} \pgfmath@def{acos}{145}{81.66272} -\pgfmath@def{acos}{146}{81.60480} \pgfmath@def{acos}{147}{81.54688} -\pgfmath@def{acos}{148}{81.48895} \pgfmath@def{acos}{149}{81.43102} -\pgfmath@def{acos}{150}{81.37307} \pgfmath@def{acos}{151}{81.31511} -\pgfmath@def{acos}{152}{81.25715} \pgfmath@def{acos}{153}{81.19917} -\pgfmath@def{acos}{154}{81.14119} \pgfmath@def{acos}{155}{81.08320} -\pgfmath@def{acos}{156}{81.02520} \pgfmath@def{acos}{157}{80.96719} -\pgfmath@def{acos}{158}{80.90917} \pgfmath@def{acos}{159}{80.85114} -\pgfmath@def{acos}{160}{80.79310} \pgfmath@def{acos}{161}{80.73505} -\pgfmath@def{acos}{162}{80.67699} \pgfmath@def{acos}{163}{80.61893} -\pgfmath@def{acos}{164}{80.56085} \pgfmath@def{acos}{165}{80.50276} -\pgfmath@def{acos}{166}{80.44466} \pgfmath@def{acos}{167}{80.38656} -\pgfmath@def{acos}{168}{80.32844} \pgfmath@def{acos}{169}{80.27031} -\pgfmath@def{acos}{170}{80.21218} \pgfmath@def{acos}{171}{80.15403} -\pgfmath@def{acos}{172}{80.09587} \pgfmath@def{acos}{173}{80.03770} -\pgfmath@def{acos}{174}{79.97953} \pgfmath@def{acos}{175}{79.92134} -\pgfmath@def{acos}{176}{79.86314} \pgfmath@def{acos}{177}{79.80493} -\pgfmath@def{acos}{178}{79.74671} \pgfmath@def{acos}{179}{79.68848} -\pgfmath@def{acos}{180}{79.63024} \pgfmath@def{acos}{181}{79.57198} -\pgfmath@def{acos}{182}{79.51372} \pgfmath@def{acos}{183}{79.45545} -\pgfmath@def{acos}{184}{79.39716} \pgfmath@def{acos}{185}{79.33886} -\pgfmath@def{acos}{186}{79.28056} \pgfmath@def{acos}{187}{79.22224} -\pgfmath@def{acos}{188}{79.16391} \pgfmath@def{acos}{189}{79.10556} -\pgfmath@def{acos}{190}{79.04721} \pgfmath@def{acos}{191}{78.98885} -\pgfmath@def{acos}{192}{78.93047} \pgfmath@def{acos}{193}{78.87208} -\pgfmath@def{acos}{194}{78.81368} \pgfmath@def{acos}{195}{78.75527} -\pgfmath@def{acos}{196}{78.69685} \pgfmath@def{acos}{197}{78.63841} -\pgfmath@def{acos}{198}{78.57997} \pgfmath@def{acos}{199}{78.52151} -\pgfmath@def{acos}{200}{78.46304} \pgfmath@def{acos}{201}{78.40455} -\pgfmath@def{acos}{202}{78.34606} \pgfmath@def{acos}{203}{78.28755} -\pgfmath@def{acos}{204}{78.22903} \pgfmath@def{acos}{205}{78.17050} -\pgfmath@def{acos}{206}{78.11195} \pgfmath@def{acos}{207}{78.05339} -\pgfmath@def{acos}{208}{77.99482} \pgfmath@def{acos}{209}{77.93624} -\pgfmath@def{acos}{210}{77.87764} \pgfmath@def{acos}{211}{77.81903} -\pgfmath@def{acos}{212}{77.76041} \pgfmath@def{acos}{213}{77.70178} -\pgfmath@def{acos}{214}{77.64313} \pgfmath@def{acos}{215}{77.58447} -\pgfmath@def{acos}{216}{77.52579} \pgfmath@def{acos}{217}{77.46711} -\pgfmath@def{acos}{218}{77.40841} \pgfmath@def{acos}{219}{77.34969} -\pgfmath@def{acos}{220}{77.29096} \pgfmath@def{acos}{221}{77.23222} -\pgfmath@def{acos}{222}{77.17347} \pgfmath@def{acos}{223}{77.11470} -\pgfmath@def{acos}{224}{77.05591} \pgfmath@def{acos}{225}{76.99712} -\pgfmath@def{acos}{226}{76.93831} \pgfmath@def{acos}{227}{76.87948} -\pgfmath@def{acos}{228}{76.82064} \pgfmath@def{acos}{229}{76.76179} -\pgfmath@def{acos}{230}{76.70292} \pgfmath@def{acos}{231}{76.64404} -\pgfmath@def{acos}{232}{76.58515} \pgfmath@def{acos}{233}{76.52624} -\pgfmath@def{acos}{234}{76.46731} \pgfmath@def{acos}{235}{76.40837} -\pgfmath@def{acos}{236}{76.34942} \pgfmath@def{acos}{237}{76.29045} -\pgfmath@def{acos}{238}{76.23147} \pgfmath@def{acos}{239}{76.17247} -\pgfmath@def{acos}{240}{76.11346} \pgfmath@def{acos}{241}{76.05443} -\pgfmath@def{acos}{242}{75.99538} \pgfmath@def{acos}{243}{75.93632} -\pgfmath@def{acos}{244}{75.87725} \pgfmath@def{acos}{245}{75.81816} -\pgfmath@def{acos}{246}{75.75906} \pgfmath@def{acos}{247}{75.69994} -\pgfmath@def{acos}{248}{75.64080} \pgfmath@def{acos}{249}{75.58165} -\pgfmath@def{acos}{250}{75.52248} \pgfmath@def{acos}{251}{75.46330} -\pgfmath@def{acos}{252}{75.40410} \pgfmath@def{acos}{253}{75.34489} -\pgfmath@def{acos}{254}{75.28566} \pgfmath@def{acos}{255}{75.22641} -\pgfmath@def{acos}{256}{75.16715} \pgfmath@def{acos}{257}{75.10787} -\pgfmath@def{acos}{258}{75.04857} \pgfmath@def{acos}{259}{74.98926} -\pgfmath@def{acos}{260}{74.92993} \pgfmath@def{acos}{261}{74.87059} -\pgfmath@def{acos}{262}{74.81123} \pgfmath@def{acos}{263}{74.75185} -\pgfmath@def{acos}{264}{74.69245} \pgfmath@def{acos}{265}{74.63304} -\pgfmath@def{acos}{266}{74.57361} \pgfmath@def{acos}{267}{74.51417} -\pgfmath@def{acos}{268}{74.45471} \pgfmath@def{acos}{269}{74.39523} -\pgfmath@def{acos}{270}{74.33573} \pgfmath@def{acos}{271}{74.27621} -\pgfmath@def{acos}{272}{74.21668} \pgfmath@def{acos}{273}{74.15713} -\pgfmath@def{acos}{274}{74.09757} \pgfmath@def{acos}{275}{74.03798} -\pgfmath@def{acos}{276}{73.97838} \pgfmath@def{acos}{277}{73.91876} -\pgfmath@def{acos}{278}{73.85912} \pgfmath@def{acos}{279}{73.79946} -\pgfmath@def{acos}{280}{73.73979} \pgfmath@def{acos}{281}{73.68010} -\pgfmath@def{acos}{282}{73.62039} \pgfmath@def{acos}{283}{73.56066} -\pgfmath@def{acos}{284}{73.50091} \pgfmath@def{acos}{285}{73.44115} -\pgfmath@def{acos}{286}{73.38136} \pgfmath@def{acos}{287}{73.32156} -\pgfmath@def{acos}{288}{73.26174} \pgfmath@def{acos}{289}{73.20190} -\pgfmath@def{acos}{290}{73.14204} \pgfmath@def{acos}{291}{73.08216} -\pgfmath@def{acos}{292}{73.02226} \pgfmath@def{acos}{293}{72.96235} -\pgfmath@def{acos}{294}{72.90241} \pgfmath@def{acos}{295}{72.84246} -\pgfmath@def{acos}{296}{72.78248} \pgfmath@def{acos}{297}{72.72249} -\pgfmath@def{acos}{298}{72.66248} \pgfmath@def{acos}{299}{72.60244} -\pgfmath@def{acos}{300}{72.54239} \pgfmath@def{acos}{301}{72.48232} -\pgfmath@def{acos}{302}{72.42223} \pgfmath@def{acos}{303}{72.36212} -\pgfmath@def{acos}{304}{72.30198} \pgfmath@def{acos}{305}{72.24183} -\pgfmath@def{acos}{306}{72.18166} \pgfmath@def{acos}{307}{72.12147} -\pgfmath@def{acos}{308}{72.06125} \pgfmath@def{acos}{309}{72.00102} -\pgfmath@def{acos}{310}{71.94077} \pgfmath@def{acos}{311}{71.88049} -\pgfmath@def{acos}{312}{71.82019} \pgfmath@def{acos}{313}{71.75988} -\pgfmath@def{acos}{314}{71.69954} \pgfmath@def{acos}{315}{71.63918} -\pgfmath@def{acos}{316}{71.57880} \pgfmath@def{acos}{317}{71.51840} -\pgfmath@def{acos}{318}{71.45798} \pgfmath@def{acos}{319}{71.39754} -\pgfmath@def{acos}{320}{71.33707} \pgfmath@def{acos}{321}{71.27658} -\pgfmath@def{acos}{322}{71.21608} \pgfmath@def{acos}{323}{71.15555} -\pgfmath@def{acos}{324}{71.09499} \pgfmath@def{acos}{325}{71.03442} -\pgfmath@def{acos}{326}{70.97382} \pgfmath@def{acos}{327}{70.91321} -\pgfmath@def{acos}{328}{70.85257} \pgfmath@def{acos}{329}{70.79190} -\pgfmath@def{acos}{330}{70.73122} \pgfmath@def{acos}{331}{70.67051} -\pgfmath@def{acos}{332}{70.60978} \pgfmath@def{acos}{333}{70.54903} -\pgfmath@def{acos}{334}{70.48826} \pgfmath@def{acos}{335}{70.42746} -\pgfmath@def{acos}{336}{70.36664} \pgfmath@def{acos}{337}{70.30579} -\pgfmath@def{acos}{338}{70.24493} \pgfmath@def{acos}{339}{70.18404} -\pgfmath@def{acos}{340}{70.12312} \pgfmath@def{acos}{341}{70.06218} -\pgfmath@def{acos}{342}{70.00122} \pgfmath@def{acos}{343}{69.94024} -\pgfmath@def{acos}{344}{69.87923} \pgfmath@def{acos}{345}{69.81820} -\pgfmath@def{acos}{346}{69.75714} \pgfmath@def{acos}{347}{69.69606} -\pgfmath@def{acos}{348}{69.63496} \pgfmath@def{acos}{349}{69.57383} -\pgfmath@def{acos}{350}{69.51268} \pgfmath@def{acos}{351}{69.45150} -\pgfmath@def{acos}{352}{69.39030} \pgfmath@def{acos}{353}{69.32908} -\pgfmath@def{acos}{354}{69.26783} \pgfmath@def{acos}{355}{69.20655} -\pgfmath@def{acos}{356}{69.14525} \pgfmath@def{acos}{357}{69.08393} -\pgfmath@def{acos}{358}{69.02258} \pgfmath@def{acos}{359}{68.96120} -\pgfmath@def{acos}{360}{68.89980} \pgfmath@def{acos}{361}{68.83837} -\pgfmath@def{acos}{362}{68.77692} \pgfmath@def{acos}{363}{68.71544} -\pgfmath@def{acos}{364}{68.65394} \pgfmath@def{acos}{365}{68.59241} -\pgfmath@def{acos}{366}{68.53086} \pgfmath@def{acos}{367}{68.46928} -\pgfmath@def{acos}{368}{68.40767} \pgfmath@def{acos}{369}{68.34604} -\pgfmath@def{acos}{370}{68.28438} \pgfmath@def{acos}{371}{68.22269} -\pgfmath@def{acos}{372}{68.16098} \pgfmath@def{acos}{373}{68.09924} -\pgfmath@def{acos}{374}{68.03748} \pgfmath@def{acos}{375}{67.97568} -\pgfmath@def{acos}{376}{67.91386} \pgfmath@def{acos}{377}{67.85202} -\pgfmath@def{acos}{378}{67.79014} \pgfmath@def{acos}{379}{67.72824} -\pgfmath@def{acos}{380}{67.66631} \pgfmath@def{acos}{381}{67.60436} -\pgfmath@def{acos}{382}{67.54237} \pgfmath@def{acos}{383}{67.48036} -\pgfmath@def{acos}{384}{67.41832} \pgfmath@def{acos}{385}{67.35626} -\pgfmath@def{acos}{386}{67.29416} \pgfmath@def{acos}{387}{67.23204} -\pgfmath@def{acos}{388}{67.16988} \pgfmath@def{acos}{389}{67.10770} -\pgfmath@def{acos}{390}{67.04550} \pgfmath@def{acos}{391}{66.98326} -\pgfmath@def{acos}{392}{66.92099} \pgfmath@def{acos}{393}{66.85870} -\pgfmath@def{acos}{394}{66.79637} \pgfmath@def{acos}{395}{66.73402} -\pgfmath@def{acos}{396}{66.67164} \pgfmath@def{acos}{397}{66.60923} -\pgfmath@def{acos}{398}{66.54679} \pgfmath@def{acos}{399}{66.48432} -\pgfmath@def{acos}{400}{66.42182} \pgfmath@def{acos}{401}{66.35929} -\pgfmath@def{acos}{402}{66.29673} \pgfmath@def{acos}{403}{66.23414} -\pgfmath@def{acos}{404}{66.17152} \pgfmath@def{acos}{405}{66.10887} -\pgfmath@def{acos}{406}{66.04619} \pgfmath@def{acos}{407}{65.98348} -\pgfmath@def{acos}{408}{65.92074} \pgfmath@def{acos}{409}{65.85796} -\pgfmath@def{acos}{410}{65.79516} \pgfmath@def{acos}{411}{65.73233} -\pgfmath@def{acos}{412}{65.66946} \pgfmath@def{acos}{413}{65.60657} -\pgfmath@def{acos}{414}{65.54364} \pgfmath@def{acos}{415}{65.48068} -\pgfmath@def{acos}{416}{65.41769} \pgfmath@def{acos}{417}{65.35467} -\pgfmath@def{acos}{418}{65.29161} \pgfmath@def{acos}{419}{65.22853} -\pgfmath@def{acos}{420}{65.16541} \pgfmath@def{acos}{421}{65.10226} -\pgfmath@def{acos}{422}{65.03908} \pgfmath@def{acos}{423}{64.97586} -\pgfmath@def{acos}{424}{64.91261} \pgfmath@def{acos}{425}{64.84933} -\pgfmath@def{acos}{426}{64.78602} \pgfmath@def{acos}{427}{64.72267} -\pgfmath@def{acos}{428}{64.65929} \pgfmath@def{acos}{429}{64.59588} -\pgfmath@def{acos}{430}{64.53244} \pgfmath@def{acos}{431}{64.46896} -\pgfmath@def{acos}{432}{64.40544} \pgfmath@def{acos}{433}{64.34190} -\pgfmath@def{acos}{434}{64.27832} \pgfmath@def{acos}{435}{64.21470} -\pgfmath@def{acos}{436}{64.15105} \pgfmath@def{acos}{437}{64.08737} -\pgfmath@def{acos}{438}{64.02365} \pgfmath@def{acos}{439}{63.95990} -\pgfmath@def{acos}{440}{63.89611} \pgfmath@def{acos}{441}{63.83229} -\pgfmath@def{acos}{442}{63.76844} \pgfmath@def{acos}{443}{63.70455} -\pgfmath@def{acos}{444}{63.64062} \pgfmath@def{acos}{445}{63.57666} -\pgfmath@def{acos}{446}{63.51266} \pgfmath@def{acos}{447}{63.44863} -\pgfmath@def{acos}{448}{63.38456} \pgfmath@def{acos}{449}{63.32045} -\pgfmath@def{acos}{450}{63.25631} \pgfmath@def{acos}{451}{63.19213} -\pgfmath@def{acos}{452}{63.12792} \pgfmath@def{acos}{453}{63.06367} -\pgfmath@def{acos}{454}{62.99938} \pgfmath@def{acos}{455}{62.93506} -\pgfmath@def{acos}{456}{62.87070} \pgfmath@def{acos}{457}{62.80630} -\pgfmath@def{acos}{458}{62.74187} \pgfmath@def{acos}{459}{62.67740} -\pgfmath@def{acos}{460}{62.61289} \pgfmath@def{acos}{461}{62.54834} -\pgfmath@def{acos}{462}{62.48376} \pgfmath@def{acos}{463}{62.41913} -\pgfmath@def{acos}{464}{62.35447} \pgfmath@def{acos}{465}{62.28977} -\pgfmath@def{acos}{466}{62.22504} \pgfmath@def{acos}{467}{62.16026} -\pgfmath@def{acos}{468}{62.09545} \pgfmath@def{acos}{469}{62.03059} -\pgfmath@def{acos}{470}{61.96570} \pgfmath@def{acos}{471}{61.90077} -\pgfmath@def{acos}{472}{61.83580} \pgfmath@def{acos}{473}{61.77079} -\pgfmath@def{acos}{474}{61.70574} \pgfmath@def{acos}{475}{61.64065} -\pgfmath@def{acos}{476}{61.57552} \pgfmath@def{acos}{477}{61.51035} -\pgfmath@def{acos}{478}{61.44514} \pgfmath@def{acos}{479}{61.37988} -\pgfmath@def{acos}{480}{61.31459} \pgfmath@def{acos}{481}{61.24926} -\pgfmath@def{acos}{482}{61.18389} \pgfmath@def{acos}{483}{61.11847} -\pgfmath@def{acos}{484}{61.05302} \pgfmath@def{acos}{485}{60.98752} -\pgfmath@def{acos}{486}{60.92199} \pgfmath@def{acos}{487}{60.85641} -\pgfmath@def{acos}{488}{60.79078} \pgfmath@def{acos}{489}{60.72512} -\pgfmath@def{acos}{490}{60.65941} \pgfmath@def{acos}{491}{60.59367} -\pgfmath@def{acos}{492}{60.52787} \pgfmath@def{acos}{493}{60.46204} -\pgfmath@def{acos}{494}{60.39616} \pgfmath@def{acos}{495}{60.33025} -\pgfmath@def{acos}{496}{60.26428} \pgfmath@def{acos}{497}{60.19828} -\pgfmath@def{acos}{498}{60.13223} \pgfmath@def{acos}{499}{60.06613} -\pgfmath@def{acos}{500}{60.00000} \pgfmath@def{acos}{501}{59.93381} -\pgfmath@def{acos}{502}{59.86759} \pgfmath@def{acos}{503}{59.80132} -\pgfmath@def{acos}{504}{59.73500} \pgfmath@def{acos}{505}{59.66864} -\pgfmath@def{acos}{506}{59.60224} \pgfmath@def{acos}{507}{59.53579} -\pgfmath@def{acos}{508}{59.46929} \pgfmath@def{acos}{509}{59.40275} -\pgfmath@def{acos}{510}{59.33617} \pgfmath@def{acos}{511}{59.26953} -\pgfmath@def{acos}{512}{59.20285} \pgfmath@def{acos}{513}{59.13613} -\pgfmath@def{acos}{514}{59.06936} \pgfmath@def{acos}{515}{59.00254} -\pgfmath@def{acos}{516}{58.93568} \pgfmath@def{acos}{517}{58.86876} -\pgfmath@def{acos}{518}{58.80180} \pgfmath@def{acos}{519}{58.73480} -\pgfmath@def{acos}{520}{58.66774} \pgfmath@def{acos}{521}{58.60064} -\pgfmath@def{acos}{522}{58.53349} \pgfmath@def{acos}{523}{58.46629} -\pgfmath@def{acos}{524}{58.39905} \pgfmath@def{acos}{525}{58.33175} -\pgfmath@def{acos}{526}{58.26441} \pgfmath@def{acos}{527}{58.19702} -\pgfmath@def{acos}{528}{58.12957} \pgfmath@def{acos}{529}{58.06208} -\pgfmath@def{acos}{530}{57.99454} \pgfmath@def{acos}{531}{57.92695} -\pgfmath@def{acos}{532}{57.85931} \pgfmath@def{acos}{533}{57.79162} -\pgfmath@def{acos}{534}{57.72388} \pgfmath@def{acos}{535}{57.65608} -\pgfmath@def{acos}{536}{57.58824} \pgfmath@def{acos}{537}{57.52035} -\pgfmath@def{acos}{538}{57.45240} \pgfmath@def{acos}{539}{57.38441} -\pgfmath@def{acos}{540}{57.31636} \pgfmath@def{acos}{541}{57.24826} -\pgfmath@def{acos}{542}{57.18010} \pgfmath@def{acos}{543}{57.11190} -\pgfmath@def{acos}{544}{57.04364} \pgfmath@def{acos}{545}{56.97533} -\pgfmath@def{acos}{546}{56.90697} \pgfmath@def{acos}{547}{56.83855} -\pgfmath@def{acos}{548}{56.77008} \pgfmath@def{acos}{549}{56.70156} -\pgfmath@def{acos}{550}{56.63298} \pgfmath@def{acos}{551}{56.56435} -\pgfmath@def{acos}{552}{56.49567} \pgfmath@def{acos}{553}{56.42693} -\pgfmath@def{acos}{554}{56.35813} \pgfmath@def{acos}{555}{56.28928} -\pgfmath@def{acos}{556}{56.22038} \pgfmath@def{acos}{557}{56.15141} -\pgfmath@def{acos}{558}{56.08240} \pgfmath@def{acos}{559}{56.01333} -\pgfmath@def{acos}{560}{55.94420} \pgfmath@def{acos}{561}{55.87501} -\pgfmath@def{acos}{562}{55.80577} \pgfmath@def{acos}{563}{55.73647} -\pgfmath@def{acos}{564}{55.66712} \pgfmath@def{acos}{565}{55.59770} -\pgfmath@def{acos}{566}{55.52823} \pgfmath@def{acos}{567}{55.45871} -\pgfmath@def{acos}{568}{55.38912} \pgfmath@def{acos}{569}{55.31947} -\pgfmath@def{acos}{570}{55.24977} \pgfmath@def{acos}{571}{55.18001} -\pgfmath@def{acos}{572}{55.11019} \pgfmath@def{acos}{573}{55.04030} -\pgfmath@def{acos}{574}{54.97036} \pgfmath@def{acos}{575}{54.90036} -\pgfmath@def{acos}{576}{54.83030} \pgfmath@def{acos}{577}{54.76018} -\pgfmath@def{acos}{578}{54.69000} \pgfmath@def{acos}{579}{54.61976} -\pgfmath@def{acos}{580}{54.54945} \pgfmath@def{acos}{581}{54.47909} -\pgfmath@def{acos}{582}{54.40866} \pgfmath@def{acos}{583}{54.33817} -\pgfmath@def{acos}{584}{54.26762} \pgfmath@def{acos}{585}{54.19701} -\pgfmath@def{acos}{586}{54.12633} \pgfmath@def{acos}{587}{54.05559} -\pgfmath@def{acos}{588}{53.98479} \pgfmath@def{acos}{589}{53.91392} -\pgfmath@def{acos}{590}{53.84299} \pgfmath@def{acos}{591}{53.77199} -\pgfmath@def{acos}{592}{53.70093} \pgfmath@def{acos}{593}{53.62981} -\pgfmath@def{acos}{594}{53.55862} \pgfmath@def{acos}{595}{53.48736} -\pgfmath@def{acos}{596}{53.41604} \pgfmath@def{acos}{597}{53.34466} -\pgfmath@def{acos}{598}{53.27320} \pgfmath@def{acos}{599}{53.20168} -\pgfmath@def{acos}{600}{53.13010} \pgfmath@def{acos}{601}{53.05844} -\pgfmath@def{acos}{602}{52.98672} \pgfmath@def{acos}{603}{52.91494} -\pgfmath@def{acos}{604}{52.84308} \pgfmath@def{acos}{605}{52.77115} -\pgfmath@def{acos}{606}{52.69916} \pgfmath@def{acos}{607}{52.62710} -\pgfmath@def{acos}{608}{52.55497} \pgfmath@def{acos}{609}{52.48276} -\pgfmath@def{acos}{610}{52.41049} \pgfmath@def{acos}{611}{52.33815} -\pgfmath@def{acos}{612}{52.26574} \pgfmath@def{acos}{613}{52.19326} -\pgfmath@def{acos}{614}{52.12070} \pgfmath@def{acos}{615}{52.04808} -\pgfmath@def{acos}{616}{51.97538} \pgfmath@def{acos}{617}{51.90261} -\pgfmath@def{acos}{618}{51.82976} \pgfmath@def{acos}{619}{51.75685} -\pgfmath@def{acos}{620}{51.68386} \pgfmath@def{acos}{621}{51.61080} -\pgfmath@def{acos}{622}{51.53766} \pgfmath@def{acos}{623}{51.46445} -\pgfmath@def{acos}{624}{51.39117} \pgfmath@def{acos}{625}{51.31781} -\pgfmath@def{acos}{626}{51.24437} \pgfmath@def{acos}{627}{51.17086} -\pgfmath@def{acos}{628}{51.09728} \pgfmath@def{acos}{629}{51.02361} -\pgfmath@def{acos}{630}{50.94987} \pgfmath@def{acos}{631}{50.87606} -\pgfmath@def{acos}{632}{50.80216} \pgfmath@def{acos}{633}{50.72819} -\pgfmath@def{acos}{634}{50.65414} \pgfmath@def{acos}{635}{50.58001} -\pgfmath@def{acos}{636}{50.50580} \pgfmath@def{acos}{637}{50.43152} -\pgfmath@def{acos}{638}{50.35715} \pgfmath@def{acos}{639}{50.28270} -\pgfmath@def{acos}{640}{50.20818} \pgfmath@def{acos}{641}{50.13357} -\pgfmath@def{acos}{642}{50.05888} \pgfmath@def{acos}{643}{49.98411} -\pgfmath@def{acos}{644}{49.90926} \pgfmath@def{acos}{645}{49.83432} -\pgfmath@def{acos}{646}{49.75930} \pgfmath@def{acos}{647}{49.68420} -\pgfmath@def{acos}{648}{49.60902} \pgfmath@def{acos}{649}{49.53375} -\pgfmath@def{acos}{650}{49.45839} \pgfmath@def{acos}{651}{49.38296} -\pgfmath@def{acos}{652}{49.30743} \pgfmath@def{acos}{653}{49.23182} -\pgfmath@def{acos}{654}{49.15613} \pgfmath@def{acos}{655}{49.08035} -\pgfmath@def{acos}{656}{49.00448} \pgfmath@def{acos}{657}{48.92852} -\pgfmath@def{acos}{658}{48.85248} \pgfmath@def{acos}{659}{48.77634} -\pgfmath@def{acos}{660}{48.70012} \pgfmath@def{acos}{661}{48.62381} -\pgfmath@def{acos}{662}{48.54741} \pgfmath@def{acos}{663}{48.47092} -\pgfmath@def{acos}{664}{48.39434} \pgfmath@def{acos}{665}{48.31767} -\pgfmath@def{acos}{666}{48.24091} \pgfmath@def{acos}{667}{48.16405} -\pgfmath@def{acos}{668}{48.08710} \pgfmath@def{acos}{669}{48.01006} -\pgfmath@def{acos}{670}{47.93293} \pgfmath@def{acos}{671}{47.85570} -\pgfmath@def{acos}{672}{47.77838} \pgfmath@def{acos}{673}{47.70096} -\pgfmath@def{acos}{674}{47.62345} \pgfmath@def{acos}{675}{47.54585} -\pgfmath@def{acos}{676}{47.46814} \pgfmath@def{acos}{677}{47.39034} -\pgfmath@def{acos}{678}{47.31244} \pgfmath@def{acos}{679}{47.23445} -\pgfmath@def{acos}{680}{47.15635} \pgfmath@def{acos}{681}{47.07816} -\pgfmath@def{acos}{682}{46.99987} \pgfmath@def{acos}{683}{46.92147} -\pgfmath@def{acos}{684}{46.84298} \pgfmath@def{acos}{685}{46.76439} -\pgfmath@def{acos}{686}{46.68569} \pgfmath@def{acos}{687}{46.60690} -\pgfmath@def{acos}{688}{46.52800} \pgfmath@def{acos}{689}{46.44899} -\pgfmath@def{acos}{690}{46.36989} \pgfmath@def{acos}{691}{46.29068} -\pgfmath@def{acos}{692}{46.21136} \pgfmath@def{acos}{693}{46.13194} -\pgfmath@def{acos}{694}{46.05241} \pgfmath@def{acos}{695}{45.97278} -\pgfmath@def{acos}{696}{45.89304} \pgfmath@def{acos}{697}{45.81319} -\pgfmath@def{acos}{698}{45.73323} \pgfmath@def{acos}{699}{45.65317} -\pgfmath@def{acos}{700}{45.57299} \pgfmath@def{acos}{701}{45.49271} -\pgfmath@def{acos}{702}{45.41231} \pgfmath@def{acos}{703}{45.33180} -\pgfmath@def{acos}{704}{45.25118} \pgfmath@def{acos}{705}{45.17045} -\pgfmath@def{acos}{706}{45.08961} \pgfmath@def{acos}{707}{45.00865} -\pgfmath@def{acos}{708}{44.92757} \pgfmath@def{acos}{709}{44.84638} -\pgfmath@def{acos}{710}{44.76508} \pgfmath@def{acos}{711}{44.68366} -\pgfmath@def{acos}{712}{44.60212} \pgfmath@def{acos}{713}{44.52046} -\pgfmath@def{acos}{714}{44.43869} \pgfmath@def{acos}{715}{44.35680} -\pgfmath@def{acos}{716}{44.27478} \pgfmath@def{acos}{717}{44.19265} -\pgfmath@def{acos}{718}{44.11039} \pgfmath@def{acos}{719}{44.02802} -\pgfmath@def{acos}{720}{43.94552} \pgfmath@def{acos}{721}{43.86289} -\pgfmath@def{acos}{722}{43.78014} \pgfmath@def{acos}{723}{43.69727} -\pgfmath@def{acos}{724}{43.61427} \pgfmath@def{acos}{725}{43.53115} -\pgfmath@def{acos}{726}{43.44790} \pgfmath@def{acos}{727}{43.36452} -\pgfmath@def{acos}{728}{43.28101} \pgfmath@def{acos}{729}{43.19737} -\pgfmath@def{acos}{730}{43.11360} \pgfmath@def{acos}{731}{43.02970} -\pgfmath@def{acos}{732}{42.94567} \pgfmath@def{acos}{733}{42.86151} -\pgfmath@def{acos}{734}{42.77721} \pgfmath@def{acos}{735}{42.69278} -\pgfmath@def{acos}{736}{42.60821} \pgfmath@def{acos}{737}{42.52351} -\pgfmath@def{acos}{738}{42.43867} \pgfmath@def{acos}{739}{42.35370} -\pgfmath@def{acos}{740}{42.26858} \pgfmath@def{acos}{741}{42.18333} -\pgfmath@def{acos}{742}{42.09793} \pgfmath@def{acos}{743}{42.01240} -\pgfmath@def{acos}{744}{41.92672} \pgfmath@def{acos}{745}{41.84090} -\pgfmath@def{acos}{746}{41.75493} \pgfmath@def{acos}{747}{41.66882} -\pgfmath@def{acos}{748}{41.58257} \pgfmath@def{acos}{749}{41.49617} -\pgfmath@def{acos}{750}{41.40962} \pgfmath@def{acos}{751}{41.32292} -\pgfmath@def{acos}{752}{41.23607} \pgfmath@def{acos}{753}{41.14908} -\pgfmath@def{acos}{754}{41.06193} \pgfmath@def{acos}{755}{40.97463} -\pgfmath@def{acos}{756}{40.88717} \pgfmath@def{acos}{757}{40.79956} -\pgfmath@def{acos}{758}{40.71180} \pgfmath@def{acos}{759}{40.62388} -\pgfmath@def{acos}{760}{40.53580} \pgfmath@def{acos}{761}{40.44756} -\pgfmath@def{acos}{762}{40.35916} \pgfmath@def{acos}{763}{40.27061} -\pgfmath@def{acos}{764}{40.18189} \pgfmath@def{acos}{765}{40.09300} -\pgfmath@def{acos}{766}{40.00396} \pgfmath@def{acos}{767}{39.91474} -\pgfmath@def{acos}{768}{39.82537} \pgfmath@def{acos}{769}{39.73582} -\pgfmath@def{acos}{770}{39.64611} \pgfmath@def{acos}{771}{39.55622} -\pgfmath@def{acos}{772}{39.46617} \pgfmath@def{acos}{773}{39.37594} -\pgfmath@def{acos}{774}{39.28554} \pgfmath@def{acos}{775}{39.19496} -\pgfmath@def{acos}{776}{39.10421} \pgfmath@def{acos}{777}{39.01328} -\pgfmath@def{acos}{778}{38.92218} \pgfmath@def{acos}{779}{38.83089} -\pgfmath@def{acos}{780}{38.73942} \pgfmath@def{acos}{781}{38.64777} -\pgfmath@def{acos}{782}{38.55594} \pgfmath@def{acos}{783}{38.46392} -\pgfmath@def{acos}{784}{38.37171} \pgfmath@def{acos}{785}{38.27932} -\pgfmath@def{acos}{786}{38.18673} \pgfmath@def{acos}{787}{38.09396} -\pgfmath@def{acos}{788}{38.00100} \pgfmath@def{acos}{789}{37.90784} -\pgfmath@def{acos}{790}{37.81448} \pgfmath@def{acos}{791}{37.72093} -\pgfmath@def{acos}{792}{37.62719} \pgfmath@def{acos}{793}{37.53324} -\pgfmath@def{acos}{794}{37.43909} \pgfmath@def{acos}{795}{37.34474} -\pgfmath@def{acos}{796}{37.25019} \pgfmath@def{acos}{797}{37.15542} -\pgfmath@def{acos}{798}{37.06046} \pgfmath@def{acos}{799}{36.96528} -\pgfmath@def{acos}{800}{36.86989} \pgfmath@def{acos}{801}{36.77429} -\pgfmath@def{acos}{802}{36.67848} \pgfmath@def{acos}{803}{36.58245} -\pgfmath@def{acos}{804}{36.48621} \pgfmath@def{acos}{805}{36.38974} -\pgfmath@def{acos}{806}{36.29305} \pgfmath@def{acos}{807}{36.19615} -\pgfmath@def{acos}{808}{36.09901} \pgfmath@def{acos}{809}{36.00165} -\pgfmath@def{acos}{810}{35.90406} \pgfmath@def{acos}{811}{35.80625} -\pgfmath@def{acos}{812}{35.70820} \pgfmath@def{acos}{813}{35.60991} -\pgfmath@def{acos}{814}{35.51139} \pgfmath@def{acos}{815}{35.41263} -\pgfmath@def{acos}{816}{35.31364} \pgfmath@def{acos}{817}{35.21440} -\pgfmath@def{acos}{818}{35.11491} \pgfmath@def{acos}{819}{35.01518} -\pgfmath@def{acos}{820}{34.91520} \pgfmath@def{acos}{821}{34.81497} -\pgfmath@def{acos}{822}{34.71449} \pgfmath@def{acos}{823}{34.61375} -\pgfmath@def{acos}{824}{34.51276} \pgfmath@def{acos}{825}{34.41150} -\pgfmath@def{acos}{826}{34.30999} \pgfmath@def{acos}{827}{34.20821} -\pgfmath@def{acos}{828}{34.10616} \pgfmath@def{acos}{829}{34.00385} -\pgfmath@def{acos}{830}{33.90126} \pgfmath@def{acos}{831}{33.79840} -\pgfmath@def{acos}{832}{33.69526} \pgfmath@def{acos}{833}{33.59184} -\pgfmath@def{acos}{834}{33.48814} \pgfmath@def{acos}{835}{33.38416} -\pgfmath@def{acos}{836}{33.27989} \pgfmath@def{acos}{837}{33.17533} -\pgfmath@def{acos}{838}{33.07047} \pgfmath@def{acos}{839}{32.96532} -\pgfmath@def{acos}{840}{32.85988} \pgfmath@def{acos}{841}{32.75413} -\pgfmath@def{acos}{842}{32.64807} \pgfmath@def{acos}{843}{32.54171} -\pgfmath@def{acos}{844}{32.43504} \pgfmath@def{acos}{845}{32.32806} -\pgfmath@def{acos}{846}{32.22076} \pgfmath@def{acos}{847}{32.11314} -\pgfmath@def{acos}{848}{32.00520} \pgfmath@def{acos}{849}{31.89693} -\pgfmath@def{acos}{850}{31.78833} \pgfmath@def{acos}{851}{31.67939} -\pgfmath@def{acos}{852}{31.57012} \pgfmath@def{acos}{853}{31.46051} -\pgfmath@def{acos}{854}{31.35056} \pgfmath@def{acos}{855}{31.24026} -\pgfmath@def{acos}{856}{31.12961} \pgfmath@def{acos}{857}{31.01860} -\pgfmath@def{acos}{858}{30.90724} \pgfmath@def{acos}{859}{30.79551} -\pgfmath@def{acos}{860}{30.68341} \pgfmath@def{acos}{861}{30.57095} -\pgfmath@def{acos}{862}{30.45811} \pgfmath@def{acos}{863}{30.34489} -\pgfmath@def{acos}{864}{30.23128} \pgfmath@def{acos}{865}{30.11729} -\pgfmath@def{acos}{866}{30.00291} \pgfmath@def{acos}{867}{29.88813} -\pgfmath@def{acos}{868}{29.77294} \pgfmath@def{acos}{869}{29.65736} -\pgfmath@def{acos}{870}{29.54136} \pgfmath@def{acos}{871}{29.42494} -\pgfmath@def{acos}{872}{29.30810} \pgfmath@def{acos}{873}{29.19084} -\pgfmath@def{acos}{874}{29.07315} \pgfmath@def{acos}{875}{28.95502} -\pgfmath@def{acos}{876}{28.83645} \pgfmath@def{acos}{877}{28.71743} -\pgfmath@def{acos}{878}{28.59796} \pgfmath@def{acos}{879}{28.47803} -\pgfmath@def{acos}{880}{28.35763} \pgfmath@def{acos}{881}{28.23677} -\pgfmath@def{acos}{882}{28.11542} \pgfmath@def{acos}{883}{27.99360} -\pgfmath@def{acos}{884}{27.87128} \pgfmath@def{acos}{885}{27.74847} -\pgfmath@def{acos}{886}{27.62516} \pgfmath@def{acos}{887}{27.50134} -\pgfmath@def{acos}{888}{27.37700} \pgfmath@def{acos}{889}{27.25214} -\pgfmath@def{acos}{890}{27.12675} \pgfmath@def{acos}{891}{27.00082} -\pgfmath@def{acos}{892}{26.87434} \pgfmath@def{acos}{893}{26.74731} -\pgfmath@def{acos}{894}{26.61973} \pgfmath@def{acos}{895}{26.49157} -\pgfmath@def{acos}{896}{26.36283} \pgfmath@def{acos}{897}{26.23351} -\pgfmath@def{acos}{898}{26.10359} \pgfmath@def{acos}{899}{25.97306} -\pgfmath@def{acos}{900}{25.84193} \pgfmath@def{acos}{901}{25.71017} -\pgfmath@def{acos}{902}{25.57778} \pgfmath@def{acos}{903}{25.44475} -\pgfmath@def{acos}{904}{25.31106} \pgfmath@def{acos}{905}{25.17671} -\pgfmath@def{acos}{906}{25.04169} \pgfmath@def{acos}{907}{24.90598} -\pgfmath@def{acos}{908}{24.76958} \pgfmath@def{acos}{909}{24.63247} -\pgfmath@def{acos}{910}{24.49464} \pgfmath@def{acos}{911}{24.35608} -\pgfmath@def{acos}{912}{24.21678} \pgfmath@def{acos}{913}{24.07672} -\pgfmath@def{acos}{914}{23.93588} \pgfmath@def{acos}{915}{23.79427} -\pgfmath@def{acos}{916}{23.65185} \pgfmath@def{acos}{917}{23.50863} -\pgfmath@def{acos}{918}{23.36457} \pgfmath@def{acos}{919}{23.21967} -\pgfmath@def{acos}{920}{23.07391} \pgfmath@def{acos}{921}{22.92728} -\pgfmath@def{acos}{922}{22.77975} \pgfmath@def{acos}{923}{22.63132} -\pgfmath@def{acos}{924}{22.48195} \pgfmath@def{acos}{925}{22.33164} -\pgfmath@def{acos}{926}{22.18036} \pgfmath@def{acos}{927}{22.02810} -\pgfmath@def{acos}{928}{21.87483} \pgfmath@def{acos}{929}{21.72053} -\pgfmath@def{acos}{930}{21.56518} \pgfmath@def{acos}{931}{21.40876} -\pgfmath@def{acos}{932}{21.25124} \pgfmath@def{acos}{933}{21.09260} -\pgfmath@def{acos}{934}{20.93281} \pgfmath@def{acos}{935}{20.77185} -\pgfmath@def{acos}{936}{20.60969} \pgfmath@def{acos}{937}{20.44630} -\pgfmath@def{acos}{938}{20.28165} \pgfmath@def{acos}{939}{20.11570} -\pgfmath@def{acos}{940}{19.94844} \pgfmath@def{acos}{941}{19.77982} -\pgfmath@def{acos}{942}{19.60981} \pgfmath@def{acos}{943}{19.43837} -\pgfmath@def{acos}{944}{19.26546} \pgfmath@def{acos}{945}{19.09105} -\pgfmath@def{acos}{946}{18.91509} \pgfmath@def{acos}{947}{18.73754} -\pgfmath@def{acos}{948}{18.55835} \pgfmath@def{acos}{949}{18.37748} -\pgfmath@def{acos}{950}{18.19487} \pgfmath@def{acos}{951}{18.01047} -\pgfmath@def{acos}{952}{17.82423} \pgfmath@def{acos}{953}{17.63609} -\pgfmath@def{acos}{954}{17.44598} \pgfmath@def{acos}{955}{17.25385} -\pgfmath@def{acos}{956}{17.05962} \pgfmath@def{acos}{957}{16.86322} -\pgfmath@def{acos}{958}{16.66457} \pgfmath@def{acos}{959}{16.46359} -\pgfmath@def{acos}{960}{16.26020} \pgfmath@def{acos}{961}{16.05430} -\pgfmath@def{acos}{962}{15.84580} \pgfmath@def{acos}{963}{15.63459} -\pgfmath@def{acos}{964}{15.42057} \pgfmath@def{acos}{965}{15.20360} -\pgfmath@def{acos}{966}{14.98357} \pgfmath@def{acos}{967}{14.76033} -\pgfmath@def{acos}{968}{14.53374} \pgfmath@def{acos}{969}{14.30364} -\pgfmath@def{acos}{970}{14.06986} \pgfmath@def{acos}{971}{13.83221} -\pgfmath@def{acos}{972}{13.59049} \pgfmath@def{acos}{973}{13.34447} -\pgfmath@def{acos}{974}{13.09392} \pgfmath@def{acos}{975}{12.83856} -\pgfmath@def{acos}{976}{12.57811} \pgfmath@def{acos}{977}{12.31225} -\pgfmath@def{acos}{978}{12.04060} \pgfmath@def{acos}{979}{11.76278} -\pgfmath@def{acos}{980}{11.47834} \pgfmath@def{acos}{981}{11.18676} -\pgfmath@def{acos}{982}{10.88748} \pgfmath@def{acos}{983}{10.57984} -\pgfmath@def{acos}{984}{10.26309} \pgfmath@def{acos}{985}{9.93636} -\pgfmath@def{acos}{986}{9.59863} \pgfmath@def{acos}{987}{9.24870} -\pgfmath@def{acos}{988}{8.88512} \pgfmath@def{acos}{989}{8.50614} -\pgfmath@def{acos}{990}{8.10961} \pgfmath@def{acos}{991}{7.69281} -\pgfmath@def{acos}{992}{7.25224} \pgfmath@def{acos}{993}{6.78328} -\pgfmath@def{acos}{994}{6.27958} \pgfmath@def{acos}{995}{5.73196} -\pgfmath@def{acos}{996}{5.12640} \pgfmath@def{acos}{997}{4.43922} -\pgfmath@def{acos}{998}{3.62430} \pgfmath@def{acos}{999}{2.56255} -\pgfmath@def{acos}{1000}{0.00000}
\ No newline at end of file +\pgfmath@def{atan}{0}{0.00000} \pgfmath@def{atan}{1}{0.05729} +\pgfmath@def{atan}{2}{0.11459} \pgfmath@def{atan}{3}{0.17188} +\pgfmath@def{atan}{4}{0.22918} \pgfmath@def{atan}{5}{0.28647} +\pgfmath@def{atan}{6}{0.34377} \pgfmath@def{atan}{7}{0.40106} +\pgfmath@def{atan}{8}{0.45835} \pgfmath@def{atan}{9}{0.51564} +\pgfmath@def{atan}{10}{0.57293} \pgfmath@def{atan}{11}{0.63022} +\pgfmath@def{atan}{12}{0.68751} \pgfmath@def{atan}{13}{0.74480} +\pgfmath@def{atan}{14}{0.80208} \pgfmath@def{atan}{15}{0.85937} +\pgfmath@def{atan}{16}{0.91665} \pgfmath@def{atan}{17}{0.97393} +\pgfmath@def{atan}{18}{1.03121} \pgfmath@def{atan}{19}{1.08848} +\pgfmath@def{atan}{20}{1.14576} \pgfmath@def{atan}{21}{1.20303} +\pgfmath@def{atan}{22}{1.26030} \pgfmath@def{atan}{23}{1.31757} +\pgfmath@def{atan}{24}{1.37483} \pgfmath@def{atan}{25}{1.43209} +\pgfmath@def{atan}{26}{1.48935} \pgfmath@def{atan}{27}{1.54661} +\pgfmath@def{atan}{28}{1.60386} \pgfmath@def{atan}{29}{1.66111} +\pgfmath@def{atan}{30}{1.71835} \pgfmath@def{atan}{31}{1.77560} +\pgfmath@def{atan}{32}{1.83284} \pgfmath@def{atan}{33}{1.89007} +\pgfmath@def{atan}{34}{1.94730} \pgfmath@def{atan}{35}{2.00453} +\pgfmath@def{atan}{36}{2.06175} \pgfmath@def{atan}{37}{2.11897} +\pgfmath@def{atan}{38}{2.17619} \pgfmath@def{atan}{39}{2.23340} +\pgfmath@def{atan}{40}{2.29061} \pgfmath@def{atan}{41}{2.34781} +\pgfmath@def{atan}{42}{2.40500} \pgfmath@def{atan}{43}{2.46220} +\pgfmath@def{atan}{44}{2.51938} \pgfmath@def{atan}{45}{2.57657} +\pgfmath@def{atan}{46}{2.63374} \pgfmath@def{atan}{47}{2.69092} +\pgfmath@def{atan}{48}{2.74808} \pgfmath@def{atan}{49}{2.80524} +\pgfmath@def{atan}{50}{2.86240} \pgfmath@def{atan}{51}{2.91955} +\pgfmath@def{atan}{52}{2.97669} \pgfmath@def{atan}{53}{3.03383} +\pgfmath@def{atan}{54}{3.09097} \pgfmath@def{atan}{55}{3.14809} +\pgfmath@def{atan}{56}{3.20521} \pgfmath@def{atan}{57}{3.26232} +\pgfmath@def{atan}{58}{3.31943} \pgfmath@def{atan}{59}{3.37653} +\pgfmath@def{atan}{60}{3.43363} \pgfmath@def{atan}{61}{3.49071} +\pgfmath@def{atan}{62}{3.54779} \pgfmath@def{atan}{63}{3.60487} +\pgfmath@def{atan}{64}{3.66193} \pgfmath@def{atan}{65}{3.71899} +\pgfmath@def{atan}{66}{3.77604} \pgfmath@def{atan}{67}{3.83308} +\pgfmath@def{atan}{68}{3.89012} \pgfmath@def{atan}{69}{3.94715} +\pgfmath@def{atan}{70}{4.00417} \pgfmath@def{atan}{71}{4.06118} +\pgfmath@def{atan}{72}{4.11819} \pgfmath@def{atan}{73}{4.17518} +\pgfmath@def{atan}{74}{4.23217} \pgfmath@def{atan}{75}{4.28915} +\pgfmath@def{atan}{76}{4.34612} \pgfmath@def{atan}{77}{4.40308} +\pgfmath@def{atan}{78}{4.46004} \pgfmath@def{atan}{79}{4.51698} +\pgfmath@def{atan}{80}{4.57392} \pgfmath@def{atan}{81}{4.63084} +\pgfmath@def{atan}{82}{4.68776} \pgfmath@def{atan}{83}{4.74467} +\pgfmath@def{atan}{84}{4.80157} \pgfmath@def{atan}{85}{4.85846} +\pgfmath@def{atan}{86}{4.91534} \pgfmath@def{atan}{87}{4.97221} +\pgfmath@def{atan}{88}{5.02907} \pgfmath@def{atan}{89}{5.08592} +\pgfmath@def{atan}{90}{5.14276} \pgfmath@def{atan}{91}{5.19959} +\pgfmath@def{atan}{92}{5.25641} \pgfmath@def{atan}{93}{5.31322} +\pgfmath@def{atan}{94}{5.37002} \pgfmath@def{atan}{95}{5.42681} +\pgfmath@def{atan}{96}{5.48359} \pgfmath@def{atan}{97}{5.54035} +\pgfmath@def{atan}{98}{5.59711} \pgfmath@def{atan}{99}{5.65385} +\pgfmath@def{atan}{100}{5.71059} \pgfmath@def{atan}{101}{5.76731} +\pgfmath@def{atan}{102}{5.82402} \pgfmath@def{atan}{103}{5.88072} +\pgfmath@def{atan}{104}{5.93741} \pgfmath@def{atan}{105}{5.99409} +\pgfmath@def{atan}{106}{6.05075} \pgfmath@def{atan}{107}{6.10741} +\pgfmath@def{atan}{108}{6.16405} \pgfmath@def{atan}{109}{6.22068} +\pgfmath@def{atan}{110}{6.27729} \pgfmath@def{atan}{111}{6.33390} +\pgfmath@def{atan}{112}{6.39049} \pgfmath@def{atan}{113}{6.44707} +\pgfmath@def{atan}{114}{6.50364} \pgfmath@def{atan}{115}{6.56019} +\pgfmath@def{atan}{116}{6.61673} \pgfmath@def{atan}{117}{6.67326} +\pgfmath@def{atan}{118}{6.72978} \pgfmath@def{atan}{119}{6.78628} +\pgfmath@def{atan}{120}{6.84277} \pgfmath@def{atan}{121}{6.89924} +\pgfmath@def{atan}{122}{6.95571} \pgfmath@def{atan}{123}{7.01216} +\pgfmath@def{atan}{124}{7.06859} \pgfmath@def{atan}{125}{7.12501} +\pgfmath@def{atan}{126}{7.18142} \pgfmath@def{atan}{127}{7.23781} +\pgfmath@def{atan}{128}{7.29419} \pgfmath@def{atan}{129}{7.35056} +\pgfmath@def{atan}{130}{7.40691} \pgfmath@def{atan}{131}{7.46324} +\pgfmath@def{atan}{132}{7.51957} \pgfmath@def{atan}{133}{7.57587} +\pgfmath@def{atan}{134}{7.63217} \pgfmath@def{atan}{135}{7.68844} +\pgfmath@def{atan}{136}{7.74471} \pgfmath@def{atan}{137}{7.80095} +\pgfmath@def{atan}{138}{7.85719} \pgfmath@def{atan}{139}{7.91340} +\pgfmath@def{atan}{140}{7.96961} \pgfmath@def{atan}{141}{8.02579} +\pgfmath@def{atan}{142}{8.08196} \pgfmath@def{atan}{143}{8.13812} +\pgfmath@def{atan}{144}{8.19426} \pgfmath@def{atan}{145}{8.25038} +\pgfmath@def{atan}{146}{8.30649} \pgfmath@def{atan}{147}{8.36258} +\pgfmath@def{atan}{148}{8.41866} \pgfmath@def{atan}{149}{8.47472} +\pgfmath@def{atan}{150}{8.53076} \pgfmath@def{atan}{151}{8.58679} +\pgfmath@def{atan}{152}{8.64280} \pgfmath@def{atan}{153}{8.69879} +\pgfmath@def{atan}{154}{8.75477} \pgfmath@def{atan}{155}{8.81073} +\pgfmath@def{atan}{156}{8.86667} \pgfmath@def{atan}{157}{8.92260} +\pgfmath@def{atan}{158}{8.97851} \pgfmath@def{atan}{159}{9.03440} +\pgfmath@def{atan}{160}{9.09027} \pgfmath@def{atan}{161}{9.14613} +\pgfmath@def{atan}{162}{9.20197} \pgfmath@def{atan}{163}{9.25779} +\pgfmath@def{atan}{164}{9.31359} \pgfmath@def{atan}{165}{9.36938} +\pgfmath@def{atan}{166}{9.42515} \pgfmath@def{atan}{167}{9.48090} +\pgfmath@def{atan}{168}{9.53663} \pgfmath@def{atan}{169}{9.59235} +\pgfmath@def{atan}{170}{9.64804} \pgfmath@def{atan}{171}{9.70372} +\pgfmath@def{atan}{172}{9.75938} \pgfmath@def{atan}{173}{9.81502} +\pgfmath@def{atan}{174}{9.87064} \pgfmath@def{atan}{175}{9.92624} +\pgfmath@def{atan}{176}{9.98182} \pgfmath@def{atan}{177}{10.03739} +\pgfmath@def{atan}{178}{10.09294} \pgfmath@def{atan}{179}{10.14846} +\pgfmath@def{atan}{180}{10.20397} \pgfmath@def{atan}{181}{10.25946} +\pgfmath@def{atan}{182}{10.31493} \pgfmath@def{atan}{183}{10.37037} +\pgfmath@def{atan}{184}{10.42580} \pgfmath@def{atan}{185}{10.48121} +\pgfmath@def{atan}{186}{10.53660} \pgfmath@def{atan}{187}{10.59197} +\pgfmath@def{atan}{188}{10.64732} \pgfmath@def{atan}{189}{10.70265} +\pgfmath@def{atan}{190}{10.75796} \pgfmath@def{atan}{191}{10.81325} +\pgfmath@def{atan}{192}{10.86852} \pgfmath@def{atan}{193}{10.92377} +\pgfmath@def{atan}{194}{10.97900} \pgfmath@def{atan}{195}{11.03420} +\pgfmath@def{atan}{196}{11.08939} \pgfmath@def{atan}{197}{11.14456} +\pgfmath@def{atan}{198}{11.19970} \pgfmath@def{atan}{199}{11.25483} +\pgfmath@def{atan}{200}{11.30993} \pgfmath@def{atan}{201}{11.36501} +\pgfmath@def{atan}{202}{11.42007} \pgfmath@def{atan}{203}{11.47511} +\pgfmath@def{atan}{204}{11.53013} \pgfmath@def{atan}{205}{11.58512} +\pgfmath@def{atan}{206}{11.64010} \pgfmath@def{atan}{207}{11.69505} +\pgfmath@def{atan}{208}{11.74998} \pgfmath@def{atan}{209}{11.80489} +\pgfmath@def{atan}{210}{11.85977} \pgfmath@def{atan}{211}{11.91464} +\pgfmath@def{atan}{212}{11.96948} \pgfmath@def{atan}{213}{12.02430} +\pgfmath@def{atan}{214}{12.07910} \pgfmath@def{atan}{215}{12.13388} +\pgfmath@def{atan}{216}{12.18863} \pgfmath@def{atan}{217}{12.24336} +\pgfmath@def{atan}{218}{12.29807} \pgfmath@def{atan}{219}{12.35275} +\pgfmath@def{atan}{220}{12.40741} \pgfmath@def{atan}{221}{12.46205} +\pgfmath@def{atan}{222}{12.51667} \pgfmath@def{atan}{223}{12.57126} +\pgfmath@def{atan}{224}{12.62583} \pgfmath@def{atan}{225}{12.68038} +\pgfmath@def{atan}{226}{12.73490} \pgfmath@def{atan}{227}{12.78940} +\pgfmath@def{atan}{228}{12.84388} \pgfmath@def{atan}{229}{12.89833} +\pgfmath@def{atan}{230}{12.95276} \pgfmath@def{atan}{231}{13.00717} +\pgfmath@def{atan}{232}{13.06155} \pgfmath@def{atan}{233}{13.11590} +\pgfmath@def{atan}{234}{13.17024} \pgfmath@def{atan}{235}{13.22455} +\pgfmath@def{atan}{236}{13.27883} \pgfmath@def{atan}{237}{13.33309} +\pgfmath@def{atan}{238}{13.38733} \pgfmath@def{atan}{239}{13.44154} +\pgfmath@def{atan}{240}{13.49573} \pgfmath@def{atan}{241}{13.54989} +\pgfmath@def{atan}{242}{13.60403} \pgfmath@def{atan}{243}{13.65814} +\pgfmath@def{atan}{244}{13.71223} \pgfmath@def{atan}{245}{13.76630} +\pgfmath@def{atan}{246}{13.82034} \pgfmath@def{atan}{247}{13.87435} +\pgfmath@def{atan}{248}{13.92834} \pgfmath@def{atan}{249}{13.98230} +\pgfmath@def{atan}{250}{14.03624} \pgfmath@def{atan}{251}{14.09015} +\pgfmath@def{atan}{252}{14.14404} \pgfmath@def{atan}{253}{14.19790} +\pgfmath@def{atan}{254}{14.25174} \pgfmath@def{atan}{255}{14.30555} +\pgfmath@def{atan}{256}{14.35933} \pgfmath@def{atan}{257}{14.41309} +\pgfmath@def{atan}{258}{14.46682} \pgfmath@def{atan}{259}{14.52053} +\pgfmath@def{atan}{260}{14.57421} \pgfmath@def{atan}{261}{14.62787} +\pgfmath@def{atan}{262}{14.68149} \pgfmath@def{atan}{263}{14.73510} +\pgfmath@def{atan}{264}{14.78867} \pgfmath@def{atan}{265}{14.84222} +\pgfmath@def{atan}{266}{14.89575} \pgfmath@def{atan}{267}{14.94924} +\pgfmath@def{atan}{268}{15.00271} \pgfmath@def{atan}{269}{15.05615} +\pgfmath@def{atan}{270}{15.10957} \pgfmath@def{atan}{271}{15.16296} +\pgfmath@def{atan}{272}{15.21632} \pgfmath@def{atan}{273}{15.26966} +\pgfmath@def{atan}{274}{15.32297} \pgfmath@def{atan}{275}{15.37625} +\pgfmath@def{atan}{276}{15.42950} \pgfmath@def{atan}{277}{15.48273} +\pgfmath@def{atan}{278}{15.53593} \pgfmath@def{atan}{279}{15.58910} +\pgfmath@def{atan}{280}{15.64224} \pgfmath@def{atan}{281}{15.69536} +\pgfmath@def{atan}{282}{15.74845} \pgfmath@def{atan}{283}{15.80151} +\pgfmath@def{atan}{284}{15.85454} \pgfmath@def{atan}{285}{15.90755} +\pgfmath@def{atan}{286}{15.96052} \pgfmath@def{atan}{287}{16.01347} +\pgfmath@def{atan}{288}{16.06640} \pgfmath@def{atan}{289}{16.11929} +\pgfmath@def{atan}{290}{16.17215} \pgfmath@def{atan}{291}{16.22499} +\pgfmath@def{atan}{292}{16.27780} \pgfmath@def{atan}{293}{16.33058} +\pgfmath@def{atan}{294}{16.38333} \pgfmath@def{atan}{295}{16.43605} +\pgfmath@def{atan}{296}{16.48875} \pgfmath@def{atan}{297}{16.54142} +\pgfmath@def{atan}{298}{16.59405} \pgfmath@def{atan}{299}{16.64666} +\pgfmath@def{atan}{300}{16.69924} \pgfmath@def{atan}{301}{16.75179} +\pgfmath@def{atan}{302}{16.80431} \pgfmath@def{atan}{303}{16.85680} +\pgfmath@def{atan}{304}{16.90927} \pgfmath@def{atan}{305}{16.96170} +\pgfmath@def{atan}{306}{17.01411} \pgfmath@def{atan}{307}{17.06648} +\pgfmath@def{atan}{308}{17.11883} \pgfmath@def{atan}{309}{17.17114} +\pgfmath@def{atan}{310}{17.22343} \pgfmath@def{atan}{311}{17.27569} +\pgfmath@def{atan}{312}{17.32792} \pgfmath@def{atan}{313}{17.38012} +\pgfmath@def{atan}{314}{17.43228} \pgfmath@def{atan}{315}{17.48442} +\pgfmath@def{atan}{316}{17.53653} \pgfmath@def{atan}{317}{17.58861} +\pgfmath@def{atan}{318}{17.64066} \pgfmath@def{atan}{319}{17.69268} +\pgfmath@def{atan}{320}{17.74467} \pgfmath@def{atan}{321}{17.79663} +\pgfmath@def{atan}{322}{17.84855} \pgfmath@def{atan}{323}{17.90045} +\pgfmath@def{atan}{324}{17.95232} \pgfmath@def{atan}{325}{18.00416} +\pgfmath@def{atan}{326}{18.05596} \pgfmath@def{atan}{327}{18.10774} +\pgfmath@def{atan}{328}{18.15949} \pgfmath@def{atan}{329}{18.21120} +\pgfmath@def{atan}{330}{18.26289} \pgfmath@def{atan}{331}{18.31454} +\pgfmath@def{atan}{332}{18.36616} \pgfmath@def{atan}{333}{18.41775} +\pgfmath@def{atan}{334}{18.46931} \pgfmath@def{atan}{335}{18.52084} +\pgfmath@def{atan}{336}{18.57234} \pgfmath@def{atan}{337}{18.62381} +\pgfmath@def{atan}{338}{18.67525} \pgfmath@def{atan}{339}{18.72665} +\pgfmath@def{atan}{340}{18.77803} \pgfmath@def{atan}{341}{18.82937} +\pgfmath@def{atan}{342}{18.88068} \pgfmath@def{atan}{343}{18.93196} +\pgfmath@def{atan}{344}{18.98321} \pgfmath@def{atan}{345}{19.03443} +\pgfmath@def{atan}{346}{19.08562} \pgfmath@def{atan}{347}{19.13677} +\pgfmath@def{atan}{348}{19.18789} \pgfmath@def{atan}{349}{19.23898} +\pgfmath@def{atan}{350}{19.29004} \pgfmath@def{atan}{351}{19.34107} +\pgfmath@def{atan}{352}{19.39206} \pgfmath@def{atan}{353}{19.44303} +\pgfmath@def{atan}{354}{19.49396} \pgfmath@def{atan}{355}{19.54486} +\pgfmath@def{atan}{356}{19.59572} \pgfmath@def{atan}{357}{19.64656} +\pgfmath@def{atan}{358}{19.69736} \pgfmath@def{atan}{359}{19.74813} +\pgfmath@def{atan}{360}{19.79887} \pgfmath@def{atan}{361}{19.84958} +\pgfmath@def{atan}{362}{19.90025} \pgfmath@def{atan}{363}{19.95089} +\pgfmath@def{atan}{364}{20.00150} \pgfmath@def{atan}{365}{20.05208} +\pgfmath@def{atan}{366}{20.10262} \pgfmath@def{atan}{367}{20.15313} +\pgfmath@def{atan}{368}{20.20361} \pgfmath@def{atan}{369}{20.25406} +\pgfmath@def{atan}{370}{20.30447} \pgfmath@def{atan}{371}{20.35485} +\pgfmath@def{atan}{372}{20.40520} \pgfmath@def{atan}{373}{20.45551} +\pgfmath@def{atan}{374}{20.50579} \pgfmath@def{atan}{375}{20.55604} +\pgfmath@def{atan}{376}{20.60626} \pgfmath@def{atan}{377}{20.65644} +\pgfmath@def{atan}{378}{20.70659} \pgfmath@def{atan}{379}{20.75670} +\pgfmath@def{atan}{380}{20.80679} \pgfmath@def{atan}{381}{20.85684} +\pgfmath@def{atan}{382}{20.90685} \pgfmath@def{atan}{383}{20.95684} +\pgfmath@def{atan}{384}{21.00678} \pgfmath@def{atan}{385}{21.05670} +\pgfmath@def{atan}{386}{21.10658} \pgfmath@def{atan}{387}{21.15643} +\pgfmath@def{atan}{388}{21.20625} \pgfmath@def{atan}{389}{21.25603} +\pgfmath@def{atan}{390}{21.30578} \pgfmath@def{atan}{391}{21.35549} +\pgfmath@def{atan}{392}{21.40517} \pgfmath@def{atan}{393}{21.45482} +\pgfmath@def{atan}{394}{21.50444} \pgfmath@def{atan}{395}{21.55402} +\pgfmath@def{atan}{396}{21.60356} \pgfmath@def{atan}{397}{21.65307} +\pgfmath@def{atan}{398}{21.70255} \pgfmath@def{atan}{399}{21.75200} +\pgfmath@def{atan}{400}{21.80140} \pgfmath@def{atan}{401}{21.85078} +\pgfmath@def{atan}{402}{21.90012} \pgfmath@def{atan}{403}{21.94943} +\pgfmath@def{atan}{404}{21.99870} \pgfmath@def{atan}{405}{22.04794} +\pgfmath@def{atan}{406}{22.09715} \pgfmath@def{atan}{407}{22.14632} +\pgfmath@def{atan}{408}{22.19546} \pgfmath@def{atan}{409}{22.24456} +\pgfmath@def{atan}{410}{22.29362} \pgfmath@def{atan}{411}{22.34266} +\pgfmath@def{atan}{412}{22.39166} \pgfmath@def{atan}{413}{22.44062} +\pgfmath@def{atan}{414}{22.48955} \pgfmath@def{atan}{415}{22.53845} +\pgfmath@def{atan}{416}{22.58731} \pgfmath@def{atan}{417}{22.63613} +\pgfmath@def{atan}{418}{22.68492} \pgfmath@def{atan}{419}{22.73368} +\pgfmath@def{atan}{420}{22.78240} \pgfmath@def{atan}{421}{22.83109} +\pgfmath@def{atan}{422}{22.87974} \pgfmath@def{atan}{423}{22.92836} +\pgfmath@def{atan}{424}{22.97694} \pgfmath@def{atan}{425}{23.02549} +\pgfmath@def{atan}{426}{23.07400} \pgfmath@def{atan}{427}{23.12248} +\pgfmath@def{atan}{428}{23.17092} \pgfmath@def{atan}{429}{23.21933} +\pgfmath@def{atan}{430}{23.26770} \pgfmath@def{atan}{431}{23.31604} +\pgfmath@def{atan}{432}{23.36434} \pgfmath@def{atan}{433}{23.41261} +\pgfmath@def{atan}{434}{23.46084} \pgfmath@def{atan}{435}{23.50904} +\pgfmath@def{atan}{436}{23.55720} \pgfmath@def{atan}{437}{23.60532} +\pgfmath@def{atan}{438}{23.65341} \pgfmath@def{atan}{439}{23.70147} +\pgfmath@def{atan}{440}{23.74949} \pgfmath@def{atan}{441}{23.79747} +\pgfmath@def{atan}{442}{23.84542} \pgfmath@def{atan}{443}{23.89334} +\pgfmath@def{atan}{444}{23.94122} \pgfmath@def{atan}{445}{23.98906} +\pgfmath@def{atan}{446}{24.03687} \pgfmath@def{atan}{447}{24.08464} +\pgfmath@def{atan}{448}{24.13238} \pgfmath@def{atan}{449}{24.18008} +\pgfmath@def{atan}{450}{24.22774} \pgfmath@def{atan}{451}{24.27537} +\pgfmath@def{atan}{452}{24.32296} \pgfmath@def{atan}{453}{24.37052} +\pgfmath@def{atan}{454}{24.41804} \pgfmath@def{atan}{455}{24.46553} +\pgfmath@def{atan}{456}{24.51298} \pgfmath@def{atan}{457}{24.56040} +\pgfmath@def{atan}{458}{24.60778} \pgfmath@def{atan}{459}{24.65512} +\pgfmath@def{atan}{460}{24.70243} \pgfmath@def{atan}{461}{24.74970} +\pgfmath@def{atan}{462}{24.79693} \pgfmath@def{atan}{463}{24.84413} +\pgfmath@def{atan}{464}{24.89130} \pgfmath@def{atan}{465}{24.93842} +\pgfmath@def{atan}{466}{24.98551} \pgfmath@def{atan}{467}{25.03257} +\pgfmath@def{atan}{468}{25.07959} \pgfmath@def{atan}{469}{25.12657} +\pgfmath@def{atan}{470}{25.17352} \pgfmath@def{atan}{471}{25.22043} +\pgfmath@def{atan}{472}{25.26731} \pgfmath@def{atan}{473}{25.31414} +\pgfmath@def{atan}{474}{25.36095} \pgfmath@def{atan}{475}{25.40771} +\pgfmath@def{atan}{476}{25.45444} \pgfmath@def{atan}{477}{25.50114} +\pgfmath@def{atan}{478}{25.54780} \pgfmath@def{atan}{479}{25.59442} +\pgfmath@def{atan}{480}{25.64100} \pgfmath@def{atan}{481}{25.68755} +\pgfmath@def{atan}{482}{25.73406} \pgfmath@def{atan}{483}{25.78054} +\pgfmath@def{atan}{484}{25.82698} \pgfmath@def{atan}{485}{25.87338} +\pgfmath@def{atan}{486}{25.91975} \pgfmath@def{atan}{487}{25.96608} +\pgfmath@def{atan}{488}{26.01237} \pgfmath@def{atan}{489}{26.05863} +\pgfmath@def{atan}{490}{26.10485} \pgfmath@def{atan}{491}{26.15103} +\pgfmath@def{atan}{492}{26.19718} \pgfmath@def{atan}{493}{26.24329} +\pgfmath@def{atan}{494}{26.28937} \pgfmath@def{atan}{495}{26.33541} +\pgfmath@def{atan}{496}{26.38141} \pgfmath@def{atan}{497}{26.42737} +\pgfmath@def{atan}{498}{26.47330} \pgfmath@def{atan}{499}{26.51919} +\pgfmath@def{atan}{500}{26.56505} \pgfmath@def{atan}{501}{26.61086} +\pgfmath@def{atan}{502}{26.65665} \pgfmath@def{atan}{503}{26.70239} +\pgfmath@def{atan}{504}{26.74810} \pgfmath@def{atan}{505}{26.79377} +\pgfmath@def{atan}{506}{26.83941} \pgfmath@def{atan}{507}{26.88500} +\pgfmath@def{atan}{508}{26.93057} \pgfmath@def{atan}{509}{26.97609} +\pgfmath@def{atan}{510}{27.02158} \pgfmath@def{atan}{511}{27.06703} +\pgfmath@def{atan}{512}{27.11244} \pgfmath@def{atan}{513}{27.15782} +\pgfmath@def{atan}{514}{27.20316} \pgfmath@def{atan}{515}{27.24846} +\pgfmath@def{atan}{516}{27.29373} \pgfmath@def{atan}{517}{27.33896} +\pgfmath@def{atan}{518}{27.38415} \pgfmath@def{atan}{519}{27.42931} +\pgfmath@def{atan}{520}{27.47443} \pgfmath@def{atan}{521}{27.51951} +\pgfmath@def{atan}{522}{27.56455} \pgfmath@def{atan}{523}{27.60956} +\pgfmath@def{atan}{524}{27.65453} \pgfmath@def{atan}{525}{27.69947} +\pgfmath@def{atan}{526}{27.74437} \pgfmath@def{atan}{527}{27.78923} +\pgfmath@def{atan}{528}{27.83405} \pgfmath@def{atan}{529}{27.87884} +\pgfmath@def{atan}{530}{27.92359} \pgfmath@def{atan}{531}{27.96830} +\pgfmath@def{atan}{532}{28.01297} \pgfmath@def{atan}{533}{28.05761} +\pgfmath@def{atan}{534}{28.10221} \pgfmath@def{atan}{535}{28.14678} +\pgfmath@def{atan}{536}{28.19130} \pgfmath@def{atan}{537}{28.23579} +\pgfmath@def{atan}{538}{28.28025} \pgfmath@def{atan}{539}{28.32466} +\pgfmath@def{atan}{540}{28.36904} \pgfmath@def{atan}{541}{28.41338} +\pgfmath@def{atan}{542}{28.45769} \pgfmath@def{atan}{543}{28.50196} +\pgfmath@def{atan}{544}{28.54619} \pgfmath@def{atan}{545}{28.59038} +\pgfmath@def{atan}{546}{28.63454} \pgfmath@def{atan}{547}{28.67865} +\pgfmath@def{atan}{548}{28.72274} \pgfmath@def{atan}{549}{28.76678} +\pgfmath@def{atan}{550}{28.81079} \pgfmath@def{atan}{551}{28.85476} +\pgfmath@def{atan}{552}{28.89869} \pgfmath@def{atan}{553}{28.94259} +\pgfmath@def{atan}{554}{28.98645} \pgfmath@def{atan}{555}{29.03027} +\pgfmath@def{atan}{556}{29.07405} \pgfmath@def{atan}{557}{29.11780} +\pgfmath@def{atan}{558}{29.16151} \pgfmath@def{atan}{559}{29.20519} +\pgfmath@def{atan}{560}{29.24882} \pgfmath@def{atan}{561}{29.29242} +\pgfmath@def{atan}{562}{29.33598} \pgfmath@def{atan}{563}{29.37951} +\pgfmath@def{atan}{564}{29.42299} \pgfmath@def{atan}{565}{29.46644} +\pgfmath@def{atan}{566}{29.50986} \pgfmath@def{atan}{567}{29.55323} +\pgfmath@def{atan}{568}{29.59657} \pgfmath@def{atan}{569}{29.63987} +\pgfmath@def{atan}{570}{29.68314} \pgfmath@def{atan}{571}{29.72636} +\pgfmath@def{atan}{572}{29.76955} \pgfmath@def{atan}{573}{29.81270} +\pgfmath@def{atan}{574}{29.85582} \pgfmath@def{atan}{575}{29.89890} +\pgfmath@def{atan}{576}{29.94194} \pgfmath@def{atan}{577}{29.98494} +\pgfmath@def{atan}{578}{30.02791} \pgfmath@def{atan}{579}{30.07084} +\pgfmath@def{atan}{580}{30.11373} \pgfmath@def{atan}{581}{30.15658} +\pgfmath@def{atan}{582}{30.19940} \pgfmath@def{atan}{583}{30.24218} +\pgfmath@def{atan}{584}{30.28492} \pgfmath@def{atan}{585}{30.32763} +\pgfmath@def{atan}{586}{30.37030} \pgfmath@def{atan}{587}{30.41293} +\pgfmath@def{atan}{588}{30.45552} \pgfmath@def{atan}{589}{30.49808} +\pgfmath@def{atan}{590}{30.54060} \pgfmath@def{atan}{591}{30.58308} +\pgfmath@def{atan}{592}{30.62553} \pgfmath@def{atan}{593}{30.66794} +\pgfmath@def{atan}{594}{30.71031} \pgfmath@def{atan}{595}{30.75264} +\pgfmath@def{atan}{596}{30.79494} \pgfmath@def{atan}{597}{30.83720} +\pgfmath@def{atan}{598}{30.87942} \pgfmath@def{atan}{599}{30.92160} +\pgfmath@def{atan}{600}{30.96375} \pgfmath@def{atan}{601}{31.00586} +\pgfmath@def{atan}{602}{31.04794} \pgfmath@def{atan}{603}{31.08997} +\pgfmath@def{atan}{604}{31.13197} \pgfmath@def{atan}{605}{31.17393} +\pgfmath@def{atan}{606}{31.21586} \pgfmath@def{atan}{607}{31.25775} +\pgfmath@def{atan}{608}{31.29960} \pgfmath@def{atan}{609}{31.34141} +\pgfmath@def{atan}{610}{31.38319} \pgfmath@def{atan}{611}{31.42493} +\pgfmath@def{atan}{612}{31.46663} \pgfmath@def{atan}{613}{31.50829} +\pgfmath@def{atan}{614}{31.54992} \pgfmath@def{atan}{615}{31.59151} +\pgfmath@def{atan}{616}{31.63306} \pgfmath@def{atan}{617}{31.67458} +\pgfmath@def{atan}{618}{31.71606} \pgfmath@def{atan}{619}{31.75750} +\pgfmath@def{atan}{620}{31.79891} \pgfmath@def{atan}{621}{31.84028} +\pgfmath@def{atan}{622}{31.88161} \pgfmath@def{atan}{623}{31.92290} +\pgfmath@def{atan}{624}{31.96416} \pgfmath@def{atan}{625}{32.00538} +\pgfmath@def{atan}{626}{32.04656} \pgfmath@def{atan}{627}{32.08771} +\pgfmath@def{atan}{628}{32.12882} \pgfmath@def{atan}{629}{32.16989} +\pgfmath@def{atan}{630}{32.21092} \pgfmath@def{atan}{631}{32.25192} +\pgfmath@def{atan}{632}{32.29288} \pgfmath@def{atan}{633}{32.33381} +\pgfmath@def{atan}{634}{32.37469} \pgfmath@def{atan}{635}{32.41554} +\pgfmath@def{atan}{636}{32.45636} \pgfmath@def{atan}{637}{32.49713} +\pgfmath@def{atan}{638}{32.53787} \pgfmath@def{atan}{639}{32.57857} +\pgfmath@def{atan}{640}{32.61924} \pgfmath@def{atan}{641}{32.65987} +\pgfmath@def{atan}{642}{32.70046} \pgfmath@def{atan}{643}{32.74101} +\pgfmath@def{atan}{644}{32.78153} \pgfmath@def{atan}{645}{32.82201} +\pgfmath@def{atan}{646}{32.86246} \pgfmath@def{atan}{647}{32.90286} +\pgfmath@def{atan}{648}{32.94323} \pgfmath@def{atan}{649}{32.98357} +\pgfmath@def{atan}{650}{33.02386} \pgfmath@def{atan}{651}{33.06412} +\pgfmath@def{atan}{652}{33.10435} \pgfmath@def{atan}{653}{33.14453} +\pgfmath@def{atan}{654}{33.18468} \pgfmath@def{atan}{655}{33.22479} +\pgfmath@def{atan}{656}{33.26487} \pgfmath@def{atan}{657}{33.30491} +\pgfmath@def{atan}{658}{33.34491} \pgfmath@def{atan}{659}{33.38488} +\pgfmath@def{atan}{660}{33.42481} \pgfmath@def{atan}{661}{33.46470} +\pgfmath@def{atan}{662}{33.50455} \pgfmath@def{atan}{663}{33.54437} +\pgfmath@def{atan}{664}{33.58416} \pgfmath@def{atan}{665}{33.62390} +\pgfmath@def{atan}{666}{33.66361} \pgfmath@def{atan}{667}{33.70328} +\pgfmath@def{atan}{668}{33.74292} \pgfmath@def{atan}{669}{33.78252} +\pgfmath@def{atan}{670}{33.82208} \pgfmath@def{atan}{671}{33.86161} +\pgfmath@def{atan}{672}{33.90110} \pgfmath@def{atan}{673}{33.94055} +\pgfmath@def{atan}{674}{33.97997} \pgfmath@def{atan}{675}{34.01935} +\pgfmath@def{atan}{676}{34.05869} \pgfmath@def{atan}{677}{34.09800} +\pgfmath@def{atan}{678}{34.13727} \pgfmath@def{atan}{679}{34.17650} +\pgfmath@def{atan}{680}{34.21570} \pgfmath@def{atan}{681}{34.25486} +\pgfmath@def{atan}{682}{34.29398} \pgfmath@def{atan}{683}{34.33307} +\pgfmath@def{atan}{684}{34.37212} \pgfmath@def{atan}{685}{34.41114} +\pgfmath@def{atan}{686}{34.45012} \pgfmath@def{atan}{687}{34.48906} +\pgfmath@def{atan}{688}{34.52797} \pgfmath@def{atan}{689}{34.56684} +\pgfmath@def{atan}{690}{34.60567} \pgfmath@def{atan}{691}{34.64447} +\pgfmath@def{atan}{692}{34.68323} \pgfmath@def{atan}{693}{34.72195} +\pgfmath@def{atan}{694}{34.76064} \pgfmath@def{atan}{695}{34.79930} +\pgfmath@def{atan}{696}{34.83791} \pgfmath@def{atan}{697}{34.87649} +\pgfmath@def{atan}{698}{34.91504} \pgfmath@def{atan}{699}{34.95354} +\pgfmath@def{atan}{700}{34.99202} \pgfmath@def{atan}{701}{35.03045} +\pgfmath@def{atan}{702}{35.06885} \pgfmath@def{atan}{703}{35.10721} +\pgfmath@def{atan}{704}{35.14554} \pgfmath@def{atan}{705}{35.18383} +\pgfmath@def{atan}{706}{35.22209} \pgfmath@def{atan}{707}{35.26031} +\pgfmath@def{atan}{708}{35.29849} \pgfmath@def{atan}{709}{35.33664} +\pgfmath@def{atan}{710}{35.37475} \pgfmath@def{atan}{711}{35.41282} +\pgfmath@def{atan}{712}{35.45086} \pgfmath@def{atan}{713}{35.48886} +\pgfmath@def{atan}{714}{35.52683} \pgfmath@def{atan}{715}{35.56476} +\pgfmath@def{atan}{716}{35.60266} \pgfmath@def{atan}{717}{35.64052} +\pgfmath@def{atan}{718}{35.67834} \pgfmath@def{atan}{719}{35.71613} +\pgfmath@def{atan}{720}{35.75388} \pgfmath@def{atan}{721}{35.79160} +\pgfmath@def{atan}{722}{35.82928} \pgfmath@def{atan}{723}{35.86692} +\pgfmath@def{atan}{724}{35.90453} \pgfmath@def{atan}{725}{35.94211} +\pgfmath@def{atan}{726}{35.97965} \pgfmath@def{atan}{727}{36.01715} +\pgfmath@def{atan}{728}{36.05461} \pgfmath@def{atan}{729}{36.09204} +\pgfmath@def{atan}{730}{36.12944} \pgfmath@def{atan}{731}{36.16680} +\pgfmath@def{atan}{732}{36.20412} \pgfmath@def{atan}{733}{36.24141} +\pgfmath@def{atan}{734}{36.27866} \pgfmath@def{atan}{735}{36.31588} +\pgfmath@def{atan}{736}{36.35306} \pgfmath@def{atan}{737}{36.39021} +\pgfmath@def{atan}{738}{36.42732} \pgfmath@def{atan}{739}{36.46440} +\pgfmath@def{atan}{740}{36.50144} \pgfmath@def{atan}{741}{36.53844} +\pgfmath@def{atan}{742}{36.57541} \pgfmath@def{atan}{743}{36.61234} +\pgfmath@def{atan}{744}{36.64924} \pgfmath@def{atan}{745}{36.68611} +\pgfmath@def{atan}{746}{36.72293} \pgfmath@def{atan}{747}{36.75973} +\pgfmath@def{atan}{748}{36.79648} \pgfmath@def{atan}{749}{36.83321} +\pgfmath@def{atan}{750}{36.86989} \pgfmath@def{atan}{751}{36.90654} +\pgfmath@def{atan}{752}{36.94316} \pgfmath@def{atan}{753}{36.97974} +\pgfmath@def{atan}{754}{37.01629} \pgfmath@def{atan}{755}{37.05280} +\pgfmath@def{atan}{756}{37.08928} \pgfmath@def{atan}{757}{37.12572} +\pgfmath@def{atan}{758}{37.16212} \pgfmath@def{atan}{759}{37.19849} +\pgfmath@def{atan}{760}{37.23483} \pgfmath@def{atan}{761}{37.27113} +\pgfmath@def{atan}{762}{37.30740} \pgfmath@def{atan}{763}{37.34363} +\pgfmath@def{atan}{764}{37.37982} \pgfmath@def{atan}{765}{37.41598} +\pgfmath@def{atan}{766}{37.45211} \pgfmath@def{atan}{767}{37.48820} +\pgfmath@def{atan}{768}{37.52426} \pgfmath@def{atan}{769}{37.56028} +\pgfmath@def{atan}{770}{37.59627} \pgfmath@def{atan}{771}{37.63222} +\pgfmath@def{atan}{772}{37.66814} \pgfmath@def{atan}{773}{37.70402} +\pgfmath@def{atan}{774}{37.73987} \pgfmath@def{atan}{775}{37.77568} +\pgfmath@def{atan}{776}{37.81146} \pgfmath@def{atan}{777}{37.84720} +\pgfmath@def{atan}{778}{37.88291} \pgfmath@def{atan}{779}{37.91859} +\pgfmath@def{atan}{780}{37.95423} \pgfmath@def{atan}{781}{37.98983} +\pgfmath@def{atan}{782}{38.02540} \pgfmath@def{atan}{783}{38.06094} +\pgfmath@def{atan}{784}{38.09644} \pgfmath@def{atan}{785}{38.13191} +\pgfmath@def{atan}{786}{38.16734} \pgfmath@def{atan}{787}{38.20274} +\pgfmath@def{atan}{788}{38.23811} \pgfmath@def{atan}{789}{38.27344} +\pgfmath@def{atan}{790}{38.30873} \pgfmath@def{atan}{791}{38.34399} +\pgfmath@def{atan}{792}{38.37922} \pgfmath@def{atan}{793}{38.41441} +\pgfmath@def{atan}{794}{38.44957} \pgfmath@def{atan}{795}{38.48469} +\pgfmath@def{atan}{796}{38.51979} \pgfmath@def{atan}{797}{38.55484} +\pgfmath@def{atan}{798}{38.58986} \pgfmath@def{atan}{799}{38.62485} +\pgfmath@def{atan}{800}{38.65980} \pgfmath@def{atan}{801}{38.69472} +\pgfmath@def{atan}{802}{38.72961} \pgfmath@def{atan}{803}{38.76446} +\pgfmath@def{atan}{804}{38.79928} \pgfmath@def{atan}{805}{38.83406} +\pgfmath@def{atan}{806}{38.86881} \pgfmath@def{atan}{807}{38.90353} +\pgfmath@def{atan}{808}{38.93821} \pgfmath@def{atan}{809}{38.97285} +\pgfmath@def{atan}{810}{39.00747} \pgfmath@def{atan}{811}{39.04205} +\pgfmath@def{atan}{812}{39.07659} \pgfmath@def{atan}{813}{39.11111} +\pgfmath@def{atan}{814}{39.14558} \pgfmath@def{atan}{815}{39.18003} +\pgfmath@def{atan}{816}{39.21444} \pgfmath@def{atan}{817}{39.24882} +\pgfmath@def{atan}{818}{39.28316} \pgfmath@def{atan}{819}{39.31747} +\pgfmath@def{atan}{820}{39.35175} \pgfmath@def{atan}{821}{39.38599} +\pgfmath@def{atan}{822}{39.42020} \pgfmath@def{atan}{823}{39.45438} +\pgfmath@def{atan}{824}{39.48852} \pgfmath@def{atan}{825}{39.52263} +\pgfmath@def{atan}{826}{39.55670} \pgfmath@def{atan}{827}{39.59074} +\pgfmath@def{atan}{828}{39.62475} \pgfmath@def{atan}{829}{39.65873} +\pgfmath@def{atan}{830}{39.69267} \pgfmath@def{atan}{831}{39.72658} +\pgfmath@def{atan}{832}{39.76045} \pgfmath@def{atan}{833}{39.79429} +\pgfmath@def{atan}{834}{39.82810} \pgfmath@def{atan}{835}{39.86188} +\pgfmath@def{atan}{836}{39.89562} \pgfmath@def{atan}{837}{39.92933} +\pgfmath@def{atan}{838}{39.96300} \pgfmath@def{atan}{839}{39.99665} +\pgfmath@def{atan}{840}{40.03025} \pgfmath@def{atan}{841}{40.06383} +\pgfmath@def{atan}{842}{40.09737} \pgfmath@def{atan}{843}{40.13088} +\pgfmath@def{atan}{844}{40.16436} \pgfmath@def{atan}{845}{40.19781} +\pgfmath@def{atan}{846}{40.23122} \pgfmath@def{atan}{847}{40.26459} +\pgfmath@def{atan}{848}{40.29794} \pgfmath@def{atan}{849}{40.33125} +\pgfmath@def{atan}{850}{40.36453} \pgfmath@def{atan}{851}{40.39778} +\pgfmath@def{atan}{852}{40.43099} \pgfmath@def{atan}{853}{40.46417} +\pgfmath@def{atan}{854}{40.49732} \pgfmath@def{atan}{855}{40.53044} +\pgfmath@def{atan}{856}{40.56352} \pgfmath@def{atan}{857}{40.59657} +\pgfmath@def{atan}{858}{40.62959} \pgfmath@def{atan}{859}{40.66257} +\pgfmath@def{atan}{860}{40.69553} \pgfmath@def{atan}{861}{40.72845} +\pgfmath@def{atan}{862}{40.76133} \pgfmath@def{atan}{863}{40.79419} +\pgfmath@def{atan}{864}{40.82701} \pgfmath@def{atan}{865}{40.85980} +\pgfmath@def{atan}{866}{40.89256} \pgfmath@def{atan}{867}{40.92528} +\pgfmath@def{atan}{868}{40.95798} \pgfmath@def{atan}{869}{40.99064} +\pgfmath@def{atan}{870}{41.02326} \pgfmath@def{atan}{871}{41.05586} +\pgfmath@def{atan}{872}{41.08842} \pgfmath@def{atan}{873}{41.12095} +\pgfmath@def{atan}{874}{41.15345} \pgfmath@def{atan}{875}{41.18592} +\pgfmath@def{atan}{876}{41.21836} \pgfmath@def{atan}{877}{41.25076} +\pgfmath@def{atan}{878}{41.28313} \pgfmath@def{atan}{879}{41.31547} +\pgfmath@def{atan}{880}{41.34777} \pgfmath@def{atan}{881}{41.38005} +\pgfmath@def{atan}{882}{41.41229} \pgfmath@def{atan}{883}{41.44450} +\pgfmath@def{atan}{884}{41.47668} \pgfmath@def{atan}{885}{41.50882} +\pgfmath@def{atan}{886}{41.54094} \pgfmath@def{atan}{887}{41.57302} +\pgfmath@def{atan}{888}{41.60507} \pgfmath@def{atan}{889}{41.63709} +\pgfmath@def{atan}{890}{41.66908} \pgfmath@def{atan}{891}{41.70103} +\pgfmath@def{atan}{892}{41.73296} \pgfmath@def{atan}{893}{41.76485} +\pgfmath@def{atan}{894}{41.79671} \pgfmath@def{atan}{895}{41.82854} +\pgfmath@def{atan}{896}{41.86034} \pgfmath@def{atan}{897}{41.89210} +\pgfmath@def{atan}{898}{41.92383} \pgfmath@def{atan}{899}{41.95554} +\pgfmath@def{atan}{900}{41.98721} \pgfmath@def{atan}{901}{42.01885} +\pgfmath@def{atan}{902}{42.05046} \pgfmath@def{atan}{903}{42.08203} +\pgfmath@def{atan}{904}{42.11358} \pgfmath@def{atan}{905}{42.14509} +\pgfmath@def{atan}{906}{42.17657} \pgfmath@def{atan}{907}{42.20802} +\pgfmath@def{atan}{908}{42.23944} \pgfmath@def{atan}{909}{42.27083} +\pgfmath@def{atan}{910}{42.30219} \pgfmath@def{atan}{911}{42.33352} +\pgfmath@def{atan}{912}{42.36481} \pgfmath@def{atan}{913}{42.39607} +\pgfmath@def{atan}{914}{42.42731} \pgfmath@def{atan}{915}{42.45851} +\pgfmath@def{atan}{916}{42.48968} \pgfmath@def{atan}{917}{42.52082} +\pgfmath@def{atan}{918}{42.55193} \pgfmath@def{atan}{919}{42.58300} +\pgfmath@def{atan}{920}{42.61405} \pgfmath@def{atan}{921}{42.64507} +\pgfmath@def{atan}{922}{42.67605} \pgfmath@def{atan}{923}{42.70701} +\pgfmath@def{atan}{924}{42.73793} \pgfmath@def{atan}{925}{42.76882} +\pgfmath@def{atan}{926}{42.79968} \pgfmath@def{atan}{927}{42.83051} +\pgfmath@def{atan}{928}{42.86131} \pgfmath@def{atan}{929}{42.89208} +\pgfmath@def{atan}{930}{42.92282} \pgfmath@def{atan}{931}{42.95353} +\pgfmath@def{atan}{932}{42.98421} \pgfmath@def{atan}{933}{43.01485} +\pgfmath@def{atan}{934}{43.04547} \pgfmath@def{atan}{935}{43.07605} +\pgfmath@def{atan}{936}{43.10661} \pgfmath@def{atan}{937}{43.13713} +\pgfmath@def{atan}{938}{43.16763} \pgfmath@def{atan}{939}{43.19809} +\pgfmath@def{atan}{940}{43.22853} \pgfmath@def{atan}{941}{43.25893} +\pgfmath@def{atan}{942}{43.28930} \pgfmath@def{atan}{943}{43.31964} +\pgfmath@def{atan}{944}{43.34996} \pgfmath@def{atan}{945}{43.38024} +\pgfmath@def{atan}{946}{43.41049} \pgfmath@def{atan}{947}{43.44071} +\pgfmath@def{atan}{948}{43.47090} \pgfmath@def{atan}{949}{43.50106} +\pgfmath@def{atan}{950}{43.53119} \pgfmath@def{atan}{951}{43.56130} +\pgfmath@def{atan}{952}{43.59137} \pgfmath@def{atan}{953}{43.62141} +\pgfmath@def{atan}{954}{43.65142} \pgfmath@def{atan}{955}{43.68140} +\pgfmath@def{atan}{956}{43.71135} \pgfmath@def{atan}{957}{43.74127} +\pgfmath@def{atan}{958}{43.77116} \pgfmath@def{atan}{959}{43.80102} +\pgfmath@def{atan}{960}{43.83086} \pgfmath@def{atan}{961}{43.86066} +\pgfmath@def{atan}{962}{43.89043} \pgfmath@def{atan}{963}{43.92017} +\pgfmath@def{atan}{964}{43.94988} \pgfmath@def{atan}{965}{43.97957} +\pgfmath@def{atan}{966}{44.00922} \pgfmath@def{atan}{967}{44.03884} +\pgfmath@def{atan}{968}{44.06844} \pgfmath@def{atan}{969}{44.09800} +\pgfmath@def{atan}{970}{44.12754} \pgfmath@def{atan}{971}{44.15704} +\pgfmath@def{atan}{972}{44.18652} \pgfmath@def{atan}{973}{44.21597} +\pgfmath@def{atan}{974}{44.24538} \pgfmath@def{atan}{975}{44.27477} +\pgfmath@def{atan}{976}{44.30413} \pgfmath@def{atan}{977}{44.33346} +\pgfmath@def{atan}{978}{44.36276} \pgfmath@def{atan}{979}{44.39203} +\pgfmath@def{atan}{980}{44.42127} \pgfmath@def{atan}{981}{44.45048} +\pgfmath@def{atan}{982}{44.47966} \pgfmath@def{atan}{983}{44.50882} +\pgfmath@def{atan}{984}{44.53794} \pgfmath@def{atan}{985}{44.56704} +\pgfmath@def{atan}{986}{44.59610} \pgfmath@def{atan}{987}{44.62514} +\pgfmath@def{atan}{988}{44.65415} \pgfmath@def{atan}{989}{44.68313} +\pgfmath@def{atan}{990}{44.71208} \pgfmath@def{atan}{991}{44.74100} +\pgfmath@def{atan}{992}{44.76989} \pgfmath@def{atan}{993}{44.79876} +\pgfmath@def{atan}{994}{44.82759} \pgfmath@def{atan}{995}{44.85640} +\pgfmath@def{atan}{996}{44.88517} \pgfmath@def{atan}{997}{44.91392} +\pgfmath@def{atan}{998}{44.94264} \pgfmath@def{atan}{999}{44.97133} +\pgfmath@def{atan}{1000}{45.00000} + +\pgfmath@def{acos}{0}{90.00000} \pgfmath@def{acos}{1}{89.94270} +\pgfmath@def{acos}{2}{89.88540} \pgfmath@def{acos}{3}{89.82811} +\pgfmath@def{acos}{4}{89.77081} \pgfmath@def{acos}{5}{89.71352} +\pgfmath@def{acos}{6}{89.65622} \pgfmath@def{acos}{7}{89.59892} +\pgfmath@def{acos}{8}{89.54162} \pgfmath@def{acos}{9}{89.48433} +\pgfmath@def{acos}{10}{89.42703} \pgfmath@def{acos}{11}{89.36973} +\pgfmath@def{acos}{12}{89.31243} \pgfmath@def{acos}{13}{89.25513} +\pgfmath@def{acos}{14}{89.19783} \pgfmath@def{acos}{15}{89.14053} +\pgfmath@def{acos}{16}{89.08322} \pgfmath@def{acos}{17}{89.02592} +\pgfmath@def{acos}{18}{88.96862} \pgfmath@def{acos}{19}{88.91131} +\pgfmath@def{acos}{20}{88.85400} \pgfmath@def{acos}{21}{88.79670} +\pgfmath@def{acos}{22}{88.73939} \pgfmath@def{acos}{23}{88.68208} +\pgfmath@def{acos}{24}{88.62476} \pgfmath@def{acos}{25}{88.56745} +\pgfmath@def{acos}{26}{88.51014} \pgfmath@def{acos}{27}{88.45282} +\pgfmath@def{acos}{28}{88.39550} \pgfmath@def{acos}{29}{88.33818} +\pgfmath@def{acos}{30}{88.28086} \pgfmath@def{acos}{31}{88.22354} +\pgfmath@def{acos}{32}{88.16622} \pgfmath@def{acos}{33}{88.10889} +\pgfmath@def{acos}{34}{88.05156} \pgfmath@def{acos}{35}{87.99423} +\pgfmath@def{acos}{36}{87.93690} \pgfmath@def{acos}{37}{87.87957} +\pgfmath@def{acos}{38}{87.82223} \pgfmath@def{acos}{39}{87.76489} +\pgfmath@def{acos}{40}{87.70755} \pgfmath@def{acos}{41}{87.65021} +\pgfmath@def{acos}{42}{87.59286} \pgfmath@def{acos}{43}{87.53552} +\pgfmath@def{acos}{44}{87.47817} \pgfmath@def{acos}{45}{87.42081} +\pgfmath@def{acos}{46}{87.36346} \pgfmath@def{acos}{47}{87.30610} +\pgfmath@def{acos}{48}{87.24874} \pgfmath@def{acos}{49}{87.19138} +\pgfmath@def{acos}{50}{87.13401} \pgfmath@def{acos}{51}{87.07664} +\pgfmath@def{acos}{52}{87.01927} \pgfmath@def{acos}{53}{86.96190} +\pgfmath@def{acos}{54}{86.90452} \pgfmath@def{acos}{55}{86.84714} +\pgfmath@def{acos}{56}{86.78975} \pgfmath@def{acos}{57}{86.73237} +\pgfmath@def{acos}{58}{86.67497} \pgfmath@def{acos}{59}{86.61758} +\pgfmath@def{acos}{60}{86.56018} \pgfmath@def{acos}{61}{86.50278} +\pgfmath@def{acos}{62}{86.44538} \pgfmath@def{acos}{63}{86.38797} +\pgfmath@def{acos}{64}{86.33056} \pgfmath@def{acos}{65}{86.27314} +\pgfmath@def{acos}{66}{86.21572} \pgfmath@def{acos}{67}{86.15830} +\pgfmath@def{acos}{68}{86.10087} \pgfmath@def{acos}{69}{86.04344} +\pgfmath@def{acos}{70}{85.98601} \pgfmath@def{acos}{71}{85.92857} +\pgfmath@def{acos}{72}{85.87113} \pgfmath@def{acos}{73}{85.81368} +\pgfmath@def{acos}{74}{85.75623} \pgfmath@def{acos}{75}{85.69877} +\pgfmath@def{acos}{76}{85.64131} \pgfmath@def{acos}{77}{85.58385} +\pgfmath@def{acos}{78}{85.52638} \pgfmath@def{acos}{79}{85.46891} +\pgfmath@def{acos}{80}{85.41143} \pgfmath@def{acos}{81}{85.35395} +\pgfmath@def{acos}{82}{85.29646} \pgfmath@def{acos}{83}{85.23897} +\pgfmath@def{acos}{84}{85.18147} \pgfmath@def{acos}{85}{85.12397} +\pgfmath@def{acos}{86}{85.06646} \pgfmath@def{acos}{87}{85.00895} +\pgfmath@def{acos}{88}{84.95144} \pgfmath@def{acos}{89}{84.89392} +\pgfmath@def{acos}{90}{84.83639} \pgfmath@def{acos}{91}{84.77886} +\pgfmath@def{acos}{92}{84.72132} \pgfmath@def{acos}{93}{84.66378} +\pgfmath@def{acos}{94}{84.60623} \pgfmath@def{acos}{95}{84.54868} +\pgfmath@def{acos}{96}{84.49112} \pgfmath@def{acos}{97}{84.43355} +\pgfmath@def{acos}{98}{84.37598} \pgfmath@def{acos}{99}{84.31841} +\pgfmath@def{acos}{100}{84.26083} \pgfmath@def{acos}{101}{84.20324} +\pgfmath@def{acos}{102}{84.14564} \pgfmath@def{acos}{103}{84.08805} +\pgfmath@def{acos}{104}{84.03044} \pgfmath@def{acos}{105}{83.97283} +\pgfmath@def{acos}{106}{83.91521} \pgfmath@def{acos}{107}{83.85759} +\pgfmath@def{acos}{108}{83.79996} \pgfmath@def{acos}{109}{83.74232} +\pgfmath@def{acos}{110}{83.68468} \pgfmath@def{acos}{111}{83.62703} +\pgfmath@def{acos}{112}{83.56938} \pgfmath@def{acos}{113}{83.51171} +\pgfmath@def{acos}{114}{83.45405} \pgfmath@def{acos}{115}{83.39637} +\pgfmath@def{acos}{116}{83.33869} \pgfmath@def{acos}{117}{83.28100} +\pgfmath@def{acos}{118}{83.22330} \pgfmath@def{acos}{119}{83.16560} +\pgfmath@def{acos}{120}{83.10789} \pgfmath@def{acos}{121}{83.05018} +\pgfmath@def{acos}{122}{82.99245} \pgfmath@def{acos}{123}{82.93472} +\pgfmath@def{acos}{124}{82.87698} \pgfmath@def{acos}{125}{82.81924} +\pgfmath@def{acos}{126}{82.76149} \pgfmath@def{acos}{127}{82.70373} +\pgfmath@def{acos}{128}{82.64596} \pgfmath@def{acos}{129}{82.58819} +\pgfmath@def{acos}{130}{82.53040} \pgfmath@def{acos}{131}{82.47261} +\pgfmath@def{acos}{132}{82.41482} \pgfmath@def{acos}{133}{82.35701} +\pgfmath@def{acos}{134}{82.29920} \pgfmath@def{acos}{135}{82.24138} +\pgfmath@def{acos}{136}{82.18355} \pgfmath@def{acos}{137}{82.12571} +\pgfmath@def{acos}{138}{82.06786} \pgfmath@def{acos}{139}{82.01001} +\pgfmath@def{acos}{140}{81.95215} \pgfmath@def{acos}{141}{81.89428} +\pgfmath@def{acos}{142}{81.83640} \pgfmath@def{acos}{143}{81.77851} +\pgfmath@def{acos}{144}{81.72062} \pgfmath@def{acos}{145}{81.66272} +\pgfmath@def{acos}{146}{81.60480} \pgfmath@def{acos}{147}{81.54688} +\pgfmath@def{acos}{148}{81.48895} \pgfmath@def{acos}{149}{81.43102} +\pgfmath@def{acos}{150}{81.37307} \pgfmath@def{acos}{151}{81.31511} +\pgfmath@def{acos}{152}{81.25715} \pgfmath@def{acos}{153}{81.19917} +\pgfmath@def{acos}{154}{81.14119} \pgfmath@def{acos}{155}{81.08320} +\pgfmath@def{acos}{156}{81.02520} \pgfmath@def{acos}{157}{80.96719} +\pgfmath@def{acos}{158}{80.90917} \pgfmath@def{acos}{159}{80.85114} +\pgfmath@def{acos}{160}{80.79310} \pgfmath@def{acos}{161}{80.73505} +\pgfmath@def{acos}{162}{80.67699} \pgfmath@def{acos}{163}{80.61893} +\pgfmath@def{acos}{164}{80.56085} \pgfmath@def{acos}{165}{80.50276} +\pgfmath@def{acos}{166}{80.44466} \pgfmath@def{acos}{167}{80.38656} +\pgfmath@def{acos}{168}{80.32844} \pgfmath@def{acos}{169}{80.27031} +\pgfmath@def{acos}{170}{80.21218} \pgfmath@def{acos}{171}{80.15403} +\pgfmath@def{acos}{172}{80.09587} \pgfmath@def{acos}{173}{80.03770} +\pgfmath@def{acos}{174}{79.97953} \pgfmath@def{acos}{175}{79.92134} +\pgfmath@def{acos}{176}{79.86314} \pgfmath@def{acos}{177}{79.80493} +\pgfmath@def{acos}{178}{79.74671} \pgfmath@def{acos}{179}{79.68848} +\pgfmath@def{acos}{180}{79.63024} \pgfmath@def{acos}{181}{79.57198} +\pgfmath@def{acos}{182}{79.51372} \pgfmath@def{acos}{183}{79.45545} +\pgfmath@def{acos}{184}{79.39716} \pgfmath@def{acos}{185}{79.33886} +\pgfmath@def{acos}{186}{79.28056} \pgfmath@def{acos}{187}{79.22224} +\pgfmath@def{acos}{188}{79.16391} \pgfmath@def{acos}{189}{79.10556} +\pgfmath@def{acos}{190}{79.04721} \pgfmath@def{acos}{191}{78.98885} +\pgfmath@def{acos}{192}{78.93047} \pgfmath@def{acos}{193}{78.87208} +\pgfmath@def{acos}{194}{78.81368} \pgfmath@def{acos}{195}{78.75527} +\pgfmath@def{acos}{196}{78.69685} \pgfmath@def{acos}{197}{78.63841} +\pgfmath@def{acos}{198}{78.57997} \pgfmath@def{acos}{199}{78.52151} +\pgfmath@def{acos}{200}{78.46304} \pgfmath@def{acos}{201}{78.40455} +\pgfmath@def{acos}{202}{78.34606} \pgfmath@def{acos}{203}{78.28755} +\pgfmath@def{acos}{204}{78.22903} \pgfmath@def{acos}{205}{78.17050} +\pgfmath@def{acos}{206}{78.11195} \pgfmath@def{acos}{207}{78.05339} +\pgfmath@def{acos}{208}{77.99482} \pgfmath@def{acos}{209}{77.93624} +\pgfmath@def{acos}{210}{77.87764} \pgfmath@def{acos}{211}{77.81903} +\pgfmath@def{acos}{212}{77.76041} \pgfmath@def{acos}{213}{77.70178} +\pgfmath@def{acos}{214}{77.64313} \pgfmath@def{acos}{215}{77.58447} +\pgfmath@def{acos}{216}{77.52579} \pgfmath@def{acos}{217}{77.46711} +\pgfmath@def{acos}{218}{77.40841} \pgfmath@def{acos}{219}{77.34969} +\pgfmath@def{acos}{220}{77.29096} \pgfmath@def{acos}{221}{77.23222} +\pgfmath@def{acos}{222}{77.17347} \pgfmath@def{acos}{223}{77.11470} +\pgfmath@def{acos}{224}{77.05591} \pgfmath@def{acos}{225}{76.99712} +\pgfmath@def{acos}{226}{76.93831} \pgfmath@def{acos}{227}{76.87948} +\pgfmath@def{acos}{228}{76.82064} \pgfmath@def{acos}{229}{76.76179} +\pgfmath@def{acos}{230}{76.70292} \pgfmath@def{acos}{231}{76.64404} +\pgfmath@def{acos}{232}{76.58515} \pgfmath@def{acos}{233}{76.52624} +\pgfmath@def{acos}{234}{76.46731} \pgfmath@def{acos}{235}{76.40837} +\pgfmath@def{acos}{236}{76.34942} \pgfmath@def{acos}{237}{76.29045} +\pgfmath@def{acos}{238}{76.23147} \pgfmath@def{acos}{239}{76.17247} +\pgfmath@def{acos}{240}{76.11346} \pgfmath@def{acos}{241}{76.05443} +\pgfmath@def{acos}{242}{75.99538} \pgfmath@def{acos}{243}{75.93632} +\pgfmath@def{acos}{244}{75.87725} \pgfmath@def{acos}{245}{75.81816} +\pgfmath@def{acos}{246}{75.75906} \pgfmath@def{acos}{247}{75.69994} +\pgfmath@def{acos}{248}{75.64080} \pgfmath@def{acos}{249}{75.58165} +\pgfmath@def{acos}{250}{75.52248} \pgfmath@def{acos}{251}{75.46330} +\pgfmath@def{acos}{252}{75.40410} \pgfmath@def{acos}{253}{75.34489} +\pgfmath@def{acos}{254}{75.28566} \pgfmath@def{acos}{255}{75.22641} +\pgfmath@def{acos}{256}{75.16715} \pgfmath@def{acos}{257}{75.10787} +\pgfmath@def{acos}{258}{75.04857} \pgfmath@def{acos}{259}{74.98926} +\pgfmath@def{acos}{260}{74.92993} \pgfmath@def{acos}{261}{74.87059} +\pgfmath@def{acos}{262}{74.81123} \pgfmath@def{acos}{263}{74.75185} +\pgfmath@def{acos}{264}{74.69245} \pgfmath@def{acos}{265}{74.63304} +\pgfmath@def{acos}{266}{74.57361} \pgfmath@def{acos}{267}{74.51417} +\pgfmath@def{acos}{268}{74.45471} \pgfmath@def{acos}{269}{74.39523} +\pgfmath@def{acos}{270}{74.33573} \pgfmath@def{acos}{271}{74.27621} +\pgfmath@def{acos}{272}{74.21668} \pgfmath@def{acos}{273}{74.15713} +\pgfmath@def{acos}{274}{74.09757} \pgfmath@def{acos}{275}{74.03798} +\pgfmath@def{acos}{276}{73.97838} \pgfmath@def{acos}{277}{73.91876} +\pgfmath@def{acos}{278}{73.85912} \pgfmath@def{acos}{279}{73.79946} +\pgfmath@def{acos}{280}{73.73979} \pgfmath@def{acos}{281}{73.68010} +\pgfmath@def{acos}{282}{73.62039} \pgfmath@def{acos}{283}{73.56066} +\pgfmath@def{acos}{284}{73.50091} \pgfmath@def{acos}{285}{73.44115} +\pgfmath@def{acos}{286}{73.38136} \pgfmath@def{acos}{287}{73.32156} +\pgfmath@def{acos}{288}{73.26174} \pgfmath@def{acos}{289}{73.20190} +\pgfmath@def{acos}{290}{73.14204} \pgfmath@def{acos}{291}{73.08216} +\pgfmath@def{acos}{292}{73.02226} \pgfmath@def{acos}{293}{72.96235} +\pgfmath@def{acos}{294}{72.90241} \pgfmath@def{acos}{295}{72.84246} +\pgfmath@def{acos}{296}{72.78248} \pgfmath@def{acos}{297}{72.72249} +\pgfmath@def{acos}{298}{72.66248} \pgfmath@def{acos}{299}{72.60244} +\pgfmath@def{acos}{300}{72.54239} \pgfmath@def{acos}{301}{72.48232} +\pgfmath@def{acos}{302}{72.42223} \pgfmath@def{acos}{303}{72.36212} +\pgfmath@def{acos}{304}{72.30198} \pgfmath@def{acos}{305}{72.24183} +\pgfmath@def{acos}{306}{72.18166} \pgfmath@def{acos}{307}{72.12147} +\pgfmath@def{acos}{308}{72.06125} \pgfmath@def{acos}{309}{72.00102} +\pgfmath@def{acos}{310}{71.94077} \pgfmath@def{acos}{311}{71.88049} +\pgfmath@def{acos}{312}{71.82019} \pgfmath@def{acos}{313}{71.75988} +\pgfmath@def{acos}{314}{71.69954} \pgfmath@def{acos}{315}{71.63918} +\pgfmath@def{acos}{316}{71.57880} \pgfmath@def{acos}{317}{71.51840} +\pgfmath@def{acos}{318}{71.45798} \pgfmath@def{acos}{319}{71.39754} +\pgfmath@def{acos}{320}{71.33707} \pgfmath@def{acos}{321}{71.27658} +\pgfmath@def{acos}{322}{71.21608} \pgfmath@def{acos}{323}{71.15555} +\pgfmath@def{acos}{324}{71.09499} \pgfmath@def{acos}{325}{71.03442} +\pgfmath@def{acos}{326}{70.97382} \pgfmath@def{acos}{327}{70.91321} +\pgfmath@def{acos}{328}{70.85257} \pgfmath@def{acos}{329}{70.79190} +\pgfmath@def{acos}{330}{70.73122} \pgfmath@def{acos}{331}{70.67051} +\pgfmath@def{acos}{332}{70.60978} \pgfmath@def{acos}{333}{70.54903} +\pgfmath@def{acos}{334}{70.48826} \pgfmath@def{acos}{335}{70.42746} +\pgfmath@def{acos}{336}{70.36664} \pgfmath@def{acos}{337}{70.30579} +\pgfmath@def{acos}{338}{70.24493} \pgfmath@def{acos}{339}{70.18404} +\pgfmath@def{acos}{340}{70.12312} \pgfmath@def{acos}{341}{70.06218} +\pgfmath@def{acos}{342}{70.00122} \pgfmath@def{acos}{343}{69.94024} +\pgfmath@def{acos}{344}{69.87923} \pgfmath@def{acos}{345}{69.81820} +\pgfmath@def{acos}{346}{69.75714} \pgfmath@def{acos}{347}{69.69606} +\pgfmath@def{acos}{348}{69.63496} \pgfmath@def{acos}{349}{69.57383} +\pgfmath@def{acos}{350}{69.51268} \pgfmath@def{acos}{351}{69.45150} +\pgfmath@def{acos}{352}{69.39030} \pgfmath@def{acos}{353}{69.32908} +\pgfmath@def{acos}{354}{69.26783} \pgfmath@def{acos}{355}{69.20655} +\pgfmath@def{acos}{356}{69.14525} \pgfmath@def{acos}{357}{69.08393} +\pgfmath@def{acos}{358}{69.02258} \pgfmath@def{acos}{359}{68.96120} +\pgfmath@def{acos}{360}{68.89980} \pgfmath@def{acos}{361}{68.83837} +\pgfmath@def{acos}{362}{68.77692} \pgfmath@def{acos}{363}{68.71544} +\pgfmath@def{acos}{364}{68.65394} \pgfmath@def{acos}{365}{68.59241} +\pgfmath@def{acos}{366}{68.53086} \pgfmath@def{acos}{367}{68.46928} +\pgfmath@def{acos}{368}{68.40767} \pgfmath@def{acos}{369}{68.34604} +\pgfmath@def{acos}{370}{68.28438} \pgfmath@def{acos}{371}{68.22269} +\pgfmath@def{acos}{372}{68.16098} \pgfmath@def{acos}{373}{68.09924} +\pgfmath@def{acos}{374}{68.03748} \pgfmath@def{acos}{375}{67.97568} +\pgfmath@def{acos}{376}{67.91386} \pgfmath@def{acos}{377}{67.85202} +\pgfmath@def{acos}{378}{67.79014} \pgfmath@def{acos}{379}{67.72824} +\pgfmath@def{acos}{380}{67.66631} \pgfmath@def{acos}{381}{67.60436} +\pgfmath@def{acos}{382}{67.54237} \pgfmath@def{acos}{383}{67.48036} +\pgfmath@def{acos}{384}{67.41832} \pgfmath@def{acos}{385}{67.35626} +\pgfmath@def{acos}{386}{67.29416} \pgfmath@def{acos}{387}{67.23204} +\pgfmath@def{acos}{388}{67.16988} \pgfmath@def{acos}{389}{67.10770} +\pgfmath@def{acos}{390}{67.04550} \pgfmath@def{acos}{391}{66.98326} +\pgfmath@def{acos}{392}{66.92099} \pgfmath@def{acos}{393}{66.85870} +\pgfmath@def{acos}{394}{66.79637} \pgfmath@def{acos}{395}{66.73402} +\pgfmath@def{acos}{396}{66.67164} \pgfmath@def{acos}{397}{66.60923} +\pgfmath@def{acos}{398}{66.54679} \pgfmath@def{acos}{399}{66.48432} +\pgfmath@def{acos}{400}{66.42182} \pgfmath@def{acos}{401}{66.35929} +\pgfmath@def{acos}{402}{66.29673} \pgfmath@def{acos}{403}{66.23414} +\pgfmath@def{acos}{404}{66.17152} \pgfmath@def{acos}{405}{66.10887} +\pgfmath@def{acos}{406}{66.04619} \pgfmath@def{acos}{407}{65.98348} +\pgfmath@def{acos}{408}{65.92074} \pgfmath@def{acos}{409}{65.85796} +\pgfmath@def{acos}{410}{65.79516} \pgfmath@def{acos}{411}{65.73233} +\pgfmath@def{acos}{412}{65.66946} \pgfmath@def{acos}{413}{65.60657} +\pgfmath@def{acos}{414}{65.54364} \pgfmath@def{acos}{415}{65.48068} +\pgfmath@def{acos}{416}{65.41769} \pgfmath@def{acos}{417}{65.35467} +\pgfmath@def{acos}{418}{65.29161} \pgfmath@def{acos}{419}{65.22853} +\pgfmath@def{acos}{420}{65.16541} \pgfmath@def{acos}{421}{65.10226} +\pgfmath@def{acos}{422}{65.03908} \pgfmath@def{acos}{423}{64.97586} +\pgfmath@def{acos}{424}{64.91261} \pgfmath@def{acos}{425}{64.84933} +\pgfmath@def{acos}{426}{64.78602} \pgfmath@def{acos}{427}{64.72267} +\pgfmath@def{acos}{428}{64.65929} \pgfmath@def{acos}{429}{64.59588} +\pgfmath@def{acos}{430}{64.53244} \pgfmath@def{acos}{431}{64.46896} +\pgfmath@def{acos}{432}{64.40544} \pgfmath@def{acos}{433}{64.34190} +\pgfmath@def{acos}{434}{64.27832} \pgfmath@def{acos}{435}{64.21470} +\pgfmath@def{acos}{436}{64.15105} \pgfmath@def{acos}{437}{64.08737} +\pgfmath@def{acos}{438}{64.02365} \pgfmath@def{acos}{439}{63.95990} +\pgfmath@def{acos}{440}{63.89611} \pgfmath@def{acos}{441}{63.83229} +\pgfmath@def{acos}{442}{63.76844} \pgfmath@def{acos}{443}{63.70455} +\pgfmath@def{acos}{444}{63.64062} \pgfmath@def{acos}{445}{63.57666} +\pgfmath@def{acos}{446}{63.51266} \pgfmath@def{acos}{447}{63.44863} +\pgfmath@def{acos}{448}{63.38456} \pgfmath@def{acos}{449}{63.32045} +\pgfmath@def{acos}{450}{63.25631} \pgfmath@def{acos}{451}{63.19213} +\pgfmath@def{acos}{452}{63.12792} \pgfmath@def{acos}{453}{63.06367} +\pgfmath@def{acos}{454}{62.99938} \pgfmath@def{acos}{455}{62.93506} +\pgfmath@def{acos}{456}{62.87070} \pgfmath@def{acos}{457}{62.80630} +\pgfmath@def{acos}{458}{62.74187} \pgfmath@def{acos}{459}{62.67740} +\pgfmath@def{acos}{460}{62.61289} \pgfmath@def{acos}{461}{62.54834} +\pgfmath@def{acos}{462}{62.48376} \pgfmath@def{acos}{463}{62.41913} +\pgfmath@def{acos}{464}{62.35447} \pgfmath@def{acos}{465}{62.28977} +\pgfmath@def{acos}{466}{62.22504} \pgfmath@def{acos}{467}{62.16026} +\pgfmath@def{acos}{468}{62.09545} \pgfmath@def{acos}{469}{62.03059} +\pgfmath@def{acos}{470}{61.96570} \pgfmath@def{acos}{471}{61.90077} +\pgfmath@def{acos}{472}{61.83580} \pgfmath@def{acos}{473}{61.77079} +\pgfmath@def{acos}{474}{61.70574} \pgfmath@def{acos}{475}{61.64065} +\pgfmath@def{acos}{476}{61.57552} \pgfmath@def{acos}{477}{61.51035} +\pgfmath@def{acos}{478}{61.44514} \pgfmath@def{acos}{479}{61.37988} +\pgfmath@def{acos}{480}{61.31459} \pgfmath@def{acos}{481}{61.24926} +\pgfmath@def{acos}{482}{61.18389} \pgfmath@def{acos}{483}{61.11847} +\pgfmath@def{acos}{484}{61.05302} \pgfmath@def{acos}{485}{60.98752} +\pgfmath@def{acos}{486}{60.92199} \pgfmath@def{acos}{487}{60.85641} +\pgfmath@def{acos}{488}{60.79078} \pgfmath@def{acos}{489}{60.72512} +\pgfmath@def{acos}{490}{60.65941} \pgfmath@def{acos}{491}{60.59367} +\pgfmath@def{acos}{492}{60.52787} \pgfmath@def{acos}{493}{60.46204} +\pgfmath@def{acos}{494}{60.39616} \pgfmath@def{acos}{495}{60.33025} +\pgfmath@def{acos}{496}{60.26428} \pgfmath@def{acos}{497}{60.19828} +\pgfmath@def{acos}{498}{60.13223} \pgfmath@def{acos}{499}{60.06613} +\pgfmath@def{acos}{500}{60.00000} \pgfmath@def{acos}{501}{59.93381} +\pgfmath@def{acos}{502}{59.86759} \pgfmath@def{acos}{503}{59.80132} +\pgfmath@def{acos}{504}{59.73500} \pgfmath@def{acos}{505}{59.66864} +\pgfmath@def{acos}{506}{59.60224} \pgfmath@def{acos}{507}{59.53579} +\pgfmath@def{acos}{508}{59.46929} \pgfmath@def{acos}{509}{59.40275} +\pgfmath@def{acos}{510}{59.33617} \pgfmath@def{acos}{511}{59.26953} +\pgfmath@def{acos}{512}{59.20285} \pgfmath@def{acos}{513}{59.13613} +\pgfmath@def{acos}{514}{59.06936} \pgfmath@def{acos}{515}{59.00254} +\pgfmath@def{acos}{516}{58.93568} \pgfmath@def{acos}{517}{58.86876} +\pgfmath@def{acos}{518}{58.80180} \pgfmath@def{acos}{519}{58.73480} +\pgfmath@def{acos}{520}{58.66774} \pgfmath@def{acos}{521}{58.60064} +\pgfmath@def{acos}{522}{58.53349} \pgfmath@def{acos}{523}{58.46629} +\pgfmath@def{acos}{524}{58.39905} \pgfmath@def{acos}{525}{58.33175} +\pgfmath@def{acos}{526}{58.26441} \pgfmath@def{acos}{527}{58.19702} +\pgfmath@def{acos}{528}{58.12957} \pgfmath@def{acos}{529}{58.06208} +\pgfmath@def{acos}{530}{57.99454} \pgfmath@def{acos}{531}{57.92695} +\pgfmath@def{acos}{532}{57.85931} \pgfmath@def{acos}{533}{57.79162} +\pgfmath@def{acos}{534}{57.72388} \pgfmath@def{acos}{535}{57.65608} +\pgfmath@def{acos}{536}{57.58824} \pgfmath@def{acos}{537}{57.52035} +\pgfmath@def{acos}{538}{57.45240} \pgfmath@def{acos}{539}{57.38441} +\pgfmath@def{acos}{540}{57.31636} \pgfmath@def{acos}{541}{57.24826} +\pgfmath@def{acos}{542}{57.18010} \pgfmath@def{acos}{543}{57.11190} +\pgfmath@def{acos}{544}{57.04364} \pgfmath@def{acos}{545}{56.97533} +\pgfmath@def{acos}{546}{56.90697} \pgfmath@def{acos}{547}{56.83855} +\pgfmath@def{acos}{548}{56.77008} \pgfmath@def{acos}{549}{56.70156} +\pgfmath@def{acos}{550}{56.63298} \pgfmath@def{acos}{551}{56.56435} +\pgfmath@def{acos}{552}{56.49567} \pgfmath@def{acos}{553}{56.42693} +\pgfmath@def{acos}{554}{56.35813} \pgfmath@def{acos}{555}{56.28928} +\pgfmath@def{acos}{556}{56.22038} \pgfmath@def{acos}{557}{56.15141} +\pgfmath@def{acos}{558}{56.08240} \pgfmath@def{acos}{559}{56.01333} +\pgfmath@def{acos}{560}{55.94420} \pgfmath@def{acos}{561}{55.87501} +\pgfmath@def{acos}{562}{55.80577} \pgfmath@def{acos}{563}{55.73647} +\pgfmath@def{acos}{564}{55.66712} \pgfmath@def{acos}{565}{55.59770} +\pgfmath@def{acos}{566}{55.52823} \pgfmath@def{acos}{567}{55.45871} +\pgfmath@def{acos}{568}{55.38912} \pgfmath@def{acos}{569}{55.31947} +\pgfmath@def{acos}{570}{55.24977} \pgfmath@def{acos}{571}{55.18001} +\pgfmath@def{acos}{572}{55.11019} \pgfmath@def{acos}{573}{55.04030} +\pgfmath@def{acos}{574}{54.97036} \pgfmath@def{acos}{575}{54.90036} +\pgfmath@def{acos}{576}{54.83030} \pgfmath@def{acos}{577}{54.76018} +\pgfmath@def{acos}{578}{54.69000} \pgfmath@def{acos}{579}{54.61976} +\pgfmath@def{acos}{580}{54.54945} \pgfmath@def{acos}{581}{54.47909} +\pgfmath@def{acos}{582}{54.40866} \pgfmath@def{acos}{583}{54.33817} +\pgfmath@def{acos}{584}{54.26762} \pgfmath@def{acos}{585}{54.19701} +\pgfmath@def{acos}{586}{54.12633} \pgfmath@def{acos}{587}{54.05559} +\pgfmath@def{acos}{588}{53.98479} \pgfmath@def{acos}{589}{53.91392} +\pgfmath@def{acos}{590}{53.84299} \pgfmath@def{acos}{591}{53.77199} +\pgfmath@def{acos}{592}{53.70093} \pgfmath@def{acos}{593}{53.62981} +\pgfmath@def{acos}{594}{53.55862} \pgfmath@def{acos}{595}{53.48736} +\pgfmath@def{acos}{596}{53.41604} \pgfmath@def{acos}{597}{53.34466} +\pgfmath@def{acos}{598}{53.27320} \pgfmath@def{acos}{599}{53.20168} +\pgfmath@def{acos}{600}{53.13010} \pgfmath@def{acos}{601}{53.05844} +\pgfmath@def{acos}{602}{52.98672} \pgfmath@def{acos}{603}{52.91494} +\pgfmath@def{acos}{604}{52.84308} \pgfmath@def{acos}{605}{52.77115} +\pgfmath@def{acos}{606}{52.69916} \pgfmath@def{acos}{607}{52.62710} +\pgfmath@def{acos}{608}{52.55497} \pgfmath@def{acos}{609}{52.48276} +\pgfmath@def{acos}{610}{52.41049} \pgfmath@def{acos}{611}{52.33815} +\pgfmath@def{acos}{612}{52.26574} \pgfmath@def{acos}{613}{52.19326} +\pgfmath@def{acos}{614}{52.12070} \pgfmath@def{acos}{615}{52.04808} +\pgfmath@def{acos}{616}{51.97538} \pgfmath@def{acos}{617}{51.90261} +\pgfmath@def{acos}{618}{51.82976} \pgfmath@def{acos}{619}{51.75685} +\pgfmath@def{acos}{620}{51.68386} \pgfmath@def{acos}{621}{51.61080} +\pgfmath@def{acos}{622}{51.53766} \pgfmath@def{acos}{623}{51.46445} +\pgfmath@def{acos}{624}{51.39117} \pgfmath@def{acos}{625}{51.31781} +\pgfmath@def{acos}{626}{51.24437} \pgfmath@def{acos}{627}{51.17086} +\pgfmath@def{acos}{628}{51.09728} \pgfmath@def{acos}{629}{51.02361} +\pgfmath@def{acos}{630}{50.94987} \pgfmath@def{acos}{631}{50.87606} +\pgfmath@def{acos}{632}{50.80216} \pgfmath@def{acos}{633}{50.72819} +\pgfmath@def{acos}{634}{50.65414} \pgfmath@def{acos}{635}{50.58001} +\pgfmath@def{acos}{636}{50.50580} \pgfmath@def{acos}{637}{50.43152} +\pgfmath@def{acos}{638}{50.35715} \pgfmath@def{acos}{639}{50.28270} +\pgfmath@def{acos}{640}{50.20818} \pgfmath@def{acos}{641}{50.13357} +\pgfmath@def{acos}{642}{50.05888} \pgfmath@def{acos}{643}{49.98411} +\pgfmath@def{acos}{644}{49.90926} \pgfmath@def{acos}{645}{49.83432} +\pgfmath@def{acos}{646}{49.75930} \pgfmath@def{acos}{647}{49.68420} +\pgfmath@def{acos}{648}{49.60902} \pgfmath@def{acos}{649}{49.53375} +\pgfmath@def{acos}{650}{49.45839} \pgfmath@def{acos}{651}{49.38296} +\pgfmath@def{acos}{652}{49.30743} \pgfmath@def{acos}{653}{49.23182} +\pgfmath@def{acos}{654}{49.15613} \pgfmath@def{acos}{655}{49.08035} +\pgfmath@def{acos}{656}{49.00448} \pgfmath@def{acos}{657}{48.92852} +\pgfmath@def{acos}{658}{48.85248} \pgfmath@def{acos}{659}{48.77634} +\pgfmath@def{acos}{660}{48.70012} \pgfmath@def{acos}{661}{48.62381} +\pgfmath@def{acos}{662}{48.54741} \pgfmath@def{acos}{663}{48.47092} +\pgfmath@def{acos}{664}{48.39434} \pgfmath@def{acos}{665}{48.31767} +\pgfmath@def{acos}{666}{48.24091} \pgfmath@def{acos}{667}{48.16405} +\pgfmath@def{acos}{668}{48.08710} \pgfmath@def{acos}{669}{48.01006} +\pgfmath@def{acos}{670}{47.93293} \pgfmath@def{acos}{671}{47.85570} +\pgfmath@def{acos}{672}{47.77838} \pgfmath@def{acos}{673}{47.70096} +\pgfmath@def{acos}{674}{47.62345} \pgfmath@def{acos}{675}{47.54585} +\pgfmath@def{acos}{676}{47.46814} \pgfmath@def{acos}{677}{47.39034} +\pgfmath@def{acos}{678}{47.31244} \pgfmath@def{acos}{679}{47.23445} +\pgfmath@def{acos}{680}{47.15635} \pgfmath@def{acos}{681}{47.07816} +\pgfmath@def{acos}{682}{46.99987} \pgfmath@def{acos}{683}{46.92147} +\pgfmath@def{acos}{684}{46.84298} \pgfmath@def{acos}{685}{46.76439} +\pgfmath@def{acos}{686}{46.68569} \pgfmath@def{acos}{687}{46.60690} +\pgfmath@def{acos}{688}{46.52800} \pgfmath@def{acos}{689}{46.44899} +\pgfmath@def{acos}{690}{46.36989} \pgfmath@def{acos}{691}{46.29068} +\pgfmath@def{acos}{692}{46.21136} \pgfmath@def{acos}{693}{46.13194} +\pgfmath@def{acos}{694}{46.05241} \pgfmath@def{acos}{695}{45.97278} +\pgfmath@def{acos}{696}{45.89304} \pgfmath@def{acos}{697}{45.81319} +\pgfmath@def{acos}{698}{45.73323} \pgfmath@def{acos}{699}{45.65317} +\pgfmath@def{acos}{700}{45.57299} \pgfmath@def{acos}{701}{45.49271} +\pgfmath@def{acos}{702}{45.41231} \pgfmath@def{acos}{703}{45.33180} +\pgfmath@def{acos}{704}{45.25118} \pgfmath@def{acos}{705}{45.17045} +\pgfmath@def{acos}{706}{45.08961} \pgfmath@def{acos}{707}{45.00865} +\pgfmath@def{acos}{708}{44.92757} \pgfmath@def{acos}{709}{44.84638} +\pgfmath@def{acos}{710}{44.76508} \pgfmath@def{acos}{711}{44.68366} +\pgfmath@def{acos}{712}{44.60212} \pgfmath@def{acos}{713}{44.52046} +\pgfmath@def{acos}{714}{44.43869} \pgfmath@def{acos}{715}{44.35680} +\pgfmath@def{acos}{716}{44.27478} \pgfmath@def{acos}{717}{44.19265} +\pgfmath@def{acos}{718}{44.11039} \pgfmath@def{acos}{719}{44.02802} +\pgfmath@def{acos}{720}{43.94552} \pgfmath@def{acos}{721}{43.86289} +\pgfmath@def{acos}{722}{43.78014} \pgfmath@def{acos}{723}{43.69727} +\pgfmath@def{acos}{724}{43.61427} \pgfmath@def{acos}{725}{43.53115} +\pgfmath@def{acos}{726}{43.44790} \pgfmath@def{acos}{727}{43.36452} +\pgfmath@def{acos}{728}{43.28101} \pgfmath@def{acos}{729}{43.19737} +\pgfmath@def{acos}{730}{43.11360} \pgfmath@def{acos}{731}{43.02970} +\pgfmath@def{acos}{732}{42.94567} \pgfmath@def{acos}{733}{42.86151} +\pgfmath@def{acos}{734}{42.77721} \pgfmath@def{acos}{735}{42.69278} +\pgfmath@def{acos}{736}{42.60821} \pgfmath@def{acos}{737}{42.52351} +\pgfmath@def{acos}{738}{42.43867} \pgfmath@def{acos}{739}{42.35370} +\pgfmath@def{acos}{740}{42.26858} \pgfmath@def{acos}{741}{42.18333} +\pgfmath@def{acos}{742}{42.09793} \pgfmath@def{acos}{743}{42.01240} +\pgfmath@def{acos}{744}{41.92672} \pgfmath@def{acos}{745}{41.84090} +\pgfmath@def{acos}{746}{41.75493} \pgfmath@def{acos}{747}{41.66882} +\pgfmath@def{acos}{748}{41.58257} \pgfmath@def{acos}{749}{41.49617} +\pgfmath@def{acos}{750}{41.40962} \pgfmath@def{acos}{751}{41.32292} +\pgfmath@def{acos}{752}{41.23607} \pgfmath@def{acos}{753}{41.14908} +\pgfmath@def{acos}{754}{41.06193} \pgfmath@def{acos}{755}{40.97463} +\pgfmath@def{acos}{756}{40.88717} \pgfmath@def{acos}{757}{40.79956} +\pgfmath@def{acos}{758}{40.71180} \pgfmath@def{acos}{759}{40.62388} +\pgfmath@def{acos}{760}{40.53580} \pgfmath@def{acos}{761}{40.44756} +\pgfmath@def{acos}{762}{40.35916} \pgfmath@def{acos}{763}{40.27061} +\pgfmath@def{acos}{764}{40.18189} \pgfmath@def{acos}{765}{40.09300} +\pgfmath@def{acos}{766}{40.00396} \pgfmath@def{acos}{767}{39.91474} +\pgfmath@def{acos}{768}{39.82537} \pgfmath@def{acos}{769}{39.73582} +\pgfmath@def{acos}{770}{39.64611} \pgfmath@def{acos}{771}{39.55622} +\pgfmath@def{acos}{772}{39.46617} \pgfmath@def{acos}{773}{39.37594} +\pgfmath@def{acos}{774}{39.28554} \pgfmath@def{acos}{775}{39.19496} +\pgfmath@def{acos}{776}{39.10421} \pgfmath@def{acos}{777}{39.01328} +\pgfmath@def{acos}{778}{38.92218} \pgfmath@def{acos}{779}{38.83089} +\pgfmath@def{acos}{780}{38.73942} \pgfmath@def{acos}{781}{38.64777} +\pgfmath@def{acos}{782}{38.55594} \pgfmath@def{acos}{783}{38.46392} +\pgfmath@def{acos}{784}{38.37171} \pgfmath@def{acos}{785}{38.27932} +\pgfmath@def{acos}{786}{38.18673} \pgfmath@def{acos}{787}{38.09396} +\pgfmath@def{acos}{788}{38.00100} \pgfmath@def{acos}{789}{37.90784} +\pgfmath@def{acos}{790}{37.81448} \pgfmath@def{acos}{791}{37.72093} +\pgfmath@def{acos}{792}{37.62719} \pgfmath@def{acos}{793}{37.53324} +\pgfmath@def{acos}{794}{37.43909} \pgfmath@def{acos}{795}{37.34474} +\pgfmath@def{acos}{796}{37.25019} \pgfmath@def{acos}{797}{37.15542} +\pgfmath@def{acos}{798}{37.06046} \pgfmath@def{acos}{799}{36.96528} +\pgfmath@def{acos}{800}{36.86989} \pgfmath@def{acos}{801}{36.77429} +\pgfmath@def{acos}{802}{36.67848} \pgfmath@def{acos}{803}{36.58245} +\pgfmath@def{acos}{804}{36.48621} \pgfmath@def{acos}{805}{36.38974} +\pgfmath@def{acos}{806}{36.29305} \pgfmath@def{acos}{807}{36.19615} +\pgfmath@def{acos}{808}{36.09901} \pgfmath@def{acos}{809}{36.00165} +\pgfmath@def{acos}{810}{35.90406} \pgfmath@def{acos}{811}{35.80625} +\pgfmath@def{acos}{812}{35.70820} \pgfmath@def{acos}{813}{35.60991} +\pgfmath@def{acos}{814}{35.51139} \pgfmath@def{acos}{815}{35.41263} +\pgfmath@def{acos}{816}{35.31364} \pgfmath@def{acos}{817}{35.21440} +\pgfmath@def{acos}{818}{35.11491} \pgfmath@def{acos}{819}{35.01518} +\pgfmath@def{acos}{820}{34.91520} \pgfmath@def{acos}{821}{34.81497} +\pgfmath@def{acos}{822}{34.71449} \pgfmath@def{acos}{823}{34.61375} +\pgfmath@def{acos}{824}{34.51276} \pgfmath@def{acos}{825}{34.41150} +\pgfmath@def{acos}{826}{34.30999} \pgfmath@def{acos}{827}{34.20821} +\pgfmath@def{acos}{828}{34.10616} \pgfmath@def{acos}{829}{34.00385} +\pgfmath@def{acos}{830}{33.90126} \pgfmath@def{acos}{831}{33.79840} +\pgfmath@def{acos}{832}{33.69526} \pgfmath@def{acos}{833}{33.59184} +\pgfmath@def{acos}{834}{33.48814} \pgfmath@def{acos}{835}{33.38416} +\pgfmath@def{acos}{836}{33.27989} \pgfmath@def{acos}{837}{33.17533} +\pgfmath@def{acos}{838}{33.07047} \pgfmath@def{acos}{839}{32.96532} +\pgfmath@def{acos}{840}{32.85988} \pgfmath@def{acos}{841}{32.75413} +\pgfmath@def{acos}{842}{32.64807} \pgfmath@def{acos}{843}{32.54171} +\pgfmath@def{acos}{844}{32.43504} \pgfmath@def{acos}{845}{32.32806} +\pgfmath@def{acos}{846}{32.22076} \pgfmath@def{acos}{847}{32.11314} +\pgfmath@def{acos}{848}{32.00520} \pgfmath@def{acos}{849}{31.89693} +\pgfmath@def{acos}{850}{31.78833} \pgfmath@def{acos}{851}{31.67939} +\pgfmath@def{acos}{852}{31.57012} \pgfmath@def{acos}{853}{31.46051} +\pgfmath@def{acos}{854}{31.35056} \pgfmath@def{acos}{855}{31.24026} +\pgfmath@def{acos}{856}{31.12961} \pgfmath@def{acos}{857}{31.01860} +\pgfmath@def{acos}{858}{30.90724} \pgfmath@def{acos}{859}{30.79551} +\pgfmath@def{acos}{860}{30.68341} \pgfmath@def{acos}{861}{30.57095} +\pgfmath@def{acos}{862}{30.45811} \pgfmath@def{acos}{863}{30.34489} +\pgfmath@def{acos}{864}{30.23128} \pgfmath@def{acos}{865}{30.11729} +\pgfmath@def{acos}{866}{30.00291} \pgfmath@def{acos}{867}{29.88813} +\pgfmath@def{acos}{868}{29.77294} \pgfmath@def{acos}{869}{29.65736} +\pgfmath@def{acos}{870}{29.54136} \pgfmath@def{acos}{871}{29.42494} +\pgfmath@def{acos}{872}{29.30810} \pgfmath@def{acos}{873}{29.19084} +\pgfmath@def{acos}{874}{29.07315} \pgfmath@def{acos}{875}{28.95502} +\pgfmath@def{acos}{876}{28.83645} \pgfmath@def{acos}{877}{28.71743} +\pgfmath@def{acos}{878}{28.59796} \pgfmath@def{acos}{879}{28.47803} +\pgfmath@def{acos}{880}{28.35763} \pgfmath@def{acos}{881}{28.23677} +\pgfmath@def{acos}{882}{28.11542} \pgfmath@def{acos}{883}{27.99360} +\pgfmath@def{acos}{884}{27.87128} \pgfmath@def{acos}{885}{27.74847} +\pgfmath@def{acos}{886}{27.62516} \pgfmath@def{acos}{887}{27.50134} +\pgfmath@def{acos}{888}{27.37700} \pgfmath@def{acos}{889}{27.25214} +\pgfmath@def{acos}{890}{27.12675} \pgfmath@def{acos}{891}{27.00082} +\pgfmath@def{acos}{892}{26.87434} \pgfmath@def{acos}{893}{26.74731} +\pgfmath@def{acos}{894}{26.61973} \pgfmath@def{acos}{895}{26.49157} +\pgfmath@def{acos}{896}{26.36283} \pgfmath@def{acos}{897}{26.23351} +\pgfmath@def{acos}{898}{26.10359} \pgfmath@def{acos}{899}{25.97306} +\pgfmath@def{acos}{900}{25.84193} \pgfmath@def{acos}{901}{25.71017} +\pgfmath@def{acos}{902}{25.57778} \pgfmath@def{acos}{903}{25.44475} +\pgfmath@def{acos}{904}{25.31106} \pgfmath@def{acos}{905}{25.17671} +\pgfmath@def{acos}{906}{25.04169} \pgfmath@def{acos}{907}{24.90598} +\pgfmath@def{acos}{908}{24.76958} \pgfmath@def{acos}{909}{24.63247} +\pgfmath@def{acos}{910}{24.49464} \pgfmath@def{acos}{911}{24.35608} +\pgfmath@def{acos}{912}{24.21678} \pgfmath@def{acos}{913}{24.07672} +\pgfmath@def{acos}{914}{23.93588} \pgfmath@def{acos}{915}{23.79427} +\pgfmath@def{acos}{916}{23.65185} \pgfmath@def{acos}{917}{23.50863} +\pgfmath@def{acos}{918}{23.36457} \pgfmath@def{acos}{919}{23.21967} +\pgfmath@def{acos}{920}{23.07391} \pgfmath@def{acos}{921}{22.92728} +\pgfmath@def{acos}{922}{22.77975} \pgfmath@def{acos}{923}{22.63132} +\pgfmath@def{acos}{924}{22.48195} \pgfmath@def{acos}{925}{22.33164} +\pgfmath@def{acos}{926}{22.18036} \pgfmath@def{acos}{927}{22.02810} +\pgfmath@def{acos}{928}{21.87483} \pgfmath@def{acos}{929}{21.72053} +\pgfmath@def{acos}{930}{21.56518} \pgfmath@def{acos}{931}{21.40876} +\pgfmath@def{acos}{932}{21.25124} \pgfmath@def{acos}{933}{21.09260} +\pgfmath@def{acos}{934}{20.93281} \pgfmath@def{acos}{935}{20.77185} +\pgfmath@def{acos}{936}{20.60969} \pgfmath@def{acos}{937}{20.44630} +\pgfmath@def{acos}{938}{20.28165} \pgfmath@def{acos}{939}{20.11570} +\pgfmath@def{acos}{940}{19.94844} \pgfmath@def{acos}{941}{19.77982} +\pgfmath@def{acos}{942}{19.60981} \pgfmath@def{acos}{943}{19.43837} +\pgfmath@def{acos}{944}{19.26546} \pgfmath@def{acos}{945}{19.09105} +\pgfmath@def{acos}{946}{18.91509} \pgfmath@def{acos}{947}{18.73754} +\pgfmath@def{acos}{948}{18.55835} \pgfmath@def{acos}{949}{18.37748} +\pgfmath@def{acos}{950}{18.19487} \pgfmath@def{acos}{951}{18.01047} +\pgfmath@def{acos}{952}{17.82423} \pgfmath@def{acos}{953}{17.63609} +\pgfmath@def{acos}{954}{17.44598} \pgfmath@def{acos}{955}{17.25385} +\pgfmath@def{acos}{956}{17.05962} \pgfmath@def{acos}{957}{16.86322} +\pgfmath@def{acos}{958}{16.66457} \pgfmath@def{acos}{959}{16.46359} +\pgfmath@def{acos}{960}{16.26020} \pgfmath@def{acos}{961}{16.05430} +\pgfmath@def{acos}{962}{15.84580} \pgfmath@def{acos}{963}{15.63459} +\pgfmath@def{acos}{964}{15.42057} \pgfmath@def{acos}{965}{15.20360} +\pgfmath@def{acos}{966}{14.98357} \pgfmath@def{acos}{967}{14.76033} +\pgfmath@def{acos}{968}{14.53374} \pgfmath@def{acos}{969}{14.30364} +\pgfmath@def{acos}{970}{14.06986} \pgfmath@def{acos}{971}{13.83221} +\pgfmath@def{acos}{972}{13.59049} \pgfmath@def{acos}{973}{13.34447} +\pgfmath@def{acos}{974}{13.09392} \pgfmath@def{acos}{975}{12.83856} +\pgfmath@def{acos}{976}{12.57811} \pgfmath@def{acos}{977}{12.31225} +\pgfmath@def{acos}{978}{12.04060} \pgfmath@def{acos}{979}{11.76278} +\pgfmath@def{acos}{980}{11.47834} \pgfmath@def{acos}{981}{11.18676} +\pgfmath@def{acos}{982}{10.88748} \pgfmath@def{acos}{983}{10.57984} +\pgfmath@def{acos}{984}{10.26309} \pgfmath@def{acos}{985}{9.93636} +\pgfmath@def{acos}{986}{9.59863} \pgfmath@def{acos}{987}{9.24870} +\pgfmath@def{acos}{988}{8.88512} \pgfmath@def{acos}{989}{8.50614} +\pgfmath@def{acos}{990}{8.10961} \pgfmath@def{acos}{991}{7.69281} +\pgfmath@def{acos}{992}{7.25224} \pgfmath@def{acos}{993}{6.78328} +\pgfmath@def{acos}{994}{6.27958} \pgfmath@def{acos}{995}{5.73196} +\pgfmath@def{acos}{996}{5.12640} \pgfmath@def{acos}{997}{4.43922} +\pgfmath@def{acos}{998}{3.62430} \pgfmath@def{acos}{999}{2.56255} +\pgfmath@def{acos}{1000}{0.00000} + + + +% Local Variables: +% tab-width: 2 +% End: diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathode.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathode.code.tex new file mode 100644 index 00000000000..d8837897558 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathode.code.tex @@ -0,0 +1,178 @@ +% Copyright 2011 by Christophe Jorssen +% +% This file may be distributed and/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 details. +\def\pgfmathode@stopadd{\pgfmathode@stopadd} + +\def\pgfmathode@addindextofunc[#1]#2{% + \begingroup + \gdef\pgfmathode@func{}% + \pgfmathode@addindextofunc@i[#1]#2\pgfmathode@stopadd} + +\def\pgfmathode@addindextofunc@i[#1]#2#3{% + \ifx#1#2 + \expandafter\gdef\expandafter\pgfmathode@func\expandafter{% + \pgfmathode@func #2[\pgfmathode@timeindex]}% + \else + \expandafter\gdef\expandafter\pgfmathode@func\expandafter{% + \pgfmathode@func #2}% + \fi + \ifx#3\pgfmathode@stopadd + \expandafter\gdef\expandafter\pgfmathode@func\expandafter{% + \expandafter{\pgfmathode@func}}% + \let\next\endgroup + \else + \def\next{\pgfmathode@addindextofunc@i[#1]#3}% + \fi + \next} + +%********************************************************************** +% Know limitation: fk cannot be a time function. Should be possible to +% use \Sol[0] as time in the set of equations. +%********************************************************************** + +% Numerically solve a differential system with 1st order Runge-Kutta +% (Euler method) +% dq1/dt = f1(t,q1,q2,...,qN) +% dq2/dt = f2(t,q1,q2,...,qN) +% ... +% dqN/dt = fN(t,q1,q2,...,qN) +% +% #1: A pgf array where the solution will be stored. +% At the end: +% #1 -> {{t(0),q1(t(0)),q2(t(0)),...,qN(t(0))}, +% {t(1),q1(t(1)),q2(t(1)),...,qN(t(1))}, +% ... +% {t(Nstep),q1(t(Nstep)),q2(t(Nstep)),...,qN(t(Nstep))}} +% #2: A pgf array with f1,f2,...,fN +% {f1} +% #3: A pgf array with initial conditions. +% {t(0),q1(t(0)),q2(t(0)),...,qN(t(0))} +% #4: t(Nstep) +% #5: Nstep (number of steps) +% +% * First order example: dq/dt = -q + 5 with IC=(t=0,q(0)=0) +% \pgfmathodeRKI{\Sol}{{-\Sol[1]+5}}{{0,0}}{3.5}{100} +% * Second order example: {dq1/dt=q2, dq2/dt=-q2/2-sin(q1)} (damped +% pendulum) +% \pgfmathodeRKI{\Sol}{{\Sol[2],-\Sol[2]/2-sin(deg(\Sol[1]))}}% +% {{0,-1,5}}{15}{50} + +\def\pgfmathode@generic@init@RK{% + \begingroup + % Sol array (#1) first element is given by the set of initial + % conditions (#3). We need to enclose it in brace so that is a now + % a "matrix" array. + \gdef#1{{#3}}% + % The set of rhs {f1(t,q1,q2,...,qN),...,fN(t,q1,q2,...,qN)} is + % given in terms of #1[0],#1[1],...,#1[N]. We need to transform to + % #1[\pgfmathode@timeindex][0],...,#1[\pgfmathode@timeindex][N], that is + % add [\pgfmathode@timeindex] after every occurence of #1 in #2. + % No need to brace #2 since it is already surounded by braces. The + % result is stored in \pgfmathode@func + \pgfmathode@addindextofunc[#1]#2% + % Set time step. Actually the number of time steps is #5-1, so we + % divide by (#5-1)+1 = #5. + \pgfmathsetmacro\pgfmathode@Sol@t{#1[0][0]}% + \pgfmathsetmacro\pgfmathode@Deltat{(#4-\pgfmathode@Sol@t)/#5}% + % Compute the order of the system: it is equal to the number of IC + % minus one (time). + \pgfmathsetmacro\pgfmathode@dimfunc{dim(#3)-1}% + \pgfmathsetmacro\pgfmathode@numstep{#5-1}} + +\def\pgfmathodeRKI#1#2#3#4#5{% + \pgfmathode@generic@init@RK + % Start the time loop for Runge-Kutta 1st order + \foreach \pgfmathode@timeindex in {0,...,\pgfmathode@numstep} {% + \message{Step \pgfmathode@timeindex...}% + % Start the function loop + \foreach \pgfmathode@funcindex in {1,...,\pgfmathode@dimfunc} {% + % The RKI algorithm + % qk[t(i)] = Deltat*fk(t(i-1),q1(t(i-1)),...qN(t(i-1))) + + % qk[t(i-1)] + % Note: this part can be really slow due to array managment in + % pgfmath. + % TODO: find a better way (at least inside this loop) + \pgfmathparse{% + \pgfmathode@Deltat*(\pgfmathode@func[\pgfmathode@funcindex-1])+ + #1[\pgfmathode@timeindex][\pgfmathode@funcindex]}% + % Store the result in a helper macro + \expandafter\xdef\csname pgfmathode@Sol@\pgfmathode@funcindex + \endcsname{\pgfmathresult}% + } + % Store step i + \pgfmathparse{\pgfmathode@Sol@t+\pgfmathode@Deltat}% + \xdef\pgfmathode@Sol@t{\pgfmathresult}% + \xdef\pgfmathode@temp{}% + \foreach \pgfmathode@funcindex in {1,...,\pgfmathode@dimfunc} {% + \ifx\pgfmathode@temp\pgfutil@empty + \xdef\pgfmathode@temp{% + \csname pgfmathode@Sol@\pgfmathode@funcindex\endcsname}% + \else + \xdef\pgfmathode@temp{% + \pgfmathode@temp, + \csname pgfmathode@Sol@\pgfmathode@funcindex\endcsname}% + \fi} + \xdef#1{% + {\expandafter\pgfutil@firstofone#1,% + {\pgfmathode@Sol@t,\pgfmathode@temp}}}% + } + \endgroup} + +% RKIV: far from working yet! +\def\pgfmathodeRKIV#1#2#3#4#5{% + \pgfmathode@generic@init@RK + % Start the time loop for Runge-Kutta 4th order + \foreach \pgfmathode@timeindex in {0,...,\pgfmathode@numstep} {% + \message{Step \pgfmathode@timeindex...}% + % Start the function loop + \foreach \pgfmathode@funcindex in {1,...,\pgfmathode@dimfunc} {% + % The RKIV algorithm + % qk[t(i)] = qk[t(i-1)] + + % (1/6) * (j1k + 2j2k + 2j3k + j4k) + % where j1k = fk(t(i-1),q1(t(i-1)),...qN(t(i-1))) * Deltat + % j2k = fk(t(i-1)+.5*Deltat, + % q1(t(i-1))+.5*j11,...qN(t(i-1))+.5*j1N) * Deltat + % j3k = fk(t(i-1)+.5*Deltat, + % q1(t(i-1))+.5*j21,...qN(t(i-1))+.5*j2N) * Deltat + % j4k = fk(t(i-1)+Deltat, + % q1(t(i-1))+j31,...qN(t(i-1))+j3N) * Deltat + % + % Compute j1k + \pgfmathparse{% + \pgfmathode@Deltat*(\pgfmathode@func[\pgfmathode@funcindex-1])+ + #1[\pgfmathode@timeindex][\pgfmathode@funcindex]}% + \expandafter\xdef\csname pgfmathode@RKIV@1@\pgfmathode@funcindex + \endcsname{\pgfmathresult}% + % Compute j2k + \pgfmathparse{% + \pgfmathode@Deltat*(\pgfmathode@func[\pgfmathode@funcindex-1])+ + #1[\pgfmathode@timeindex][\pgfmathode@funcindex]}% + \expandafter\xdef\csname pgfmathode@RKIV@1@\pgfmathode@funcindex + \endcsname{\pgfmathresult}% + } + % Store step i + \pgfmathparse{\pgfmathode@Sol@t+\pgfmathode@Deltat}% + \xdef\pgfmathode@Sol@t{\pgfmathresult}% + \xdef\pgfmathode@temp{}% + \foreach \pgfmathode@funcindex in {1,...,\pgfmathode@dimfunc} {% + \ifx\pgfmathode@temp\pgfutil@empty + \xdef\pgfmathode@temp{% + \csname pgfmathode@Sol@\pgfmathode@funcindex\endcsname}% + \else + \xdef\pgfmathode@temp{% + \pgfmathode@temp, + \csname pgfmathode@Sol@\pgfmathode@funcindex\endcsname}% + \fi} + \xdef#1{% + {\expandafter\pgfutil@firstofone#1,% + {\pgfmathode@Sol@t,\pgfmathode@temp}}}% + } + \endgroup} + + +\endinput
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex index 81f6545897e..71843fb2499 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex @@ -7,83 +7,92 @@ \newif\ifpgfmath@quickparse \newif\ifpgfmathfloat \newif\ifpgfmathunitsdeclared +\newif\ifpgfmathmathunitsdeclared \newif\ifpgfmathignoreunitscale \def\pgfmathprint#1{\pgfmathparse{#1}\pgfmathresult} \def\pgfmathparse{% - \begingroup% - \pgfmath@catcodes% - \pgfmath@quickparsefalse% - \ifpgfmathfloat% - \let\pgfmath@parse@next=\pgfmathfloatparsenumber% - \else% - \let\pgfmath@parse@next=\pgfmathparse@% - \fi% - \pgfmath@parse@next} + \begingroup + \pgfmath@catcodes + \pgfmath@quickparsefalse + % Test for the fpu library + \ifpgfmathfloat + \let\pgfmath@parse@next=\pgfmathfloatparsenumber + \else + \let\pgfmath@parse@next=\pgfmathparse@ + \fi + \pgfmath@parse@next} \def\pgfmath@catcodes{% Maybe unecessary. - \catcode`\==12% - \catcode`\,=12% - \catcode`\|=12% - \catcode`\&=12% + \catcode`\==12% + \catcode`\,=12% + \catcode`\|=12% + \catcode`\&=12% } \def\pgfmathqparse{% - \begingroup% - \pgfmath@catcodes% - \pgfmath@quickparsetrue% - \pgfmathparse@} - + \begingroup + \pgfmath@catcodes + \pgfmath@quickparsetrue + \pgfmathparse@} + \def\pgfmathparse@#1{% - % Stuff for calc compatiability. - \let\real=\pgfmath@calc@real% - \let\minof=\pgfmath@calc@minof% - \let\maxof=\pgfmath@calc@maxof% - \let\ratio=\pgfmath@calc@ratio% - \let\widthof=\pgfmath@calc@widthof% - \let\heightof=\pgfmath@calc@heightof% - \let\depthof=\pgfmath@calc@depthof% - % Restore font. - \pgfmath@selectfont% + % We are inside a group (opened in |\pgfmathparse| or + % |\pgfmathqparse|). + % Stuff for calc compatiability. + \let\real=\pgfmath@calc@real + \let\minof=\pgfmath@calc@minof + \let\maxof=\pgfmath@calc@maxof + \let\ratio=\pgfmath@calc@ratio + \let\widthof=\pgfmath@calc@widthof + \let\heightof=\pgfmath@calc@heightof + \let\depthof=\pgfmath@calc@depthof + % Restore font (defined in pgfmathutil.code.tex) + \pgfmath@selectfont % Expand expression so any reamining CSs are registers - % or box dimensions (i.e., \wd, \ht, \dp). + % or box dimensions (i.e. |\wd|, |\ht|, |\dp|). \edef\pgfmath@expression{#1}% - % No units yet. - \global\pgfmathunitsdeclaredfalse% + % No (math) units yet. + \global\pgfmathunitsdeclaredfalse + \global\pgfmathmathunitsdeclaredfalse % Set up stack. \pgfmath@stack@operation={{}{}{}}% - \pgfmath@stack@operand={{}{}{}}% - \let\pgfmath@stack@operation@top=\pgfmath@stack@empty% - \let\pgfmath@stack@operand@top=\pgfmath@stack@empty% - % An expression always begins with an operand. - \expandafter\pgfmath@bgroup@strip\expandafter{\pgfmath@expression}% - \expandafter\pgfmath@parse@@operand\pgfmath@bgroup@stripped @@@@\pgfmath@parse@stop% -}% + \pgfmath@stack@operand={{}{}{}}% + \let\pgfmath@stack@operation@top=\pgfmath@stack@empty + \let\pgfmath@stack@operand@top=\pgfmath@stack@empty + % An expression always begins with an operand. + \expandafter\pgfmath@bgroup@strip\expandafter{\pgfmath@expression}% + % |\pgfmath@bgroup@stripped| is the result of + % |\pgfmath@bgroup@strip| + \expandafter\pgfmath@parse@@operand\pgfmath@bgroup@stripped @@@@\pgfmath@parse@stop% +} \def\pgfmath@parse@end#1\pgfmath@parse@stop{% - \pgfmathpostparse% - \pgfmath@smuggleone\pgfmathresult% - \endgroup% - \ignorespaces}% + \pgfmathpostparse + \pgfmath@smuggleone\pgfmathresult% + \endgroup + \ignorespaces} -\let\pgfmathpostparse=\relax% +\let\pgfmathpostparse=\relax % For compatiability with older version. % \def\pgfmathscaleresult{% - \ifpgfmathunitsdeclared% - \else% - \ifpgfmathignoreunitscale% - \else% - \afterassignment\pgfmath@gobbletilpgfmath@% + \ifpgfmathunitsdeclared + \else + \ifpgfmathignoreunitscale + \else + \afterassignment\pgfmath@gobbletilpgfmath@% \pgfmath@x\pgfmathresultunitscale pt\relax\pgfmath@% \expandafter\pgfmath@x\pgfmathresult\pgfmath@x% \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@x}}% - \fi% - \fi% + \fi + \fi } + \def\pgfmathsetresultunitscale#1{\def\pgfmathresultunitscale{#1}} + \def\pgfmathresultunitscale{1} % Stuff for compatability with the calc package. @@ -116,19 +125,29 @@ \edef\pgfmath@char@hash{\the\pgfmath@toks} \def\pgfmath@tokens@make#1#2{% - \def\pgfmath@prefix{#1}% - \expandafter\pgfmath@tokens@@make#2{}} - + % Defines for each token or balenced text in |#2| a control sequence + % |\pgfmath@token@<#1>@\string<one token from #2>| and stores |#2| + % in it. + \def\pgfmath@prefix{#1}% + % Note the empty group |{}| at the end that ends the loop in + % |\pgfmath@token@@make|. + \expandafter\pgfmath@tokens@@make#2{}} + \def\pgfmath@tokens@@make#1{% - \def\pgfmath@token{#1}% - \ifx\pgfmath@token\pgfmath@empty% - \else% - \pgfmath@namedef{pgfmath@token@\pgfmath@prefix @\string#1}{#1}% - \expandafter\pgfmath@tokens@@make% - \fi} + \def\pgfmath@token{#1}% + \ifx\pgfmath@token\pgfmath@empty + % End of loop: all tokens or balanced texts were parsed. + \else + \pgfmath@namedef{pgfmath@token@\pgfmath@prefix @\string#1}{#1}% + \expandafter\pgfmath@tokens@@make% + \fi} \pgfmath@tokens@make{box}{\wd\ht\dp} +\ifx\dimexpr\@undefined\else % needed for classic tex + \pgfmath@tokens@make{dimexpr}{\dimexpr\glueexpr} +\fi \pgfmath@tokens@make{unit}{{bp}{cc}{cm}{dd}{em}{ex}{in}{mm}{pc}{pt}{sp}} +\pgfmath@tokens@make{mathunit}{{mu}} \pgfmath@tokens@make{numeric}{.0123456789} \pgfmath@tokens@make{number}{0123456789} \pgfmath@tokens@make{functional}{_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ} @@ -145,39 +164,42 @@ \pgfmath@namedef{pgfmath@base@0B}{2} % Determine if a register is a count or a dimension/skip register. -% \newif\ifpgfmath@dimen@ \def\pgfmath@dimen@#1{% - \begingroup% - \afterassignment\pgfmath@dimen@@% - #1=0.0pt\relax\pgfmath@} + \begingroup + \afterassignment\pgfmath@dimen@@% + #1=0.0pt\relax\pgfmath@} \def\pgfmath@dimen@@#1#2\pgfmath@{% - \endgroup% - \ifx#1.% - \pgfmath@dimen@false% - \else% - \pgfmath@dimen@true% - \fi} + \endgroup + \ifx#1.% + \pgfmath@dimen@false + \else + \pgfmath@dimen@true + \fi} \def\pgfmath@parse@ifbgroup#1#2{% - \let\pgfmath@parse@bgroup@after=#1% - \let\pgfmath@parse@nobgroup@after=#2% - \futurelet\pgfmath@token@let% - \pgfmath@parse@@ifbgroup} - + \let\pgfmath@parse@bgroup@after=#1% + \let\pgfmath@parse@nobgroup@after=#2% + \futurelet\pgfmath@token@let% + \pgfmath@parse@@ifbgroup} + \def\pgfmath@parse@@ifbgroup{% - \ifx\pgfmath@token@let\bgroup% - \let\pgfmath@parse@next=\pgfmath@parse@@@ifbgroup% - \else% - \ifx\pgfmath@token@let\pgfmath@sptoken% - \let\pgfmath@parse@next=\pgfmath@parse@@@@ifbgroup% - \else% - \let\pgfmath@parse@next=\pgfmath@parse@nobgroup@after% - \fi% - \fi% - \pgfmath@parse@next} - -\def\pgfmath@parse@@@ifbgroup#1{\pgfmath@parse@bgroup@after\pgfmath@bgroup#1\pgfmath@egroup} + \ifx\pgfmath@token@let\bgroup + \let\pgfmath@parse@next=\pgfmath@parse@@@ifbgroup + \else + % |\pgfmath@sptoken| defined in \file{pgfmathutil.code.tex}. + \ifx\pgfmath@token@let\pgfmath@sptoken + \let\pgfmath@parse@next=\pgfmath@parse@@@@ifbgroup + \else + \let\pgfmath@parse@next=\pgfmath@parse@nobgroup@after + \fi + \fi + \pgfmath@parse@next} + +% I (CJ) *think* it replaces |{| and |}| by |\pgfmath@bgroup| and +% |\pgfmath@egroup|? +\def\pgfmath@parse@@@ifbgroup#1{% + \pgfmath@parse@bgroup@after\pgfmath@bgroup#1\pgfmath@egroup} { \def\:{\pgfmath@parse@@@@ifbgroup} @@ -185,81 +207,96 @@ } % Parse an operand. -% -\def\pgfmath@parse@operand{\expandafter\pgfmath@parse@@operand\pgfmath@token@next}% - -\def\pgfmath@parse@@operand{\pgfmath@parse@ifbgroup{\pgfmath@parse@@operand}{\pgfmath@parse@@operand@}} - +\def\pgfmath@parse@operand{% + \expandafter\pgfmath@parse@@operand\pgfmath@token@next} + +% This is the entry point for the parser. It is called at the end of +% |\pgfmathparse@| with the following syntax +% |\expandafter\pgfmath@parse@@operand\pgfmath@bgroup@stripped +% @@@@\pgfmath@parse@stop|. +% Note: we are inside a group. +\def\pgfmath@parse@@operand{% + \pgfmath@parse@ifbgroup{\pgfmath@parse@@operand}{\pgfmath@parse@@operand@}} + +% An operand is +% * |+| (unary plus), +% * |-| (unary minus), +% * a prefix operator \def\pgfmath@parse@@operand@#1{% - \def\pgfmath@token{#1}% - \ifx\pgfmath@token\pgfmath@char@plus% Ignore. - \let\pgfmath@parse@next=\pgfmath@parse@@operand% - \else% - \ifx\pgfmath@token\pgfmath@char@minus% - \pgfmath@stack@push@operation{neg}% Unary minus. - \let\pgfmath@parse@next=\pgfmath@parse@@operand% - \else% - \expandafter\ifx\csname pgfmath@operation@\expandafter\string\pgfmath@token @prefix\endcsname\pgfmath@token% - \let\pgfmath@parse@next=\pgfmath@parse@prefix@operator% - \else% - \ifpgfmath@quickparse% - \let\pgfmath@parse@next=\pgfmath@qparse@operand% - \else% - \let\pgfmath@number=\pgfmath@empty% - \expandafter\ifx\csname pgfmath@token@functional@\string#1\endcsname\relax% - \let\pgfmath@base=\pgfmath@empty% - \let\pgfmath@token@next=\pgfmath@token% - \if#10% Check for octal prefix. - \def\pgfmath@base{8}% - \fi% - \let\pgfmath@parse@next=\pgfmath@parse@number% - \else% - \let\pgfmath@function=\pgfmath@token% - \let\pgfmath@parse@next=\pgfmath@parse@function% - \fi% - \fi% - \fi% - \fi% - \fi% - \pgfmath@parse@next% + \def\pgfmath@token{#1}% + \ifx\pgfmath@token\pgfmath@char@plus + % Unary (prefix) plus + \let\pgfmath@parse@next=\pgfmath@parse@@operand% + \else + \ifx\pgfmath@token\pgfmath@char@minus + % Unary (prefix) minus + \pgfmath@stack@push@operation{neg}% + \let\pgfmath@parse@next=\pgfmath@parse@@operand + \else + % See |\pgfmathdeclareoperator| (below). Note that |+| and |-| + % that are also declared as operators have been tested before so + % they should never be parsed as binary (infix) operator at this stage. + \expandafter\ifx\csname pgfmath@operation@\expandafter\string\pgfmath@token @prefix\endcsname\pgfmath@token + \let\pgfmath@parse@next=\pgfmath@parse@prefix@operator + \else + \ifpgfmath@quickparse + \let\pgfmath@parse@next=\pgfmath@qparse@operand + \else + \let\pgfmath@number=\pgfmath@empty + \expandafter\ifx\csname pgfmath@token@functional@\string#1\endcsname\relax% + \let\pgfmath@base=\pgfmath@empty% + \let\pgfmath@token@next=\pgfmath@token% + \if#10% Check for octal prefix. + \def\pgfmath@base{8}% + \fi% + \let\pgfmath@parse@next=\pgfmath@parse@number% + \else% + \let\pgfmath@function=\pgfmath@token% + \let\pgfmath@parse@next=\pgfmath@parse@function% + \fi% + \fi% + \fi% + \fi% + \fi% + \pgfmath@parse@next% } % Parse prefix operators. % \def\pgfmath@parse@prefix@operator{% - \ifx\pgfmath@token\pgfmath@char@quote% Quote character. - \let\pgfmath@parse@next=\pgfmath@parse@operand@quote% - \else% - \ifx\pgfmath@token\pgfmath@char@exclamation% Prefix !. - \pgfmath@stack@push@operation{not}% - \let\pgfmath@parse@next=\pgfmath@parse@@operand% - \else% Anything else, just push and hope. - \expandafter\pgfmath@stack@push@operation\expandafter{\pgfmath@token}% - \let\pgfmath@parse@next=\pgfmath@parse@@operand% - \fi% - \fi% - \pgfmath@parse@next% + \ifx\pgfmath@token\pgfmath@char@quote% Quote character. + \let\pgfmath@parse@next=\pgfmath@parse@operand@quote% + \else% + \ifx\pgfmath@token\pgfmath@char@exclamation% Prefix !. + \pgfmath@stack@push@operation{not}% + \let\pgfmath@parse@next=\pgfmath@parse@@operand% + \else% Anything else, just push and hope. + \expandafter\pgfmath@stack@push@operation\expandafter{\pgfmath@token}% + \let\pgfmath@parse@next=\pgfmath@parse@@operand% + \fi% + \fi% + \pgfmath@parse@next% }% % Quote part of an expression. % \def\pgfmath@parse@operand@quote#1"{% - \def\pgfmathresult{#1}% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \pgfmath@parse@@operator% + \def\pgfmathresult{#1}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \pgfmath@parse@@operator% } % Quick operand parsing. Should always have units. % No functions, base conversion, quoting or scientific notation % are permitted. \def\pgfmath@qparse@operand{% - \afterassignment\pgfmath@qparse@@operand% - \pgfmath@dimen\pgfmath@token} + \afterassignment\pgfmath@qparse@@operand% + \pgfmath@dimen\pgfmath@token} \def\pgfmath@qparse@@operand{% - \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \pgfmath@parse@@operator% + \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \pgfmath@parse@@operator% } % Parse a number, which can take the form: @@ -274,337 +311,414 @@ % \def\pgfmath@parse@number{\pgfmath@parse@ifbgroup{\pgfmath@parse@number}{\pgfmath@parse@number@}} \def\pgfmath@parse@number@#1{% - \let\pgfmath@token=\pgfmath@token@next% - \def\pgfmath@token@next{#1}% - \pgfmath@parse@@number} + \let\pgfmath@token=\pgfmath@token@next% + \def\pgfmath@token@next{#1}% + \pgfmath@parse@@number} \def\pgfmath@parse@@number{% - \ifx\pgfmath@token\pgfmath@egroup@token% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmath@number}% - \let\pgfmath@parse@next=\pgfmath@parse@@@operator% - \else% - \expandafter\ifcat\pgfmath@token\relax% A CS? - \expandafter\ifx\csname pgfmath@token@box@\expandafter\string\pgfmath@token\endcsname\relax% - % So, is the CS is a dimension or a count register? - \expandafter\pgfmath@dimen@\pgfmath@token% - \ifpgfmath@dimen@% A dimension register. - \global\pgfmathunitsdeclaredtrue% - \pgfmath@dimen=\pgfmath@number\pgfmath@token% - \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \let\pgfmath@parse@next=\pgfmath@parse@operator% - \else% A count register. - \pgfmath@count=\pgfmath@token% - \expandafter\def\expandafter\pgfmath@number\expandafter{\the\pgfmath@count}% - \expandafter\ifcat\pgfmath@token@next\relax% - % A CS following a count register should be \wd, \ht or \dp. - \let\pgfmath@parse@next=\pgfmath@parse@number% - \else% - \let\pgfmathresult=\pgfmath@number% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \let\pgfmath@parse@next=\pgfmath@parse@operator% - \fi% - \fi% - \else% - % This should be a box specification, for example, 0.5\wd\mybox. - \global\pgfmathunitsdeclaredtrue% - \pgfmath@dimen=\pgfmath@number\pgfmath@token\pgfmath@token@next% - \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \let\pgfmath@parse@next=\pgfmath@parse@@operator% - \fi% - \else% - \expandafter\ifx\csname pgfmath@token@numeric@\expandafter\string\pgfmath@token\endcsname\relax% - % It isn't numeric (i.e., 012345679.), so it might be units... - \expandafter\ifx\csname pgfmath@token@unit@\pgfmath@token\expandafter\string\pgfmath@token@next\endcsname\relax% - % ...or the exponent characters... - \expandafter\ifx\csname pgfmath@token@exponent@\pgfmath@token\endcsname\relax% - % ...or a base prefix... - \expandafter\ifx\csname pgfmath@base@\pgfmath@number\pgfmath@token\endcsname\relax% - % ...none of the above... - \ifx\pgfmath@base\pgfmath@empty% - \let\pgfmathresult=\pgfmath@number% - \else% - \ifx\pgfmath@number\pgfmath@char@zero% - \let\pgfmathresult=\pgfmath@number% - \else% - % Convert from octal. - \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\pgfmath@number}{8}{10}% - \fi% - \fi% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \let\pgfmath@parse@next=\pgfmath@parse@@@operator% - \else% - % ...here, it is a base prefix 0x, 0X, 0b or 0B - \expandafter\let\expandafter\pgfmath@base\expandafter=% - \csname pgfmath@base@\pgfmath@number\pgfmath@token\endcsname% - \let\pgfmath@parse@next=\pgfmath@parse@base% - \fi% - \else% ... and here, it is the exponent characters. - \let\pgfmath@parse@next=\pgfmath@parse@exponent% - \fi% - \else% ...but here it is units. - \global\pgfmathunitsdeclaredtrue% - \pgfmath@dimen=\pgfmath@number\pgfmath@token\pgfmath@token@next\relax% - \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \let\pgfmath@parse@next=\pgfmath@parse@@operator% - \fi% - \else% It is numeric. - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgfmath@number% - \expandafter\expandafter\expandafter{\expandafter\pgfmath@number\pgfmath@token}% - \ifx\pgfmath@token\pgfmath@char@period% - \let\pgfmath@base=\pgfmath@empty% - \fi% - \let\pgfmath@parse@next=\pgfmath@parse@number% - \fi% - \fi% - \fi% - \pgfmath@parse@next% + \ifx\pgfmath@token\pgfmath@egroup@token% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmath@number}% + \let\pgfmath@parse@next=\pgfmath@parse@@@operator% + \else% + \expandafter\ifcat\pgfmath@token\relax% A CS? + \expandafter\ifx\csname pgfmath@token@dimexpr@\expandafter\string\pgfmath@token\endcsname\relax% + \expandafter\ifx\pgfmath@token\numexpr% + \let\pgfmath@parse@next=\pgfmath@parse@numexpr% + \else% + \expandafter\ifx\pgfmath@token\muexpr% + \let\pgfmath@parse@next=\pgfmath@parse@muexpr% + \else% + \expandafter\ifx\csname pgfmath@token@box@\expandafter\string\pgfmath@token\endcsname\relax% + % So, is the CS is a dimension or a count register? + \expandafter\pgfmath@dimen@\pgfmath@token% + \ifpgfmath@dimen@% A dimension register. + \global\pgfmathunitsdeclaredtrue% + \pgfmath@dimen=\pgfmath@number\pgfmath@token% + \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \let\pgfmath@parse@next=\pgfmath@parse@operator% + \else% A count register. + \pgfmath@count=\pgfmath@token% + \expandafter\def\expandafter\pgfmath@number\expandafter{\the\pgfmath@count}% + \expandafter\ifcat\pgfmath@token@next\relax% + % A CS following a count register should be \wd, \ht or \dp. + \let\pgfmath@parse@next=\pgfmath@parse@number% + \else% + \let\pgfmathresult=\pgfmath@number% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \let\pgfmath@parse@next=\pgfmath@parse@operator% + \fi% + \fi% + \else% + % This should be a box specification, for example, 0.5\wd\mybox. + \global\pgfmathunitsdeclaredtrue% + \pgfmath@dimen=\pgfmath@number\pgfmath@token\pgfmath@token@next% + \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \let\pgfmath@parse@next=\pgfmath@parse@@operator% + \fi% + \fi% + \fi% + \else% + \global\pgfmathunitsdeclaredtrue% + \let\pgfmath@parse@next=\pgfmath@parse@dimexpr% + \fi% + \else% + \expandafter\ifx\csname pgfmath@token@numeric@\expandafter\string\pgfmath@token\endcsname\relax% + % It isn't numeric (i.e., 012345679.), so it might be units... + \expandafter\ifx\csname pgfmath@token@unit@\pgfmath@token\expandafter\string\pgfmath@token@next\endcsname\relax% + % ...or the exponent characters... + \expandafter\ifx\csname pgfmath@token@exponent@\pgfmath@token\endcsname\relax% + % ...or a base prefix... + \expandafter\ifx\csname pgfmath@base@\pgfmath@number\pgfmath@token\endcsname\relax% + % ...or a math unit... + \expandafter\ifx\csname pgfmath@token@mathunit@\pgfmath@token\expandafter\string\pgfmath@token@next\endcsname\relax% + % ...none of the above... + \ifx\pgfmath@base\pgfmath@empty% + \let\pgfmathresult=\pgfmath@number% + \else% + \ifx\pgfmath@number\pgfmath@char@zero% + \let\pgfmathresult=\pgfmath@number% + \else% + % Convert from octal. + \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\pgfmath@number}{8}{10}% + \fi% + \fi% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \let\pgfmath@parse@next=\pgfmath@parse@@@operator% + \else% + % ...here, it is a math unit (mu). Treat it as a pt. + \global\pgfmathunitsdeclaredtrue% + \global\pgfmathmathunitsdeclaredtrue% + \pgfmath@dimen=\pgfmath@number pt\relax% + \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \let\pgfmath@parse@next=\pgfmath@parse@@operator% + \fi% + \else% + % ...here, it is a base prefix 0x, 0X, 0b or 0B + \expandafter\let\expandafter\pgfmath@base\expandafter=% + \csname pgfmath@base@\pgfmath@number\pgfmath@token\endcsname% + \let\pgfmath@parse@next=\pgfmath@parse@base% + \fi% + \else% ... and here, it is the exponent characters. + \let\pgfmath@parse@next=\pgfmath@parse@exponent% + \fi% + \else% ...but here it is units. + \global\pgfmathunitsdeclaredtrue% + \pgfmath@dimen=\pgfmath@number\pgfmath@token\pgfmath@token@next\relax% + \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \let\pgfmath@parse@next=\pgfmath@parse@@operator% + \fi% + \else% It is numeric. + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgfmath@number% + \expandafter\expandafter\expandafter{\expandafter\pgfmath@number\pgfmath@token}% + \ifx\pgfmath@token\pgfmath@char@period% + \let\pgfmath@base=\pgfmath@empty% + \fi% + \let\pgfmath@parse@next=\pgfmath@parse@number% + \fi% + \fi% + \fi% + \pgfmath@parse@next% +} + + +% Parse a \dimexpr +\def\pgfmath@parse@dimexpr{% + \afterassignment\pgfmath@parse@dimexpr@% + \expandafter\expandafter\expandafter\pgfmath@dimen\expandafter\pgfmath@token\pgfmath@token@next% +} +\def\pgfmath@parse@dimexpr@{% + \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \pgfmath@parse@@operator% +} + + +% Parse a \muexpr +\def\pgfmath@parse@muexpr{% + \begingroup% + \afterassignment\pgfmath@parse@muexpr@% + \expandafter\expandafter\expandafter\muskip\expandafter\expandafter\expandafter0\expandafter\pgfmath@token\expandafter\pgfmath@token@next% +} +\def\pgfmath@parse@muexpr@{% + \expandafter\endgroup% + \expandafter\edef\expandafter\pgfmathresult\expandafter{\expandafter\pgfMATH@STRIPMU\the\muskip0}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \pgfmath@parse@@operator% +} + +{ +\catcode`\m=12 +\catcode`\u=12 +\gdef\pgfMATH@STRIPMU#1mu{#1} +} + + +% Parse a \numexpr +\def\pgfmath@parse@numexpr{% + \afterassignment\pgfmath@parse@numexpr@% + \expandafter\expandafter\expandafter\pgfmath@count\expandafter\pgfmath@token\pgfmath@token@next% +} +\def\pgfmath@parse@numexpr@#1{% + \expandafter\def\expandafter\pgfmath@number\expandafter{\the\pgfmath@count}% + \def\pgfmath@token@next{#1}% + \expandafter\ifcat\pgfmath@token@next\relax% + % A CS following a count register should be \wd, \ht or \dp. + \let\pgfmath@parse@next=\pgfmath@parse@number% + \else% + \let\pgfmathresult=\pgfmath@number% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \let\pgfmath@parse@next=\pgfmath@parse@operator% + \fi% + \pgfmath@parse@next% } + % Parse the exponent of a number. % % REMARK: this method will be overwritten by the FPU library. Please % keep changes consistent... \def\pgfmath@parse@exponent{% - \afterassignment\pgfmath@parse@@exponent% - \pgfmath@count\pgfmath@token@next} + \afterassignment\pgfmath@parse@@exponent% + \pgfmath@count\pgfmath@token@next} \def\pgfmath@parse@@exponent{% - \pgfmathscientific{\pgfmath@number}{\the\pgfmath@count}% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \pgfmath@parse@@operator% + \pgfmathscientific{\pgfmath@number}{\the\pgfmath@count}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \pgfmath@parse@@operator% } % Parse binary or hexadecimal numbers (octal numbers done elsehwere). % \def\pgfmath@parse@base{% - \ifnum\pgfmath@base=2\relax% - \let\pgfmath@parse@next=\pgfmath@parse@binary% - \else% - \ifnum\pgfmath@base=16\relax% - \let\pgfmath@parse@next=\pgfmath@parse@hexadecimal% - \else% - \pgfmath@error{Unexpected numerical base `\pgfmath@base'}{}% - \def\pgfmathresult{0}% - \let\pgfmath@parse@next=\pgfmath@parse@end% - \fi% - \fi% - \let\pgfmath@number=\pgfmath@empty% - \expandafter\pgfmath@parse@next\pgfmath@token@next% + \ifnum\pgfmath@base=2\relax% + \let\pgfmath@parse@next=\pgfmath@parse@binary% + \else% + \ifnum\pgfmath@base=16\relax% + \let\pgfmath@parse@next=\pgfmath@parse@hexadecimal% + \else% + \pgfmath@error{Unexpected numerical base `\pgfmath@base'}{}% + \def\pgfmathresult{0}% + \let\pgfmath@parse@next=\pgfmath@parse@end% + \fi% + \fi% + \let\pgfmath@number=\pgfmath@empty% + \expandafter\pgfmath@parse@next\pgfmath@token@next% } - + \def\pgfmath@parse@binary#1{% - \expandafter\ifx\csname pgfmath@token@binary@#1\endcsname\relax% - \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\pgfmath@number}{2}{10}% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \def\pgfmath@token@next{#1}% - \let\pgfmath@parse@next=\pgfmath@parse@operator% - \else% - \expandafter\def\expandafter\pgfmath@number\expandafter{\pgfmath@number#1}% - \let\pgfmath@parse@next=\pgfmath@parse@binary% - \fi% - \pgfmath@parse@next% + \expandafter\ifx\csname pgfmath@token@binary@#1\endcsname\relax% + \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\pgfmath@number}{2}{10}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \def\pgfmath@token@next{#1}% + \let\pgfmath@parse@next=\pgfmath@parse@operator% + \else% + \expandafter\def\expandafter\pgfmath@number\expandafter{\pgfmath@number#1}% + \let\pgfmath@parse@next=\pgfmath@parse@binary% + \fi% + \pgfmath@parse@next% } \def\pgfmath@parse@hexadecimal#1{% - \expandafter\ifx\csname pgfmath@token@hexadecimal@#1\endcsname\relax% - \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\pgfmath@number}{16}{10}% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \def\pgfmath@token@next{#1}% - \let\pgfmath@parse@next=\pgfmath@parse@operator% - \else% - \expandafter\def\expandafter\pgfmath@number\expandafter{\pgfmath@number#1}% - \let\pgfmath@parse@next=\pgfmath@parse@hexadecimal% - \fi% - \pgfmath@parse@next% + \expandafter\ifx\csname pgfmath@token@hexadecimal@#1\endcsname\relax% + \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\pgfmath@number}{16}{10}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \def\pgfmath@token@next{#1}% + \let\pgfmath@parse@next=\pgfmath@parse@operator% + \else% + \expandafter\def\expandafter\pgfmath@number\expandafter{\pgfmath@number#1}% + \let\pgfmath@parse@next=\pgfmath@parse@hexadecimal% + \fi% + \pgfmath@parse@next% } - + % Parse a function. % \def\pgfmath@parse@function{\pgfmath@parse@ifbgroup{\pgfmath@parse@function}{\pgfmath@parse@@function}} \def\pgfmath@parse@function@{\futurelet\pgfmath@token@let\pgfmath@parse@@function} \def\pgfmath@parse@@function{% - \ifx\pgfmath@token@let\pgfmath@sptoken% - \let\pgfmath@token=\pgfmath@empty% - \let\pgfmath@parse@next=\pgfmath@parse@@@@function% - \else% - \let\pgfmath@parse@next=\pgfmath@parse@@@function% - \fi% - \pgfmath@parse@next} + \ifx\pgfmath@token@let\pgfmath@sptoken% + \let\pgfmath@token=\pgfmath@empty% + \let\pgfmath@parse@next=\pgfmath@parse@@@@function% + \else% + \let\pgfmath@parse@next=\pgfmath@parse@@@function% + \fi% + \pgfmath@parse@next} \def\pgfmath@parse@@@function#1{% - \expandafter\ifx\csname pgfmath@token@functional@\expandafter\string#1\endcsname\relax% - \expandafter\ifx\csname pgfmath@token@number@\expandafter\string#1\endcsname\relax% - \def\pgfmath@token{#1}% Not from A-Z, a-z, 0-9, or _. - \let\pgfmath@parse@next=\pgfmath@parse@@@@function% - \else% It is from 0-9. - \expandafter\def\expandafter\pgfmath@function\expandafter{\pgfmath@function#1}% - \let\pgfmath@parse@next=\pgfmath@parse@function@% - \fi% - \else% It is from from A-Z, a-z, or _. - \edef\pgfmath@function{\pgfmath@function#1}% - \let\pgfmath@parse@next=\pgfmath@parse@function@% - \fi% - \pgfmath@parse@next} + \expandafter\ifx\csname pgfmath@token@functional@\expandafter\string#1\endcsname\relax% + \expandafter\ifx\csname pgfmath@token@number@\expandafter\string#1\endcsname\relax% + \def\pgfmath@token{#1}% Not from A-Z, a-z, 0-9, or _. + \let\pgfmath@parse@next=\pgfmath@parse@@@@function% + \else% It is from 0-9. + \expandafter\def\expandafter\pgfmath@function\expandafter{\pgfmath@function#1}% + \let\pgfmath@parse@next=\pgfmath@parse@function@% + \fi% + \else% It is from from A-Z, a-z, or _. + \edef\pgfmath@function{\pgfmath@function#1}% + \let\pgfmath@parse@next=\pgfmath@parse@function@% + \fi% + \pgfmath@parse@next} \def\pgfmath@parse@@@@function{% - \expandafter\ifx\csname pgfmath@function@\pgfmath@function\endcsname\relax% - \pgfmath@error{Unknown function `\pgfmath@function'}{}% - \def\pgfmathresult{0}% - \let\pgfmath@parse@next=\pgfmath@parse@end% - \else% - \expandafter\ifnum\csname pgfmath@operation@\pgfmath@function @arity\endcsname=0\relax% - % Functions with zero arity are called directly. - \csname pgfmath\pgfmath@function @\endcsname% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \let\pgfmath@parse@next=\pgfmath@parse@@operator% - \else% Otherwise, they are pushed onto the operator stack - \expandafter\pgfmath@stack@push@operation\expandafter{\pgfmath@function}% - \let\pgfmath@parse@next=\pgfmath@parse@@operand% - \fi% - \fi% - \expandafter\pgfmath@parse@next\pgfmath@token} + \expandafter\ifx\csname pgfmath@function@\pgfmath@function\endcsname\relax% + \pgfmath@error{Unknown function `\pgfmath@function'}{}% + \def\pgfmathresult{0}% + \let\pgfmath@parse@next=\pgfmath@parse@end% + \else% + \expandafter\ifnum\csname pgfmath@operation@\pgfmath@function @arity\endcsname=0\relax% + % Functions with zero arity are called directly. + \csname pgfmath\pgfmath@function @\endcsname% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \let\pgfmath@parse@next=\pgfmath@parse@@operator% + \else% Otherwise, they are pushed onto the operator stack + \expandafter\pgfmath@stack@push@operation\expandafter{\pgfmath@function}% + \let\pgfmath@parse@next=\pgfmath@parse@@operand% + \fi% + \fi% + \expandafter\pgfmath@parse@next\pgfmath@token} % Parse an operator. % \def\pgfmath@parse@operator{\pgfmath@parse@ifbgroup{\pgfmath@parse@operator}{\pgfmath@parse@operator@}}% \def\pgfmath@parse@operator@#1{% Get one token. - \let\pgfmath@token=\pgfmath@token@next% - \def\pgfmath@token@next{#1}% - \pgfmath@parse@@@operator} + \let\pgfmath@token=\pgfmath@token@next% + \def\pgfmath@token@next{#1}% + \pgfmath@parse@@@operator} \def\pgfmath@parse@@operator{\pgfmath@parse@ifbgroup{\pgfmath@parse@@operator}{\pgfmath@parse@@operator@}}% \def\pgfmath@parse@@operator@#1{% Get first token... - \def\pgfmath@token{#1}% - \pgfmath@parse@ifbgroup{\pgfmath@parse@@operator@@}{\pgfmath@parse@@operator@@}}% + \def\pgfmath@token{#1}% + \pgfmath@parse@ifbgroup{\pgfmath@parse@@operator@@}{\pgfmath@parse@@operator@@}}% \def\pgfmath@parse@@operator@@#1{% ...and second token. - \def\pgfmath@token@next{#1}% - \pgfmath@parse@@@operator} + \def\pgfmath@token@next{#1}% + \pgfmath@parse@@@operator} \def\pgfmath@parse@@@operator{% - \expandafter\ifx\csname pgfmath@operator@\pgfmath@token\expandafter\string\pgfmath@token@next\endcsname\relax% - % Not a double character operator. - \expandafter\ifx\csname pgfmath@operator@\pgfmath@token\endcsname\relax% - % Not a single character operator. - \pgfmath@error{Unknown operator `\pgfmath@token' or `\pgfmath@token\pgfmath@token@next'}{}% - \def\pgfmathresult{0}% - \let\pgfmath@parse@next=\pgfmath@parse@end% - \else% - \expandafter\pgfmath@operation@process\expandafter{\pgfmath@token}% - \ifx\pgfmath@token\pgfmath@text@@% - \let\pgfmath@parse@next=\pgfmath@parse@end% - \else% - \expandafter\ifx\csname pgfmath@operation@\pgfmath@token @postfix\endcsname\pgfmath@token% - % Postfix operators are followed by an operator. - \ifx\pgfmath@token@next\pgfmath@char@leftbracket% Except [. - \let\pgfmath@parse@next=\pgfmath@parse@operand% - \else% - \let\pgfmath@parse@next=\pgfmath@parse@operator% - \fi% - \else% - % Any other operator is followed by an operand. - \let\pgfmath@parse@next=\pgfmath@parse@operand% - \fi% - \fi% - \fi% - \else% - % A double character operator... - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% - \pgfmath@token\expandafter\expandafter\expandafter% - {\expandafter\pgfmath@token\pgfmath@token@next}% - \expandafter\pgfmath@operation@process\expandafter{\pgfmath@token}% - % ...is always followed by an operand. - \let\pgfmath@parse@next=\pgfmath@parse@@operand% - \fi% - \pgfmath@parse@next% + \expandafter\ifx\csname pgfmath@operator@\pgfmath@token\expandafter\string\pgfmath@token@next\endcsname\relax% + % Not a double character operator. + \expandafter\ifx\csname pgfmath@operator@\pgfmath@token\endcsname\relax% + % Not a single character operator. + \pgfmath@error{Unknown operator `\pgfmath@token' or `\pgfmath@token\pgfmath@token@next'}{}% + \def\pgfmathresult{0}% + \let\pgfmath@parse@next=\pgfmath@parse@end% + \else% + \expandafter\pgfmath@operation@process\expandafter{\pgfmath@token}% + \ifx\pgfmath@token\pgfmath@text@@% + \let\pgfmath@parse@next=\pgfmath@parse@end% + \else% + \expandafter\ifx\csname pgfmath@operation@\pgfmath@token @postfix\endcsname\pgfmath@token% + % Postfix operators are followed by an operator. + \ifx\pgfmath@token@next\pgfmath@char@leftbracket% Except [. + \let\pgfmath@parse@next=\pgfmath@parse@operand% + \else% + \let\pgfmath@parse@next=\pgfmath@parse@operator% + \fi% + \else% + % Any other operator is followed by an operand. + \let\pgfmath@parse@next=\pgfmath@parse@operand% + \fi% + \fi% + \fi% + \else% + % A double character operator... + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% + \pgfmath@token\expandafter\expandafter\expandafter% + {\expandafter\pgfmath@token\pgfmath@token@next}% + \expandafter\pgfmath@operation@process\expandafter{\pgfmath@token}% + % ...is always followed by an operand. + \let\pgfmath@parse@next=\pgfmath@parse@@operand% + \fi% + \pgfmath@parse@next% } % Process an operation. % \def\pgfmath@operation@process#1{% - \def\pgfmath@operator{#1}% - \ifx\pgfmath@stack@operation@top\pgfmath@stack@empty% - \else% - \pgfmath@operation@@process% - \fi% - \expandafter\ifx\csname pgfmath@token@specials@#1\endcsname\relax% - \pgfmath@stack@push@operation{#1}% - \fi% + \def\pgfmath@operator{#1}% + \ifx\pgfmath@stack@operation@top\pgfmath@stack@empty% + \else% + \pgfmath@operation@@process% + \fi% + \expandafter\ifx\csname pgfmath@token@specials@#1\endcsname\relax% + \pgfmath@stack@push@operation{#1}% + \fi% } % Process the operation stack. % \def\pgfmath@operation@@process{% - \ifx\pgfmath@stack@operation@top\pgfmath@stack@empty% - \let\pgfmath@parse@next=\relax% - \else% - \ifnum\csname pgfmath@operation@\pgfmath@operator @precedence\endcsname>% - \csname pgfmath@operation@\pgfmath@stack@operation@top @precedence\endcsname\relax% - % If the precedence of the scanned operator is greater than the - % precedence of the operator at the top of the stack, do nothing. - \let\pgfmath@parse@next=\relax% - \else% - \let\pgfmath@stack@operation@last=\pgfmath@stack@operation@top% - \expandafter\ifx\csname pgfmath@operator@\pgfmath@stack@operation@top\endcsname\relax% - \pgfmath@function@@@process% - \else% - \pgfmath@operator@@@process% - \fi% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \expandafter\ifx\csname pgfmath@token@group@\pgfmath@stack@operation@last\pgfmath@operator\endcsname\relax% - \let\pgfmath@parse@next=\pgfmath@operation@@process% - \else% - \let\pgfmath@parse@next=\relax% - \fi% - \fi% - \fi% - \pgfmath@parse@next% + \ifx\pgfmath@stack@operation@top\pgfmath@stack@empty% + \let\pgfmath@parse@next=\relax% + \else% + \ifnum\csname pgfmath@operation@\pgfmath@operator @precedence\endcsname>% + \csname pgfmath@operation@\pgfmath@stack@operation@top @precedence\endcsname\relax% + % If the precedence of the scanned operator is greater than the + % precedence of the operator at the top of the stack, do nothing. + \let\pgfmath@parse@next=\relax% + \else% + \let\pgfmath@stack@operation@last=\pgfmath@stack@operation@top% + \expandafter\ifx\csname pgfmath@operator@\pgfmath@stack@operation@top\endcsname\relax% + \pgfmath@function@@@process% + \else% + \pgfmath@operator@@@process% + \fi% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \expandafter\ifx\csname pgfmath@token@group@\pgfmath@stack@operation@last\pgfmath@operator\endcsname\relax% + \let\pgfmath@parse@next=\pgfmath@operation@@process% + \else% + \let\pgfmath@parse@next=\relax% + \fi% + \fi% + \fi% + \pgfmath@parse@next% } % Process an operator. % \def\pgfmath@operator@@@process{% Process an operator. - \pgfmath@stack@pop@operation\pgfmath@@operator% - \pgfmath@stack@pop@operand\pgfmath@operand@a% - \ifcase\csname pgfmath@operation@\pgfmath@@operator @arity\endcsname\relax% - % Zero arity operators (!). - \or% - \pgfmath@operator@@@@process{\pgfmath@operand@a}% - \or% - \pgfmath@stack@pop@operand\pgfmath@operand@b% - \pgfmath@operator@@@@process{\pgfmath@operand@b}{\pgfmath@operand@a}% - \or% - \pgfmath@stack@pop@operand\pgfmath@operand@b% - \expandafter\pgfmath@operator@@@@process\expandafter% - {\expandafter\pgfmath@operand@b\expandafter}\pgfmath@operand@a% - \else% - % No operators with more than tenary arity. - \fi% + \pgfmath@stack@pop@operation\pgfmath@@operator% + \pgfmath@stack@pop@operand\pgfmath@operand@a% + \ifcase\csname pgfmath@operation@\pgfmath@@operator @arity\endcsname\relax% + % Zero arity operators (!). + \or% + \pgfmath@operator@@@@process{\pgfmath@operand@a}% + \or% + \pgfmath@stack@pop@operand\pgfmath@operand@b% + \pgfmath@operator@@@@process{\pgfmath@operand@b}{\pgfmath@operand@a}% + \or% + \pgfmath@stack@pop@operand\pgfmath@operand@b% + \expandafter\pgfmath@operator@@@@process\expandafter% + {\expandafter\pgfmath@operand@b\expandafter}\pgfmath@operand@a% + \else% + % No operators with more than tenary arity. + \fi% } \def\pgfmath@operator@@@@process{% - \csname pgfmath% - \csname pgfmath@operation@\pgfmath@@operator @name\endcsname% - @\endcsname} + \csname pgfmath% + \csname pgfmath@operation@\pgfmath@@operator @name\endcsname% + @\endcsname} % Process a function. % \def\pgfmath@function@@@process{% Process a function. - \ifnum\csname pgfmath@operation@\pgfmath@stack@operation@top @arity\endcsname>0\relax% - \pgfmath@stack@pop@operation\pgfmath@@function% - \pgfmath@stack@pop@operand\pgfmath@@operand% - \ifnum\csname pgfmath@operation@\pgfmath@@function @arity\endcsname>1\relax% - \ifnum\csname pgfmath@operation@\pgfmath@@function @arity\endcsname>9\relax% - \csname pgfmath\pgfmath@@function @\endcsname{\pgfmath@@operand}% - \else% - \expandafter\pgfmath@function@@@@process\pgfmath@@operand% - \fi - \else% - \expandafter\pgfmath@function@@@@process\expandafter{\pgfmath@@operand}% - \fi% - \fi% + \ifnum\csname pgfmath@operation@\pgfmath@stack@operation@top @arity\endcsname>0\relax% + \pgfmath@stack@pop@operation\pgfmath@@function% + \pgfmath@stack@pop@operand\pgfmath@@operand% + \ifnum\csname pgfmath@operation@\pgfmath@@function @arity\endcsname>1\relax% + \ifnum\csname pgfmath@operation@\pgfmath@@function @arity\endcsname>9\relax% + \csname pgfmath\pgfmath@@function @\endcsname{\pgfmath@@operand}% + \else% + \expandafter\pgfmath@function@@@@process\pgfmath@@operand% + \fi + \else% + \expandafter\pgfmath@function@@@@process\expandafter{\pgfmath@@operand}% + \fi% + \fi% } \def\pgfmath@function@@@@process{\csname pgfmath\pgfmath@@function @\endcsname} @@ -616,32 +730,32 @@ \let\pgfmath@stack@empty=\pgfmath@empty \def\pgfmath@stack@push#1#2{% - \def\pgfmath@stack@top{#2}% - \expandafter\expandafter\expandafter#1% - \expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter% - {\expandafter\pgfmath@stack@top\expandafter}\the#1}}% + \def\pgfmath@stack@top{#2}% + \expandafter\expandafter\expandafter#1% + \expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter% + {\expandafter\pgfmath@stack@top\expandafter}\the#1}}% \def\pgfmath@stack@pop#1#2{\expandafter\pgfmath@stack@@pop\the#1\pgfmath@stack@stop{#1}{#2}} \def\pgfmath@stack@@pop#1#2#3\pgfmath@stack@stop#4#5{\def#5{#1}#4={{#2}#3}\def\pgfmath@stack@top{#2}} \def\pgfmath@stack@push@operation#1{% - \pgfmath@stack@push\pgfmath@stack@operation{#1}% - \let\pgfmath@stack@operation@top=\pgfmath@stack@top} + \pgfmath@stack@push\pgfmath@stack@operation{#1}% + \let\pgfmath@stack@operation@top=\pgfmath@stack@top} \def\pgfmath@stack@pop@operation#1{% - \pgfmath@stack@pop\pgfmath@stack@operation{#1}% - \let\pgfmath@stack@operation@top=\pgfmath@stack@top} - + \pgfmath@stack@pop\pgfmath@stack@operation{#1}% + \let\pgfmath@stack@operation@top=\pgfmath@stack@top} + % REMARK: This method will be overwritten by the FPU library. Please % keep any changes consistent. \def\pgfmath@stack@push@operand#1{% - \pgfmath@stack@push\pgfmath@stack@operand{#1}% - \let\pgfmath@stack@operand@top=\pgfmath@stack@top} + \pgfmath@stack@push\pgfmath@stack@operand{#1}% + \let\pgfmath@stack@operand@top=\pgfmath@stack@top} \def\pgfmath@stack@pop@operand#1{% - \pgfmath@stack@pop\pgfmath@stack@operand{#1}% - \let\pgfmath@stack@operand@top=\pgfmath@stack@top} - + \pgfmath@stack@pop\pgfmath@stack@operand{#1}% + \let\pgfmath@stack@operand@top=\pgfmath@stack@top} + % Declare an operator for the parser. % @@ -649,13 +763,20 @@ % the parser is not fully robust for arbitrary operators. % \def\pgfmathdeclareoperator#1#2#3#4#5{% - \pgfmath@namedef{pgfmath@operator@\string#1}{#1}% - \pgfmath@namedef{pgfmath@operation@\string#1@name}{#2}% - \pgfmath@namedef{pgfmath@operation@\string#1@arity}{#3}% - \pgfmath@namedef{pgfmath@operation@\string#1@#4}{#1}% - \pgfmath@namedef{pgfmath@operation@\string#1@precedence}{#5}% + \ifx\pgfmath@operatorlist\pgfutil@empty + \edef\pgfmath@operatorlist{{\string#1}}% + \else + \edef\pgfmath@operatorlist{\pgfmath@operatorlist,{\string#1}}% + \fi + \pgfmath@namedef{pgfmath@operator@\string#1}{#1}% + \pgfmath@namedef{pgfmath@operation@\string#1@name}{#2}% + \pgfmath@namedef{pgfmath@operation@\string#1@arity}{#3}% + \pgfmath@namedef{pgfmath@operation@\string#1@#4}{#1}% + \pgfmath@namedef{pgfmath@operation@\string#1@precedence}{#5}% } +\def\pgfmath@operatorlist{} + \pgfmathdeclareoperator{+}{add} {2}{infix}{500} \pgfmathdeclareoperator{-}{subtract}{2}{infix}{500} \pgfmathdeclareoperator{*}{multiply}{2}{infix}{700} @@ -671,7 +792,7 @@ \pgfmathdeclareoperator{<=}{notgreater}{2}{infix} {250} \pgfmathdeclareoperator{&&}{and} {2}{infix} {200} \pgfmathdeclareoperator{||}{or} {2}{infix} {200} -\pgfmathdeclareoperator{!=}{notequalto}{2}{infix} {250} +\pgfmathdeclareoperator{!=}{notequal} {2}{infix} {250} \pgfmathdeclareoperator{!} {not} {1}{prefix}{975} \pgfmathdeclareoperator{?} {ifthenelse}{3}{infix} {100} \pgfmathdeclareoperator{:} {@@collect} {2}{infix}{101} @@ -702,11 +823,11 @@ % Begin and end array access []. % \def\pgfmath@startindex@#1#2{% - \expandafter\pgfmatharray@#1{#2}% - \expandafter\pgfmath@bgroup@strip\expandafter{\pgfmathresult}% - \ifx\pgfmath@token@let\bgroup% - \expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{\pgfmathresult}}% - \fi} + \expandafter\pgfmatharray@#1{#2}% + \expandafter\pgfmath@bgroup@strip\expandafter{\pgfmathresult}% + \ifx\pgfmath@token@let\bgroup% + \expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{\pgfmathresult}}% + \fi} \def\pgfmath@endindex@{}% Never actually called. % Begin and end array {}. @@ -716,57 +837,63 @@ \def\pgfmath@@collect@#1#2{% - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% - \pgfmathresult\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter% - {\expandafter#1\expandafter}\expandafter{#2}}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% + \pgfmathresult\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter% + {\expandafter#1\expandafter}\expandafter{#2}}% } % Collect items separated by ,. % \def\pgfmath@collect@#1#2{% - \expandafter\def\expandafter\pgfmath@collect@original\expandafter{#1}% - \expandafter\pgfmath@bgroup@strip\expandafter{#1}% - \ifx\pgfmath@token@let\bgroup% - \ifx\pgfmath@collect@original\pgfmath@bgroup@stripped% - \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmath@bgroup@stripped}% - \else% - \expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{\pgfmath@bgroup@stripped}}% - \fi% - \else% - \expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{\pgfmath@bgroup@stripped}}% - \fi% - \expandafter\pgfmath@bgroup@strip\expandafter{#2}% - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% - \pgfmathresult\expandafter\expandafter\expandafter% - {\expandafter\pgfmathresult\expandafter{\pgfmath@bgroup@stripped}}% + \expandafter\def\expandafter\pgfmath@collect@original\expandafter{#1}% + \expandafter\pgfmath@bgroup@strip\expandafter{#1}% + \ifx\pgfmath@token@let\bgroup% + \ifx\pgfmath@collect@original\pgfmath@bgroup@stripped% + \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmath@bgroup@stripped}% + \else% + \expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{\pgfmath@bgroup@stripped}}% + \fi% + \else% + \expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{\pgfmath@bgroup@stripped}}% + \fi% + \expandafter\pgfmath@bgroup@strip\expandafter{#2}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% + \pgfmathresult\expandafter\expandafter\expandafter% + {\expandafter\pgfmathresult\expandafter{\pgfmath@bgroup@stripped}}% } % Strip braces from a token sequence. % \def\pgfmath@bgroup@strip#1{% - \def\pgfmath@bgroup@strip@last{#1}% - \pgfmath@bgroup@@strip{#1}\pgfmath@\pgfmath@@\pgfmath@@@} + \def\pgfmath@bgroup@strip@last{#1}% + \pgfmath@bgroup@@strip{#1}\pgfmath@\pgfmath@@\pgfmath@@@} \def\pgfmath@bgroup@strip@#1{% - \def\pgfmath@bgroup@strip@last{#1}% - \pgfmath@bgroup@@strip#1\pgfmath@\pgfmath@@\pgfmath@@@} + \def\pgfmath@bgroup@strip@last{#1}% + \pgfmath@bgroup@@strip#1\pgfmath@\pgfmath@@\pgfmath@@@} \def\pgfmath@bgroup@pgfmath@{\pgfmath@} -\def\pgfmath@bgroup@@strip{\futurelet\pgfmath@token@let\pgfmath@bgroup@@@strip} -\def\pgfmath@bgroup@@@strip#1#2#3\pgfmath@@@{% - \ifx\pgfmath@token@let\bgroup% - \def\pgfmath@bgroup@test{#2}% - \ifx\pgfmath@bgroup@test\pgfmath@bgroup@pgfmath@% - \def\pgfmath@next{\pgfmath@bgroup@strip@{#1}}% - \else% - \let\pgfmath@bgroup@stripped=\pgfmath@bgroup@strip@last% - \let\pgfmath@next=\relax% - \fi% - \else% - \pgfmath@bgroup@@@@strip#1#2#3% - \let\pgfmath@next=\relax% - \fi% - \pgfmath@next% -} +\def\pgfmath@bgroup@@strip{% + \futurelet\pgfmath@token@let\pgfmath@bgroup@@@strip} -\def\pgfmath@bgroup@@@@strip#1\pgfmath@\pgfmath@@{\def\pgfmath@bgroup@stripped{#1}}% +\def\pgfmath@bgroup@@@strip#1#2#3\pgfmath@@@{% + \ifx\pgfmath@token@let\bgroup + \def\pgfmath@bgroup@test{#2}% + \ifx\pgfmath@bgroup@test\pgfmath@bgroup@pgfmath@ + \def\pgfmath@next{\pgfmath@bgroup@strip@{#1}}% + \else + \let\pgfmath@bgroup@stripped=\pgfmath@bgroup@strip@last + \let\pgfmath@next=\relax + \fi + \else + \pgfmath@bgroup@@@@strip#1#2#3% + \let\pgfmath@next=\relax + \fi + \pgfmath@next} + +\def\pgfmath@bgroup@@@@strip#1\pgfmath@\pgfmath@@{% + \def\pgfmath@bgroup@stripped{#1}} + +% Local Variables: +% tab-width: 2 +% End:
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathutil.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathutil.code.tex index 5e353007618..44d39c75b6a 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathutil.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathutil.code.tex @@ -80,7 +80,7 @@ \let\pgfmath@yc\pgf@yc \let\pgfmath@tempdima\pgfutil@tempdima -\let\pgfmath@tempdima\pgfutil@tempdima +\let\pgfmath@tempdimb\pgfutil@tempdimb \let\c@pgfmath@counta\c@pgf@counta \let\c@pgfmath@countb\c@pgf@countb @@ -177,7 +177,7 @@ \let\pgfmath@PackageWarning\PackageWarning% \fi% \ifx\PackageError\pgfmath@undefined - \def\pgfmath@PackageError#1#2#3{\immediate\write-1{Package #1: Error! #2.}}% + \def\pgfmath@PackageError#1#2#3{\errmessage{Package #1 Error: #2.}}% \else% \let\pgfmath@PackageError\PackageError% \fi% diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulebending.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulebending.code.tex new file mode 100644 index 00000000000..f0a28bfff68 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulebending.code.tex @@ -0,0 +1,355 @@ +% Copyright 2013 by Till Tantau +% +% This file may be distributed and/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 details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulebending.code.tex,v 1.18 2013/09/30 18:30:15 tantau Exp $ + + +% +% This file defines commands for drawing bending arrows and lines. +% + +\usepgfmodule{nonlineartransformations} +\usepgflibrary{curvilinear} + + +% Configuration options for arrow tips: + +\pgfkeys{ + /pgf/arrow keys/flex/.code=\pgfarrowsaddtooptions{\pgf@arrows@the@rigidity#1pt\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@flex}, + /pgf/arrow keys/flex/.default=1, + /pgf/arrow keys/flex'/.code=\pgfarrowsaddtooptions{\pgf@arrows@the@rigidity#1pt\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@flex@prime}, + /pgf/arrow keys/flex'/.default=1, + /pgf/arrow keys/bend/.code=\pgfarrowsaddtooptions{\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@bend} +} + + +\def\pgf@arrow@mode@is@flex{1} +\def\pgf@arrow@mode@is@flex@prime{2} +\def\pgf@arrow@mode@is@bend{3} + +\newdimen\pgf@arrows@the@rigidity + +% +% +% Handle the end of a curve +% +% + +% First, the preparation. This is, essenatially, setting up the +% nonlinear transformation + +\def\pgf@prep@curveend{ + \pgftransformreset% + \pgfsetcurvilinearbeziercurve{\pgfpointlastonpath}{\pgfpointsecondlastonpath}{\pgfpointthirdlastonpath}{\pgfpointfourthlastonpath} +} + +% Second, the shortening. + +\def\pgf@do@shorten@curvedend{% + \expandafter\expandafter\expandafter\pgf@do@shorten@curvedend@unpack\expandafter\pgfpointfourthlastonpath\pgfpointthirdlastonpath% +} +\def\pgf@do@shorten@curvedend@unpack\pgfqpoint#1#2\pgfqpoint#3#4{% + \pgf@process{\pgfcurvilineardistancetotime{\pgf@path@shortening@distance}}% + % Compute new curve: + \pgfpointcurveattime{\pgf@x}{\pgfpointlastonpath}{\pgfpointsecondlastonpath}{\pgfpointthirdlastonpath}{\pgfpointfourthlastonpath}% + % \pgfx/y and \pgf xa/xb already correct. Need to setup remaining vector... + \pgf@xb#3% + \pgf@yb#4% + \pgf@xb\pgf@time@t\pgf@xb% + \pgf@yb\pgf@time@t\pgf@yb% + \advance\pgf@xb by\pgf@time@s\pgf@xc% + \advance\pgf@yb by\pgf@time@s\pgf@yc% + \edef\pgfprocessresultsubpathsuffix{% + \expandafter\noexpand\pgfsubpathfourthlasttoken{#1}{#2}% + \noexpand\pgfsyssoftpath@curvetosupportatoken{\the\pgf@xb}{\the\pgf@yb}% + \noexpand\pgfsyssoftpath@curvetosupportbtoken{\the\pgf@xa}{\the\pgf@ya}% + \noexpand\pgfsyssoftpath@curvetotoken{\the\pgf@x}{\the\pgf@y}}% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgfprocessresultpathsuffix% + \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultsubpathprefix\pgfprocessresultsubpathsuffix}% +} + +% Third, the drawing + +\def\pgf@do@draw@curvedend{% + \pgf@do@draw@curved\pgf@end@tip@sequence% +} + +\def\pgf@do@draw@curved#1{% + {% + \pgftransformreset% + \pgf@xb\pgf@arrow@tip@total@length% xb will keep track of the total length + \let\pgf@arrow@handle\pgf@draw@curved% + \let\pgf@arrow@handle@dot\relax% + #1% + }% +} + +\def\pgf@draw@curved#1#2{% + % Prepare: + {% + \pgfarrows@getid{#1}{#2}% + % Do shift: + \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid@shift\csname pgf@ar@ends@\pgf@arrow@id\endcsname% + \expandafter\let\expandafter\pgf@arrow@bending@mode\csname pgf@ar@bending@mode@#1\endcsname% + \ifx\pgf@arrow@bending@mode\pgfutil@empty\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@flex\fi% + % do swap: + {% + \csname pgf@ar@saves@\pgf@arrow@id\endcsname% + \ifcase\pgf@arrow@flex@mode\relax% + \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid\csname pgf@ar@visual@\pgf@arrow@id\endcsname% like flex + \or% + \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid\csname pgf@ar@visual@\pgf@arrow@id\endcsname% + \or% + \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid\csname pgf@ar@ends@\pgf@arrow@id\endcsname% + \or% + \pgf@arrow@drawer@bend% + \fi% + % hull points inside the above + }% + \expandafter}% + % Transform to next tip: + \expandafter\pgf@xb\the\pgf@xb% +} +\def\pgf@falsetext{false} + +\def\pgf@arrow@drawer@rigid@shift#1#2#3{% tip end, back end, line end, sep + % Let xa be the actual back end of the current arrow plus the back end: + \advance\pgf@xb by#2% + \pgf@xa\pgf@xb% + % Update the xb: + \pgf@x#1% + \advance\pgf@x by\pgfarrowsep% + \advance\pgf@xb by-\pgf@x% +} + + +\def\pgf@arrow@drawer@bend{% + \pgftransformnonlinear{\pgf@arrow@bending@mode{\pgf@x}{\pgf@y}} + \pgftransformscale{-1}% + \pgftransformxshift{-\pgf@xa}% + % Do slant: + \ifdim\pgfarrows@slant pt=0pt% + \else% + \pgftransformxslant{\pgfarrows@slant}% + \fi% + \ifpgfarrowswap% + \pgftransformyscale{-1}% + \fi% + {% + \pgf@relevantforpicturesizefalse% + \pgfscope% + \pgf@arrows@color@setup% + \csname pgf@ar@inst@code@\pgf@arrow@id\endcsname% + \endpgfscope% + }% + \pgf@arrows@bending@hull% +} + +\def\pgf@arrow@drawer@rigid#1#2#3{% (rigid) start, (rigid) end, dummy + % Compute the rigid positions: + \pgf@x#1% start + \pgf@y#2% flexibility*(end-start) + start + \advance\pgf@y by-\pgf@x% + \pgf@y\pgf@sys@tonumber\pgf@arrows@the@rigidity\pgf@y% + \advance\pgf@y by\pgf@x% + % Are they equal? + \ifdim\pgf@x=\pgf@y% + % Yes, do tangent: + \pgf@bending@do@tangent% + \else% + \pgf@bending@do@flex% + \fi% + \pgf@xc#1% + \pgf@xc-\pgf@xc% + \pgftransformxshift{+\pgf@xc}% + % Do slant: + \ifdim\pgfarrows@slant pt=0pt% + \else% + \pgftransformxslant{\pgfarrows@slant}% + \fi% + % do swap: + \ifpgfarrowswap% + \pgftransformyscale{-1}% + \fi% + \pgfscope% + \pgf@arrows@color@setup% + \pgflowlevelsynccm\csname pgf@ar@cache@\pgf@arrow@id\endcsname% + \endpgfscope% + \pgf@arrows@rigid@hull% +} + +\def\pgf@bending@do@tangent{% + \pgf@xb\pgf@xa% + \advance\pgf@xb by-\pgf@x% + \pgfcurvilineardistancetotime{\pgf@xb}% + \pgf@xb\pgf@x% + % Compute points: + \ifdim\pgf@xb=0pt% + \pgf@bending@possible@degenerate% + \else% + \pgf@bending@do@tangent@normal% + \fi% + \pgf@ya-\pgf@y% + \pgfsettransformentries% + {\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}% + {\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@x}{\pgf@xc}{\pgf@yc}% +}% + +\def\pgf@bending@do@tangent@normal{% + \pgfpointcurveattime{\pgf@xb}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}% + \pgf@xc\pgf@x% save + \pgf@yc\pgf@y% save + % compute normal: + \advance\pgf@xb by-\pgf@xa% + \advance\pgf@yb by-\pgf@ya% + \pgf@process{\pgfpointnormalised{\pgf@x=\pgf@xb\pgf@y=\pgf@yb}} +} + +\def\pgf@bending@possible@degenerate{% + \ifx\pgf@curvilinear@line@a\pgf@curvilinear@line@b% degenerate! + \ifx\pgf@curvilinear@line@a\pgf@curvilinear@line@c% double degenerate! + \let\pgf@ref\pgf@curvilinear@line@d% + \else + \let\pgf@ref\pgf@curvilinear@line@c% + \fi% + \pgf@process{\pgf@curvilinear@line@a}% + \pgf@xc\pgf@x% save + \pgf@yc\pgf@y% save + \pgf@process{\pgf@ref}% + \advance\pgf@x by-\pgf@xc + \advance\pgf@y by-\pgf@yc + \pgf@process{\pgfpointnormalised{}} + \pgf@x-\pgf@x + \pgf@y-\pgf@y + \else% + \pgf@bending@do@tangent@normal% + \fi% +} + +\def\pgf@bending@do@flex{ + \pgf@xb\pgf@xa% + \pgf@xc\pgf@xa% + \advance\pgf@xc by-\pgf@x% + \advance\pgf@xb by-\pgf@y% + \pgfcurvilineardistancetotime{\pgf@xc}% + \pgf@xc\pgf@x% + \pgfcurvilineardistancetotime{\pgf@xb}% + \pgf@xb\pgf@x% + % Compute points: + \pgf@process{\pgfpointcurveattime{\pgf@xc}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}}% + \pgf@xc\pgf@x\pgf@yc\pgf@y% + \pgf@process{\pgfpointcurveattime{\pgf@xb}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}}% + \pgf@xb\pgf@x\pgf@yb\pgf@y% + \pgftransformarrow{\pgfqpoint{\pgf@xb}{\pgf@yb}}{\pgfqpoint{\pgf@xc}{\pgf@yc}}% +} + + + + + + +% Convex hull stuff: + +\def\pgf@arrows@bending@hull{% + \ifpgf@relevantforpicturesize% + % Do bb update: + \expandafter\let\expandafter\pgf@temp\csname pgf@ar@hull@\pgf@arrow@id\endcsname% + \ifx\pgf@temp\pgfutil@empty\else% + \let\pgf@arrow@hull@point\pgf@arrow@bending@hull@point@first% + \pgf@temp% + \pgf@arrow@bending@update@bb% + \fi% + \fi% +} + +\def\pgf@arrow@bending@hull@point@first#1#2{% + \pgfpointtransformednonlinear{\pgfqpoint{#1}{#2}}% + \pgf@xa\pgf@x\pgf@xb\pgf@x% + \pgf@ya\pgf@y\pgf@yb\pgf@y% + \let\pgf@arrow@hull@point\pgf@arrow@bending@hull@point@other% +} +\def\pgf@arrow@bending@hull@point@other#1#2{% + \pgfpointtransformednonlinear{\pgfqpoint{#1}{#2}}% + \ifdim\pgf@x<\pgf@xa\pgf@xa\pgf@x\else\ifdim\pgf@x>\pgf@xb\pgf@xb\pgf@x\fi\fi% + \ifdim\pgf@y<\pgf@ya\pgf@ya\pgf@y\else\ifdim\pgf@y>\pgf@yb\pgf@yb\pgf@y\fi\fi% +} + +\def\pgf@arrow@bending@update@bb{% + \ifdim\pgf@picmaxx=-16000pt\relax% + \global\pgf@picminx\pgf@xa% + \global\pgf@picmaxx\pgf@xb% + \global\pgf@picminy\pgf@ya% + \global\pgf@picmaxy\pgf@yb% + \else% + \ifdim\pgf@xa<\pgf@picminx\global\pgf@picminx\pgf@xa\fi% + \ifdim\pgf@ya<\pgf@picminy\global\pgf@picminy\pgf@ya\fi% + \ifdim\pgf@xb>\pgf@picmaxx\global\pgf@picmaxx\pgf@xb\fi% + \ifdim\pgf@yb>\pgf@picmaxy\global\pgf@picmaxy\pgf@yb\fi% + \fi% +} + + + + +% +% +% Handle the start of a curve +% +% + + +% First, the preparation. + +\def\pgf@prep@curvedstart{ + \pgftransformreset% + \pgfsetcurvilinearbeziercurve{\pgfpointfirstonpath}{\pgfpointsecondonpath}{\pgfpointthirdonpath}{\pgfpointfourthonpath}% +} + +% Second, the shortening. + +\def\pgf@do@shorten@curvedstart{% + \expandafter\expandafter\expandafter\pgf@do@shorten@curvedstart@unpack\expandafter\pgfpointthirdonpath\pgfpointfourthonpath% +} +\def\pgf@do@shorten@curvedstart@unpack\pgfqpoint#1#2\pgfqpoint#3#4{% + \pgf@process{\pgfcurvilineardistancetotime{\pgf@path@shortening@distance}}% + % Compute new curve: + \pgfpointcurveattime{\pgf@x}{\pgfpointfirstonpath}{\pgfpointsecondonpath}{\pgfpointthirdonpath}{\pgfpointfourthonpath}% + % \pgfx/y and \pgf xa/xb already correct. Need to setup remaining vector... + \pgf@xb#1% + \pgf@yb#2% + \pgf@xb\pgf@time@t\pgf@xb% + \pgf@yb\pgf@time@t\pgf@yb% + \advance\pgf@xb by\pgf@time@s\pgf@xc% + \advance\pgf@yb by\pgf@time@s\pgf@yc% + \edef\pgfpointfirstonpath{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \edef\pgfpointsecondonpath{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}% + \edef\pgfprocessresultpathsuffix{% + \noexpand\pgfsyssoftpath@movetotoken{\the\pgf@x}{\the\pgf@y}% + \noexpand\pgfsyssoftpath@curvetosupportatoken{\the\pgf@xa}{\the\pgf@ya}% + \noexpand\pgfsyssoftpath@curvetosupportbtoken{\the\pgf@xb}{\the\pgf@yb}% + \noexpand\pgfsyssoftpath@curvetotoken{#3}{#4}% + } + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgfprocessresultpathsuffix% + \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultpathsuffix\pgfsubpathend}% +} + + +% Third, the drawing + +\def\pgf@do@draw@curvedstart{% + \pgf@do@draw@curved\pgf@start@tip@sequence% +} + + + + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex index 1c78bb221e6..243f8ce225d 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduledatavisualization.code.tex,v 1.37 2010/08/24 21:28:58 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduledatavisualization.code.tex,v 1.47 2013/07/19 13:16:48 tantau Exp $ \usepgfmodule{oo,shapes} \usepgflibrary{fpu} @@ -156,6 +156,7 @@ \def\pgfdvpathlinetotoken{6} \def\pgfdvdirectionfromtoken{7} \def\pgfdvdirectiontotoken{8} + \def\pgfdvdirectionattoken{9} % Method % @@ -169,7 +170,10 @@ % Add data that is to be visualized. The code #1 should call the % \pgfdatapoint macro for each data point it creates. \method add data(#1) { - \pgfooappend{data}{#1} + \pgf@dv@stripped@add#1\pgf@stop + } + \def\pgf@dv@stripped@add#1\pgf@stop{% + \pgfooappend{data}{#1}% } @@ -480,20 +484,22 @@ -% Compute a normalized vector pointing from some point to another. +% Compute a normalized vector at the current point pointing along a +% line from #1 to #2. % % #1 = code for setting the attributes of the first point % #2 = code for setting the attributes of the second point % -% Using #1 and #2 you specify two data points. These are then -% localized on the canvas and a vector pointing from the first data -% point to the second one is returned. However, for instance in polar +% The current point should be a point on a line from #1 to +% #2. Both points as well as the current point are +% localized on the canvas and a vector pointing from the first point +% to the second one is returned. However, for instance in polar % coordinates the vector may actually "point along" the angle axis. % % Internally, this command first sets up the first data point and then -% emits a "path" signal with the \pgfdvpathdirectionfromtoken set and +% emits a "direction" signal with the \pgfdvpathdirectionfromtoken set and % then sets up the second point and emits the corresponding -% ...totoken. +% ...totoken. Finally, the \pgfdvpathdirectionattoken is emitted. % \def\pgfpointdvdirection#1#2{% @@ -504,16 +510,14 @@ } { #2 - \pgfdv@generic{\pgf@signaldirection}{\pgfdvdirectiontotoken}{ - \edef\pgf@dv@dir@xa{\the\pgf@x} - \edef\pgf@dv@dir@ya{\the\pgf@y} + \pgfdv@generic{\pgf@signaldirection}{\pgfdvdirectiontotoken}{\xdef\pgf@dv@to{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}} + } + {\pgfdv@generic{\pgf@signaldirection}{\pgfdvdirectionattoken}{% \pgf@process{ \pgfpointnormalised{% - \pgfpointdiff{\pgf@dv@from}{\pgfqpoint{\pgf@dv@dir@xa}{\pgf@dv@dir@ya}} + \pgfpointdiff{\pgf@dv@from}{\pgf@dv@to} } - } - } - } + }}} } } @@ -529,7 +533,7 @@ -% Run the rendering pipeline on a dataset. +% Run the rendering pipeline on a dataset and/or save the dataset. % % #1 = options with path /pgf/data/ % #2 = optionally data given inline in curly braces. @@ -541,14 +545,27 @@ % accumulate. Data can be in different formats, as specified by the % "format" key, and you can define new formats. % -% The setting of the following keys is important: +% The settings of the following keys are important: +% +% /pgf/data visualization/obj +% contains a handle to the dv-object +% +% /pgf/data/format +% stores the format (see below) +% +% /pgf/data/read from file +% determines where the data is. +% +% /pgf/data/store in group +% when nonempty, the data is stored here instead of being fed to the +% rendering pipeline % -% /pgf/data visualization/obj contains a handle to the dv-object -% /pgf/data/format stores the format (see below) -% /pgf/data/source determines where the data is. +% /pgf/data/use group +% when nonempty, data that has previsouly been stored here using +% |define group| is read from here and all other keys are ignored % -% If source is empty, the data is stored in the argument that -% follows. Otherwise, the file whose name is stored in source is read. +% If "read from file" is empty, the data is stored in the argument that +% follows. Otherwise, the data is read from the specified source file. % This data is stored in an internal variable, which is local to the % current group. % @@ -594,51 +611,78 @@ % 2200, 2300, 2250, 2260 % } % -% \pgfdata[source=data,format=comma separated columns] +% \pgfdata[read from file=data.csv,format=comma separated columns] % % \dv.survey() % \dv.visualize() -\def\pgfdata{\pgfutil@ifnextchar[{\pgf@dataset@data@opt}{\pgf@dataset@data@opt[]}}%} -\def\pgf@dataset@data@opt[#1]{% +\def\pgfdata{\pgfutil@ifnextchar[{\pgf@datagroup@data@opt}{\pgf@datagroup@data@opt[]}}%} +\def\pgf@datagroup@data@opt[#1]{% % Ok, add one data thing... - \pgfkeysvalueof{/pgf/data visualization/obj}.add data(\pgf@do@data{#1})% \begingroup% \pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}% \pgfkeysgetvalue{/pgf/data/continue code}\pgf@dv@cont@code% \global\let\pgf@dv@cont@code\pgf@dv@cont@code% - \pgfkeysgetvalue{/pgf/data/format}\pgf@dv@format% - \expandafter\let\expandafter\pgf@dv@format@catcodes\csname pgfdv@format@\pgf@dv@format @catcodes\endcsname% - \ifx\pgf@dv@format@catcodes\relax - \PackageError{pgf}{Unknown data format '\pgf@dv@format'}{}% + \pgfkeysgetvalue{/pgf/data/use group}\pgf@dv@use@group% + \ifx\pgf@dv@use@group\pgfutil@empty% + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data(\pgf@do@data{#1})}% + \expandafter\pgf@datagroup@data@opt@cont% \else% - \pgfkeysgetvalue{/pgf/data/source}\pgf@dv@source% - \ifx\pgf@dv@source\pgfutil@empty% - \let\pgf@next\pgf@dataset@grab@inline% + \expandafter\ifx\csname pgf@dv@group@@\pgf@dv@use@group\endcsname\relax% + \pgferror{Undefined data group '\pgf@dv@use@group'}% \else% - \let\pgf@next\pgf@dataset@grab@external% + {% + \pgfkeys{/pgf/data/define group/.code=}% no redefinitions during use + \csname pgf@dv@group@@\pgf@dv@use@group\endcsname% + }% \fi% - \pgf@next% + \endgroup% + \expandafter\pgf@dv@cont@code% + \fi% +} +\def\pgf@datagroup@data@opt@cont{% + \pgfkeysgetvalue{/pgf/data/format}\pgf@dv@format% + \expandafter\let\expandafter\pgf@dv@format@catcodes\csname pgfdv@format@\pgf@dv@format @catcodes\endcsname% + \ifx\pgf@dv@format@catcodes\relax + \pgferror{Unknown data format '\pgf@dv@format'}% + \else% + \pgfkeysgetvalue{/pgf/data/read from file}\pgf@dv@source% + \ifx\pgf@dv@source\pgfutil@empty% + \let\pgf@next\pgf@datagroup@grab@inline% + \else% + \let\pgf@next\pgf@datagroup@grab@external% + \fi% + \pgf@next% } -\def\pgf@dataset@grab@inline{% + +\def\pgf@datagroup@grab@inline{% \pgfutil@ifnextchar\bgroup{% \begingroup% \catcode`\^^M=\active% \pgf@dv@format@catcodes% - \pgf@dataset@grab@@inline}% - {\PackageError{pgf}{Opening brace expected}{}}% + \pgf@datagroup@grab@@inline}% + {\pgferror{Opening brace expected}}% } -\def\pgf@dataset@grab@external{% +\def\pgf@datagroup@grab@external{% \fi% \endgroup% - \pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@dataset@do@external}}})% + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@datagroup@do@external}}})}% \pgf@dv@cont@code% } +\def\pgf@dv@do@adddata#1{% + \pgfkeysgetvalue{/pgf/data/store in group}\pgf@dv@temp% + \ifx\pgf@dv@temp\pgfutil@empty% + #1% + \else% + \expandafter\pgfutil@g@addto@macro\csname pgf@dv@group@@\pgf@dv@temp\endcsname{#1}% + \fi% +} + {\catcode`\^^M=\active% - \gdef\pgf@dataset@grab@@inline#1{% + \gdef\pgf@datagroup@grab@@inline#1{% \endgroup% - \pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@dataset@do@inline#1^^M\pgf@@eol}}})% + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@datagroup@do@inline#1^^M\pgf@@eol}}})}% \fi% \endgroup% \pgf@dv@cont@code% @@ -663,19 +707,19 @@ % Read external file % -\def\pgf@dataset@do@external{% +\def\pgf@datagroup@do@external{% \csname pgfdv@format@\pgfkeysvalueof{/pgf/data/format}@catcodes\endcsname% - \immediate\openin\r@pgf@reada=\pgfkeysvalueof{/pgf/data/source} % + \immediate\openin\r@pgf@reada=\pgfkeysvalueof{/pgf/data/read from file} % \ifeof\r@pgf@reada\relax - \PackageError{pgf}{Data source '\pgfkeysvalueof{/pgf/data/source}' not found}{}% + \pgferror{Data file '\pgfkeysvalueof{/pgf/data/read from file}' not found}% \else - \pgf@dataset@readline% + \pgf@datagroup@readline% \fi \immediate\closein\r@pgf@reada% } \def\pgf@partext{\par}% -\def\pgf@dataset@readline{% +\def\pgf@datagroup@readline{% \immediate\read\r@pgf@reada to \pgf@temp% \ifx\pgf@temp\pgf@partext% \pgf@dv@format@emptyline% @@ -686,7 +730,7 @@ \expandafter\pgf@dv@format@line\pgf@temp\pgfeol% \fi% \fi% - \ifeof\r@pgf@reada\else\expandafter\pgf@dataset@readline\fi% + \ifeof\r@pgf@reada\else\expandafter\pgf@datagroup@readline\fi% } @@ -694,7 +738,7 @@ % Read inline data % -\def\pgf@dataset@do@inline{% +\def\pgf@datagroup@do@inline{% \pgf@dv@handle@line% } @@ -712,8 +756,12 @@ \pgfkeys{ /pgf/data/data visualization obj/.initial=\undefined, /pgf/data/format/.initial=table,% the default format - /pgf/data/source/.initial=, - /pgf/data/continue code/.initial= + /pgf/data/read from file/.initial=, + /pgf/data/inline/.style={read from file=}, + /pgf/data/continue code/.initial=, + /pgf/data/store in group/.initial=, + /pgf/data/new group/.code={\expandafter\global\expandafter\let\csname pgf@dv@group@@#1\endcsname\pgfutil@empty}, + /pgf/data/use group/.initial=, } @@ -737,7 +785,7 @@ % a data set is visualized and the format is set to #1, this handler % is used to parse the data. % -% In detail, the \dataset command will select a source. Before this +% In detail, the \pgfdata command will select a source. Before this % source is read, #2 will be executed to setup the % catcodes. Additionally, each time the data is parsed, #3 will be % called. Then, for each nonempty line of the source, the @@ -791,12 +839,23 @@ % % Example: % -% \data[format=key value pairs] { +% \data[format=named] { % x=5, y=6, hi=9 % x=7, y=6, lo=10 % } -\pgfdeclaredataformat{key value pairs}{}{}{#1}{{\pgfkeys{/data point/.cd,#1}\pgfdatapoint}}{}{} +\pgfdeclaredataformat{named}{}{}{#1}{\pgf@dv@parse@named#1,\pgf@stop}{}{} +\def\pgf@dv@parse@named{% + \pgfutil@ifnextchar\pgf@stop{\pgfdatapoint\pgfutil@gobble}{\pgf@dv@parse@named@} +} +\def\pgf@dv@parse@named@#1=#2,#3\pgf@stop{% + \foreach \pgf@dv@temp in {#2} {% + \def\pgf@dv@tempb{/data point/#1=}% + \expandafter\expandafter\expandafter\pgfkeys% + \expandafter\expandafter\expandafter{\expandafter\pgf@dv@tempb\pgf@dv@temp}% + \pgf@dv@parse@named#3\pgf@stop% + } +} @@ -892,7 +951,7 @@ \def\pgf@dv@parse@table{% \pgfutil@ifnextchar"% Special, but ignored right now... - {\PackageError{pgf}{csv with quotes not yet implemented}{}} + {\pgferror{csv with quotes not yet implemented}} {\pgf@dv@till@separator} } \def\pgf@dv@table@handle#1{% @@ -924,7 +983,7 @@ \def\pgf@dv@doparse@headline{% \pgfutil@ifnextchar"% Special, but ignored right now... - {\PackageError{pgf}{csv with quotes not yet implemented}{}} + {\pgferror{csv with quotes not yet implemented}} {\pgf@dv@till@separator@head} } \def\pgf@dv@head@handle#1{% @@ -1158,6 +1217,27 @@ \let#1=\pgfmathresult% } +% Multiply by small number +% +% #1 = macro that should store the result of applying the +% corresponding operation to the following: +% #2 = entered number +% #3 = fixed point number like 2 or 0.5, but not 10000000000 +% +% Description: +% +% Sets #1 to the result of applying an operation to #2 and #3 +% +% Example: +% +% \pgfdvmathenter{\a}{2000} +% \pgfdvmathadd{\b}{\a}{0.2} +% % \b now stores 400 + +\def\pgfdvmathmulfixed#1#2#3{% + \pgfmathfloatmultiplyfixed{#2}{#3}% + \let#1=\pgfmathresult% +} @@ -1457,12 +1537,15 @@ \attribute out min; % Start of the second range (the value of c). + \attribute out min; + % End of the second range (the value of d). + \attribute trans in min; % Transformed value of the start of the first range (the value % f(a)). \attribute scale; - % The scaling factor, that is, the value of (f(d)-f(c))/(b-a). + % The scaling factor, that is, the value of (f(b)-f(a))/(d-c). % Constructor @@ -1540,6 +1623,7 @@ \pgfdvmathenter{\pgf@out@interval@max}{#4} % Let's start with the output, it's easier... \pgfoolet{out min}{\pgf@out@interval@min} + \pgfoolet{out max}{\pgf@out@interval@max} \pgfdvmathsub{\pgf@out@diff}{\pgf@out@interval@max}{\pgf@out@interval@min} \let\pgfvalue=\pgf@in@interval@min \pgfoovalueof{trans} @@ -1568,8 +1652,10 @@ \pgfkeysgetvalue{/data point/\pgfoovalueof{in}}\pgf@dv@external@value% \fi% \ifx\pgf@dv@external@value\pgfutil@empty% + \pgf@dv@mapper@pos@check% \else% \ifx\pgf@dv@external@value\relax% + \pgf@dv@mapper@pos@check% \else% % % Clip? \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}% @@ -1581,20 +1667,20 @@ % \fi% \fi% \fi% - \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/min}\pgf@dv@external@value% - \ifx\pgf@dv@external@value\relax\else% - \ifx\pgf@dv@external@value\pgfutil@empty\else% - \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}% - \pgf@dv@mapper@trans{/min} - \fi - \fi - \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/max}\pgf@dv@external@value% - \ifx\pgf@dv@external@value\relax\else% - \ifx\pgf@dv@external@value\pgfutil@empty\else% - \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}% - \pgf@dv@mapper@trans{/max} - \fi - \fi +% \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/min}\pgf@dv@external@value% +% \ifx\pgf@dv@external@value\relax\else% +% \ifx\pgf@dv@external@value\pgfutil@empty\else% +% \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}% +% \pgf@dv@mapper@trans{/min} +% \fi +% \fi +% \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/max}\pgf@dv@external@value% +% \ifx\pgf@dv@external@value\relax\else% +% \ifx\pgf@dv@external@value\pgfutil@empty\else% +% \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}% +% \pgf@dv@mapper@trans{/max} +% \fi +% \fi \fi% } @@ -1616,6 +1702,22 @@ \pgfdvmathexitbyserializing{\pgf@temp}{\pgfvalue}% \pgfkeyslet{/data point/\pgfoovalueof{out}#1}\pgf@temp% } + + \def\pgf@dv@mapper@pos@check{% + \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/out pos}\pgf@dv@pos@value% + \ifx\pgf@dv@pos@value\relax\else\if\pgf@dv@pos@value\pgfutil@empty\else% + \pgfmathsetmacro{\pgf@dv@pos@num}{\pgf@dv@pos@value}% + \pgfmathsetmacro{\pgf@dv@pos@num@prime}{1-\pgf@dv@pos@num}% + % Ok, compute transformed min position: + \pgfooget{out min}{\pgf@out@interval@min} + \pgfooget{out max}{\pgf@out@interval@max} + \pgfdvmathmulfixed{\pgf@out@interval@min}{\pgf@out@interval@min}{\pgf@dv@pos@num@prime} + \pgfdvmathmulfixed{\pgf@out@interval@max}{\pgf@out@interval@max}{\pgf@dv@pos@num} + \pgfdvmathadd{\pgf@out@val}{\pgf@out@interval@min}{\pgf@out@interval@max}% + \pgfdvmathexitbyserializing{\pgf@temp}{\pgf@out@val}% + \pgfkeyslet{/data point/\pgfoovalueof{out}}\pgf@temp% + \fi\fi% + } } @@ -1868,8 +1970,15 @@ % "seen" during the survey phase. Based on this value, the size of, % say, an axis can be detemined later on. % - % In case the attribute has the sub-attributes "min" and "max", they - % are also taken into account. + % You can also set the key "sub attributes" of the attribute. In + % this case, this key should contain -- as the name suggests -- a + % list of subkeys that should also be taken into account for the + % computation of the minimum and maximum value. Inside the "sub + % attributes" key, each subkey should be surrounded by a call of + % \pgfdvsub. For instance, if there are two sub attributes "/data + % point/velocity/min" and "/data point/velocity/max" for a key + % "/data point/velocity", then "/data point/velocity/sub attributes" + % should be set to "\pgfdvsub{/min}\pgfdvsub{/max}". \attribute attribute; % The to-be-surveyed attribute @@ -1902,9 +2011,12 @@ % Adjust the interval as if during the survey this value were % encountered \method include attribute value(#1) { - \def\pgf@dv@val{#1} + \pgf@dv@assign@val@stripped#1\pgf@stop% \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv) } + \def\pgf@dv@assign@val@stripped#1\pgf@stop{% + \def\pgf@dv@val{#1} + } % Slot % @@ -1913,34 +2025,36 @@ % interval. % \method survey() { - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}}\pgf@dv@val% - \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv) - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}/min}\pgf@dv@val% - \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv) - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}/max}\pgf@dv@val% - \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv) + \let\pgfdvsub\pgf@dv@range@surv@sub + \pgfdvsub{}% + \pgfkeysvalueof{/data point/\pgfoovalueof{attribute}/sub attributes} } - \def\pgf@dv@range@surv{% + \def\pgf@dv@range@surv@sub#1{ + \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}#1}\pgf@dv@val% \ifx\pgf@dv@val\relax% \else% \edef\pgf@dv@val{\pgf@dv@val}% \ifx\pgf@dv@val\pgfutil@empty% \else% - \pgfdvmathenter{\pgf@dv@value}{\pgf@dv@val}% - % Now, protocol value - \ifx\pgfdvmin\pgfutil@empty% - \let\pgfdvmin\pgf@dv@value% - \else% - \pgfdvmathifless{\pgf@dv@value}{\pgfdvmin}{\let\pgfdvmin\pgf@dv@value}{}% - \fi% - \ifx\pgfdvmax\pgfutil@empty% - \let\pgfdvmax\pgf@dv@value% - \else% - \pgfdvmathifless{\pgfdvmax}{\pgf@dv@value}{\let\pgfdvmax\pgf@dv@value}{}% - \fi% + \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv)% \fi% - \fi + \fi% + } + + \def\pgf@dv@range@surv{% + \pgfdvmathenter{\pgf@dv@value}{\pgf@dv@val}% + % Now, protocol value + \ifx\pgfdvmin\pgfutil@empty% + \let\pgfdvmin\pgf@dv@value% + \else% + \pgfdvmathifless{\pgf@dv@value}{\pgfdvmin}{\let\pgfdvmin\pgf@dv@value}{}% + \fi% + \ifx\pgfdvmax\pgfutil@empty% + \let\pgfdvmax\pgf@dv@value% + \else% + \pgfdvmathifless{\pgfdvmax}{\pgf@dv@value}{\let\pgfdvmax\pgf@dv@value}{}% + \fi% } } @@ -1976,6 +2090,10 @@ % filter should set \pgfdvfilterpassedfalse for to-be-filtered data % point. % + % You can specify "projection code" that changes the canvas x and + % canvas y positions. This projection code allows you to draw, say, + % projected points instead of the actual data point. + % % The keys /data point/<name>/execute at begin and /data % point/<name>/execute at end, where <name> is the name of % the visualizer, should store code that is to be executed directly @@ -1987,7 +2105,7 @@ % The to-be-used handlers \attribute name; - % Filter code + % The attribute \attribute filter=\pgfdvnamedvisualizerfilter; % Filter code @@ -2000,7 +2118,15 @@ % cache. Every 100 steps this cache is moved to positions. The idea % behind this is that it will avoid the quadratic time increase that % is normally caused when a protocol is build in TeX. - + + \attribute projection code; + % This code is empty by default. However, you can set it for + % instance to the following + % + % \pgfkeyssetvalue{/data point/y=0}\pgfdvmapdatapointtocanvas + % + % in order to visualize the data point with its y-coordinate + % replaced by 0. % Constructor % @@ -2025,6 +2151,11 @@ \pgfooset{filter}{#1} } + % Setter + \method set projection code(#1) { + \pgfooset{projection code}{#1} + } + % Slot \method protocol() { \pgfdvfilterpassedtrue @@ -2037,7 +2168,17 @@ \def\pgf@dv@line@cache@it{ % Cache it \pgfooget{cache}\pgf@dv@cache - \edef\pgf@dv@add{\noexpand\pgf@dv@ph{\pgfkeysvalueof{/data point/canvas x}}{\pgfkeysvalueof{/data point/canvas y}}}% + \pgfkeysgetvalue{/data point/outlier}\pgf@temp% + \ifx\pgf@temp\pgfutil@empty + {% + \pgfoovalueof{projection code} + \xdef\pgf@dv@add{\noexpand\pgf@dv@ph{\pgfkeysvalueof{/data + point/canvas x}}{\pgfkeysvalueof{/data point/canvas y}}}% + } + \else% + % An outlier! + \gdef\pgf@dv@add{\pgf@dv@outliner}% + \fi% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\pgf@dv@cache% \expandafter\expandafter\expandafter{\expandafter\pgf@dv@cache\pgf@dv@add}% @@ -2072,10 +2213,10 @@ \else \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at begin} \tikz@dv@temp - \pgfplotstreamstart + \pgfdvnewstreamtrue \pgfoovalueof{positions} \pgfoovalueof{cache} - \pgfplotstreamend + \ifpgfdvnewstream\else\pgfplotstreamend\fi \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at end} \fi } @@ -2084,15 +2225,22 @@ \pgfoolet{cache}\pgfutil@empty } - \def\pgf@dv@ph#1#2{\pgfplotstreampoint{\pgfqpoint{#1}{#2}}} + \def\pgf@dv@ph#1#2{\ifpgfdvnewstream\pgfplotstreamstart\pgfdvnewstreamfalse\fi\pgfplotstreampoint{\pgfqpoint{#1}{#2}}} + \def\pgf@dv@outliner{\ifpgfdvnewstream\else\pgfplotstreamend\pgfdvnewstreamtrue\fi} } +\newif\ifpgfdvnewstream \newcount\pgf@lib@dv@cache@count +\pgfkeys{% + /data point/outlier/.initial=, + /data point/outlier/.default=true +} + % A possible filter for unnamed visualizers % -% #1 = Text to be compared with key /data point/visualizer +% #1 = Text to be compared with key /data point/set % % Description: % @@ -2103,10 +2251,10 @@ % point/visualizer. % % When objects allow you to set a filter, you can use this filter to -% test against /data point/visualizer being equal to #1. +% test against /data point/set being equal to #1. \def\pgfdvvisualizerfilter#1{% - \pgfkeysgetvalue{/data point/visualizer}\pgf@dv@visualizer% + \pgfkeysgetvalue{/data point/set}\pgf@dv@visualizer% \def\pgf@temp{#1}% \ifx\pgf@temp\pgf@dv@visualizer% \else @@ -2122,10 +2270,10 @@ % % This filter works like \pgfdvvisualizerfilter, only it assumes the % the object defines a "name" attribute. In this case, the value of -% /data point/visualizer is tested against this attribute. +% /data point/set is tested against this attribute. \def\pgfdvnamedvisualizerfilter{% - \pgfkeysgetvalue{/data point/visualizer}\pgf@dv@visualizer% + \pgfkeysgetvalue{/data point/set}\pgf@dv@visualizer% \pgfooget{name}\pgf@temp% \ifx\pgf@temp\pgf@dv@visualizer% \else @@ -2140,16 +2288,19 @@ % Class rectangle visualizer % % This visualizer visualizes a datapoint as a rectangle. It needs - % two attributes a1 and a2, each of which must have min and max - % subattributes. Then, it draws a rectangle between (a1/min,a2/min) - % and (a1/max,a2/max). - - \attribute attribute 1; - \attribute attribute 2; - % The attributes + % a name, so that /data point/<name>/attribute 1 and /data + % point/<name>/attribute 2 store two attributes names a1 to a2. Then, + % provided the current value of /data point/set equals name, for + % each data point a rectangle between (a1/min,a2/min) and + % (a1/max,a2/max) is created. + - \attribute use path attribute; - % The attribute that stores the to-be-taken action + \attribute name; + % The name + + \attribute a1; + \attribute a2; + % The attributes, filled from /data point/<name>/attribute 1 and 2 % Constructor @@ -2157,47 +2308,65 @@ % #1 = first attribute % #2 = second attribute % - \method rectangle visualizer(#1,#2,#3) { - \pgfooset{attribute 1}{#1} - \pgfooset{attribute 2}{#2} - \pgfooset{use path attribute}{#3} + \method rectangle visualizer(#1) { + \pgfooset{name}{#1} } % Method \method default connects() { \pgfoothis.get handle(\pgf@dv@me) \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,visualize,visualize datapoint signal) + \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal) } - + + % Slot + \method phase(#1) {% + \ifx#1\pgfdvbeginsurvey% + \pgfooeset{a1}{/data point/\pgfkeysvalueof{/data point/\pgfoovalueof{name}/attribute 1}} + \pgfooeset{a2}{/data point/\pgfkeysvalueof{/data point/\pgfoovalueof{name}/attribute 2}} + \pgfkeyssetvalue{\pgfoovalueof{a1}/sub attributes}{\pgfdvsub{/min}\pgfdvsub{/max}} + \pgfkeyssetvalue{\pgfoovalueof{a2}/sub attributes}{\pgfdvsub{/min}\pgfdvsub{/max}} + \fi% + } + % Slot \method visualize() { { - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute 1}/min}\pgf@dv@amin - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute 1}/max}\pgf@dv@amax - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute 2}/min}\pgf@dv@bmin - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute 2}/max}\pgf@dv@bmax + \pgfkeysgetvalue{/data point/set}\pgf@dv@visualizer% + \pgfooget{name}\pgf@temp% + \ifx\pgf@temp\pgf@dv@visualizer% + \pgf@dv@rect@do + \fi + } + } + + \def\pgf@dv@rect@do{ + \pgfkeysgetvalue{\pgfoovalueof{a1}/min}\pgf@dv@amin \ifx\pgf@dv@amin\relax\else\ifx\pgf@dv@amin\pgfutil@empty\else - \ifx\pgf@dv@bmin\relax\else\ifx\pgf@dv@bmin\pgfutil@empty\else + \pgfkeysgetvalue{\pgfoovalueof{a1}/max}\pgf@dv@amax \ifx\pgf@dv@amax\relax\else\ifx\pgf@dv@amax\pgfutil@empty\else + \pgfkeysgetvalue{\pgfoovalueof{a2}/min}\pgf@dv@bmin + \ifx\pgf@dv@bmin\relax\else\ifx\pgf@dv@bmin\pgfutil@empty\else + \pgfkeysgetvalue{\pgfoovalueof{a2}/max}\pgf@dv@bmax \ifx\pgf@dv@bmax\relax\else\ifx\pgf@dv@bmax\pgfutil@empty\else - \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 1}}{\pgf@dv@amin} - \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 2}}{\pgf@dv@bmin} - \pgfpathdvmoveto - \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 2}}{\pgf@dv@bmax} - \pgfpathdvlineto - \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 1}}{\pgf@dv@amax} - \pgfpathdvlineto - \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 2}}{\pgf@dv@bmin} - \pgfpathdvlineto - \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 1}}{\pgf@dv@amin} - \pgfpathdvlineto - \pgfpathclose - \pgfkeysvalueof{/data point/\pgfoovalueof{use path attribute}} + \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at begin} + \pgfkeyssetvalue{\pgfoovalueof{a1}}{\pgf@dv@amin} + \pgfkeyssetvalue{\pgfoovalueof{a2}}{\pgf@dv@bmin} + \pgfpathdvmoveto + \pgfkeyssetvalue{\pgfoovalueof{a2}}{\pgf@dv@bmax} + \pgfpathdvlineto + \pgfkeyssetvalue{\pgfoovalueof{a1}}{\pgf@dv@amax} + \pgfpathdvlineto + \pgfkeyssetvalue{\pgfoovalueof{a2}}{\pgf@dv@bmin} + \pgfpathdvlineto + \pgfkeyssetvalue{\pgfoovalueof{a1}}{\pgf@dv@amin} + \pgfpathdvlineto + \pgfpathclose + \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at end} \fi\fi \fi\fi \fi\fi \fi\fi - } } } @@ -2253,10 +2422,7 @@ % \method label visualizer(#1,#2,#3,#4) { \pgfooset{attribute}{#1} - \ifx#2\pgfutil@empty - \else - \pgfdvmathenter{\pgf@temp}{#2} - \fi + \expandafter\pgfdvmathenter\expandafter{\expandafter\pgf@temp\expandafter}\expandafter{#2} \pgfoolet{threshold}\pgf@temp \pgfooset{code}{#3} \pgfooset{filter}{#4} @@ -2532,6 +2698,10 @@ } % Method + \method default connects() { + } + + % Method \method add entry(#1) { \pgfooappend{entries}{{#1}} \c@pgf@counta=\pgfoovalueof{number of entries}\relax% @@ -2795,6 +2965,12 @@ \method set max(#1) { \pgfooset{max}{#1} } + \method let min(#1) { + \pgfoolet{min}{#1} + } + \method let max(#1) { + \pgfoolet{max}{#1} + } % Getter % @@ -2835,16 +3011,9 @@ % present or that have a certain property. By default, for every % data point a counter is incremented and the value of this counter % is stored in an attribute. You can also specify an increment for - % the counter and some action that should be taken when the counter - % reaches zero. You can also specify that certain data points should + % the counter. You can specify that certain data points should % not have an effect on the counter. - % - % Counters can serve different purposes. - % - % 1. For plotting points in a table or sequence, the counter can be - % used to provide the position along one axis. - % 2. By using the counter as a repetitive count down one can for - % instance have only every 10th data point be marked. + \attribute attribute; % The attribute that will be set to the current value of the counter @@ -2852,6 +3021,9 @@ \attribute val=0; % The current value of the counter + \attribute max=0; + % The current value of the counter + \attribute step=1; % The stepping by which the counter is incremented for each % datapoint @@ -2880,6 +3052,11 @@ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal) } + % Getter + \method get max(#1) { + \pgfooget{max}{#1} + } + % Setter \method set value(#1) { \pgfooset{val}{#1} @@ -2889,6 +3066,7 @@ % Setter \method set start value(#1) { \pgfooset{start val}{#1} + \pgfooset{max}{#1} } % Setter @@ -2909,6 +3087,11 @@ \pgfmathparse{\pgfoovalueof{val}+\pgfoovalueof{step}}% \pgfoolet{val}\pgfmathresult% \pgfkeyslet{/data point/\pgfoovalueof{attribute}}\pgfmathresult% + \ifdim\pgfmathresult pt>\pgfoovalueof{max}pt\relax% + \pgfoolet{max}\pgfmathresult% + \fi% + \pgfooget{max}\pgfmathresult% + \pgfkeyslet{/data point/\pgfoovalueof{attribute}/max}\pgfmathresult% \fi% } diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex index 9834e91f0ec..c2bf2582a29 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex @@ -92,8 +92,8 @@ \long\def\pgfdeclaredecoration#1#2#3{% \let\pgf@mod@dec@next=\pgf@mod@dec@firstofone% \pgfifmetadecoration{#1}{% - \PackageError{pgf}{You cannot declare a decoration of the same - name as a meta-decoration}{}% + \pgferror{You cannot declare a decoration of the same + name as a meta-decoration}% \let\pgf@mod@dec@next=\pgfutil@gobble% }{}% \pgf@mod@dec@next @@ -141,8 +141,8 @@ \long\def\pgfdeclaremetadecoration#1#2#3{% \let\pgf@mod@dec@next=\pgf@mod@dec@firstofone% \pgfifdecoration{#1}{% - \PackageError{pgf}{You cannot declare a meta-decoration of the - same name as a decoration}{}% + \pgferror{You cannot declare a meta-decoration of the + same name as a decoration}% \let\pgf@mod@dec@next=\pgfutil@gobble% }{}% \pgf@mod@dec@next{% @@ -193,38 +193,38 @@ % % Example: % -% \pgfdeclaredecoration{circles}{red circles}{ -% \state{red circles}[width=10pt, repeat state=2, next state=blue circles] -% { -% \pgfmathparse{round(rnd*100)} -% \pgfsetstrokecolor{red!\pgfmathresult!brown} -% \pgfsetfillcolor{orange!\pgfmathresult!yellow} -% \pgfpathcircle{\pgfpointorigin}{2.5pt} -% \pgfusepath{stroke,fill} -% } -% \state{blue circles}[width=10pt, repeat state=1, next state=red circles] -% { -% \pgfmathparse{round(rnd*100)} -% \pgfsetstrokecolor{blue!\pgfmathresult!gray} -% \pgfsetfillcolor{blue!\pgfmathresult!white} -% \pgfpathcircle{\pgfpointorigin}{2.5pt} -% \pgfusepath{stroke,fill} -% } -% \state{final}{} -% } -% -% \pgfpicture -% \pgfdecoratepath{circles} -% { -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfpoint{0cm}{3cm}}{\pgfpoint{4cm}{0cm}}{\pgfpoint{4cm}{3cm}} -% } -% \endpgfpicture +% \pgfdeclaredecoration{circles}{red circles}{ +% \state{red circles}[width=10pt, repeat state=2, next state=blue circles] +% { +% \pgfmathparse{round(rnd*100)} +% \pgfsetstrokecolor{red!\pgfmathresult!brown} +% \pgfsetfillcolor{orange!\pgfmathresult!yellow} +% \pgfpathcircle{\pgfpointorigin}{2.5pt} +% \pgfusepath{stroke,fill} +% } +% \state{blue circles}[width=10pt, repeat state=1, next state=red circles] +% { +% \pgfmathparse{round(rnd*100)} +% \pgfsetstrokecolor{blue!\pgfmathresult!gray} +% \pgfsetfillcolor{blue!\pgfmathresult!white} +% \pgfpathcircle{\pgfpointorigin}{2.5pt} +% \pgfusepath{stroke,fill} +% } +% \state{final}{} +% } +% +% \pgfpicture +% \pgfdecoratepath{circles} +% { +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{3cm}}{\pgfpoint{4cm}{0cm}}{\pgfpoint{4cm}{3cm}} +% } +% \endpgfpicture % \long\def\pgfdecoratepath#1#2{% - \pgfdecoration{{#1}{\pgfdecoratedpathlength}{\pgfdecoratebeforecode}{\pgfdecorateaftercode}}% - #2% - \endpgfdecoration} + \pgfdecoration{{#1}{\pgfdecoratedpathlength}{\pgfdecoratebeforecode}{\pgfdecorateaftercode}}% + #2% + \endpgfdecoration} @@ -240,37 +240,37 @@ % % Example: % -% \pgfdeclaredecoration{stars}{move}{ -% \state{move}[width=7.5pt, next state=star]{} -% \state{star}[width=7.5pt, next state=move] -% { -% \pgfmathparse{round(rnd*100)} -% \pgfsetfillcolor{yellow!\pgfmathresult!orange} -% \pgfsetstrokecolor{yellow!\pgfmathresult!red} -% \pgfmathparse{rnd*.75+.25} -% \pgftransformscale{\pgfmathresult} -% \pgfnode{star}{center}{}{}{\pgfusepath{stroke,fill}} -% } -% \state{final} -% { -% \pgfpathmoveto{\pgfpointdecoratedpathlast} -% } -% } -% -% \pgfpicture -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfqpoint{0cm}{2cm}}{\pgfqpoint{3cm}{2cm}}{\pgfqpoint{3cm}{0cm}} -% \pgfpathcurveto{\pgfqpoint{3cm}{-3cm}}{\pgfqpoint{0cm}{0cm}}{\pgfqpoint{0cm}{-3cm}} -% \pgfpathcurveto{\pgfqpoint{0cm}{-5cm}}{\pgfqpoint{3cm}{-5cm}}{\pgfqpoint{3cm}{-3cm}} -% \pgfdecoratecurrentpath{stars} -% \endpgfpicture +% \pgfdeclaredecoration{stars}{move}{ +% \state{move}[width=7.5pt, next state=star]{} +% \state{star}[width=7.5pt, next state=move] +% { +% \pgfmathparse{round(rnd*100)} +% \pgfsetfillcolor{yellow!\pgfmathresult!orange} +% \pgfsetstrokecolor{yellow!\pgfmathresult!red} +% \pgfmathparse{rnd*.75+.25} +% \pgftransformscale{\pgfmathresult} +% \pgfnode{star}{center}{}{}{\pgfusepath{stroke,fill}} +% } +% \state{final} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathlast} +% } +% } +% +% \pgfpicture +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfqpoint{0cm}{2cm}}{\pgfqpoint{3cm}{2cm}}{\pgfqpoint{3cm}{0cm}} +% \pgfpathcurveto{\pgfqpoint{3cm}{-3cm}}{\pgfqpoint{0cm}{0cm}}{\pgfqpoint{0cm}{-3cm}} +% \pgfpathcurveto{\pgfqpoint{0cm}{-5cm}}{\pgfqpoint{3cm}{-5cm}}{\pgfqpoint{3cm}{-3cm}} +% \pgfdecoratecurrentpath{stars} +% \endpgfpicture % \def\pgfdecoratecurrentpath#1{% - \pgfgetpath\pgf@decorate@currentpath% - \pgfsetpath\pgfutil@empty% - \pgfdecoration{{#1}{\pgfdecoratedpathlength}{\pgfdecoratebeforecode}{\pgfdecorateaftercode}}% - \pgfsetpath\pgf@decorate@currentpath% - \endpgfdecoration} + \pgfgetpath\pgf@decorate@currentpath% + \pgfsetpath\pgfutil@empty% + \pgfdecoration{{#1}{\pgfdecoratedpathlength}{\pgfdecoratebeforecode}{\pgfdecorateaftercode}}% + \pgfsetpath\pgf@decorate@currentpath% + \endpgfdecoration} @@ -282,22 +282,22 @@ % Definitions: % % `existing path' -% - any unsed path exsiting prior to the environment. +% - any unsed path exsiting prior to the environment. % % `decorated path' -% - the path that is being decorated. +% - the path that is being decorated. % -% `decoration path' -% - any unused path left by the decoration automaton. +% `decoration path' +% - any unused path left by the decoration automaton. % % The action of the environment is as follows: % -% 1. Any existing path is saved. -% 2. Construction commands are executed forming the decorated path. -% 3. If the first command in the decorated path is not a `move to', +% 1. Any existing path is saved. +% 2. Construction commands are executed forming the decorated path. +% 3. If the first command in the decorated path is not a `move to', % the last known position from the exisiting path is inserted. -% 4. The saved existing path is reinstalled. -% 5. The decoration automaton is executed along the decorated path. +% 4. The saved existing path is reinstalled. +% 5. The decoration automaton is executed along the decorated path. % % Parameters: % @@ -322,142 +322,142 @@ % <before code> is executed just before the decoration automaton % starts and <after code> is executed just after the automaton stops. % If <before code> or <after code> are empty, they can be omitted. -% The macros \pgfdecoratedpathfirst and \pgfdecoratedpathlast +% The macros \pgfdecoratedpathfirst and \pgfdecoratedpathlast % will be set up as the first and last points on the current section % of the decorated path. % % When the environment exits, the following macros will be set up: % -% \pgfdecorateexistingpath -% - the existing path. +% \pgfdecorateexistingpath +% - the existing path. % -% \pgfdecoratedpath -% - the decorated path. +% \pgfdecoratedpath +% - the decorated path. % -% \pgfdecorationpath -% - any unused decoration path. +% \pgfdecorationpath +% - any unused decoration path. % -% \pgfpointdecoratedpathlast +% \pgfpointdecoratedpathlast % - the last point on the decorated path. % % Examples (require pgfdecorations library): % -% \pgfpicture -% \pgfdecoration -% { -% {lineto}{\pgfdecoratedpathlength/3}, -% {zigzag}{\pgfdecoratedpathlength/3}, -% {lineto}{\pgfdecoratedpathlength/3} -% } -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} -% \endpgfdecoration -% \pgfusepath{stroke} -% \endpgfpicture -% -% -% \pgfpicture -% \pgfdecoration -% { -% {lineto}{\pgfdecoratedpathlength/5}{}{\pgfusepath{stroke}}, -% {zigzag}{\pgfdecoratedpathlength/5} -% { -% \pgfpathmoveto{\pgfpointdecoratedpathfirst} -% } -% { -% \pgfsetstrokecolor{red} -% \pgfusepath{stroke} -% }, -% {lineto}{\pgfdecoratedpathlength/5} -% { -% \pgfpathmoveto{\pgfpointdecoratedpathfirst} -% } -% { -% \pgfsetstrokecolor{black} -% \pgfusepath{stroke} -% }, -% {zigzag}{\pgfdecoratedpathlength/5} -% { -% \pgfpathmoveto{\pgfpointdecoratedpathfirst} -% } -% { -% \pgfsetstrokecolor{red} -% \pgfusepath{stroke} -% }, -% {lineto}{\pgfdecoratedpathlength/5} -% { -% \pgfpathmoveto{\pgfpointdecoratedpathfirst} -% } -% { -% \pgfsetstrokecolor{black} -% \pgfusepath{stroke} -% } -% } -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} -% \endpgfdecoration -% -% \endpgfpicture -% -% -% -% \pgfdeclaredecoration{polygons}{move}{ -% \state{move}[width=7.5pt, next state=polygon]{} -% \state{polygon}[width=7.5pt, next state=move] -% { -% \pgfmathparse{round(rnd*100)} -% \pgfsetfillcolor{green!\pgfmathresult!yellow} -% \pgfsetstrokecolor{green!\pgfmathresult!brown} -% \pgfnode{regular polygon}{center}{}{}{\pgfusepath{stroke,fill}} -% } -% \state{final} -% { -% \pgfpathmoveto{\pgfpointdecoratedpathlast} -% } -% } -% -% \pgfpicture -% \pgfdecoration -% { -% {polygons}{45pt}, -% {lineto}{30pt} -% {\pgfpathmoveto{\pgfpointdecoratedpathfirst}} -% { -% \pgfsetstrokecolor{yellow!50!orange} -% \pgfusepath{stroke} -% }, -% {polygons}{45pt}, -% {lineto}{30pt} -% {\pgfpathmoveto{\pgfpointdecoratedpathfirst}} -% { -% \pgfsetstrokecolor{green!50!blue} -% \pgfusepath{stroke} -% }, -% {polygons}{\pgfdecoratedremainingdistance} -% } -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} -% \endpgfdecoration -% \endpgfpicture -% -% -% \pgfpicture -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} -% \pgfgetpath\temppath -% \pgfsetstrokecolor{red} -% \pgfusepath{stroke} -% -% \pgfset{decoration text={Here is some text all the way along this curve!}} -% \pgfdecoration{{text}{\pgfdecoratedremainingdistance}} -% \pgfsetpath\temppath -% \endpgfdecoration -% \endpgfpicture +% \pgfpicture +% \pgfdecoration +% { +% {lineto}{\pgfdecoratedpathlength/3}, +% {zigzag}{\pgfdecoratedpathlength/3}, +% {lineto}{\pgfdecoratedpathlength/3} +% } +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} +% \endpgfdecoration +% \pgfusepath{stroke} +% \endpgfpicture +% +% +% \pgfpicture +% \pgfdecoration +% { +% {lineto}{\pgfdecoratedpathlength/5}{}{\pgfusepath{stroke}}, +% {zigzag}{\pgfdecoratedpathlength/5} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathfirst} +% } +% { +% \pgfsetstrokecolor{red} +% \pgfusepath{stroke} +% }, +% {lineto}{\pgfdecoratedpathlength/5} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathfirst} +% } +% { +% \pgfsetstrokecolor{black} +% \pgfusepath{stroke} +% }, +% {zigzag}{\pgfdecoratedpathlength/5} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathfirst} +% } +% { +% \pgfsetstrokecolor{red} +% \pgfusepath{stroke} +% }, +% {lineto}{\pgfdecoratedpathlength/5} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathfirst} +% } +% { +% \pgfsetstrokecolor{black} +% \pgfusepath{stroke} +% } +% } +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} +% \endpgfdecoration +% +% \endpgfpicture +% +% +% +% \pgfdeclaredecoration{polygons}{move}{ +% \state{move}[width=7.5pt, next state=polygon]{} +% \state{polygon}[width=7.5pt, next state=move] +% { +% \pgfmathparse{round(rnd*100)} +% \pgfsetfillcolor{green!\pgfmathresult!yellow} +% \pgfsetstrokecolor{green!\pgfmathresult!brown} +% \pgfnode{regular polygon}{center}{}{}{\pgfusepath{stroke,fill}} +% } +% \state{final} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathlast} +% } +% } +% +% \pgfpicture +% \pgfdecoration +% { +% {polygons}{45pt}, +% {lineto}{30pt} +% {\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% { +% \pgfsetstrokecolor{yellow!50!orange} +% \pgfusepath{stroke} +% }, +% {polygons}{45pt}, +% {lineto}{30pt} +% {\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% { +% \pgfsetstrokecolor{green!50!blue} +% \pgfusepath{stroke} +% }, +% {polygons}{\pgfdecoratedremainingdistance} +% } +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} +% \endpgfdecoration +% \endpgfpicture +% +% +% \pgfpicture +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} +% \pgfgetpath\temppath +% \pgfsetstrokecolor{red} +% \pgfusepath{stroke} +% +% \pgfset{decoration text={Here is some text all the way along this curve!}} +% \pgfdecoration{{text}{\pgfdecoratedremainingdistance}} +% \pgfsetpath\temppath +% \endpgfdecoration +% \endpgfpicture % \def\pgfdecoration#1{% \begingroup% \def\pgf@decorate@decorationlist{#1}% - \pgf@decoration@env% + \pgf@decoration@env% } \def\endpgfdecoration{% @@ -498,47 +498,47 @@ % % Example: % -% \pgfdeclaremetadecoration{fancy line}{line to}{ -% \state{line to}[width=1cm, next state=zigzag] -% { -% \decoration{lineto} -% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} -% \afterdecoration -% { -% \pgfsetstrokecolor{black} -% \pgfusepath{stroke} -% } -% } -% \state{zigzag}[width=2cm, next state=line to] -% { -% \decoration{zigzag} -% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} -% \afterdecoration -% { -% \pgfsetstrokecolor{red} -% \pgfusepath{stroke} -% } -% } -% \state{final} -% { -% \decoration{lineto} -% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} -% \afterdecoration -% { -% \pgfsetstrokecolor{black} -% \pgfusepath{stroke} -% } -% } -% } -% -% \pgfpicture -% \pgfmetadecoration{fancy line} -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfqpoint{0cm}{2cm}}{\pgfqpoint{3cm}{2cm}}{\pgfqpoint{3cm}{0cm}} -% \pgfpathcurveto{\pgfqpoint{3cm}{-3cm}}{\pgfqpoint{0cm}{0cm}}{\pgfqpoint{0cm}{-3cm}} -% \pgfpathcurveto{\pgfqpoint{0cm}{-5cm}}{\pgfqpoint{3cm}{-5cm}}{\pgfqpoint{3cm}{-3cm}} -% \endpgfmetadecoration -% \endpgfpicture +% \pgfdeclaremetadecoration{fancy line}{line to}{ +% \state{line to}[width=1cm, next state=zigzag] +% { +% \decoration{lineto} +% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% \afterdecoration +% { +% \pgfsetstrokecolor{black} +% \pgfusepath{stroke} +% } +% } +% \state{zigzag}[width=2cm, next state=line to] +% { +% \decoration{zigzag} +% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% \afterdecoration +% { +% \pgfsetstrokecolor{red} +% \pgfusepath{stroke} +% } +% } +% \state{final} +% { +% \decoration{lineto} +% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% \afterdecoration +% { +% \pgfsetstrokecolor{black} +% \pgfusepath{stroke} +% } +% } +% } +% +% \pgfpicture +% \pgfmetadecoration{fancy line} +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfqpoint{0cm}{2cm}}{\pgfqpoint{3cm}{2cm}}{\pgfqpoint{3cm}{0cm}} +% \pgfpathcurveto{\pgfqpoint{3cm}{-3cm}}{\pgfqpoint{0cm}{0cm}}{\pgfqpoint{0cm}{-3cm}} +% \pgfpathcurveto{\pgfqpoint{0cm}{-5cm}}{\pgfqpoint{3cm}{-5cm}}{\pgfqpoint{3cm}{-3cm}} +% \endpgfmetadecoration +% \endpgfpicture % \def\pgfmetadecoration#1{% \begingroup% @@ -550,47 +550,47 @@ } \def\endpgfmetadecoration{% - \pgf@decoration@endenv% - \ifx\pgfdecoratedpath\pgfutil@empty% - \else% - \let\pgfmetadecoratedpathlength\pgf@decorate@totalpathlength% - \def\pgfmetadecoratedinputsegmentremainingdistance{\pgfdecoratedremainingdistance}% - \def\pgfmetadecoratedinputsegmentcompleteddistance{\pgfdecoratedcompleteddistance}% - % - % Perform the meta decoration... - % - \expandafter\let\expandafter\pgf@metadecoration@current@state% - \csname pgf@metadecoration@@\pgf@metadecoration@name @initial\endcsname% - \pgf@metadecoration@run% - % - % ..until the final state. - % - \let\pgf@decorate@tempname\pgfutil@empty% - \let\pgf@decorate@tempbefore\pgfutil@empty% - \let\pgf@decorate@tempafter\pgfutil@empty% - \csname pgf@metadecoration@@\pgf@metadecoration@name @\pgf@metadecoration@current@state @code\endcsname% - \ifx\pgf@decorate@tempname\pgfutil@empty% - \def\pgf@decorate@tempname{moveto} - \fi% - \pgf@decorate@invoke{% - {\pgf@decorate@tempname}{\pgfdecoratedremainingdistance}% - {\pgf@decorate@tempbefore}{\pgf@decorate@tempafter}% - }% - \fi% - \pgfgetpath\pgfdecorationpath% - % - % Take stuff outside the group. - % - \global\let\pgf@decorate@decorationpathtemp\pgfdecorationpath% - \global\let\pgf@decorate@decoratedpathtemp\pgfdecoratedpath% - \global\let\pgf@decorate@existingpathtemp\pgfdecorateexistingpath% - \global\let\pgfpoint@decorated@pathlasttemp\pgfpoint@decorated@pathlast% - \endgroup% - % - % Are we in LaTeX? - % - \pgfutil@ifnextchar\@checkend{\aftergroup\pgf@decorate@installmacrosatend}% - {\pgf@decorate@installmacrosatend}% + \pgf@decoration@endenv% + \ifx\pgfdecoratedpath\pgfutil@empty% + \else% + \let\pgfmetadecoratedpathlength\pgf@decorate@totalpathlength% + \def\pgfmetadecoratedinputsegmentremainingdistance{\pgfdecoratedremainingdistance}% + \def\pgfmetadecoratedinputsegmentcompleteddistance{\pgfdecoratedcompleteddistance}% + % + % Perform the meta decoration... + % + \expandafter\let\expandafter\pgf@metadecoration@current@state% + \csname pgf@metadecoration@@\pgf@metadecoration@name @initial\endcsname% + \pgf@metadecoration@run% + % + % ..until the final state. + % + \let\pgf@decorate@tempname\pgfutil@empty% + \let\pgf@decorate@tempbefore\pgfutil@empty% + \let\pgf@decorate@tempafter\pgfutil@empty% + \csname pgf@metadecoration@@\pgf@metadecoration@name @\pgf@metadecoration@current@state @code\endcsname% + \ifx\pgf@decorate@tempname\pgfutil@empty% + \def\pgf@decorate@tempname{moveto} + \fi% + \pgf@decorate@invoke{% + {\pgf@decorate@tempname}{\pgfdecoratedremainingdistance}% + {\pgf@decorate@tempbefore}{\pgf@decorate@tempafter}% + }% + \fi% + \pgfgetpath\pgfdecorationpath% + % + % Take stuff outside the group. + % + \global\let\pgf@decorate@decorationpathtemp\pgfdecorationpath% + \global\let\pgf@decorate@decoratedpathtemp\pgfdecoratedpath% + \global\let\pgf@decorate@existingpathtemp\pgfdecorateexistingpath% + \global\let\pgfpoint@decorated@pathlasttemp\pgfpoint@decorated@pathlast% + \endgroup% + % + % Are we in LaTeX? + % + \pgfutil@ifnextchar\@checkend{\aftergroup\pgf@decorate@installmacrosatend}% + {\pgf@decorate@installmacrosatend}% } @@ -606,26 +606,26 @@ \let\pgfdecorationpath\pgfutil@empty% \let\pgfdecoratedpath\pgfutil@empty% \let\pgfpoint@decorated@pathlast\pgfpointorigin% - \edef\pgfpoint@decorate@existingpathlast{\pgf@x\the\pgf@path@lastx\pgf@y\the\pgf@path@lasty}% + \edef\pgfpoint@decorate@existingpathlast{\pgf@x\the\pgf@path@lastx\pgf@y\the\pgf@path@lasty}% % % Begin a group so transformations don't mess things up. % - \bgroup% + \bgroup% } \def\pgf@decorate@path@check@moveto#1{% - \expandafter\pgf@decorate@path@@check@moveto#1\pgf@decorate@stop\pgf@decorate@@stop} + \expandafter\pgf@decorate@path@@check@moveto#1\pgf@decorate@stop\pgf@decorate@@stop} \def\pgf@decorate@token@stop{\pgf@decorate@stop}% \def\pgf@decorate@path@@check@moveto#1#2#3#4\pgf@decorate@@stop#5#6{% - \def\pgf@decorate@temp{#4}% - \pgf@x=#2\relax% - \pgf@y=#3\relax% - \ifx\pgf@decorate@temp\pgf@decorate@token@stop% - #5% - \else% - #6% - \fi% + \def\pgf@decorate@temp{#4}% + \pgf@x=#2\relax% + \pgf@y=#3\relax% + \ifx\pgf@decorate@temp\pgf@decorate@token@stop% + #5% + \else% + #6% + \fi% } \def\pgf@decoration@endenv{% @@ -638,20 +638,20 @@ \pgfsetpath\pgfdecorateexistingpath% % \ifx\pgfdecoratedpath\pgfutil@empty% - \PackageError{PGF}{I cannot decorate an empty path}{}% + \pgferror{I cannot decorate an empty path}% \else% - % - % If the path consists of a single moveto token, make it - % a very small horizontal line. - % - \pgf@decorate@path@check@moveto\pgfdecoratedpath{% - \advance\pgf@x by0.0001pt\relax% - \edef\pgfdecoratedpath{% - \expandafter\noexpand\pgfdecoratedpath% - \noexpand\pgfsyssoftpath@linetotoken{\the\pgf@x}{\the\pgf@y}% - }% - }% - {}% + % + % If the path consists of a single moveto token, make it + % a very small horizontal line. + % + \pgf@decorate@path@check@moveto\pgfdecoratedpath{% + \advance\pgf@x by0.0001pt\relax% + \edef\pgfdecoratedpath{% + \expandafter\noexpand\pgfdecoratedpath% + \noexpand\pgfsyssoftpath@linetotoken{\the\pgf@x}{\the\pgf@y}% + }% + }% + {}% % % Remove special round tokens and get points. % @@ -668,7 +668,7 @@ % Reverse objects if necessary. % \ifpgf@decorate@inputsegmentobjects@reverse% - \pgf@decorate@inputsegmentobjects@reverse{\pgf@decorate@inputsegmentobjects}{\pgf@decorate@inputsegmentobjects}% + \pgf@decorate@inputsegmentobjects@reverse{\pgf@decorate@inputsegmentobjects}{\pgf@decorate@inputsegmentobjects}% \fi% % \let\pgf@decorated@remainingdistance\pgf@decorate@totalpathlength% @@ -687,13 +687,13 @@ \pgf@decorate@processnextinputsegmentobject% \pgf@decorate@distancetomove0pt\relax% \fi% -}% +}% \def\pgf@decorate@installmacrosatend{% - \let\pgfdecorationpath\pgf@decorate@decorationpathtemp% + \let\pgfdecorationpath\pgf@decorate@decorationpathtemp% \let\pgfdecoratedpath\pgf@decorate@decoratedpathtemp% \let\pgfdecorateexistingpath\pgf@decorate@existingpathtemp% \let\pgfpoint@decorated@pathlast\pgfpoint@decorated@pathlasttemp% @@ -710,18 +710,18 @@ % A version of \pgfutil@for which doesn't expand each value in #3. % \def\pgf@decorate@for#1:=#2\do#3{% - \def\pgf@decorate@for@var{#1}% - \def\pgf@decorate@for@action{#3}% - \expandafter\pgf@decorate@@for#2,\pgf@stop,} - + \def\pgf@decorate@for@var{#1}% + \def\pgf@decorate@for@action{#3}% + \expandafter\pgf@decorate@@for#2,\pgf@stop,} + \def\pgf@decorate@@for#1,{% - \ifx#1\pgf@stop% - \expandafter\let\pgf@decorate@for@var\pgfutil@empty% - \else% - \expandafter\def\pgf@decorate@for@var{#1}% - \pgf@decorate@for@action% - \expandafter\pgf@decorate@@for% - \fi% + \ifx#1\pgf@stop% + \expandafter\let\pgf@decorate@for@var\pgfutil@empty% + \else% + \expandafter\def\pgf@decorate@for@var{#1}% + \pgf@decorate@for@action% + \expandafter\pgf@decorate@@for% + \fi% } @@ -730,97 +730,97 @@ % #1 - {<name>}{<distance>}{<before code>}{<after code>} % \def\pgf@decorate@invoke#1{% - \pgf@decorate@@invoke#1\pgf@decorate@invoke\pgf@decorate@invoke\pgf@decorate@invoke\pgf@stop} - + \pgf@decorate@@invoke#1\pgf@decorate@invoke\pgf@decorate@invoke\pgf@decorate@invoke\pgf@stop} + \def\pgf@decorate@@invoke#1#2#3#4#5\pgf@stop{% - \pgfutil@ifundefined{pgf@decorate@@#1@initial}% - {% - \PackageError{PGF}{Unknown decoration `#1'}{}% - }% - {% - \def\pgf@decorate@name{#1}% - \ifx\pgf@decorate@invoke#3% - \let\pgf@decorate@beforecode\pgfutil@empty% - \else% - \def\pgf@decorate@beforecode{#3}% - \fi% - \ifx\pgf@decorate@invoke#4% - \let\pgf@decorate@aftercode\pgfutil@empty% - \else% - \def\pgf@decorate@aftercode{#4}% - \fi% - % - % Make remaining distance and the decorated path length `public'. - % - \pgfdecoratedremainingdistance\pgf@decorated@remainingdistance\relax% - \let\pgfdecoratedpathlength\pgf@decorate@totalpathlength% - % - \pgfmathsetlength\pgf@xa{#2}% - \ifdim\pgf@xa>\pgf@decorated@remainingdistance\relax% - \pgf@xa\pgf@decorated@remainingdistance\relax% - \fi% - \edef\pgf@decorate@currentpathlength{\the\pgf@xa}% - % - % Calculate the distance remaining to the end of the entire path. - % - \pgf@xa-\pgf@decorate@currentpathlength\relax% - \advance\pgf@xa\pgf@decorated@remainingdistance\relax% - \edef\pgf@decorated@remainingdistance{\the\pgf@xa}% - % - % Set up the macros and distances for the current section - % of the decorated path. - % - \let\pgfdecoratedpathlength\pgf@decorate@currentpathlength% - \pgfdecoratedremainingdistance\pgfdecoratedpathlength\relax% - \pgfdecoratedcompleteddistance0pt\relax% - % - % Execute user-defined code beore decoration. - % - \pgf@decorate@beforecode% - % - % Run the decoration... - % - \expandafter\let\expandafter\pgf@decorate@current@state% - \csname pgf@decorate@@\pgf@decorate@name @initial\endcsname% - \pgf@decorate@run% - % - % ...until the final state. - % - \ifdim\pgf@decorated@remainingdistance<1pt\relax% Should be =0pt, but need to control for inaccuracies. - \let\pgfpoint@decorated@pathlast\pgfpoint@decorated@totalpathlast% - \else% - % - % Set up \pgfpoint@decorated@pathlast if the end of - % the total decorated path has not been reached. - % - {% - \pgf@decorate@movealonginputsegment{\the\pgfdecoratedremainingdistance}% - \pgf@decorate@transformtoinputsegment% - \pgfpointorigin% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \global\pgf@x\pgf@x% - \global\pgf@y\pgf@y% - }% - \edef\pgfpoint@decorated@pathlast{\pgf@x\the\pgf@x\pgf@y\the\pgf@y}% - \fi% - {% - \pgftransformreset% - \pgf@decorate@transformtoinputsegment% - \pgf@decorate@additionaltransform% - \csname pgf@decorate@@\pgf@decorate@name @final@code\endcsname% - }% - \pgf@decorate@movealonginputsegment{\the\pgfdecoratedremainingdistance}% - % - % Execute user-defined code after decoration. - % - \pgf@decorate@aftercode% - % - % Update the input segment objects. - % - \let\pgf@decorate@additionaltransform\pgfutil@empty% - \let\pgf@decorate@inputsegmentobjects\pgf@decorate@inputsegmentobjects@aftersplit% - \let\pgfpoint@decorated@pathfirst\pgfpoint@decorated@pathlast% - }% + \pgfutil@ifundefined{pgf@decorate@@#1@initial}% + {% + \pgferror{Unknown decoration `#1'}% + }% + {% + \def\pgf@decorate@name{#1}% + \ifx\pgf@decorate@invoke#3% + \let\pgf@decorate@beforecode\pgfutil@empty% + \else% + \def\pgf@decorate@beforecode{#3}% + \fi% + \ifx\pgf@decorate@invoke#4% + \let\pgf@decorate@aftercode\pgfutil@empty% + \else% + \def\pgf@decorate@aftercode{#4}% + \fi% + % + % Make remaining distance and the decorated path length `public'. + % + \pgfdecoratedremainingdistance\pgf@decorated@remainingdistance\relax% + \let\pgfdecoratedpathlength\pgf@decorate@totalpathlength% + % + \pgfmathsetlength\pgf@xa{#2}% + \ifdim\pgf@xa>\pgf@decorated@remainingdistance\relax% + \pgf@xa\pgf@decorated@remainingdistance\relax% + \fi% + \edef\pgf@decorate@currentpathlength{\the\pgf@xa}% + % + % Calculate the distance remaining to the end of the entire path. + % + \pgf@xa-\pgf@decorate@currentpathlength\relax% + \advance\pgf@xa\pgf@decorated@remainingdistance\relax% + \edef\pgf@decorated@remainingdistance{\the\pgf@xa}% + % + % Set up the macros and distances for the current section + % of the decorated path. + % + \let\pgfdecoratedpathlength\pgf@decorate@currentpathlength% + \pgfdecoratedremainingdistance\pgfdecoratedpathlength\relax% + \pgfdecoratedcompleteddistance0pt\relax% + % + % Execute user-defined code beore decoration. + % + \pgf@decorate@beforecode% + % + % Run the decoration... + % + \expandafter\let\expandafter\pgf@decorate@current@state% + \csname pgf@decorate@@\pgf@decorate@name @initial\endcsname% + \pgf@decorate@run% + % + % ...until the final state. + % + \ifdim\pgf@decorated@remainingdistance<1pt\relax% Should be =0pt, but need to control for inaccuracies. + \let\pgfpoint@decorated@pathlast\pgfpoint@decorated@totalpathlast% + \else% + % + % Set up \pgfpoint@decorated@pathlast if the end of + % the total decorated path has not been reached. + % + {% + \pgf@decorate@movealonginputsegment{\the\pgfdecoratedremainingdistance}% + \pgf@decorate@transformtoinputsegment% + \pgfpointorigin% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% + \edef\pgfpoint@decorated@pathlast{\pgf@x\the\pgf@x\pgf@y\the\pgf@y}% + \fi% + {% + \pgftransformreset% + \pgf@decorate@transformtoinputsegment% + \pgf@decorate@additionaltransform% + \csname pgf@decorate@@\pgf@decorate@name @final@code\endcsname% + }% + \pgf@decorate@movealonginputsegment{\the\pgfdecoratedremainingdistance}% + % + % Execute user-defined code after decoration. + % + \pgf@decorate@aftercode% + % + % Update the input segment objects. + % + \let\pgf@decorate@additionaltransform\pgfutil@empty% + \let\pgf@decorate@inputsegmentobjects\pgf@decorate@inputsegmentobjects@aftersplit% + \let\pgfpoint@decorated@pathfirst\pgfpoint@decorated@pathlast% + }% } @@ -832,25 +832,25 @@ % \pgfpointdecoratedpathfirst % \def\pgfpointdecoratedpathfirst{% - {% - \pgftransforminvert% - \pgfpoint@decorated@pathfirst% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \global\pgf@x\pgf@x% - \global\pgf@y\pgf@y% - }% + {% + \pgftransforminvert% + \pgfpoint@decorated@pathfirst% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% }% % \pgfpointdecoratedpathlast % \def\pgfpointdecoratedpathlast{% - {% - \pgftransforminvert% - \pgfpoint@decorated@pathlast% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \global\pgf@x\pgf@x% - \global\pgf@y\pgf@y% - }% + {% + \pgftransforminvert% + \pgfpoint@decorated@pathlast% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% }% % \pgfpointdecoratedinputsegmentfirst @@ -858,27 +858,27 @@ % The first point of the current sub-path. % \def\pgfpointdecoratedinputsegmentfirst{% - {% - \pgftransforminvert% - \pgf@decorate@inputsegment@first% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \global\pgf@x\pgf@x% - \global\pgf@y\pgf@y% - }% -}% + {% + \pgftransforminvert% + \pgf@decorate@inputsegment@first% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% +}% % \pgfpointdecoratedinputsegmentlast % % The final point of the current sub-path. % \def\pgfpointdecoratedinputsegmentlast{% - {% - \pgftransforminvert% - \pgf@decorate@inputsegment@last% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \global\pgf@x\pgf@x% - \global\pgf@y\pgf@y% - }% + {% + \pgftransforminvert% + \pgf@decorate@inputsegment@last% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% }% @@ -887,7 +887,7 @@ % Run a normal decoration. % \def\pgf@decorate@run{% - \let\pgf@decorate@next\pgf@decorate@do@state% + \let\pgf@decorate@next\pgf@decorate@do@state% \ifx\pgf@decorate@current@state\pgf@final@text% \let\pgf@decorate@next\relax% \fi% @@ -931,10 +931,10 @@ % Next iteration. % \ifnum\pgf@decorate@repeatstate>0\relax% - \advance\pgf@decorate@repeatstate-1\relax% + \advance\pgf@decorate@repeatstate-1\relax% \else% - \pgf@decorate@repeatstate-1\relax% - \let\pgf@decorate@current@state\pgf@decorate@next@state% + \pgf@decorate@repeatstate-1\relax% + \let\pgf@decorate@current@state\pgf@decorate@next@state% \fi% \pgf@decorate@run% } @@ -1063,13 +1063,13 @@ \def\pgf@metadecoration@decoration#1{% - \edef\pgf@decorate@tempname{#1}% + \edef\pgf@decorate@tempname{#1}% } \def\pgf@metadecoration@beforedecoration#1{% - \def\pgf@decorate@tempbefore{#1}% + \def\pgf@decorate@tempbefore{#1}% } \def\pgf@metadecoration@afterdecoration#1{% - \def\pgf@decorate@tempafter{#1}% + \def\pgf@decorate@tempafter{#1}% } @@ -1078,7 +1078,7 @@ % Run a meta decoration. % \def\pgf@metadecoration@run{% - \let\pgf@metadecoration@next\pgf@metadecoration@do@state% + \let\pgf@metadecoration@next\pgf@metadecoration@do@state% \ifx\pgf@metadecoration@current@state\pgf@final@text% \let\pgf@metadecoration@next\relax% \fi% @@ -1086,7 +1086,7 @@ } \def\pgf@metadecoration@do@state{% - \let\pgf@metadecoration@next\relax% + \let\pgf@metadecoration@next\relax% \let\pgf@metadecoration@next@state\pgf@metadecoration@current@state% % % Set up some macros. @@ -1107,7 +1107,7 @@ } \def\pgf@metadecoration@do@code{% - % + % % Execute code. % \let\pgf@decorate@tempname\pgfutil@empty% @@ -1117,11 +1117,11 @@ \let\pgfpointmetadecoratedpathlast\pgfpointdecoratedpathlast% \csname pgf@metadecoration@@\pgf@metadecoration@name @\pgf@metadecoration@current@state @code\endcsname% \ifx\pgf@decorate@tempname\pgfutil@empty% - \def\pgf@decorate@tempname{moveto} - \fi% + \def\pgf@decorate@tempname{moveto} + \fi% \pgf@decorate@invoke{% - {\pgf@decorate@tempname}{\pgf@metadecoration@width}% - {\pgf@decorate@tempbefore}{\pgf@decorate@tempafter}% + {\pgf@decorate@tempname}{\pgf@metadecoration@width}% + {\pgf@decorate@tempbefore}{\pgf@decorate@tempafter}% }% % % Next iteration. @@ -1141,7 +1141,7 @@ \def\pgf@metadecoration@switch@if#1to #2\pgf@stop{% \ifx\pgf@metadecoration@next\relax% - \pgfmathsetlength\pgf@x{#1}% + \pgfmathsetlength\pgf@x{#1}% \ifdim\pgf@decorated@remainingdistance<\pgf@x% \def\pgf@metadecoration@current@state{#2}% \let\pgf@metadecoration@next\pgf@metadecoration@run% @@ -1151,7 +1151,7 @@ \def\pgf@metadecoration@switch@ifinputsegment#1to #2\pgf@stop{% \ifx\pgf@metadecoration@next\relax% - \pgfmathsetlength\pgf@x{#1}% + \pgfmathsetlength\pgf@x{#1}% \ifdim\pgfdecoratedinputsegmentremainingdistance<\pgf@x% \def\pgf@metadecoration@current@state{#2}% \let\pgf@metadecoration@next\pgf@metadecoration@run% @@ -1164,10 +1164,10 @@ % Move along the path by a specified distance. % \def\pgf@decorate@movealongpath#1{% - \pgfmathsetlength\pgf@decorate@distancetomove{#1}% - \advance\pgfdecoratedcompleteddistance\pgf@decorate@distancetomove% - \advance\pgfdecoratedremainingdistance-\pgf@decorate@distancetomove% - \pgf@decorate@@movealongpath% + \pgfmathsetlength\pgf@decorate@distancetomove{#1}% + \advance\pgfdecoratedcompleteddistance\pgf@decorate@distancetomove% + \advance\pgfdecoratedremainingdistance-\pgf@decorate@distancetomove% + \pgf@decorate@@movealongpath% } \def\pgf@decorate@@movealongpath{% \advance\pgfdecoratedinputsegmentcompleteddistance\pgf@decorate@distancetomove% @@ -1188,107 +1188,107 @@ } \def\pgf@decorate@@@movealongpath{% - % - % Move along input segment for real. - % - \pgf@decorate@movealonginputsegment{\the\pgf@decorate@distancetomove}% - \pgf@decorate@distancetomove0pt\relax% - % - % Grrr. Hacking to control some inaccuracies. - % - \ifdim\pgf@decorate@inputsegmenttime pt>1pt\relax% - \let\pgf@decorate@inputsegmenttimetemp\pgf@decorate@inputsegmenttime% - \pgf@decorate@processnextinputsegmentobject% - \pgf@x\pgf@decorate@inputsegmenttimetemp pt\relax% - \advance\pgf@x-1pt\relax% - \edef\pgf@decorate@inputsegmenttime{\pgfmath@tonumber{\pgf@x}}% - \ifx\pgf@decorate@currentinputsegmentobjects\pgfutil@empty% - \pgfdecoratedremainingdistance0pt\relax% - \fi% - \fi% + % + % Move along input segment for real. + % + \pgf@decorate@movealonginputsegment{\the\pgf@decorate@distancetomove}% + \pgf@decorate@distancetomove0pt\relax% + % + % Grrr. Hacking to control some inaccuracies. + % + \ifdim\pgf@decorate@inputsegmenttime pt>1pt\relax% + \let\pgf@decorate@inputsegmenttimetemp\pgf@decorate@inputsegmenttime% + \pgf@decorate@processnextinputsegmentobject% + \pgf@x\pgf@decorate@inputsegmenttimetemp pt\relax% + \advance\pgf@x-1pt\relax% + \edef\pgf@decorate@inputsegmenttime{\pgfmath@tonumber{\pgf@x}}% + \ifx\pgf@decorate@currentinputsegmentobjects\pgfutil@empty% + \pgfdecoratedremainingdistance0pt\relax% + \fi% + \fi% } % Return the next input segment object in a macro % \def\pgf@decorate@getnextinputsegmentobject#1{% - \ifx\pgf@decorate@currentinputsegmentobjects\pgfutil@empty% - \let\pgf@next\relax% - \else% - \def\pgf@decorate@temp{#1}% - \let\pgf@next\pgf@decorate@@getnextinputsegmentobject% - \fi% - \pgf@next% + \ifx\pgf@decorate@currentinputsegmentobjects\pgfutil@empty% + \let\pgf@next\relax% + \else% + \def\pgf@decorate@temp{#1}% + \let\pgf@next\pgf@decorate@@getnextinputsegmentobject% + \fi% + \pgf@next% } \def\pgf@decorate@@getnextinputsegmentobject{% - \expandafter\pgf@decorate@@@getnextinputsegmentobject\pgf@decorate@currentinputsegmentobjects\pgf@stop} + \expandafter\pgf@decorate@@@getnextinputsegmentobject\pgf@decorate@currentinputsegmentobjects\pgf@stop} \def\pgf@decorate@@@getnextinputsegmentobject#1#2\pgf@stop{% - \expandafter\def\pgf@decorate@temp{#1}% - \def\pgf@decorate@currentinputsegmentobjects{#2}} + \expandafter\def\pgf@decorate@temp{#1}% + \def\pgf@decorate@currentinputsegmentobjects{#2}} % Process the next input segment object. % \def\pgf@decorate@processnextinputsegmentobject{% - \let\pgfdecorationpreviousinputsegment\pgfdecoratecurrentinputsegment% - \let\pgf@decorate@currentinputsegmentobject\pgf@decorate@nextinputsegmentobject% - \pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject% - % - % If the current input segment object is a moveto, execute the - % object macro and get the next input segment object. - % - \pgf@decorate@is@closepath@false% - \pgf@decorate@currentinputsegmentobject% - \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto% - \pgfpathmoveto{\pgf@decorate@inputsegment@first}% - \let\pgfdecorationpreviousinputsegment\pgfdecorationcurrentinputsegment% - \let\pgf@decorate@currentinputsegmentobject\pgf@decorate@nextinputsegmentobject% - \pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject% - \pgf@decorate@is@closepath@false% - \pgf@decorate@currentinputsegmentobject% - \fi% - % - % Teensy hack in case a path goes nowhere. - % - \ifdim\pgfdecoratedinputsegmentlength=0pt\relax% - \def\pgfdecoratedinputsegmentlength{0.05pt}% Arbitrary choice >0pt. - \fi% - \pgfdecoratedinputsegmentremainingdistance\pgfdecoratedinputsegmentlength\relax% - \pgfdecoratedinputsegmentcompleteddistance0pt\relax% - \def\pgf@decorate@inputsegmenttime{0}% - % - % Get the angle at the start of the input segment. - % - \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto% - \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% - \let\pgfdecoratedangle\pgfmathresult% - \let\pgfdecoratedinputsegmentstartangle\pgfmathresult% - \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% - \let\pgfdecoratedinputsegmentendangle\pgfmathresult% - \else% - \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@last}% - \let\pgfdecoratedangle\pgfmathresult% - \let\pgfdecoratedinputsegmentstartangle\pgfmathresult% - \let\pgfdecoratedinputsegmentendangle\pgfmathresult% - \fi% - % - % Get the angle to the next input segment. - % - \begingroup% - \pgf@decorate@nextinputsegmentobject% - \global\let\pgf@decorate@temp\pgfdecorationcurrentinputsegment% - \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto% - \expandafter\pgf@decorate@currentinputsegmentobject% - \fi% - \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto% - \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% - \else% - \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@last}% - \fi% - \pgf@x-\pgfdecoratedangle pt\relax% - \advance\pgf@x\pgfmathresult pt\relax% - \edef\pgfdecoratedangletonextinputsegment{\the\pgf@x}% - \pgfmath@smuggleone\pgfdecoratedangletonextinputsegment% - \endgroup% - \let\pgfdecorationnextinputsegmentobject\pgf@decorate@temp% + \let\pgfdecorationpreviousinputsegment\pgfdecoratecurrentinputsegment% + \let\pgf@decorate@currentinputsegmentobject\pgf@decorate@nextinputsegmentobject% + \pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject% + % + % If the current input segment object is a moveto, execute the + % object macro and get the next input segment object. + % + \pgf@decorate@is@closepath@false% + \pgf@decorate@currentinputsegmentobject% + \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto% + \pgfpathmoveto{\pgf@decorate@inputsegment@first}% + \let\pgfdecorationpreviousinputsegment\pgfdecorationcurrentinputsegment% + \let\pgf@decorate@currentinputsegmentobject\pgf@decorate@nextinputsegmentobject% + \pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject% + \pgf@decorate@is@closepath@false% + \pgf@decorate@currentinputsegmentobject% + \fi% + % + % Teensy hack in case a path goes nowhere. + % + \ifdim\pgfdecoratedinputsegmentlength=0pt\relax% + \def\pgfdecoratedinputsegmentlength{0.05pt}% Arbitrary choice >0pt. + \fi% + \pgfdecoratedinputsegmentremainingdistance\pgfdecoratedinputsegmentlength\relax% + \pgfdecoratedinputsegmentcompleteddistance0pt\relax% + \def\pgf@decorate@inputsegmenttime{0}% + % + % Get the angle at the start of the input segment. + % + \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto% + \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + \let\pgfdecoratedangle\pgfmathresult% + \let\pgfdecoratedinputsegmentstartangle\pgfmathresult% + \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% + \let\pgfdecoratedinputsegmentendangle\pgfmathresult% + \else% + \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@last}% + \let\pgfdecoratedangle\pgfmathresult% + \let\pgfdecoratedinputsegmentstartangle\pgfmathresult% + \let\pgfdecoratedinputsegmentendangle\pgfmathresult% + \fi% + % + % Get the angle to the next input segment. + % + \begingroup% + \pgf@decorate@nextinputsegmentobject% + \global\let\pgf@decorate@temp\pgfdecorationcurrentinputsegment% + \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto% + \expandafter\pgf@decorate@currentinputsegmentobject% + \fi% + \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto% + \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + \else% + \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@last}% + \fi% + \pgf@x-\pgfdecoratedangle pt\relax% + \advance\pgf@x\pgfmathresult pt\relax% + \edef\pgfdecoratedangletonextinputsegment{\the\pgf@x}% + \pgfmath@smuggleone\pgfdecoratedangletonextinputsegment% + \endgroup% + \let\pgfdecorationnextinputsegmentobject\pgf@decorate@temp% } @@ -1315,56 +1315,55 @@ % Input segment object moveto. % \def\pgf@decorate@inputsegmentobject@moveto#1{% - \def\pgf@decorate@inputsegment@first{#1}% - \def\pgf@decorate@inputsegment@supporta{#1}% - \def\pgf@decorate@inputsegment@supportb{#1}% - \def\pgf@decorate@inputsegment@last{#1}% - \edef\pgf@decorate@lastmoveto{#1}% - \def\pgfdecoratedinputsegmentlength{0pt}% - \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto% + \def\pgf@decorate@inputsegment@first{#1}% + \def\pgf@decorate@inputsegment@supporta{#1}% + \def\pgf@decorate@inputsegment@supportb{#1}% + \def\pgf@decorate@inputsegment@last{#1}% + \edef\pgf@decorate@lastmoveto{#1}% + \def\pgfdecoratedinputsegmentlength{0pt}% + \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto% } % Input segment object lineto. % \def\pgf@decorate@inputsegmentobject@lineto#1#2#3{% - \def\pgfdecoratedinputsegmentlength{#1}% - \def\pgf@decorate@inputsegment@first{#2}% - \def\pgf@decorate@inputsegment@last{#3}% - % - % Supports should be defined like this, so if treated as a curve, - % equal time steps will correspond to equal distances. - % - \pgfpointdiff{#2}{#3}% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \pgfextract@process\pgf@decorate@inputsegment@supporta{% - \pgf@process{#2}% - \advance\pgf@x0.333333\pgf@xa% - \advance\pgf@y0.333333\pgf@ya% - }% - \pgfextract@process\pgf@decorate@inputsegment@supportb{% - \pgf@process{#2}% - \advance\pgf@x0.666666\pgf@xa% - \advance\pgf@y0.666666\pgf@ya% - }% - % - \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@line% - \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@line% - \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentlineto% + \def\pgfdecoratedinputsegmentlength{#1}% + \def\pgf@decorate@inputsegment@first{#2}% + \def\pgf@decorate@inputsegment@last{#3}% + % + % Supports should be defined like this, so if treated as a curve, + % equal time steps will correspond to equal distances. + % + \pgfpointdiff{#2}{#3}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgfextract@process\pgf@decorate@inputsegment@supporta{% + \pgf@process{#2}% + \advance\pgf@x0.333333\pgf@xa% + \advance\pgf@y0.333333\pgf@ya% + }% + \pgfextract@process\pgf@decorate@inputsegment@supportb{% + \pgf@process{#2}% + \advance\pgf@x0.666666\pgf@xa% + \advance\pgf@y0.666666\pgf@ya% + }% + \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@line% + \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@line% + \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentlineto% } % Input segment object curveto. % \def\pgf@decorate@inputsegmentobject@curveto#1#2#3#4#5{% - \def\pgfdecoratedinputsegmentlength{#1}% - \def\pgf@decorate@inputsegment@first{#2}% - \def\pgf@decorate@inputsegment@supporta{#3}% - \def\pgf@decorate@inputsegment@supportb{#4}% - \def\pgf@decorate@inputsegment@last{#5}% - % - \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@curve% - \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@curve% - \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto% + \def\pgfdecoratedinputsegmentlength{#1}% + \def\pgf@decorate@inputsegment@first{#2}% + \def\pgf@decorate@inputsegment@supporta{#3}% + \def\pgf@decorate@inputsegment@supportb{#4}% + \def\pgf@decorate@inputsegment@last{#5}% + % + \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@curve% + \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@curve% + \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto% } % Input segment object closepath. @@ -1377,31 +1376,31 @@ \def\pgfdecoratedinputsegmentlength{#1}% \def\pgf@decorate@inputsegment@first{#2}% \def\pgf@decorate@inputsegment@last{#3}% - % - \pgfpointdiff{#2}{#3}% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \pgfextract@process\pgf@decorate@inputsegment@supporta{% - \pgf@process{#2}% - \advance\pgf@x0.333333\pgf@xa% - \advance\pgf@y0.333333\pgf@ya% - }% - \pgfextract@process\pgf@decorate@inputsegment@supportb{% - \pgf@process{#2}% - \advance\pgf@x0.666666\pgf@xa% - \advance\pgf@y0.666666\pgf@ya% - }% - % + % + \pgfpointdiff{#2}{#3}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgfextract@process\pgf@decorate@inputsegment@supporta{% + \pgf@process{#2}% + \advance\pgf@x0.333333\pgf@xa% + \advance\pgf@y0.333333\pgf@ya% + }% + \pgfextract@process\pgf@decorate@inputsegment@supportb{% + \pgf@process{#2}% + \advance\pgf@x0.666666\pgf@xa% + \advance\pgf@y0.666666\pgf@ya% + }% + % \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@line% \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@line% - \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentclosepath% + \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentclosepath% } % Input segment object endofinputsegments. % \def\pgf@decorate@inputsegmentobject@endofinputsegments{% - \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentlast% + \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentlast% } @@ -1414,93 +1413,92 @@ % This macro controls how the automaton moves along a curve sub-path. % \def\pgf@decorate@movealonginputsegment@curve#1{% - \ifdim#1=0pt\relax% - \else% - \pgfpointcurveattime{\pgf@decorate@inputsegmenttime}% - {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% - {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \pgf@xb\pgf@decorate@inputsegmenttime pt\relax% - % - % Reduce the initial time step, depending on the length - % of the path. To do: Optimise this step (should also depend on #1). - % - \ifdim\pgf@decorate@currentpathlength<128pt\relax% - \pgf@yb.03125pt\relax% - \else% - \ifdim\pgf@decorate@currentpathlength<512pt\relax% - \pgf@yb.015625pt\relax% - \else% - \ifdim\pgf@decorate@currentpathlength<2048pt\relax% - \pgf@yb.00390625pt\relax% - \else% - \pgf@yb.0009765625pt\relax% - \fi% - \fi% - \fi% - \c@pgf@counta1\relax% - \pgfutil@tempdima0pt\relax% - \pgfmathloop% - \advance\pgf@xb\c@pgf@counta\pgf@yb% - % - % We would like to use \pgfpointcurveattime. However, we must not - % overuse \pgf@process or \pgfmath stuff within this loop, - % otherwise we increase the chances of save stack overflow. - % - \edef\pgf@decorate@temp{% - \pgf@xa\the\pgf@xa% - \pgf@xb\the\pgf@xb% - \pgf@ya\the\pgf@ya% - \pgf@yb\the\pgf@yb% - }% - % - \pgfpoint@decorate@curveattime{\pgfmath@tonumber{\pgf@xb}}% - {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% - {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% - % - \pgf@decorate@temp% - % - \pgf@xc\pgf@xa% - \pgf@yc\pgf@ya% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \advance\pgf@x-\pgf@xc% - \advance\pgf@y-\pgf@yc% - \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% - \pgfutil@tempdimb\pgfmathresult pt\relax% - \advance\pgfutil@tempdima\c@pgf@counta\pgfutil@tempdimb% - \ifnum\c@pgf@counta>0\relax% - \ifdim\pgfutil@tempdima>#1\relax% - \c@pgf@counta-\c@pgf@counta% - \pgf@yb.5\pgf@yb% - \fi% - \else% - \ifdim\pgfutil@tempdima<#1\relax% - \c@pgf@counta-\c@pgf@counta% - \pgf@yb.5\pgf@yb% - \fi% - \fi% - \ifdim\pgf@yb=0pt\relax% *Should* be OK. - \else% - \repeatpgfmathloop% - \edef\pgf@decorate@inputsegmenttime{\pgfmath@tonumber{\pgf@xb}}% - % - % Now calculate the angle at the new time on the curve. - % - % We can use \pgfpointcurveattime safely here. - % - \pgfpointcurveattime{\pgf@decorate@inputsegmenttime}% - {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% - {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% - \edef\pgf@marshal{% - \noexpand\pgfmathanglebetweenpoints% - {\pgf@x\the\pgf@xb\pgf@y\pgf@yb}% - {\pgf@x\the\pgf@xa\pgf@y\pgf@ya}% - }% - \pgf@marshal% - \let\pgfdecoratedangle\pgfmathresult% - \fi% + \ifdim#1=0pt\relax% + \else% + \pgfpointcurveattime{\pgf@decorate@inputsegmenttime}% + {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgf@xb\pgf@decorate@inputsegmenttime pt\relax% + % + % Reduce the initial time step, depending on the length + % of the path. To do: Optimise this step (should also depend on #1). + % + \ifdim\pgf@decorate@currentpathlength<128pt\relax% + \pgf@yb.03125pt\relax% + \else% + \ifdim\pgf@decorate@currentpathlength<512pt\relax% + \pgf@yb.015625pt\relax% + \else% + \ifdim\pgf@decorate@currentpathlength<2048pt\relax% + \pgf@yb.00390625pt\relax% + \else% + \pgf@yb.0009765625pt\relax% + \fi% + \fi% + \fi% + \c@pgf@counta1\relax% + \pgfutil@tempdima0pt\relax% + \pgfmathloop% + \advance\pgf@xb\c@pgf@counta\pgf@yb% + % + % We would like to use \pgfpointcurveattime. However, we must not + % overuse \pgf@process or \pgfmath stuff within this loop, + % otherwise we increase the chances of save stack overflow. + % + \edef\pgf@decorate@temp{% + \pgf@xa\the\pgf@xa% + \pgf@xb\the\pgf@xb% + \pgf@ya\the\pgf@ya% + \pgf@yb\the\pgf@yb% + }% + % + \pgfpoint@decorate@curveattime{\pgfmath@tonumber{\pgf@xb}}% + {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% + \pgf@decorate@temp% + % + \pgf@xc\pgf@xa% + \pgf@yc\pgf@ya% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \advance\pgf@x-\pgf@xc% + \advance\pgf@y-\pgf@yc% + \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% + \pgfutil@tempdimb\pgfmathresult pt\relax% + \advance\pgfutil@tempdima\c@pgf@counta\pgfutil@tempdimb% + \ifnum\c@pgf@counta>0\relax% + \ifdim\pgfutil@tempdima>#1\relax% + \c@pgf@counta-\c@pgf@counta% + \pgf@yb.5\pgf@yb% + \fi% + \else% + \ifdim\pgfutil@tempdima<#1\relax% + \c@pgf@counta-\c@pgf@counta% + \pgf@yb.5\pgf@yb% + \fi% + \fi% + \ifdim\pgf@yb=0pt\relax% *Should* be OK. + \else% + \repeatpgfmathloop% + \edef\pgf@decorate@inputsegmenttime{\pgfmath@tonumber{\pgf@xb}}% + % + % Now calculate the angle at the new time on the curve. + % + % We can use \pgfpointcurveattime safely here. + % + \pgfpointcurveattime{\pgf@decorate@inputsegmenttime}% + {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% + \edef\pgf@marshal{% + \noexpand\pgfmathanglebetweenpoints% + {\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb}% + {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}% + }% + \pgf@marshal% + \let\pgfdecoratedangle\pgfmathresult% + \fi% } % \pgfpoint@decorate@curveattime @@ -1549,141 +1547,140 @@ % Applies the necessary transform for a line sub-path. % \def\pgf@decorate@transformtoinputsegment@line{% - \pgftransformshift{% - \pgfpointadd{\pgf@decorate@inputsegment@first}% - {\pgfpointpolar{\pgfdecoratedangle}{\pgfdecoratedinputsegmentcompleteddistance}}% - }% - \pgftransformrotate{\pgfdecoratedangle}% + \pgftransformshift{% + \pgfpointlineatdistance{\pgfdecoratedinputsegmentcompleteddistance}{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@last} + }% + \pgftransformrotate{\pgfdecoratedangle}% } % Applies the necessary transform for a curve sub-path. % \def\pgf@decorate@transformtoinputsegment@curve{% - \pgfslopedattimetrue% - \pgfallowupsidedownattimetrue% - \pgftransformcurveattime{\pgf@decorate@inputsegmenttime}% - {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% - {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% + \pgfslopedattimetrue% + \pgfallowupsidedownattimetrue% + \pgftransformcurveattime{\pgf@decorate@inputsegmenttime}% + {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% } -% \pgf@decorate@parsesoftpath -% -% Parses an instance of a soft path into intermediate line and curve -% sub-path objects which the decoration automaton can use to traverse +% \pgf@decorate@parsesoftpath +% +% Parses an instance of a soft path into intermediate line and curve +% sub-path objects which the decoration automaton can use to traverse % the decorated path. -% -% The soft path should be well formed and only contain `primative' -% soft path tokens, that is: moveto, lineto, curvetosupporta, -% curvetosupportb, curveto, rectcorner, rectsize, and closepath. -% (i.e., all specialround tokens should have removed using -% \pgfprocessround) -% -% The overall length of the path is also calculated and returned -% in the macro \pgfdecoratedpathlength. -% -% Parameters: -% -% #1 - a macro containing a well formed soft path. -% #2 - a macro to store the intermediate sub-path representations. -% -% Example: -% -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathlineto{\pgfpoint{0pt}{12pt}} -% \pgfpathlineto{\pgfpoint{12pt}{0pt}} -% \pgfgetpath\softpath -% -% \pgf@decorate@parsesoftpath{\softpath}{\parsedsoftpath} -% -% results in: -% -% \parsedsoftpath -> -% {\pgf@decorate@inputsegmentobject@lineto{12pt}{\pgf@x 0pt\pgf@y 0pt}{\pgf@x 0pt\pgf@y 12pt}} -% {\pgf@decorate@inputsegmentobject@lineto{12pt}{\pgf@x 0pt\pgf@y 12pt}{\pgf@x 12pt\pgf@y 12pt}} -% -% \pgfdecoratedpathlength -> -% 24pt +% +% The soft path should be well formed and only contain `primative' +% soft path tokens, that is: moveto, lineto, curvetosupporta, +% curvetosupportb, curveto, rectcorner, rectsize, and closepath. +% (i.e., all specialround tokens should have removed using +% \pgfprocessround) +% +% The overall length of the path is also calculated and returned +% in the macro \pgfdecoratedpathlength. +% +% Parameters: +% +% #1 - a macro containing a well formed soft path. +% #2 - a macro to store the intermediate sub-path representations. +% +% Example: +% +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathlineto{\pgfpoint{0pt}{12pt}} +% \pgfpathlineto{\pgfpoint{12pt}{0pt}} +% \pgfgetpath\softpath +% +% \pgf@decorate@parsesoftpath{\softpath}{\parsedsoftpath} +% +% results in: +% +% \parsedsoftpath -> +% {\pgf@decorate@inputsegmentobject@lineto{12pt}{\pgf@x 0pt\pgf@y 0pt}{\pgf@x 0pt\pgf@y 12pt}} +% {\pgf@decorate@inputsegmentobject@lineto{12pt}{\pgf@x 0pt\pgf@y 12pt}{\pgf@x 12pt\pgf@y 12pt}} +% +% \pgfdecoratedpathlength -> +% 24pt % \def\pgf@decorate@parsesoftpath#1#2{% - \def\pgf@decorate@inputsegmentobjectsmacro{#2}% - \let\pgf@decorate@inputsegmentobjects\pgfutil@empty% - \pgfutil@tempdima0pt\relax% - \let\pgfpoint@decorate@lastparsed\pgfpoint@decorate@existingpathlast% - \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@origin% - \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% - \let\pgfpoint@decorated@firstparsed\pgfutil@empty% - \expandafter\pgf@decorate@@parsesoftpath#1\pgf@stop% + \def\pgf@decorate@inputsegmentobjectsmacro{#2}% + \let\pgf@decorate@inputsegmentobjects\pgfutil@empty% + \pgfutil@tempdima0pt\relax% + \let\pgfpoint@decorate@lastparsed\pgfpoint@decorate@existingpathlast% + \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@origin% + \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% + \let\pgfpoint@decorated@firstparsed\pgfutil@empty% + \expandafter\pgf@decorate@@parsesoftpath#1\pgf@stop% } \def\pgf@decorate@@parsesoftpath#1{% - \ifx#1\pgf@stop% - \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% <- removes final moveto (may not be desirable). - \pgf@decorate@addtoinputsegmentobjects{\pgf@decorate@inputsegmentobject@endofinputsegments}% - \pgf@decorate@addtoinputsegmentobjects{\pgf@decorate@inputsegmentobject@endofinputsegments}% - \expandafter\let\pgf@decorate@inputsegmentobjectsmacro\pgf@decorate@inputsegmentobjects% - \edef\pgf@decorate@totalpathlength{\the\pgfutil@tempdima}% - \let\pgf@next\relax% - \else% - \ifx#1\pgfsyssoftpath@movetotoken% - \let\pgf@next\pgf@decorate@parsemoveto% - \else% - \ifx#1\pgfsyssoftpath@linetotoken% - \let\pgf@next\pgf@decorate@parselineto% - \else% - \ifx#1\pgfsyssoftpath@curvetosupportatoken% - \let\pgf@next\pgf@decorate@parsecurveto% - \else% - \ifx#1\pgfsyssoftpath@closepathtoken% - \let\pgf@next\pgf@decorate@parseclosepath% - \else% - \ifx#1\pgfsyssoftpath@rectcornertoken% - \let\pgf@next\pgf@decorate@parserect% - \else% - \PackageError{PGF}{Unrecognised soft path token `#1'}{}% - \fi% - \fi% - \fi% - \fi% - \fi% - \fi% - \pgf@next} + \ifx#1\pgf@stop% + \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% <- removes final moveto (may not be desirable). + \pgf@decorate@addtoinputsegmentobjects{\pgf@decorate@inputsegmentobject@endofinputsegments}% + \pgf@decorate@addtoinputsegmentobjects{\pgf@decorate@inputsegmentobject@endofinputsegments}% + \expandafter\let\pgf@decorate@inputsegmentobjectsmacro\pgf@decorate@inputsegmentobjects% + \edef\pgf@decorate@totalpathlength{\the\pgfutil@tempdima}% + \let\pgf@next\relax% + \else% + \ifx#1\pgfsyssoftpath@movetotoken% + \let\pgf@next\pgf@decorate@parsemoveto% + \else% + \ifx#1\pgfsyssoftpath@linetotoken% + \let\pgf@next\pgf@decorate@parselineto% + \else% + \ifx#1\pgfsyssoftpath@curvetosupportatoken% + \let\pgf@next\pgf@decorate@parsecurveto% + \else% + \ifx#1\pgfsyssoftpath@closepathtoken% + \let\pgf@next\pgf@decorate@parseclosepath% + \else% + \ifx#1\pgfsyssoftpath@rectcornertoken% + \let\pgf@next\pgf@decorate@parserect% + \else% + \pgferror{Unrecognised soft path token `#1'}% + \fi% + \fi% + \fi% + \fi% + \fi% + \fi% + \pgf@next} \def\pgf@decorate@addtoinputsegmentobjects#1{% - % - % If there is an input segment object waiting (i.e. a moveto), insert it here. - % - \ifx\pgf@decorate@queueinputsegmentobject\pgfutil@empty% - \else% - \let\pgf@decorate@temp\pgf@decorate@queueinputsegmentobject% - \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% - \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% - \fi% - \ifx\pgfpoint@decorated@firstparsed\pgfutil@empty% - #1% - \let\pgfpoint@decorated@firstparsed\pgf@decorate@inputsegment@first% - \fi% - \expandafter\def\expandafter\pgf@decorate@inputsegmentobjects\expandafter% - {\pgf@decorate@inputsegmentobjects{#1}}% -} - -% Convert \pgfsyssoftpath@movetotoken{<X>}{<Y>} into the following + % + % If there is an input segment object waiting (i.e. a moveto), insert it here. + % + \ifx\pgf@decorate@queueinputsegmentobject\pgfutil@empty% + \else% + \let\pgf@decorate@temp\pgf@decorate@queueinputsegmentobject% + \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% + \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% + \fi% + \ifx\pgfpoint@decorated@firstparsed\pgfutil@empty% + #1% + \let\pgfpoint@decorated@firstparsed\pgf@decorate@inputsegment@first% + \fi% + \expandafter\def\expandafter\pgf@decorate@inputsegmentobjects\expandafter% + {\pgf@decorate@inputsegmentobjects{#1}}% +} + +% Convert \pgfsyssoftpath@movetotoken{<X>}{<Y>} into the following % representation: -% -% \pgf@decorate@inputsegmentobject@moveto{\pgf@x X\pgf@y Y} +% +% \pgf@decorate@inputsegmentobject@moveto{\pgf@x X\pgf@y Y} % -% The moveto input segment object is not added immediately, so that -% only the last of multiple movetos is inserted. -% +% The moveto input segment object is not added immediately, so that +% only the last of multiple movetos is inserted. +% \def\pgf@decorate@parsemoveto#1#2{% - \def\pgf@decorate@queueinputsegmentobject{\pgf@decorate@inputsegmentobject@moveto{\pgf@x#1\pgf@y#2}}% - \def\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% - \pgf@decorate@@parsesoftpath% + \def\pgf@decorate@queueinputsegmentobject{\pgf@decorate@inputsegmentobject@moveto{\pgf@x#1\pgf@y#2}}% + \def\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% + \pgf@decorate@@parsesoftpath% } % Convert \pgfsyssoftpath@linetotoken{<X>}{<Y>} into the following @@ -1692,47 +1689,47 @@ % \pgf@decorate@inputsegmentobject@lineto{<length>}{\pgf@x <Last X> \pgf@y <Last Y}{\pgf@x <X> \pgf@y <Y>} % \def\pgf@decorate@parselineto#1#2{% - \pgf@decorate@linelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% - \advance\pgfutil@tempdima\pgfmathresult pt\relax% - \edef\pgf@decorate@temp{% - \noexpand\pgf@decorate@inputsegmentobject@lineto{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% - }% - \edef\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% - \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% - \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% - \pgf@decorate@@parsesoftpath% -} - + \pgf@decorate@linelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% + \advance\pgfutil@tempdima\pgfmathresult pt\relax% + \edef\pgf@decorate@temp{% + \noexpand\pgf@decorate@inputsegmentobject@lineto{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% + }% + \edef\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% + \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% + \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% + \pgf@decorate@@parsesoftpath% +} + % Convert \pgfsyssoftpath@curvetosupportatoken{<Xa>}{<Ya>}...etc % into the following representation: % % \pgf@decorate@inputsegmentobject@curveto{<length>}{\pgf@x <Last X> \pgf@y <Last Y} -% {\pgf@x <Xa> \pgf@y <Ya>}{\pgf@x <Xb> \pgf@y <Yb>}{\pgf@x <X> \pgf@y <Y>} +% {\pgf@x <Xa> \pgf@y <Ya>}{\pgf@x <Xb> \pgf@y <Yb>}{\pgf@x <X> \pgf@y <Y>} % \def\pgf@decorate@parsecurveto#1#2\pgfsyssoftpath@curvetosupportbtoken#3#4\pgfsyssoftpath@curvetotoken#5#6{% - \pgf@decorate@curvelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}{\pgf@x#3\pgf@y#4}{\pgf@x#5\pgf@y#6}% - \advance\pgfutil@tempdima\pgfmathresult pt\relax% - \edef\pgf@decorate@temp{% - \noexpand\pgf@decorate@inputsegmentobject@curveto{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}% - {\pgf@x#1\pgf@y#2}{\pgf@x#3\pgf@y#4}{\pgf@x#5\pgf@y#6}% - }% - \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% - \edef\pgfpoint@decorate@lastparsed{\pgf@x#5\pgf@y#6}% - \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% - \pgf@decorate@@parsesoftpath% + \pgf@decorate@curvelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}{\pgf@x#3\pgf@y#4}{\pgf@x#5\pgf@y#6}% + \advance\pgfutil@tempdima\pgfmathresult pt\relax% + \edef\pgf@decorate@temp{% + \noexpand\pgf@decorate@inputsegmentobject@curveto{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}% + {\pgf@x#1\pgf@y#2}{\pgf@x#3\pgf@y#4}{\pgf@x#5\pgf@y#6}% + }% + \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% + \edef\pgfpoint@decorate@lastparsed{\pgf@x#5\pgf@y#6}% + \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% + \pgf@decorate@@parsesoftpath% } \def\pgf@decorate@parseclosepath#1#2{% - \pgf@decorate@linelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% - \advance\pgfutil@tempdima\pgfmathresult pt\relax% - \edef\pgf@decorate@temp{% - \noexpand\pgf@decorate@inputsegmentobject@closepath{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% - }% - \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% - \edef\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% - \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% - \pgf@decorate@@parsesoftpath% + \pgf@decorate@linelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% + \advance\pgfutil@tempdima\pgfmathresult pt\relax% + \edef\pgf@decorate@temp{% + \noexpand\pgf@decorate@inputsegmentobject@closepath{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% + }% + \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% + \edef\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% + \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% + \pgf@decorate@@parsesoftpath% } % Convert \pgfsyssoftpath@rectcornertoken{<X>}{<Y>}\pgfsyssoftpath@rectsizetoken{<Xa>}{<Ya>} @@ -1756,52 +1753,52 @@ % \newif\ifpgfdecoraterectangleclockwise \def\pgf@decorate@parserect#1#2\pgfsyssoftpath@rectsizetoken#3#4{% - % - % Subvert \pgf@decorate@parsesoftpath so parsing macros will - % return here instead of continuing to parse the soft path. - % - \let\pgf@decorate@orig@@parsesoftpath\pgf@decorate@@parsesoftpath% - \let\pgf@decorate@@parsesoftpath\relax% - \pgf@decorate@parsemoveto{#1}{#2}% - \pgf@xa#1\relax% - \pgf@ya#2\relax% - \ifpgfdecoraterectangleclockwise% - \advance\pgf@ya#4% - \pgf@yb\pgf@ya% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parselineto\pgf@temp% - \advance\pgf@xa#3% - \pgf@xb\pgf@xa% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parselineto\pgf@temp% - \advance\pgf@ya-#4% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parselineto\pgf@temp% - \advance\pgf@xa-#3% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parseclosepath\pgf@temp% - \else% - \advance\pgf@xa#3% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \pgf@xb\pgf@xa% - \expandafter\pgf@decorate@parselineto\pgf@temp% - \advance\pgf@ya#4% - \pgf@yb\pgf@ya% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parselineto\pgf@temp% - \advance\pgf@xa-#3% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parselineto\pgf@temp% - \advance\pgf@ya-#4% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parseclosepath\pgf@temp% - \fi% - % - % Restore the parsing. - % - \let\pgf@decorate@@parsesoftpath\pgf@decorate@orig@@parsesoftpath% - \edef\pgf@marshal{\noexpand\pgf@decorate@parsemoveto{\the\pgf@xb}{\the\pgf@yb}}% - \pgf@marshal% + % + % Subvert \pgf@decorate@parsesoftpath so parsing macros will + % return here instead of continuing to parse the soft path. + % + \let\pgf@decorate@orig@@parsesoftpath\pgf@decorate@@parsesoftpath% + \let\pgf@decorate@@parsesoftpath\relax% + \pgf@decorate@parsemoveto{#1}{#2}% + \pgf@xa#1\relax% + \pgf@ya#2\relax% + \ifpgfdecoraterectangleclockwise% + \advance\pgf@ya#4% + \pgf@yb\pgf@ya% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@xa#3% + \pgf@xb\pgf@xa% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@ya-#4% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@xa-#3% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parseclosepath\pgf@temp% + \else% + \advance\pgf@xa#3% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \pgf@xb\pgf@xa% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@ya#4% + \pgf@yb\pgf@ya% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@xa-#3% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@ya-#4% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parseclosepath\pgf@temp% + \fi% + % + % Restore the parsing. + % + \let\pgf@decorate@@parsesoftpath\pgf@decorate@orig@@parsesoftpath% + \edef\pgf@marshal{\noexpand\pgf@decorate@parsemoveto{\the\pgf@xb}{\the\pgf@yb}}% + \pgf@marshal% } @@ -1812,8 +1809,8 @@ % Define \pgfmathresult as the distance between #1 and #2 (without units). % \def\pgf@decorate@linelength#1#2{% - \pgf@process{\pgfpointdiff{#1}{#2}}% - \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% + \pgf@process{\pgfpointdiff{#1}{#2}}% + \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% } % \pgf@decorate@curvelength @@ -1824,138 +1821,138 @@ % To approximate the length of the curve P (sort of) use: % % curveLength(P,q) -% Q = subdivideLeft(P); -% R = subdivideRight(P); +% Q = subdivideLeft(P); +% R = subdivideRight(P); % return curveLength'(Q,q) + curveLength'(R,q); % % curveLength'(P,q) -% <P1,P2,P3,P4> <- P; +% <P1,P2,P3,P4> <- P; % P' = P4 - P1; % x = P'.x(); -% y = P'.y(); +% y = P'.y(); % if (x < q) && (y < q) -% return |P'|; -% else% -% Q = subdivideLeft(P); -% R = subdivideRight(P); +% return |P'|; +% else% +% Q = subdivideLeft(P); +% R = subdivideRight(P); % return curveLength'(Q,q) + curveLength'(R,q); % % Where q is some small value (`tolerance'). % \newif\ifpgf@decorate@subdivide \def\pgf@decorate@curvelength#1#2#3#4{% - % - % Always begin with a subdivision in case #1 = #4. - % - \begingroup% - \pgf@decorate@recursive@subdividecurve@left{#1}{#2}{#3}{#4}% - \pgfutil@tempdimb\pgfmathresult pt\relax% - \pgf@decorate@recursive@subdividecurve@right{#1}{#2}{#3}{#4}% - \advance\pgfutil@tempdimb\pgfmathresult pt\relax% - \pgfmath@returnone\pgfutil@tempdimb% - \endgroup% -} - + % + % Always begin with a subdivision in case #1 = #4. + % + \begingroup% + \pgf@decorate@recursive@subdividecurve@left{#1}{#2}{#3}{#4}% + \pgfutil@tempdimb\pgfmathresult pt\relax% + \pgf@decorate@recursive@subdividecurve@right{#1}{#2}{#3}{#4}% + \advance\pgfutil@tempdimb\pgfmathresult pt\relax% + \pgfmath@returnone\pgfutil@tempdimb% + \endgroup% +} + \def\pgf@decorate@@curvelength#1#2#3#4{% - \begingroup% - \pgf@decorate@curvecordlength{#1}{#2}{#3}{#4}% - \ifpgf@decorate@subdivide% - \pgf@decorate@recursive@subdividecurve@left{#1}{#2}{#3}{#4}% - \pgfutil@tempdimb\pgfmathresult pt\relax% - \pgf@decorate@recursive@subdividecurve@right{#1}{#2}{#3}{#4}% - \advance\pgfutil@tempdimb\pgfmathresult pt\relax% - \expandafter\pgfmath@returnone\expandafter\pgfutil@tempdimb% - \else% - \expandafter\pgfmath@returnone\expandafter\pgfmathresult\expandafter p\expandafter t\expandafter% - \fi% - \endgroup% + \begingroup% + \pgf@decorate@curvecordlength{#1}{#2}{#3}{#4}% + \ifpgf@decorate@subdivide% + \pgf@decorate@recursive@subdividecurve@left{#1}{#2}{#3}{#4}% + \pgfutil@tempdimb\pgfmathresult pt\relax% + \pgf@decorate@recursive@subdividecurve@right{#1}{#2}{#3}{#4}% + \advance\pgfutil@tempdimb\pgfmathresult pt\relax% + \expandafter\pgfmath@returnone\expandafter\pgfutil@tempdimb% + \else% + \expandafter\pgfmath@returnone\expandafter\pgfmathresult\expandafter p\expandafter t\expandafter% + \fi% + \endgroup% } \def\pgf@decorate@curvelength@tolerance{1pt} \def\pgf@decorate@curvecordlength#1#2#3#4{% - % - % Calculate the curve cord vector. - % - #4\relax% - \pgf@xa\pgf@x\pgf@ya\pgf@y% - #1\relax% - \advance\pgf@xa-\pgf@x% - \advance\pgf@ya-\pgf@y% - \ifdim\pgf@xa<0pt\relax\pgf@xa-\pgf@xa\fi% - \ifdim\pgf@ya<0pt\relax\pgf@ya-\pgf@ya\fi% - % - % Always subdivide, unless... - % - \pgf@decorate@subdividetrue% - % - % The cord vector is small. - % - \ifdim\pgf@xa<\pgf@decorate@curvelength@tolerance\relax% - \ifdim\pgf@ya<\pgf@decorate@curvelength@tolerance\relax% - \pgfmathveclen@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgf@ya}}% - \pgf@decorate@subdividefalse% - \fi% - \fi% + % + % Calculate the curve cord vector. + % + #4\relax% + \pgf@xa\pgf@x\pgf@ya\pgf@y% + #1\relax% + \advance\pgf@xa-\pgf@x% + \advance\pgf@ya-\pgf@y% + \ifdim\pgf@xa<0pt\relax\pgf@xa-\pgf@xa\fi% + \ifdim\pgf@ya<0pt\relax\pgf@ya-\pgf@ya\fi% + % + % Always subdivide, unless... + % + \pgf@decorate@subdividetrue% + % + % The cord vector is small. + % + \ifdim\pgf@xa<\pgf@decorate@curvelength@tolerance\relax% + \ifdim\pgf@ya<\pgf@decorate@curvelength@tolerance\relax% + \pgfmathveclen@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgf@ya}}% + \pgf@decorate@subdividefalse% + \fi% + \fi% } \def\pgf@decorate@recursive@subdividecurve@left#1#2#3#4{% - {% - % - % The left curve (from t=0 to t=.5) - % - #1\relax% - \pgfutil@tempdima\pgf@x% - \pgfutil@tempdimb\pgf@y% - \pgf@xa.5\pgf@x\pgf@ya.5\pgf@y% - \pgf@xb.25\pgf@x\pgf@yb.25\pgf@y% - \pgf@xc.125\pgf@x\pgf@yc.125\pgf@y% - #2\relax% - \advance\pgf@xa.5\pgf@x\advance\pgf@ya.5\pgf@y% - \advance\pgf@xb.5\pgf@x\advance\pgf@yb.5\pgf@y% - \advance\pgf@xc.375\pgf@x\advance\pgf@yc.375\pgf@y% - #3\relax% - \advance\pgf@xb.25\pgf@x\advance\pgf@yb.25\pgf@y% - \advance\pgf@xc.375\pgf@x\advance\pgf@yc.375\pgf@y% - #4\relax% - \advance\pgf@xc.125\pgf@x\advance\pgf@yc.125\pgf@y% - \xdef\pgf@marshal{% - \noexpand\pgf@decorate@@curvelength% - {\pgf@x\the\pgfutil@tempdima\pgf@y\the\pgfutil@tempdimb}% - {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb} - {\pgf@x\the\pgf@xc\pgf@y\the\pgf@yc}% - }% - }% - \pgf@marshal% + {% + % + % The left curve (from t=0 to t=.5) + % + #1\relax% + \pgfutil@tempdima\pgf@x% + \pgfutil@tempdimb\pgf@y% + \pgf@xa.5\pgf@x\pgf@ya.5\pgf@y% + \pgf@xb.25\pgf@x\pgf@yb.25\pgf@y% + \pgf@xc.125\pgf@x\pgf@yc.125\pgf@y% + #2\relax% + \advance\pgf@xa.5\pgf@x\advance\pgf@ya.5\pgf@y% + \advance\pgf@xb.5\pgf@x\advance\pgf@yb.5\pgf@y% + \advance\pgf@xc.375\pgf@x\advance\pgf@yc.375\pgf@y% + #3\relax% + \advance\pgf@xb.25\pgf@x\advance\pgf@yb.25\pgf@y% + \advance\pgf@xc.375\pgf@x\advance\pgf@yc.375\pgf@y% + #4\relax% + \advance\pgf@xc.125\pgf@x\advance\pgf@yc.125\pgf@y% + \xdef\pgf@marshal{% + \noexpand\pgf@decorate@@curvelength% + {\pgf@x\the\pgfutil@tempdima\pgf@y\the\pgfutil@tempdimb}% + {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb} + {\pgf@x\the\pgf@xc\pgf@y\the\pgf@yc}% + }% + }% + \pgf@marshal% } \def\pgf@decorate@recursive@subdividecurve@right#1#2#3#4{% - {% - % - % The right curve (from t=0.5 to t=1) - % - #1\relax% - \pgfutil@tempdima.125\pgf@x\pgfutil@tempdimb.125\pgf@y% - #2\relax% - \advance\pgfutil@tempdima.375\pgf@x\advance\pgfutil@tempdimb.375\pgf@y% - \pgf@xa.25\pgf@x\pgf@ya.25\pgf@y% - #3\relax% - \advance\pgfutil@tempdima.375\pgf@x\advance\pgfutil@tempdimb.375\pgf@y% - \advance\pgf@xa.5\pgf@x\advance\pgf@ya.5\pgf@y% - \pgf@xb.5\pgf@x\pgf@yb.5\pgf@y% - #4\relax% - \advance\pgfutil@tempdima.125\pgf@x\advance\pgfutil@tempdimb.125\pgf@y% - \advance\pgf@xa.25\pgf@x\advance\pgf@ya.25\pgf@y% - \advance\pgf@xb.5\pgf@x\advance\pgf@yb.5\pgf@y% - \pgf@xc\pgf@x\pgf@yc\pgf@y% - \xdef\pgf@marshal{% - \noexpand\pgf@decorate@@curvelength% - {\pgf@x\the\pgfutil@tempdima\pgf@y\the\pgfutil@tempdimb}% - {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb} - {\pgf@x\the\pgf@xc\pgf@y\the\pgf@yc}% - }% - }% - \pgf@marshal% + {% + % + % The right curve (from t=0.5 to t=1) + % + #1\relax% + \pgfutil@tempdima.125\pgf@x\pgfutil@tempdimb.125\pgf@y% + #2\relax% + \advance\pgfutil@tempdima.375\pgf@x\advance\pgfutil@tempdimb.375\pgf@y% + \pgf@xa.25\pgf@x\pgf@ya.25\pgf@y% + #3\relax% + \advance\pgfutil@tempdima.375\pgf@x\advance\pgfutil@tempdimb.375\pgf@y% + \advance\pgf@xa.5\pgf@x\advance\pgf@ya.5\pgf@y% + \pgf@xb.5\pgf@x\pgf@yb.5\pgf@y% + #4\relax% + \advance\pgfutil@tempdima.125\pgf@x\advance\pgfutil@tempdimb.125\pgf@y% + \advance\pgf@xa.25\pgf@x\advance\pgf@ya.25\pgf@y% + \advance\pgf@xb.5\pgf@x\advance\pgf@yb.5\pgf@y% + \pgf@xc\pgf@x\pgf@yc\pgf@y% + \xdef\pgf@marshal{% + \noexpand\pgf@decorate@@curvelength% + {\pgf@x\the\pgfutil@tempdima\pgf@y\the\pgfutil@tempdimb}% + {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb} + {\pgf@x\the\pgf@xc\pgf@y\the\pgf@yc}% + }% + }% + \pgf@marshal% } @@ -1965,138 +1962,138 @@ % #2 - a macro holding the reversed input segment objects. % \def\pgf@decorate@inputsegmentobjects@reverse#1#2{% - \def\pgf@decorate@path@storein{#2}% - \def\pgf@decorate@inputsegments@@temp{}% - \expandafter\pgf@decorate@inputsegments@@reverse@pass@first#1\pgf@stop} + \def\pgf@decorate@path@storein{#2}% + \def\pgf@decorate@inputsegments@@temp{}% + \expandafter\pgf@decorate@inputsegments@@reverse@pass@first#1\pgf@stop} \def\pgf@decorate@inputsegments@@reverse@pass@first#1#2\pgf@stop{% - \def\pgf@decorate@temp{#1}% - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% - \pgf@decorate@inputsegments@@temp\expandafter\expandafter\expandafter% - {\expandafter\pgf@decorate@temp\pgf@decorate@inputsegments@@temp}% - \def\pgf@decorate@test{#2} - \ifx\pgf@decorate@test\pgfutil@empty% - \def\pgf@decorate@next{% - \expandafter\pgf@decorate@inputsegmentobjects@reverse@pass@second\pgf@decorate@inputsegments@@temp\pgf@stop% - }% - \else% - \def\pgf@decorate@next{\pgf@decorate@inputsegments@@reverse@pass@first#2\pgf@stop}% - \fi% - \pgf@decorate@next% -} + \def\pgf@decorate@temp{#1}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% + \pgf@decorate@inputsegments@@temp\expandafter\expandafter\expandafter% + {\expandafter\pgf@decorate@temp\pgf@decorate@inputsegments@@temp}% + \def\pgf@decorate@test{#2} + \ifx\pgf@decorate@test\pgfutil@empty% + \def\pgf@decorate@next{% + \expandafter\pgf@decorate@inputsegmentobjects@reverse@pass@second\pgf@decorate@inputsegments@@temp\pgf@stop% + }% + \else% + \def\pgf@decorate@next{\pgf@decorate@inputsegments@@reverse@pass@first#2\pgf@stop}% + \fi% + \pgf@decorate@next% +} \def\pgf@decorate@inputsegmentobjects@reverse@pass@second#1#2#3\pgf@stop{% - \def\pgf@decorate@inputsegments@temp{#3}% - \def\pgf@decorate@inputsegments@@temp{}% - \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty - \let\pgf@decorate@last@object=\pgfutil@empty - \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingtrue% - \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse% - \expandafter\pgf@decorate@path@@reverse@pass@second\pgf@decorate@inputsegments@temp\pgf@stop}% + \def\pgf@decorate@inputsegments@temp{#3}% + \def\pgf@decorate@inputsegments@@temp{}% + \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty + \let\pgf@decorate@last@object=\pgfutil@empty + \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingtrue% + \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse% + \expandafter\pgf@decorate@path@@reverse@pass@second\pgf@decorate@inputsegments@temp\pgf@stop}% \def\pgf@decorate@path@@reverse@pass@second#1{% - \ifx#1\pgf@stop% - \expandafter\def\expandafter\pgf@decorate@inputsegments@@temp\expandafter{% - \pgf@decorate@inputsegments@@temp% - {\pgf@decorate@inputsegmentobject@endofinputsegments}% - {\pgf@decorate@inputsegmentobject@endofinputsegments} - }% - \expandafter\let\pgf@decorate@path@storein=\pgf@decorate@inputsegments@@temp% - \let\pgf@decorate@next=\relax% - \else% - \ifx#1\pgf@decorate@inputsegmentobject@moveto% - \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@moveto% - \else% - \ifx#1\pgf@decorate@inputsegmentobject@lineto% - \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@lineto% - \else% - \ifx#1\pgf@decorate@inputsegmentobject@curveto% - \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@curveto% - \else% - \ifx#1\pgf@decorate@inputsegmentobject@closepath% - \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@closepath% - \else% - \fi% - \fi% - \fi% - \fi% - \fi% - \pgf@decorate@next% + \ifx#1\pgf@stop% + \expandafter\def\expandafter\pgf@decorate@inputsegments@@temp\expandafter{% + \pgf@decorate@inputsegments@@temp% + {\pgf@decorate@inputsegmentobject@endofinputsegments}% + {\pgf@decorate@inputsegmentobject@endofinputsegments} + }% + \expandafter\let\pgf@decorate@path@storein=\pgf@decorate@inputsegments@@temp% + \let\pgf@decorate@next=\relax% + \else% + \ifx#1\pgf@decorate@inputsegmentobject@moveto% + \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@moveto% + \else% + \ifx#1\pgf@decorate@inputsegmentobject@lineto% + \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@lineto% + \else% + \ifx#1\pgf@decorate@inputsegmentobject@curveto% + \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@curveto% + \else% + \ifx#1\pgf@decorate@inputsegmentobject@closepath% + \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@closepath% + \else% + \fi% + \fi% + \fi% + \fi% + \fi% + \pgf@decorate@next% } \newif\ifpgf@decorate@inputsegmentobjects@reverse@moveto@waiting \def\pgf@decorate@inputsegmentobjects@reverse@moveto#1{% - \ifpgf@decorate@inputsegmentobjects@reverse@closepath@waiting% - \edef\pgf@decorate@current@inputsegmentobject{% - {\noexpand\pgf@decorate@inputsegmentobject@closepath% - {\pgf@decorate@reverse@closepath@length}% - {\pgf@decorate@last}% - {#1}% - }% - }% - \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse% - \else% - \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty% - \fi% - \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingtrue% - \pgf@decorate@path@@@reverse@pass@second% + \ifpgf@decorate@inputsegmentobjects@reverse@closepath@waiting% + \edef\pgf@decorate@current@inputsegmentobject{% + {\noexpand\pgf@decorate@inputsegmentobject@closepath% + {\pgf@decorate@reverse@closepath@length}% + {\pgf@decorate@last}% + {#1}% + }% + }% + \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse% + \else% + \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty% + \fi% + \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingtrue% + \pgf@decorate@path@@@reverse@pass@second% } \newif\ifpgf@decorate@inputsegmentobjects@reverse@closepath@waiting \def\pgf@decorate@inputsegmentobjects@reverse@closepath#1#2#3{% - \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingtrue% - \def\pgf@decorate@reverse@closepath@length{#1}% - \def\pgf@decorate@current@inputsegmentobject{}% - \pgf@decorate@inputsegmentobjects@reverse@lineto{#1}{#2}{#3}% + \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingtrue% + \def\pgf@decorate@reverse@closepath@length{#1}% + \def\pgf@decorate@current@inputsegmentobject{}% + \pgf@decorate@inputsegmentobjects@reverse@lineto{#1}{#2}{#3}% } \def\pgf@decorate@inputsegmentobjects@reverse@lineto#1#2#3#4{% - \ifpgf@decorate@inputsegmentobjects@reverse@moveto@waiting% - \def\pgf@decorate@current@inputsegmentobject{{\pgf@decorate@inputsegmentobject@moveto{#3}}}% - \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingfalse% - \else% - \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty% - \fi% - \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@lineto{#1}{#3}{#2}}}% - \ifx#4\pgf@decorate@inputsegmentobject@moveto% - \ifpgf@decorate@inputsegmentobjects@reverse@closepath@waiting% - \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@closepath{#1}{#3}{#2}}}% - \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse% - \else% - \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@lineto{#1}{#3}{#2}}}% - \fi% - \fi% - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% - \pgf@decorate@current@inputsegmentobject\expandafter\expandafter\expandafter% - {\expandafter\pgf@decorate@current@inputsegmentobject\pgf@decorate@append@inputsegmentobject} - \def\pgf@decorate@last{#2}% - \pgf@decorate@path@@@reverse@pass@second#4% + \ifpgf@decorate@inputsegmentobjects@reverse@moveto@waiting% + \def\pgf@decorate@current@inputsegmentobject{{\pgf@decorate@inputsegmentobject@moveto{#3}}}% + \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingfalse% + \else% + \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty% + \fi% + \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@lineto{#1}{#3}{#2}}}% + \ifx#4\pgf@decorate@inputsegmentobject@moveto% + \ifpgf@decorate@inputsegmentobjects@reverse@closepath@waiting% + \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@closepath{#1}{#3}{#2}}}% + \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse% + \else% + \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@lineto{#1}{#3}{#2}}}% + \fi% + \fi% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% + \pgf@decorate@current@inputsegmentobject\expandafter\expandafter\expandafter% + {\expandafter\pgf@decorate@current@inputsegmentobject\pgf@decorate@append@inputsegmentobject} + \def\pgf@decorate@last{#2}% + \pgf@decorate@path@@@reverse@pass@second#4% } \def\pgf@decorate@inputsegmentobjects@reverse@curveto#1#2#3#4#5{% - \ifpgf@decorate@inputsegmentobjects@reverse@moveto@waiting% - \def\pgf@decorate@current@inputsegmentobject{% - {\pgf@decorate@inputsegmentobject@moveto{#5}}% - {\pgf@decorate@inputsegmentobject@curveto{#1}{#5}{#4}{#3}{#2}}% - }% - \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingfalse% - \else% - \def\pgf@decorate@current@inputsegmentobject{{\pgf@decorate@inputsegmentobject@curveto{#1}{#5}{#4}{#3}{#2}}}% - \fi% - \def\pgf@decorate@last{#2}% - \pgf@decorate@path@@@reverse@pass@second% + \ifpgf@decorate@inputsegmentobjects@reverse@moveto@waiting% + \def\pgf@decorate@current@inputsegmentobject{% + {\pgf@decorate@inputsegmentobject@moveto{#5}}% + {\pgf@decorate@inputsegmentobject@curveto{#1}{#5}{#4}{#3}{#2}}% + }% + \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingfalse% + \else% + \def\pgf@decorate@current@inputsegmentobject{{\pgf@decorate@inputsegmentobject@curveto{#1}{#5}{#4}{#3}{#2}}}% + \fi% + \def\pgf@decorate@last{#2}% + \pgf@decorate@path@@@reverse@pass@second% } \def\pgf@decorate@path@@@reverse@pass@second{% - \ifx\pgf@decorate@current@inputsegmentobject\pgfutil@empty% - \else% - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% - \pgf@decorate@inputsegments@@temp\expandafter\expandafter\expandafter% - {\expandafter\pgf@decorate@inputsegments@@temp\pgf@decorate@current@inputsegmentobject}% - \fi% - \pgf@decorate@path@@reverse@pass@second% + \ifx\pgf@decorate@current@inputsegmentobject\pgfutil@empty% + \else% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% + \pgf@decorate@inputsegments@@temp\expandafter\expandafter\expandafter% + {\expandafter\pgf@decorate@inputsegments@@temp\pgf@decorate@current@inputsegmentobject}% + \fi% + \pgf@decorate@path@@reverse@pass@second% }% diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulematrix.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulematrix.code.tex index 32024c047d6..a9344f6c95c 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulematrix.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulematrix.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulematrix.code.tex,v 1.4 2010/08/24 21:28:58 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulematrix.code.tex,v 1.8 2013/09/17 17:34:00 tantau Exp $ \usepgfmodule{shapes} @@ -156,7 +156,7 @@ \def\pgfmatrix#1#2#3#4#5#6{% \ifpgfmatrix% - \PackageError{pgf}{You cannot nest pgfmatrix environments, yet}{} + \pgferror{You cannot nest pgfmatrix environments, yet} \fi% \bgroup% \everycr{}% @@ -270,26 +270,7 @@ \pgfutil@ifnextchar[{\pgf@matrix@cell@cont}{\pgf@matrix@cell@cont[0pt]}}%} \def\pgf@matrix@cell@cont[#1]{% - \ifnum\pgfmatrixcurrentcolumn<\pgf@matrix@numberofcolumns% - \else% - {% - \global\pgf@matrix@fixedfalse% - \pgf@x=0pt% - \pgf@matrix@addtolength{\pgf@x}{\pgfmatrixcolumnsep}% - \pgf@matrix@addtolength{\pgf@x}{#1}% - \ifpgf@matrix@fixed% - \expandafter\pgfutil@g@addto@macro\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname% - {\global\pgf@picmaxx=0pt}% - \fi% - \advance\pgfmatrixcurrentcolumn by1\relax % only temporary for the following: - \expandafter\xdef\csname pgf@matrix@column@sep@\the\pgfmatrixcurrentcolumn\endcsname{\the\pgf@x}% - \ifpgf@matrix@fixed% - \expandafter\gdef\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname{\global\pgf@picminx=0pt}% - \else% - \expandafter\global\expandafter\let\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname=\pgfutil@empty% - \fi% - }% - \fi% + \xdef\pgf@matrix@last@nextcell@options{#1}% &\pgf@matrix@correct@calltrue&% }% @@ -402,19 +383,41 @@ \def\pgf@matrix@endcell{% \ifpgf@matrix@empty@cell@% \else% - \expandafter\pgfmatrixendcode% - \fi + \expandafter\expandafter\expandafter\pgfmatrixendcode% + \expandafter\ifpgf@matrix@last@cell@in@row\expandafter\pgf@matrix@last@cell@in@rowtrue\expandafter\fi% + \fi% \pgfsys@endpicture% + \ifnum\pgfmatrixcurrentcolumn<\pgf@matrix@numberofcolumns% + \else% + \ifpgf@matrix@last@cell@in@row\else% + {% + \global\pgf@matrix@fixedfalse% + \pgf@x=0pt% + \pgf@matrix@addtolength{\pgf@x}{\pgfmatrixcolumnsep}% + \pgf@matrix@addtolength{\pgf@x}{\pgf@matrix@last@nextcell@options}% + \ifpgf@matrix@fixed% + \expandafter\pgfutil@g@addto@macro\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname% + {\global\pgf@picmaxx=0pt}% + \fi% + \advance\pgfmatrixcurrentcolumn by1\relax % only temporary for the following: + \expandafter\xdef\csname pgf@matrix@column@sep@\the\pgfmatrixcurrentcolumn\endcsname{\the\pgf@x}% + \ifpgf@matrix@fixed% + \expandafter\gdef\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname{\global\pgf@picminx=0pt}% + \else% + \expandafter\global\expandafter\let\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname=\pgfutil@empty% + \fi% + }% + \fi\fi% + % Special case of the empty picture + \ifdim\pgf@picmaxx=-16000pt\relax% + \global\pgf@picmaxx=0pt\relax% + \global\pgf@picminx=0pt\relax% + \global\pgf@picmaxy=0pt\relax% + \global\pgf@picminy=0pt\relax% + \fi% \csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname% \pgf@matrix@row@finish% \egroup\egroup% - % Special case of the empty picture - \ifdim\pgf@picmaxx=-16000pt\relax% - \pgf@picmaxx=0pt\relax% - \pgf@picminx=0pt\relax% - \pgf@picmaxy=0pt\relax% - \pgf@picminy=0pt\relax% - \fi% % % Step 5: Horizontal gap % @@ -495,8 +498,7 @@ \def\pgf@matrix@padding{% \ifpgf@matrix@correct@call% \else% - \PackageError{pgfbasematrix}{Single ampersand used with wrong - catcode}{}% + \pgferror{Single ampersand used with wrong catcode}% \fi% \hskip\pgf@matrix@paddingskip\hfil% } @@ -599,13 +601,15 @@ % if the cell contains nothing, the following \let will be at the % beginning (macro expansion has stopped here since neither \omit % nor \span was found) - \let\pgf@matrix@signal@cell@end=\pgf@matrix@signal@cell@end% + \let\pgf@matrix@signal@cell@end=\pgf@matrix@signal@cell@end + \pgf@matrix@last@cell@in@rowtrue% &\pgf@matrix@correct@calltrue% \global\pgf@matrix@fixedfalse% \pgf@y=0pt% \pgf@matrix@addtolength\pgf@y{\pgfmatrixrowsep}% \pgfutil@ifnextchar[{\pgfmatrixendrow@skip}{\pgf@matrix@finish@line}% } +\newif\ifpgf@matrix@last@cell@in@row \def\pgf@matrix@signal@cell@end{\pgf@matrix@signal@cell@end} % exact definition does not matter, only needs to be unique. diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulenonlineartransformations.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulenonlineartransformations.code.tex new file mode 100644 index 00000000000..913f2edff9d --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulenonlineartransformations.code.tex @@ -0,0 +1,342 @@ +% Copyright 2013 by Till Tantau +% +% This file may be distributed and/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 details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulenonlineartransformations.code.tex,v 1.4 2013/10/09 18:30:27 tantau Exp $ + + +% +% This file defines commands for nonlinear coordinate systems. This is +% needed, for instance, for bend arrow heads. +% +% +% Non-linear coordinate systems transform coordinates, in addition to +% the normal linear transformations, in a, well, non-linear way. An +% example are polar coordinates. +% +% Like the linear transformations, non-linear transformations are +% applied on a low level and they are integrated into the whole path +% construction mechanism. So, while \pgfpointpolar also "does +% something nonlinear", it just provides a way of computing a +% coordinate. In contrast, installing a polar transformation will +% transform everything being drawn using the \pgfpath... commands an +% will even turn a straight line into a circle. +% +% Since computing non-linear transformations is expensive, they are +% only applied "if really necessary". + + + + +% Return a transformed point +% +% #1 = a point +% +% Description: +% +% Applies the current transformation and the current nonlinear +% transformation to the given point and returns the result in \pgf@x/y. + +\def\pgfpointtransformednonlinear#1{% + \pgf@process{% + #1% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \pgf@nlt@list% + } +} + + + + +% Approximate the nonlinear translation locally +% +% Description: +% +% Does a "local syncronization" of the nonlinear transformation with +% the linear transformation regarding the translation part of the +% current nonlinear transformatoin. The *linear* transformation will be +% updated so that it translates things to the point to which the +% nonlinear transformation transforms the origin. The nonlinear +% transformation will be reset. +% +% The net effect is that you can now draw things near the origin as +% before, but with just a linear transformation in force. Note that +% the coordinate system will not be rotated, only a shift is done (use +% the "real" local sync for a full sync). + +\def\pgfapproximatenonlineartranslation{% + \ifx\pgf@nlt@list\pgfutil@empty% + \else% + \pgfpointtransformednonlinear{\pgfpointorigin}% + \pgf@pt@x=\pgf@x% + \pgf@pt@y=\pgf@y% + \let\pgf@nlt@list\pgfutil@empty% + \let\pgf@nlt@moveto\pgf@lt@moveto% + \let\pgf@nlt@lineto\pgf@lt@lineto% + \let\pgf@nlt@curveto\pgf@lt@curveto% + \let\pgf@nlt@closepath\pgf@lt@closepath% + \fi% +} + + + +% Local sync translation +% +% Description: +% +% Does a "complete local syncronization" of the nonlinear +% transformation with the linear transformation. The *linear* +% transformation will be updated so that it transforms things to the +% point to which the nonlinear transformation transforms the +% origin. The nonlinear transformation will be reset. +% +% The net effect is that you can now draw things near the origin as +% before, but with just a linear transformation in force. + +\def\pgfapproximatenonlineartransformation{% + \ifx\pgf@nlt@list\pgfutil@empty% + \else% + \pgfpointtransformednonlinear{\pgfpoint{1pt}{0pt}}% + \pgf@xa\pgf@x + \pgf@ya\pgf@y + \pgfpointtransformednonlinear{\pgfpoint{0pt}{1pt}}% + \pgf@xb\pgf@x + \pgf@yb\pgf@y + \pgfpointtransformednonlinear{\pgfpointorigin}% + \advance\pgf@xa by-\pgf@x + \advance\pgf@xb by-\pgf@x + \advance\pgf@ya by-\pgf@y + \advance\pgf@yb by-\pgf@y + \pgfsettransformentries{\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@xb}{\pgf@sys@tonumber\pgf@yb}{\pgf@x}{\pgf@y}% + \let\pgf@nlt@list\pgfutil@empty% + \let\pgf@nlt@moveto\pgf@lt@moveto% + \let\pgf@nlt@lineto\pgf@lt@lineto% + \let\pgf@nlt@curveto\pgf@lt@curveto% + \let\pgf@nlt@closepath\pgf@lt@closepath% + \fi% +} + + + +% Adds a non-linear transformation to the current list of +% transformations. +% +% #1 = code +% +% Description: +% +% When the code #1 is called, \pgf@x and \pgf@y will be set to some +% values, let us call this the point p. The nonlinear transformation +% will now map this point to a new point f(p). The coordinates of this +% point shoudl be returned in \pgf@x and \pgf@y. Furthermore, consider +% the two "unit tangents" (going in $x$-direction and in +% $y$-direction) at point p. The nonlinear transformaiton will map +% these to new tangents, t_x and t_y. The (not necessarily normalized) +% vectors t_x and t_y should be returned in pgf@xa and -ya and pgf@xb +% and pgf@yb. The macro should not do any global assignments except to +% \pgf@x and \pgf@y, but may do arbitrary local assignments. +% +% The effect of installing a new transformation is the following: As +% long as there is at least one nonlinear transformation installed, +% whenever the path construction commands add a curve or line to the +% softpath, the line or curve will be "bend" by applying all of the +% nonlinear transformation installed. In particular, straight lines +% will be replaced by curves. +% +% Note that the normal linear transformation are always applied before +% any nonlinear transformations are applied. + +\def\pgftransformnonlinear#1{% + \expandafter\def\expandafter\pgf@nlt@list\expandafter{\pgf@nlt@list#1}% + \let\pgf@nlt@moveto\pgf@nlt@moveto@nlt + \let\pgf@nlt@lineto\pgf@nlt@lineto@nlt + \let\pgf@nlt@curveto\pgf@nlt@curveto@nlt + \let\pgf@nlt@closepath\pgf@nlt@closepath@nlt +} + +\def\pgf@nlt@moveto@nlt#1#2{% + {% + \pgfutil@tempdima#1% + \pgfutil@tempdimb#2% + \pgf@x\pgfutil@tempdima% + \pgf@y\pgfutil@tempdimb% + \xdef\pgf@nlt@last@moveto@orig{{\the\pgf@x}{\the\pgf@y}}% + \pgf@nlt@list% + \xdef\pgf@nlt@last@moveto@trans{{\the\pgf@x}{\the\pgf@y}}% + \xdef\pgf@nlt@last@moveto@xaxis{{\the\pgf@xa}{\the\pgf@ya}}% + \xdef\pgf@nlt@last@moveto@yaxis{{\the\pgf@xb}{\the\pgf@yb}}% + \pgf@protocolsizes{\pgf@x}{\pgf@y}% + \pgfsyssoftpath@moveto{\the\pgf@x}{\the\pgf@y}% + \global\let\pgf@nlt@last@coord@orig\pgf@nlt@last@moveto@orig% + \global\let\pgf@nlt@last@coord@trans\pgf@nlt@last@moveto@trans% + \global\let\pgf@nlt@last@coord@xaxis\pgf@nlt@last@moveto@xaxis% + \global\let\pgf@nlt@last@coord@yaxis\pgf@nlt@last@moveto@yaxis% + }% +} + + +\def\pgf@nlt@lineto@nlt#1#2{% + {% + \edef\pgf@temp{\pgf@xc\the#1\pgf@yc\the#2}% + \pgf@temp% + \expandafter\pgfqpoint\pgf@nlt@last@coord@orig% + \expandafter\pgf@nlt@set@temps\pgf@nlt@last@coord@trans% + % Test, whether the points are quite near: + \pgf@xa\pgf@x\advance\pgf@xa by-\pgf@xc% + \pgf@ya\pgf@y\advance\pgf@ya by-\pgf@yc% + \pgfutil@tempswafalse% + \ifdim\pgf@xa<0.1pt\relax\ifdim\pgf@xa>-0.1pt\relax\ifdim\pgf@ya<0.1pt\relax\ifdim\pgf@ya>-0.1pt\relax\pgfutil@tempswatrue\fi\fi\fi\fi% + \ifpgfutil@tempswa% + \pgf@x\pgf@xc\pgf@y\pgf@yc% + \xdef\pgf@nlt@last@coord@orig{{\the\pgf@x}{\the\pgf@y}}% + \pgf@process{\pgf@nlt@list}% + \xdef\pgf@nlt@last@coord@trans{{\the\pgf@x}{\the\pgf@y}}% + \xdef\pgf@nlt@last@coord@xaxis{{\the\pgf@xa}{\the\pgf@ya}}% + \xdef\pgf@nlt@last@coord@yaxis{{\the\pgf@xb}{\the\pgf@yb}}% + \pgf@protocolsizes{\pgf@x}{\pgf@y}% + \pgfsyssoftpath@lineto{\the\pgf@x}{\the\pgf@y}% + \else% + % Compute support points + \pgf@xb=.333333\pgf@x% + \advance\pgf@xb by.666666\pgf@xc% + \pgf@yb=.333333\pgf@y% + \advance\pgf@yb by.666666\pgf@yc% + \pgf@xa=.333333\pgf@xc% + \advance\pgf@xa by.666666\pgf@x% + \pgf@ya=.333333\pgf@yc% + \advance\pgf@ya by.666666\pgf@y% + \pgf@nlt@inner@curve% + \fi% + }% +} + +\def\pgf@nlt@set@temps#1#2{% + \pgfutil@tempdima#1\pgfutil@tempdimb#2% +} + +\def\pgf@nlt@curveto@nlt#1#2#3#4#5#6{% + {% + \edef\pgf@temp{\pgf@xa\the#1\pgf@ya\the#2\pgf@xb\the#3\pgf@yb\the#4\pgf@xc\the#5\pgf@yc\the#6}% + \pgf@temp% + \pgf@nlt@inner@curve% + }% +} + +\newdimen\pgftransformnonlinearflatness +\pgftransformnonlinearflatness=5pt +\def\pgfsettransformnonlinearflatness#1{\pgfmathsetlength\pgftransformnonlinearflatness{#1}} + + + +% Compute a curve from \pgf@nlt@last@coord@orig to \pgf@xc/\pgf@yc via the +% controls \pgf@xa/\pgf@ya and \pgf@xb/\pgf@yb. +\def\pgf@nlt@inner@curve{% + \expandafter\pgfqpoint\pgf@nlt@last@coord@orig% + % Save delta of supports: + \pgfutil@tempdima\pgf@xa\advance\pgfutil@tempdima by-\pgf@xb + \pgfutil@tempdimb\pgf@ya\advance\pgfutil@tempdimb by-\pgf@yb + \begingroup + % Replace supports by relative supports + \advance\pgf@xa by-\pgf@x% + \advance\pgf@ya by-\pgf@y% + \advance\pgf@xb by-\pgf@xc% + \advance\pgf@yb by-\pgf@yc% + % + % Now, test whether the flatness is satisfied: + % + \pgfutil@tempswafalse + \ifdim\pgfutil@tempdima>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgfutil@tempdima<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgfutil@tempdimb>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgfutil@tempdimb<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@xa>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@xa<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@ya>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@ya<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@xb>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@xb<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@yb>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@yb<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifpgfutil@tempswa% + \endgroup% Undo the adjustmenst... + {% + \edef\pgf@orig@xya{\pgf@xa\the\pgf@xa\pgf@ya\the\pgf@ya} + \edef\pgf@orig@xyb{\pgf@xb\the\pgf@xb\pgf@yb\the\pgf@yb} + \edef\pgf@orig@xyc{\pgf@xc\the\pgf@xc\pgf@yc\the\pgf@yc} + \pgfpointcurveattime{.5}% + {\expandafter\pgfqpoint\pgf@nlt@last@coord@orig}% + {\pgf@x\pgf@xa\pgf@y\pgf@ya}% + {\pgf@x\pgf@xb\pgf@y\pgf@yb}% + {\pgf@x\pgf@xc\pgf@y\pgf@yc}% + % First new curve: + % Start is at last@coord@orig, + % first support is at last@coord@orig*t + s*(original xa/ya) + % second support is at xb/yb + % target is at x/y + {% + % Target: + \pgf@xc\pgf@x\pgf@yc\pgf@y + % First support: + \expandafter\pgfqpoint\pgf@nlt@last@coord@orig% + \pgf@orig@xya% + \pgf@xa\pgf@time@s\pgf@xa\advance\pgf@xa by\pgf@time@t\pgf@x% + \pgf@ya\pgf@time@s\pgf@ya\advance\pgf@ya by\pgf@time@t\pgf@y% + \pgf@nlt@inner@curve% + }% + % Second new curve: + % Start is at (new) last@coord@orig + % first support is at xa/ya + % second support is at t*(original xb/yb) + s*(original xc/yc) + % target is at original xc/yc + {% + \pgf@orig@xyb% + \pgf@orig@xyc% + \pgf@xb\pgf@time@t\pgf@xb\advance\pgf@xb by\pgf@time@s\pgf@xc% + \pgf@yb\pgf@time@t\pgf@yb\advance\pgf@yb by\pgf@time@s\pgf@yc% + \pgf@nlt@inner@curve% + }% + }% + \else% + \endgroup% Snap back... + \pgf@nlt@do@inner@curve% + \fi% +} + +\def\pgf@nlt@do@inner@curve{% + \pgf@process{\pgf@x\pgf@xa\pgf@y\pgf@ya\pgf@nlt@list}% + \pgf@xa\pgf@x\pgf@ya\pgf@y% + \pgf@process{\pgf@x\pgf@xb\pgf@y\pgf@yb\pgf@nlt@list}% + \pgf@xb\pgf@x\pgf@yb\pgf@y% + \xdef\pgf@nlt@last@coord@orig{{\the\pgf@xc}{\the\pgf@yc}}% + \pgf@process{\pgf@x\pgf@xc\pgf@y\pgf@yc\pgf@nlt@list}% + \pgf@xc\pgf@x\pgf@yc\pgf@y% + \xdef\pgf@nlt@last@coord@trans{{\the\pgf@xc}{\the\pgf@yc}}% + \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% + \pgf@protocolsizes{\pgf@xb}{\pgf@yb}% + \pgf@protocolsizes{\pgf@xc}{\pgf@yc}% + \pgfsyssoftpath@curveto{\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xb}{\the\pgf@yb}{\the\pgf@xc}{\the\pgf@yc}% +} + + +\def\pgf@nlt@closepath@nlt{% + {% + \expandafter\pgfqpoint\pgf@nlt@last@moveto@orig% + \expandafter\pgf@nlt@set@temps\pgf@nlt@last@coord@orig% + \advance\pgfutil@tempdima by-\pgf@x% + \advance\pgfutil@tempdimb by-\pgf@y% + \pgfutil@tempswatrue% + \ifdim\pgfutil@tempdima<0.01pt\relax\ifdim\pgfutil@tempdima>-0.01pt\relax\ifdim\pgfutil@tempdimb<0.01pt\relax\ifdim\pgfutil@tempdimb>-0.01pt\relax\pgfutil@tempswafalse\fi\fi\fi\fi% + \ifpgfutil@tempswa% + \pgf@nlt@lineto@nlt{\pgf@x}{\pgf@y}% + \fi% + \pgfsyssoftpath@closepath% + }% +} + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleoo.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleoo.code.tex index e80d3ac06bb..eba114885ea 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleoo.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleoo.code.tex @@ -1,4 +1,5 @@ % Copyright 2006 by Till Tantau +% Copyright 2011 by Saso Zivanovic % % This file may be distributed and/or modified % @@ -6,12 +7,12 @@ % 2. under the GNU Public License. % % See the file doc/generic/pgf/licenses/LICENSE for more details. - -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleoo.code.tex,v 1.8 2010/02/22 22:49:21 tantau Exp $ +% +% Based on pgfmoduleoo.code.tex v1.8 by Till Tantau. This version adds inheritance. -% Support of object-oriented programming in TeX. +% Support of object-oriented programming in TeX, with inheritance. % The oo support works as follows: @@ -52,30 +53,215 @@ % % Description: % -% This command declares a class for futurue use. Inside #2, the macro +% This command declares a class for future use. Inside #2, the macro % \method can be used to declare a method. The \method macro takes a % method name, parameters (methods are normal TeX macros, after all) % and body. -\long\def\pgfooclass#1#2{% - \def\pgfoo@classname{#1}% +% base classes are put in parenthesis before the new class name, but +% are optional. +\def\pgfooclass{% + \pgfutil@ifnextchar ({% + \pgfooclass@ + }{% + \pgfooclass@() + }% +} +\long\def\pgfooclass@(#1)#2#3{% + \def\pgfoo@classname{#2}% + \expandafter\ifx\csname pgfooY\pgfoo@classname.@pgfooinit\endcsname\relax\else + \pgferror{class #2 is already defined}% + \fi + \pgfoo@ciii{#2}{#1}% + \expandafter\let\csname pgfooY#2@pgfoo@mro\endcsname\pgfoo@mro \let\pgfoo@origmethod=\method% \let\pgfoo@origattribute=\attribute% \let\method=\pgfoo@declaremethod% \let\attribute=\pgfoo@declareattribute% - \let\pgfoo@attribute@collection=\pgfutil@empty% - \let\pgfoo@attribute@collection@gc=\pgfutil@empty% - #2% - % Attribute initializer: - \expandafter\let\csname pgfooY\pgfoo@classname.@pgfooinit\endcsname\pgfoo@attribute@collection% - \expandafter\let\csname pgfooY\pgfoo@classname.@pgfoogc\endcsname\pgfoo@attribute@collection@gc% - % Always persent methods: + \let\pgfoo@attributes=\pgfutil@empty% + \let\pgfoo@methods=\pgfutil@empty% + #3% + % inherit + \def\pgfoo@temp@baseclasses{#1}% + \pgfoo@inherit@methods + \pgfoo@inherit@attributes + % Always present (and never inherited) methods: \expandafter\let\csname pgfooY\pgfoo@classname.get handle\endcsname\pgfoo@obj% \expandafter\let\csname pgfooY\pgfoo@classname.get id\endcsname\pgfoo@id% + % for compatibility with previous versions of pgfoo, define method + % with the same name as the class as a synonym for init + \expandafter\let\expandafter\pgfoo@init\csname pgfooY\pgfoo@classname.init\endcsname + \expandafter\let\csname pgfooY\pgfoo@classname.\pgfoo@classname\endcsname\pgfoo@init + % Cleanup \let\method=\pgfoo@origmethod% \let\attribute=\pgfoo@origattribute% } +\def\pgfoo@emptyinit(){} +\def\pgfoo@escapeif#1#2\fi{\fi#1}% a little helper + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Compute MRO using C3 algorithm +% The sequences are enclosed in brackets; elements of sequences and +% the big list are terminated by a comma and a dot, respectively. (Why +% comma *and* a dot: TeX's parset---brackets don't form groups! Soooo, +% why not braces? Because I don't know how do delete excess "{},"s...) + +% #1 = current class, #2 = list of base classes +\def\pgfoo@ciii#1#2{% + % \pgfoo@seq will hold a list of sequences. + % (i) the first sequence has just one element: the current class + \def\pgfoo@seq{[#1,].}% + % (ii) every subclass has a sequence (in the order as they were + % given): the class' sequence is its mro. + \pgfutil@for\pgfoo@baseclass:={#2}\do{% + \edef\pgfoo@baseclass@mro{\csname pgfooY\pgfoo@baseclass @pgfoo@mro\endcsname}% + \expandafter\ifx\expandafter\relax\pgfoo@baseclass@mro\relax\else + \edef\pgfoo@seq{\pgfoo@seq[\pgfoo@baseclass@mro,].}% + \fi + }% + % The final sequence is a sequence of base classes, in the order as + % they were given. + \ifx\relax#2\relax\else + \edef\pgfoo@seq{\pgfoo@seq[#2,].}% + \fi + \edef\pgfoo@temp{()(\pgfoo@seq)}% + \expandafter\pgfoo@ciii@merge\pgfoo@temp +} + +% #1 = MRO so far +% #2 = remaining sequences +% no empty sequences [] should arrive here: they should be removed +% before calling this macro +\def\pgfoo@ciii@merge(#1)(#2){% + \ifx\relax#2\relax + \pgfoo@ciii@done(#1)% + \else\pgfoo@escapeif{% split #2 + \pgfoo@ciii@merge@A(#1)(#2)% + }\fi% +} +% a splitter: to be only called from \pgfoo@ciii@merge +\def\pgfoo@ciii@merge@A(#1)(#2.#3){% + \ifx\relax#3\relax % if #3 is empty, we can take the shortcut + \pgfoo@ciii@mergeA@done(#1)(#2)% + \else\pgfoo@escapeif{% + \pgfoo@ciii@merge@checkHead(#1)()(#2)()(#3)% + }\fi +} + +\def\pgfoo@ciii@mergeA@done(#1)([#2]){% + \pgfoo@ciii@done(#1#2)% +} + +% #1 = MRO so far +% #2 = sequences with bad heads (dot after each sequence) +% [#3,#4] = the sequence whose head we're testing right +% now---obviously, it should not be empty! (#3 has no comma, +% #4 has a comma after each class name) +% #5 = #3 does not occur in the tail of these sequences (dot after +% each sequence) +% #6 = the remaining sequences (dot after each sequence) +\def\pgfoo@ciii@merge@checkHead(#1)(#2)([#3,#4])(#5)(#6){% + \pgfutil@in@{[#3,}{#2}% + \ifpgfutil@in@\pgfoo@escapeif{% #3 is already blacklisted + \pgfoo@ciii@clean\pgfoo@ciii@merge@checkHead@P{(#1)(#2[#3,#4].)(#5#6)}% + }\else\pgfoo@escapeif{% + \ifx\relax#6\relax\pgfoo@escapeif{% no more sequences to test the head against! + % so, #3 is a good head, and we can recurse + \pgfoo@ciii@goodHeadFound(#1)(#3)(#2[#4].#5)% + }\else\pgfoo@escapeif{% split #6 and get to work + \pgfoo@ciii@merge@checkHead@A(#1)(#2)([#3,#4])(#5)(#6)% + }\fi + }\fi +} +% splitter: to be only called from \pgfoo@ciii@merge@checkHead +% we will check if #3 occurs in the tail of #6 +\def\pgfoo@ciii@merge@checkHead@A(#1)(#2)([#3,#4])(#5)(#6.#7){% + \pgfoo@ciii@merge@checkHead@B(#1)(#2)([#3,#4])(#5)(#6)(#7)% +} +% splitter: to be only called from \pgfoo@ciii@merge@checkHead@A +% &worker: we will check if #3 occurs in #7. If it does, #3 is a bad head. +\def\pgfoo@ciii@merge@checkHead@B(#1)(#2)([#3,#4])(#5)([#6,#7])(#8){% +% \def\pgfoo@ciii@tempA{#3}\def\pgfoo@ciii@tempB{#5}% +% \ifx\pgfoo@ciii@tempA\pgfoo@ciii@tempB +% \pgferror{An attempt to derive from the same class twice}% +% \else\pgfoo@escapeif{% + \pgfutil@in@{,#3,}{,#7}% + \ifpgfutil@in@\pgfoo@escapeif{% bad head! get next head and restart + % but: need to clean up first! + \pgfoo@ciii@clean\pgfoo@ciii@merge@checkHead@P{(#1)(#2[#3,#4].)(#5[#6,#7].#8)}% + }\else\pgfoo@escapeif{% so far, so good + \ifx\relax#8\relax\pgfoo@escapeif{% if #8 is empty, we won: + % #3 is a good head! we will move it to MRO + % but clean-up first! + \pgfoo@ciii@goodHeadFound(#1)(#3)(#2[#4].#5[#6,#7].)% + }\else\pgfoo@escapeif{% proceed to the first seq in #8 + \pgfoo@ciii@clean\pgfoo@ciii@merge@checkHead{(#1)(#2)([#3,#4])(#5[#6,#7].)(#8)}% + }\fi + }\fi +% }\fi +} + +% #1 = MRO +% #2 = good head +% #3 = the remaining sequences (in need of removing the good head from +% them, and then also some general cleanup) +\def\pgfoo@ciii@goodHeadFound(#1)(#2)(#3){% + \pgfutil@in@{,#2,}{#3}% + \ifpgfutil@in@\pgfoo@escapeif{% + \def\pgfoo@ciii@removeGoodHead(##1)(##2)(##3,#2,##4){% + \pgfoo@ciii@goodHeadFound(##1)(##2)(##3,##4)}% + \pgfoo@ciii@removeGoodHead(#1)(#2)(#3)% + }\else\pgfoo@escapeif{% + \pgfutil@in@{[#2,}{#3}% + \ifpgfutil@in@\pgfoo@escapeif{% + \def\pgfoo@ciii@removeGoodHead(##1)(##2)(##3[#2,##4){% + \pgfoo@ciii@goodHeadFound(##1)(##2)(##3[##4)}% + \pgfoo@ciii@removeGoodHead(#1)(#2)(#3)% + }\else\pgfoo@escapeif{% + \pgfoo@ciii@clean\pgfoo@ciii@merge{(#1#2,)(#3)}% + }\fi + }\fi +} + +% mediates between the bad head exit of \pgfoo@ciii@merge@checkHead@B +% and \pgfoo@ciii@merge@checkHead; we need the mediator because #3 +% below might have been affected by cleaning. +\def\pgfoo@ciii@merge@checkHead@P(#1)(#2)(#3){% + \if\relax#3\relax % no more good head candidates! + \pgferror{Bad MRO: There is no good (monotonic etc.) + Method Resolution Order for your class hierarchy}% + \else\pgfoo@escapeif{% + \pgfoo@ciii@merge@checkHead@Q(#1)(#2)(#3)% + }\fi +} +% splitter for \pgfoo@ciii@merge@checkHead@P +% #3 = the sequence containing the newest good head candidate +\def\pgfoo@ciii@merge@checkHead@Q(#1)(#2)(#3.#4){% + \pgfoo@ciii@merge@checkHead(#1)(#2)(#3)()(#4)% +} + +% cyclically removes all occurrences of "[]," and "[]." (i.e., empty +% sequences) in #2. When done, calls #1 with whatever remains. +\def\pgfoo@ciii@clean#1#2{% clean commas + \pgfutil@in@{[].}{#2}% clean dots + \ifpgfutil@in@\pgfoo@escapeif{% + \pgfoo@ciii@clean@dot#1#2\pgfoo@ciii@clean@END + }\else\pgfoo@escapeif{% + #1#2% + }\fi +} +\def\pgfoo@ciii@clean@dot#1#2[].#3\pgfoo@ciii@clean@END{% + \pgfoo@ciii@clean#1{#2#3}% +} + +\def\pgfoo@ciii@done(#1,){% + \def\pgfoo@mro{#1}% +} + +% end of C3 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Declare a method @@ -111,10 +297,71 @@ % } % } +% define the method macro and append the method to the method collection \def\pgfoo@declaremethod#1(#2)#3{% - \expandafter\long\expandafter\def\csname pgfooY\pgfoo@classname.#1\endcsname(#2){#3}% + \def\pgfoo@method{#1}% + \ifx\pgfoo@classname\pgfoo@method + \def\pgfoo@method{init}% + \fi + \expandafter\long\expandafter\def\csname pgfooY\pgfoo@classname.\pgfoo@method\endcsname(#2){#3}% + \edef\pgfoo@methods{\pgfoo@methods,\pgfoo@method}% +} + +\def\pgfoo@inherit@methods{% + % for non-derived classes: + \expandafter\ifx\expandafter\relax\pgfoo@temp@baseclasses\relax + % if init is not defined, define an empty one + \expandafter\ifx\csname pgfooY\pgfoo@classname.init\endcsname\relax + \expandafter\let\csname pgfooY\pgfoo@classname.init\endcsname\pgfoo@emptyinit% + \edef\pgfoo@methods{,init\pgfoo@methods}% + \fi + \fi + \if\relax\pgfoo@methods\relax\else + % gobble the initial comma + \edef\pgfoo@methods{\expandafter\pgfutil@gobble\pgfoo@methods}% + \fi + % remember the list of collected methods + \expandafter\let\csname pgfooY\pgfoo@classname @pgfoo@methods\endcsname\pgfoo@methods + % get MRO + \expandafter\let\expandafter\pgfoo@mro\csname pgfooY\pgfoo@classname @pgfoo@mro\endcsname + % loop throough base classes in MRO + \pgfutil@for\pgfoo@baseclass:=\pgfoo@mro\do{% + \ifx\pgfoo@baseclass\pgfoo@classname % skip self + \else\pgfoo@escapeif{% + % get methods defined in this base class + \expandafter\let\expandafter\pgfoo@methods\csname pgfooY\pgfoo@baseclass @pgfoo@methods\endcsname + \pgfutil@for\pgfoo@method:=\pgfoo@methods\do{% for each method + % check if it is already defined in our class + \expandafter\ifx\csname pgfooY\pgfoo@classname.\pgfoo@method\endcsname\relax + % if not, link the method name from our class to base class + \edef\pgfoo@temp{\noexpand\let + \expandafter\noexpand\csname pgfooY\pgfoo@classname.\pgfoo@method\endcsname + \expandafter\noexpand\csname pgfooY\pgfoo@baseclass.\pgfoo@method\endcsname}% + \pgfoo@temp + \fi + }% + }\fi + }% } +\def\pgfoosuper(#1,#2).#3({% + #2.get id(\pgfoo@temp@id)% + \edef\pgfoo@classname{\csname pgfooX\pgfoo@temp@id @class\endcsname}% + \def\pgfoo@super@A##1,#1,##2.##3({% + \pgfoo@super@B##2.##3(% + }% + \expandafter\let\expandafter\pgfoo@mro\csname pgfooY\pgfoo@classname @pgfoo@mro\endcsname + \expandafter\pgfoo@super@A\expandafter,\pgfoo@mro,.#3(% +} +\def\pgfoo@super@B#1,#2.#3({% + \expandafter\ifx\csname pgfooY#1.#3\endcsname\relax + \pgfoo@escapeif{\pgfoo@super@B#2.#3(}% + \else + \pgfoo@escapeif{\expandafter\pgfoo@caller\pgfoo@temp@id.#1.#3(}% + \fi +} + + % Declare an attribute % @@ -136,21 +383,78 @@ \ifpgfutil@in@% \pgfoo@declareunpack#1;% \else% - \expandafter\def\expandafter\pgfoo@attribute@collection\expandafter{\pgfoo@attribute@collection\pgfoolet{#1}\pgfutil@empty}% - \expandafter\def\expandafter\pgfoo@attribute@collection@gc\expandafter{\pgfoo@attribute@collection@gc\pgfoolet{#1}\relax}% + \pgfoo@declareattribute@\let{#1}\pgfutil@empty \fi% \fi% } -\def\pgfoo@declareunpack#1=#2;{% - \expandafter\def\expandafter\pgfoo@attribute@collection\expandafter{\pgfoo@attribute@collection\pgfooset{#1}{#2}}% - \expandafter\def\expandafter\pgfoo@attribute@collection@gc\expandafter{\pgfoo@attribute@collection@gc\pgfoolet{#1}\relax}% +\def\pgfoo@declareunpack#1=#2;{\pgfoo@declareattribute@\def{#1}{{#2}}} +\def\pgfoo@declareunpackspace#1 =#2;{\pgfoo@declareattribute@\def{#1}{{#2}}} + +% put the initial value in the class's namespace +% put the attr name in a list +\def\pgfoo@declareattribute@#1#2#3{% + \expandafter#1\csname pgfooY\pgfoo@classname @#2\endcsname#3% + \expandafter\def\expandafter\pgfoo@attributes\expandafter{\pgfoo@attributes,#2}% } -\def\pgfoo@declareunpackspace#1 =#2;{% - \expandafter\def\expandafter\pgfoo@attribute@collection\expandafter{\pgfoo@attribute@collection\pgfooset{#1}{#2}}% - \expandafter\def\expandafter\pgfoo@attribute@collection@gc\expandafter{\pgfoo@attribute@collection@gc\pgfoolet{#1}\relax}% + +% for each base class: +% for each attribute declared in that class: +% add the attr on a list if it's not there yet +% convert the list of (attr,class which it comes from) into an +% efficient sequence of triples \op{attrname}\pointer-to-initial-value +% (\op is then set differently in init and garbage collection) +\def\pgfoo@inherit@attributes{% + % store the list of attributes declared in this class for use in + % derived classes + \if\relax\pgfoo@attributes\relax\else + \edef\pgfoo@attributes{\expandafter\pgfutil@gobble\pgfoo@attributes}% gobble comma + \fi + \expandafter\let\csname pgfooY\pgfoo@classname.@pgfoo@attributes\endcsname\pgfoo@attributes% + % get MRO + \expandafter\let\expandafter\pgfoo@mro\csname pgfooY\pgfoo@classname @pgfoo@mro\endcsname + \def\pgfoo@allattributes{}% here we will store the attrs declared in base classes + \pgfutil@for\pgfoo@baseclass:=\pgfoo@mro\do{% for each base class in MRO order + % the attributes declared in this base class + \expandafter\let\expandafter\pgfoo@attributes\csname pgfooY\pgfoo@baseclass.@pgfoo@attributes\endcsname + \pgfutil@for\pgfoo@attribute:=\pgfoo@attributes\do{% for each attribute + % check if we have already found it in some previous base class + \edef\pgfoo@temp{{,\pgfoo@attribute=}{\pgfoo@allattributes,}} + \expandafter\pgfutil@in@\pgfoo@temp + \ifpgfutil@in@\else % don't overwrite + % append to the list + \edef\pgfoo@allattributes{\pgfoo@allattributes,\pgfoo@attribute=\pgfoo@baseclass}% + \fi + }% + }% + \if\relax\pgfoo@allattributes\relax\else + \edef\pgfoo@allattributes{\expandafter\pgfutil@gobble\pgfoo@allattributes}% gobble comma + \fi + % this macro will hold a list of attributes from all base classes + % we run this macro at init and gc + \def\pgfoo@process@attributes{} + \pgfutil@for\pgfoo@attributeclass:=\pgfoo@allattributes\do{% for each (attribute, class) pair + % append to the attribute processor + \expandafter\pgfoo@inherit@attributes@appendattribute\pgfoo@attributeclass.% + }% + \expandafter\let\csname pgfooY\pgfoo@classname .@pgfoo@process@attributes\endcsname\pgfoo@process@attributes } +% #1=attr, #2=class which the attr comes from +\def\pgfoo@inherit@attributes@appendattribute#1=#2.{% + \def\pgfoo@tempA{\pgfoo@attribute@op{#1}}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgfoo@tempB\expandafter\expandafter\expandafter{\expandafter\pgfoo@tempA\csname pgfooY#2@#1\endcsname}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgfoo@process@attributes\expandafter\expandafter\expandafter{\expandafter\pgfoo@process@attributes\pgfoo@tempB}% + % above is just this: + % \def\pgfoo@process@attributes{\pgfoo@process@attributes\pgfoo@attribute@op{#1}% + % \csname pgfooY#2@#1\endcsname} + % with \pgfoo@process@attributes and \csname expanded exactly once: +} + +% \pgfoo@attribute@op for garbace collection +\def\pgfoo@gc@attribute#1#2{\pgfoolet{#1}\relax} + + \newcount\pgfoo@objectcount \newcount\pgfoothis@count @@ -250,6 +554,21 @@ +% Help macro for scanning arguments +\newtoks\pgfoo@toks + +\def\pgfoo@collect@args{% + \pgfutil@ifnextchar\bgroup\pgfoo@collect@args@group\pgfoo@collect@args@nogroup% +} +\def\pgfoo@collect@args@nogroup#1){% + \pgfoo@toks{#1}% + \pgfoo@continue% +} +\def\pgfoo@collect@args@group#1{% + \pgfutil@ifnextchar){\pgfoo@toks{{#1}}\expandafter\pgfoo@continue\pgfutil@gobble}{\pgfoo@collect@args@nogroup{#1}}% +} + + % Instantiate an object % % Possible syntax: @@ -276,32 +595,73 @@ }% }% } -\def\pgfoo@new#1=new #2(#3){% +\def\pgfoo@new#1=new #2({% \expandafter\ifx\csname pgfooY#2.get id\endcsname\relax% - \PackageError{pgfoo}{Unknown class '#2'}{}% + \pgferror{Unknown class '#2'}% \else% - \advance\pgfoo@objectcount by 1\relax% - \edef\pgfoolastobj{\noexpand\pgfoo@caller{\the\pgfoo@objectcount}}% - \expandafter\gdef\csname pgfooX\the\pgfoo@objectcount @class\endcsname{#2}% - \let#1\pgfoolastobj% + \pgfoo@new@create#1{#2}% {% \pgfoothis@count\pgfoo@objectcount% - \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.@pgfooinit\endcsname% + \let\pgfoo@attribute@op\pgfoolet + \csname pgfooY#2.@pgfoo@process@attributes\endcsname% }% - \pgfoolastobj.#2(#3)% - \aftergroup\pgfoogc% cleanup after group + \let\pgfoo@continue=\pgf@oo@new@cont% + \expandafter\pgfoo@collect@args% \fi% } -\def\pgfoo@new@attribute#1=new #2(#3){% - \pgfoo@new\pgf@oo@temp=new #2(#3)% - \pgfoolet{#1}\pgf@oo@temp% + +\def\pgf@oo@new@cont{% + \expandafter\pgfoolastobj\expandafter.\expandafter i\expandafter n\expandafter i\expandafter t\expandafter(\the\pgfoo@toks)% + \aftergroup\pgfoogc% cleanup after group } +\def\pgfoo@new@attribute#1=new #2({% + \expandafter\ifx\csname pgfooY#2.get id\endcsname\relax% + \pgferror{Unknown class '#2'}% + \else% + \pgfoo@new@create\pgfoo@temp{#2}% + {% + \pgfoothis@count\pgfoo@objectcount% + \let\pgfoo@attribute@op\pgfoolet% + \csname pgfooY#2.@pgfoo@process@attributes\endcsname% + }% + \pgfoolet{#1}\pgfoo@temp% + \let\pgfoo@continue=\pgf@oo@new@cont% + \expandafter\pgfoo@collect@args% + \fi% +} -\def\pgfoo@caller#1.#2(#3){% +\def\pgf@oo@new@cont{% + \expandafter\pgfoolastobj\expandafter.\expandafter i\expandafter n\expandafter i\expandafter t\expandafter(\the\pgfoo@toks)% + \aftergroup\pgfoogc% cleanup after group +} + +\def\pgfoo@new@create#1#2{% + \advance\pgfoo@objectcount by 1\relax% + \edef\pgfoolastobj{\noexpand\pgfoo@caller{\the\pgfoo@objectcount}}% + \expandafter\gdef\csname pgfooX\the\pgfoo@objectcount @class\endcsname{#2}% + \let#1\pgfoolastobj% +} + +\def\pgfoo@caller#1.#2({% + \expandafter\let\expandafter\pgfoo@caller@temp\csname pgfooY\csname pgfooX#1@class\endcsname.#2\endcsname% + \ifx\pgfoo@caller@temp\relax% + % assume that #2 is of form "superclass.method" + \expandafter\let\expandafter\pgfoo@caller@temp\csname pgfooY#2\endcsname% + \ifx\pgfoo@caller@temp\relax% + \pgferror{Object #1 has no method '#2'}% + \fi% + \fi% \def\pgf@marshal{% \pgfoothis@count=#1\relax% - \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.#2\endcsname(#3)% + }% + \let\pgfoo@continue\pgfoo@caller@cont% + \pgfoo@collect@args% +} +\def\pgfoo@caller@cont{% + \edef\pgf@marshal{% + \pgf@marshal% + \noexpand\pgfoo@caller@temp(\the\pgfoo@toks)% }% \expandafter\pgf@marshal\expandafter\pgfoothis@count\the\pgfoothis@count\relax% } @@ -309,11 +669,18 @@ % The special "this" object -\def\pgfoothis.#1(#2){% - \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.#1\endcsname(#2)% +\def\pgfoothis.#1({% + \expandafter\let\expandafter\pgfoo@caller@temp\csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.#1\endcsname% + \ifx\pgfoo@caller@temp\relax% + % assume that #1 is of form "superclass.method" + \expandafter\let\expandafter\pgfoo@caller@temp\csname pgfooY#1\endcsname% + \fi% + \let\pgfoo@continue\pgfoothis@cont% + \pgfoo@collect@args% +} +\def\pgfoothis@cont{% + \expandafter\pgfoo@caller@temp\expandafter(\the\pgfoo@toks)% } - - @@ -390,7 +757,8 @@ \else% % Cleanup this object: % The following is the fast version of \pgfooobj{\the\pgfoo@objectcount}.@pgfoogc: - \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.@pgfoogc\endcsname% + \let\pgfoo@attribute@op\pgfoo@gc@attribute + \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.@pgfoo@process@attributes\endcsname% \expandafter\global\expandafter\let\csname pgfooX\the\pgfoothis@count @class\endcsname\relax% \fi% \pgfoo@next% @@ -398,6 +766,28 @@ +% +% +% Object class +% defines method "copy" +% +% + +\pgfooclass{object}{% + \method copy(#1) {% + % create a new object + \edef\pgfoo@temp@classname{\csname pgfooX\the\pgfoothis@count @class\endcsname}% + \expandafter\pgfoo@new@create\expandafter#1\expandafter{\pgfoo@temp@classname}% + \def\pgfoo@copy@attributes##1##2{% + \pgfooget{##1}\pgfoo@attrvalue + \expandafter\let\csname pgfooX\the\pgfoo@objectcount @##1\endcsname\pgfoo@attrvalue + }% + \let\pgfoo@attribute@op\pgfoo@copy@attributes + \csname pgfooY\pgfoo@temp@classname .@pgfoo@process@attributes\endcsname + \aftergroup\pgfoogc% cleanup after group + } +} + % % diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleparser.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleparser.code.tex index ed13b25324c..0a08a5e9d4e 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleparser.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleparser.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleparser.code.tex,v 1.1 2009/01/12 12:56:09 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleparser.code.tex,v 1.2 2013/07/15 12:05:34 tantau Exp $ % % This file defines commands for defining a letter-by-letter parser @@ -43,9 +43,9 @@ \expandafter\let\expandafter\pgf@parser@action% \csname pgf@parser@a@\pgf@parser @all@\meaning\pgf@parser@symbol\endcsname% \ifx\pgf@parser@action\relax% - \PackageError{pgfparse}{Unexpected character + \pgferror{Unexpected character '\meaning\pgf@parser@symbol' in parser '\pgf@parser' in state - '\pgf@parser@state'}{}% + '\pgf@parser@state'}% \fi% \fi% \pgf@parser@action% diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleplot.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleplot.code.tex index ea55ca8517b..8620a91e4de 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleplot.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleplot.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleplot.code.tex,v 1.8 2010/10/22 17:34:17 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleplot.code.tex,v 1.12 2013/07/31 16:22:24 tantau Exp $ % PGF's plotting interface works as follows: @@ -16,26 +16,35 @@ % need to provide the coordinates (obviously) of the points that % should be plotted. The coordinates are given via a long stream of % commands. These commands are \pgfplotstreamstart, which is -% given exactly once at the beginning, \pgfplotstreampoint, of which there -% are numerous in the middle, \pgfplotstreamspecial, of which there may be -% numerous in the middle, and \pgfplotstreamend, which must be given -% at the end. Between these commands arbitrary other commands may be -% given. Here is an example: +% given exactly once at the beginning, the commands +% \pgfplotstreampoint, \pgfplotstreampointoutlier, +% \pgfplotstreampointundefined, \pgfplotstreamnewdataset, of which +% there are numerous in the middle, the special \pgfplotstreamspecial, +% of which there may be numerous in the middle, and \pgfplotstreamend, +% which must be given at the end. Between these commands arbitrary +% other commands may be given. Here is an example: % % ... % \pgfplotstreamstart % \pgfplotstreampoint{\pgfpointxy{0}{0}} % \pgfplotstreampoint{\pgfpointxy{1}{1}} +% \pgfplotstreamnewdataset % \pgfplotstreampoint{\pgfpointxy{2}{4}} % \relax -% \pgfplotstreampoint{\pgfpointxy{3}{9}} +% \pgfplotstreampointoutlier{\pgfpointxy{3}{9}} % \pgfplotstreamspecial{some handler-dependent special stuff} % \pgfplotstreamend % % By themselves, the \pgfplotstreamxxxx commands do not do anything by % default. Rather, to ``use'' such a stream, you must first install a % stream handler. For example, the ``lineto'' handler will simply -% translate every \pgfplotstreampoint into a \pgfpathlineto. +% basically every \pgfplotstreampoint into a \pgfpathlineto. +% +% One special things is the handling of "jumps" in a stream. For +% instance, when a lineto handler encounters an "outlier" or a new +% data set, the current line should end and a new subpath should start +% (unless configured otherwise). For this, the special jump handler is +% important. % % Example: % @@ -55,9 +64,111 @@ % are set by the handlers: \def\pgfplotstreamstart{\pgf@plotstreamstart} \def\pgfplotstreampoint#1{\gdef\pgfplotlastpoint{#1}\pgf@plotstreampoint{#1}} +\def\pgfplotstreampointoutlier#1{\pgfplot@outliers{}{\pgf@plotstreamjump}{\pgfplotstreampoint{#1}}}% +\def\pgfplotstreampointundefined{\pgfplot@outliers{}{\pgf@plotstreamjump}{}}% +\def\pgfplotstreamnewdataset{\pgfplot@outliers{}{\pgf@plotstreamjump}{}}% \def\pgfplotstreamspecial{\pgf@plotstreamspecial} \def\pgfplotstreamend{\pgf@plotstreamend} +\def\pgfplot@ignorer#1#2#3{#1} +\def\pgfplot@jumper#1#2#3{#2} +\def\pgfplot@plotter#1#2#3{#3} + +\let\pgfplot@outliers\pgfplot@jumper +\let\pgfplot@undefined\pgfplot@jumper +\let\pgfplot@newdata\pgfplot@jumper + +\pgfset{ + handle outlier points in plots/.is choice, + handle outlier points in plots/ignore/.code=\let\pgfplot@outliers\pgfplot@ignorer, + handle outlier points in plots/jump/.code=\let\pgfplot@outliers\pgfplot@jumper, + handle outlier points in plots/plot/.code=\let\pgfplot@outliers\pgfplot@plotter, + handle undefined points in plots/.is choice, + handle undefined points in plots/ignore/.code=\let\pgfplot@undefined\pgfplot@ignorer, + handle undefined points in plots/jump/.code=\let\pgfplot@undefined\pgfplot@jumper, + handle new data sets in plots/.is choice, + handle new data sets in plots/ignore/.code=\let\pgfplot@newdata\pgfplot@ignorer, + handle new data sets in plots/jump/.code=\let\pgfplot@newdata\pgfplot@jumper, +} + + +% Declares a new plot handler +% +% #1 = macro that should install the stream handler subsequently +% #2 = parameter list of said macro. +% #3 = keys as described below +% +% Description: +% +% When you declare a new plot handler, you provide, through keys, +% different "actions" that should be taken when the different stream +% commands are used: +% +% start = some code to be executed when \pgfplotstreamstart is called +% for this plothandler +% end = same for the end of the stream +% point = code to be executed for a point of the stream +% jump = code to be executed for a "jump" in the stream +% special = code to be executed for \pgfplotstreamspecial +% start macro = here and for the following keys, the to-be-executed +% code is stored in the given macro +% end macro = see above +% jump macro = see above +% point macro = see above +% special macro = see above +% +% Example: +% +% \pgfdeclareplothandler{\ultrasimplehandler}{}{ +% point=\pgfpathlineto{##1} +% } + +\def\pgfdeclareplothandler#1#2#3{% + \def#1#2{% + \pgfkeys{% + /pgf/plots/@handler options/.cd, + start=\relax, + end macro=\relax, + point macro=\pgfutil@gobble, + jump macro=\relax, + special macro=\pgfutil@gobble,% + #3% + }% + }% +} + +\pgfkeys{% + /pgf/plots/@handler options/.cd, + start/.code=% + \gdef\pgf@plotstreamstart{% + \global\pgf@plot@startedfalse% + \global\let\pgf@plotstreamend\pgf@plotstreamend@init% + \global\let\pgf@plotstreampoint\pgf@plotstreampoint@init% + \global\let\pgf@plotstreamjump\pgf@plotstreamjump@init% + \global\let\pgf@plotstreamspecial\pgf@plotstreamspecial@init% + #1% + },% + start macro/.code=% + \gdef\pgf@plotstreamstart{% + \global\pgf@plot@startedfalse% + \global\let\pgf@plotstreamend\pgf@plotstreamend@init% + \global\let\pgf@plotstreampoint\pgf@plotstreampoint@init% + \global\let\pgf@plotstreamjump\pgf@plotstreamjump@init% + \global\let\pgf@plotstreamspecial\pgf@plotstreamspecial@init% + #1% + },% + end/.code=\gdef\pgf@plotstreamend@init{#1}, + end macro/.code=\global\let\pgf@plotstreamend@init#1, + point/.code=\gdef\pgf@plotstreampoint@init##1{#1}, + point macro/.code=\global\let\pgf@plotstreampoint@init#1, + jump/.code=\gdef\pgf@plotstreamjump@init{#1}, + jump macro/.code=\global\let\pgf@plotstreamjump@init#1, + special/.code=\gdef\pgf@plotstreamspecial@init##1{#1}, + special macro/.code=\global\let\pgf@plotstreamspecial@init#1, +} + +\newif\ifpgf@plot@started + @@ -88,6 +199,7 @@ + % % Handlers % @@ -103,12 +215,9 @@ % \pgfplothandlerlineto % \pgfplotxyfile{mytable} -\def\pgfplothandlerlineto{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@line@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% +\pgfdeclareplothandler{\pgfplothandlerlineto}{}{ + point macro=\pgf@plot@line@handler, + jump=\global\let\pgf@plotstreampoint\pgf@plot@line@handler@move% } \def\pgf@plot@line@handler#1{% @@ -116,29 +225,48 @@ \global\let\pgf@plotstreampoint=\pgfpathlineto% } +\def\pgf@plot@line@handler@move#1{% + \pgfpathmoveto{#1}% + \global\let\pgf@plotstreampoint=\pgfpathlineto% +} + % This handler turns creates a series of lineto commands, with the -% last command being a closepath, resulting in a closed path. +% last command being a closepath, resulting in a closed path. If a +% jump is encountered, the current subpath is closed and a new subpath +% is started. % % Example: % % \pgfplothandlerpolygon % \pgfplotxyfile{mytable} -\def\pgfplothandlerpolygon{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@line@handler@close% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgfpathclose% - }% -} +\pgfdeclareplothandler{\pgfplothandlerpolygon}{}{% + point macro=\pgf@plot@line@handler@close, + jump macro=\pgf@plot@next@close@and@moveto, + end macro=\pgf@plot@polygon@stop +}% \def\pgf@plot@line@handler@close#1{% \pgfpathmoveto{#1}% + \global\pgf@plot@startedtrue% \global\let\pgf@plotstreampoint=\pgfpathlineto% } +\def\pgf@plot@polygon@stop{% + \ifpgf@plot@started% + \pgfpathclose% + \fi% + \global\pgf@plot@startedfalse% +} + +\def\pgf@plot@next@close@and@moveto{% + \ifpgf@plot@started% + \pgfpathclose% + \fi% + \global\let\pgf@plotstreampoint\pgf@plot@line@handler@close% +} % More handlers are defined in pgflibraryplothandlers @@ -154,14 +282,7 @@ % \pgfplothandlerdiscard % \pgfplotxyfile{mytable} -\def\pgfplothandlerdiscard{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgfutil@gobble% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% -} - +\pgfdeclareplothandler{\pgfplothandlerdiscard}{}{} @@ -178,14 +299,12 @@ % \pgftransformxshift{1cm} % \myplot -\def\pgfplothandlerrecord#1{% - \def\pgf@plot@recordto{#1}% - \gdef#1{\pgfplotstreamstart}% - \def\pgf@plotstreamstart{% - \gdef\pgf@plotstreampoint####1{\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreampoint{####1}}}% - \gdef\pgf@plotstreamspecial####1{\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreamspecial{####1}}}% - \gdef\pgf@plotstreamend{\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreamend}}% - }% +\pgfdeclareplothandler{\pgfplothandlerrecord}{#1}{% + start=\gdef#1{\pgfplotstreamstart}, + point=\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreampoint{##1}}, + jump=\expandafter\gdef\expandafter#1\expandafter{#1\pgf@plotstreamjump}, + special=\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreamspecial{##1}}, + end=\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreamend}, } @@ -212,9 +331,10 @@ \pgfplotstreamstart% \openin\r@pgf@reada=#1 \ifeof\r@pgf@reada - \PackageWarning{pgf}{Plot data file `#1' not found.} + \pgfwarning{Plot data file `#1' not found.} \else \catcode`\#=14 + \catcode`\^^M=5 \pgf@readxyfile% \fi \pgfplotstreamend% @@ -228,7 +348,9 @@ \let\par=\pgf@savedpar% \edef\pgf@temp{\pgf@temp}% \ifx\pgf@temp\pgfutil@empty% + \ifeof\r@pgf@reada\else\pgfplotstreamnewdataset\fi% \else\ifx\pgf@temp\pgf@partext% + \ifeof\r@pgf@reada\else\pgfplotstreamnewdataset\fi% \else% \expandafter\pgf@parsexyline\pgf@temp\pgf@stop% \fi\fi% @@ -236,9 +358,18 @@ } \def\pgf@parsexyline#1 #2 #3\pgf@stop{% - \pgfplotstreampoint{\pgfpointxy{#1}{#2}}% + \edef\pgf@xyline@flag@val{#3}% + \ifx\pgf@xyline@flag@val\pgf@xyline@flag@undef% + \pgfplotstreampointundefined% + \else\ifx\pgf@xyline@flag@val\pgf@xyline@flag@out% + \pgfplotstreampointoutlier{\pgfpointxy{#1}{#2}}% + \else% + \pgfplotstreampoint{\pgfpointxy{#1}{#2}}% + \fi\fi% } +\edef\pgf@xyline@flag@out{o\space}% +\edef\pgf@xyline@flag@undef{u\space}% @@ -261,9 +392,10 @@ \pgfplotstreamstart% \openin\r@pgf@reada=#1 \ifeof\r@pgf@reada - \PackageWarning{pgf}{Plot data file `#1' not found.} + \pgfwarning{Plot data file `#1' not found.} \else \catcode`\#=14 + \catcode`\^^M=5 \pgf@readxyzfile% \fi \pgfplotstreamend% @@ -273,7 +405,9 @@ \def\pgf@readxyzfile{% \pgfutil@read\r@pgf@reada to \pgf@temp% \ifx\pgf@temp\pgfutil@empty% + \ifeof\r@pgf@reada\else\pgfplotstreamnewdataset\fi% \else\ifx\pgf@temp\pgf@partext% + \ifeof\r@pgf@reada\else\pgfplotstreamnewdataset\fi% \else% \expandafter\pgf@parsexyzline\pgf@temp\pgf@stop% \fi\fi% @@ -281,7 +415,14 @@ } \def\pgf@parsexyzline#1 #2 #3 #4\pgf@stop{% - \pgfplotstreampoint{\pgfpointxyz{#1}{#2}{#3}}% + \edef\pgf@xyline@flag@val{#4}% + \ifx\pgf@xyline@flag@val\pgf@xyline@flag@undef% + \pgfplotstreampointundefined% + \else\ifx\pgf@xyline@flag@val\pgf@xyline@flag@out% + \pgfplotstreampointoutlier{\pgfpointxyz{#1}{#2}{#3}}% + \else% + \pgfplotstreampoint{\pgfpointxyz{#1}{#2}{#3}}% + \fi\fi% } @@ -314,6 +455,9 @@ \let\pgf@plotwrite=\w@pgf@writea \newif\ifpgf@resample@plot +\pgfkeys{% + /pgf/plot/gnuplot call/.initial={gnuplot}} + \def\pgfplotgnuplot{\pgfutil@ifnextchar[{\pgf@plotgnuplot}{\pgf@plotgnuplot[\jobname]}}%} \def\pgf@plotgnuplot[#1]#2{% \pgf@resample@plottrue% @@ -344,25 +488,27 @@ \immediate\pgfutil@write\pgf@plotwrite{\pgf@gnuplot@head}% \immediate\pgfutil@write\pgf@plotwrite{#2}% \immediate\closeout\pgf@plotwrite% - \immediate\pgfutil@write18{gnuplot \pgf@plotgnuplotfile}% + \immediate\pgfutil@write18{% + \pgfkeysvalueof{/pgf/plot/gnuplot call} \pgf@plotgnuplotfile}% \fi% - % temporarily redefine \pgf@parsexyline - \let\pgf@savedparsexyline=\pgf@parsexyline% - \let\pgf@parsexyline=\pgf@parsegnuplotxyline% +% \let\pgf@savedparsexyline=\pgf@parsexyline% +% \let\pgf@parsexyline=\pgf@parsegnuplotxyline% \pgfplotxyfile{\pgf@plottablefile}% - \let\pgf@parsexyline=\pgf@savedparsexyline% -} - -\def\pgf@parsegnuplotxyline#1 #2 #3\pgf@stop{% - \edef\pgf@xyline@flag@val{#3}% - \edef\pgf@xyline@flag@undef{u\space}% - \ifx\pgf@xyline@flag@val\pgf@xyline@flag@undef% - \else% - \pgfplotstreampoint{\pgfpointxy{#1}{#2}}% - \fi% +% \let\pgf@parsexyline=\pgf@savedparsexyline% } - +% \def\pgf@parsegnuplotxyline#1 #2 #3\pgf@stop{% +% \edef\pgf@xyline@flag@val{#3}% +% \edef\pgf@xyline@flag@out{o\space}% +% \edef\pgf@xyline@flag@undef{u\space}% +% \ifx\pgf@xyline@flag@val\pgf@xyline@flag@undef% +% \pgfplotstreampointundefined% +% \else\ifx\pgf@xyline@flag@val\pgf@xyline@flag@out% +% \pgfplotstreampointoutlier{\pgfpointxy{#1}{#2}}% +% \else% +% \pgfplotstreampoint{\pgfpointxy{#1}{#2}}% +% \fi\fi% +% } % This producer handler plots a function using pgf's mathematical engine. % diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleshapes.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleshapes.code.tex index da75b3e2e43..7e4e65d4c38 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleshapes.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleshapes.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleshapes.code.tex,v 1.13 2010/09/09 13:52:57 cjorssen Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleshapes.code.tex,v 1.34 2013/10/31 15:44:19 tantau Exp $ @@ -38,12 +38,12 @@ \def\pgfmultipartnode#1#2#3#4{% \pgfutil@ifundefined{pgf@sh@s@#1}% - {\PackageError{pgf}{Unknown shape ``#1''}{}}% + {\pgferror{Unknown shape ``#1''}}% {% {% \let\pgf@sh@savedmacros=\pgfutil@empty% MW \let\pgf@sh@savedpoints=\pgfutil@empty% - \def\shape@name{#1}% CJ + \def\pgf@sm@shape@name{#1}% CJ % TT added prefix! \csname pgf@sh@s@#1\endcsname% \pgf@sh@savedpoints% \pgf@sh@savedmacros% MW @@ -57,15 +57,8 @@ }% % Save the saved points and the transformation matrix \edef\pgf@node@name{#3}% - \ifx\pgf@positionnodelater@macro\relax% - \else% - % Rename node - \edef\pgf@node@name{not yet positioned@\pgf@node@name}% - % Interrupt bounding box! - \pgfinterruptboundingbox% - % Put everything in our box: - \setbox\pgfpositionnodelaterbox=\hbox\bgroup% - % + \ifpgflatenodepositioning + \pgf@shapes@late@pos@begin% \fi% \ifx\pgf@node@name\pgfutil@empty% \else% @@ -74,20 +67,29 @@ \expandafter\pgf@sh@@temp\expandafter{\pgf@sh@savedpoints}% \edef\pgf@sh@@temp{\noexpand\gdef\expandafter\noexpand\csname pgf@sh@ma@\pgf@node@name\endcsname}% MW \expandafter\pgf@sh@@temp\expandafter{\pgf@sh@savedmacros}% MW - \pgfgettransform\pgf@temp + \pgfgettransform\pgf@temp% \expandafter\xdef\csname pgf@sh@nt@\pgf@node@name\endcsname{\pgf@temp}% \expandafter\xdef\csname pgf@sh@pi@\pgf@node@name\endcsname{\pgfpictureid}% \fi% \pgfutil@ifundefined{pgf@sh@bbg@#1}{} {{\pgfscope\csname pgf@sh@bbg@#1\endcsname\endpgfscope}}% - \pgfutil@ifundefined{pgf@sh@bg@#1}{}% - {\csname pgf@sh@bg@#1\endcsname#4}% + \pgfutil@ifundefined{pgf@sh@bg@#1}{% + \global\let\pgfpositionnodelaterpath\pgfutil@empty% + }% + {\csname pgf@sh@bg@#1\endcsname% + \ifpgflatenodepositioning% + \pgfsyssoftpath@getcurrentpath\pgfpositionnodelaterpath% + \pgfprocessround{\pgfpositionnodelaterpath}{\pgfpositionnodelaterpath}% + \global\let\pgfpositionnodelaterpath\pgfpositionnodelaterpath% + \fi% + #4}% \pgfutil@ifundefined{pgf@sh@fbg@#1}{} {{\pgfscope\csname pgf@sh@fbg@#1\endcsname\endpgfscope}}% {% \expandafter\pgfutil@for\expandafter\pgf@shape@com\expandafter:\expandafter=\csname pgf@sh@boxes@#1\endcsname\do{% {% \pgftransformshift{\pgf@sh@reanchor{#1}{\pgf@shape@com}}% + \pgfapproximatenonlineartransformation% \expandafter\pgfqboxsynced\expandafter{\csname pgfnodepart\pgf@shape@com box\endcsname}% }% }% @@ -98,23 +100,44 @@ {\csname pgf@sh@fg@#1\endcsname#4}% \pgfutil@ifundefined{pgf@sh@ffg@#1}{}% {{\pgfscope\csname pgf@sh@ffg@#1\endcsname\endpgfscope}}% - \ifx\pgf@positionnodelater@macro\relax% - \expandafter\pgf@nodecallback\expandafter{\pgf@node@name}% + \ifpgflatenodepositioning% + \pgf@shapes@late@pos@end% \else% - \egroup% Close box - \edef\pgfpositionnodelaterminx{\the\pgf@picminx}% - \edef\pgfpositionnodelaterminy{\the\pgf@picminy}% - \edef\pgfpositionnodelatermaxx{\the\pgf@picmaxx}% - \edef\pgfpositionnodelatermaxy{\the\pgf@picmaxy}% - \let\pgfpositionnodelatername=\pgf@node@name% - \pgf@positionnodelater@macro% - \endpgfinterruptboundingbox% + \expandafter\pgf@nodecallback\expandafter{\pgf@node@name}% \fi% }% }% } - +\def\pgf@shapes@late@pos@begin{% + % Rename node + \edef\pgf@node@name{not yet positionedPGFINTERNAL\pgf@node@name}% + % Interrupt bounding box! + \pgfinterruptboundingbox% + % Put everything in our box: + \pgf@relevantforpicturesizetrue% + \setbox\pgfpositionnodelaterbox=\hbox% + \bgroup% +} + +\def\pgf@shapes@late@pos@end{% + \egroup% Close box + \ifdim\pgf@picminx>\pgf@picmaxx\relax% happens for empty nodes + \def\pgfpositionnodelaterminx{0.0pt}% + \let\pgfpositionnodelaterminy\pgfpositionnodelaterminx% + \let\pgfpositionnodelatermaxx\pgfpositionnodelaterminx% + \let\pgfpositionnodelatermaxy\pgfpositionnodelaterminx% + \else% + \edef\pgfpositionnodelaterminx{\the\pgf@picminx}% + \edef\pgfpositionnodelaterminy{\the\pgf@picminy}% + \edef\pgfpositionnodelatermaxx{\the\pgf@picmaxx}% + \edef\pgfpositionnodelatermaxy{\the\pgf@picmaxy}% + \fi% + \let\pgfpositionnodelatername=\pgf@node@name% + \pgf@positionnodelater@macro% + \endpgfinterruptboundingbox% +} + \def\pgf@shift@node#1#2{% % This internal command shifts the recorded coordinates for node #1 % by the vector #2. It is used to @@ -199,7 +222,7 @@ % \pgfpositionnodelatername % The name of the just-created-node. This name will be the % originally "desired" name of the box plus the prefix "not yet -% positioned box@". +% positioned boxPGFINTERNAL". % % \pgfpositionnodelaterminx % \pgfpositionnodelatermaxx @@ -218,11 +241,21 @@ % When \pgfpositionnodenow is called, the macros mentioned above % should have the exact same values they had when #1 is called. -\def\pgfpositionnodelater#1{\let\pgf@positionnodelater@macro=#1\relax} +\def\pgfpositionnodelater#1{% + \let\pgf@positionnodelater@macro=#1% + \ifx\pgf@positionnodelater@macro\relax% + \pgflatenodepositioningfalse% + \else% + \pgflatenodepositioningtrue% + \fi% +} +\newif\ifpgflatenodepositioning \pgfpositionnodelater{\relax} \def\pgfpositionnodelaterbox{0} + + % Position a node that has been scheduled for later insertion % % #1 = position in the picture, where the original anchor should go, @@ -232,7 +265,7 @@ % % This command works in concert with \pgfpositionnodelater, see the % description there. When \pgfpositionnodenow is called, the macros -% \pgfpositionnodelaterbox and so one should be set to the values they +% \pgfpositionnodelaterbox and so on should be set to the values they % had when the macro given to \pgfpositionnodelater was called. Then, % the box described by these macros will be inserted into the picture % at the position given #1. More precisely, the original node will @@ -241,13 +274,13 @@ % into the actual picture. \def\pgfpositionnodenow#1{% + \pgfinterruptpath% {% \pgfpointtransformed{#1}% \edef\pgf@temp@shift{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}} \pgftransformreset% \pgftransformshift{\pgf@temp@shift}% - \setbox\pgfpositionnodelaterbox=\hbox{\pgfsys@beginpicture\box\pgfpositionnodelaterbox\pgfsys@endpicture}% - \pgfqboxsynced{\pgfpositionnodelaterbox}% + \pgfsys@pictureboxsynced\pgfpositionnodelaterbox% \pgf@shift@node{\pgfpositionnodelatername}{\pgf@temp@shift}% % Bounding box update... \pgfpointtransformed{\pgfqpoint{\pgfpositionnodelaterminx}{\pgfpositionnodelaterminy}}% @@ -257,15 +290,65 @@ % Naming and callbacks \expandafter\pgfpositionnodenow@rename\pgfpositionnodelatername\relax% }% + % Late setup% + {% + \csname pgf@lns@\pgfpositionnodelatername\endcsname% + \expandafter\global\expandafter\let\csname pgf@lns@\pgfpositionnodelatername\endcsname\relax% + }% + \endpgfinterruptpath% } -\def\pgfpositionnodenow@rename not yet positioned@#1\relax{% - \pgfnoderename{#1}{not yet positioned@#1} +\def\pgfpositionnodenow@rename not yet positionedPGFINTERNAL#1\relax{% + \pgfnoderename{#1}{not yet positionedPGFINTERNAL#1} \pgf@nodecallback{#1}% } +% "Fake" a node +% +% #1 = node name +% +% Description: +% +% This command will setup things so that it "looks like" a node named +% #1 has been created, but, in reality, no node is created. The idea +% is that a node created in this way can be referenced by systems +% using the late positioning, which will only create the node later +% on. +% +\def\pgffakenode#1{% + \edef\pgf@temp{\ifpgflatenodepositioning not yet positionedPGFINTERNAL\fi#1}% + \expandafter\gdef\csname pgf@sh@ns@\pgf@temp\endcsname{coordinate}% + \expandafter\gdef\csname pgf@sh@np@\pgf@temp\endcsname{\def\centerpoint{\pgfpointorigin}}% + \expandafter\gdef\csname pgf@sh@nt@\pgf@temp\endcsname{{1}{0}{0}{1}{0pt}{0pt}}% + \expandafter\global\expandafter\let\csname pgf@sh@ma@\pgf@temp\endcsname\pgfutil@empty% + \expandafter\xdef\csname pgf@sh@pi@\pgf@temp\endcsname{\pgfpictureid}% +} + + + +% Specify code that should be executed after a node has been created +% +% #1 = node name +% #2 = later code +% +% Description: +% +% This macro allows you to provide some code #2 that will be executed +% right after a node has been positioned using \pgfpositionnodenow. If +% the node has already been positioned (if the late positioning is not +% switched on), nothing happens. + +\def\pgfnodepostsetupcode#1#2{% + \ifpgflatenodepositioning% + \expandafter\ifx\csname pgf@lns@not yet positionedPGFINTERNAL#1\endcsname\relax% + \expandafter\gdef\csname pgf@lns@not yet positionedPGFINTERNAL#1\endcsname{#2}% + \else% + \expandafter\pgfutil@g@addto@macro\csname pgf@lns@not yet positionedPGFINTERNAL#1\endcsname{#2}% + \fi% + \fi% +} @@ -334,19 +417,23 @@ \edef\pgf@temp{#1}% \ifx\pgf@temp\pgfutil@empty% do nothing \else% - \pgf@process{\pgfpointtransformed{#2}}% - \expandafter\gdef\csname pgf@sh@ns@#1\endcsname{coordinate}% - \expandafter\xdef\csname pgf@sh@np@#1\endcsname{% - \noexpand\def\noexpand\centerpoint{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - } - \expandafter\gdef\csname pgf@sh@nt@#1\endcsname{{1}{0}{0}{1}{0pt}{0pt}}% - \expandafter\global\expandafter\let\csname pgf@sh@ma@#1\endcsname\pgfutil@empty% - \expandafter\gdef\csname pgf@sh@pi@#1\endcsname{\pgfpictureid}% + \ifpgflatenodepositioning% + {\pgftransformshift{#2}\pgfnode{coordinate}{center}{}{#1}{}}% + \else% + \pgf@process{\pgfpointtransformed{#2}}% + \expandafter\gdef\csname pgf@sh@ns@#1\endcsname{coordinate}% + \expandafter\xdef\csname pgf@sh@np@#1\endcsname{% + \noexpand\def\noexpand\centerpoint{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + } + \expandafter\gdef\csname pgf@sh@nt@#1\endcsname{{1}{0}{0}{1}{0pt}{0pt}}% + \expandafter\global\expandafter\let\csname pgf@sh@ma@#1\endcsname\pgfutil@empty% + \expandafter\xdef\csname pgf@sh@pi@#1\endcsname{\pgfpictureid}% + \fi% \fi% } \def\pgf@sh@redeferredanchor#1#2{% CJ - \expandafter\gdef\csname pgf@anchor@\shape@name @#1\endcsname{#2}}% CJ + \expandafter\gdef\csname pgf@anchor@\pgf@sm@shape@name @#1\endcsname{#2}}% CJ @@ -393,7 +480,7 @@ {% \pgfutil@ifundefined{pgf@anchor@generic@#2}{% \pgfmathsetcounter{pgf@counta}{#2}% - \csname pgf@anchor@#1@border\endcsname{\pgfqpointpolar{\c@pgf@counta}{1pt}}% + \csname pgf@anchor@#1@border\endcsname{\pgfqpointpolar{\the\c@pgf@counta}{1pt}}% }{% \csname pgf@anchor@generic@#2\endcsname{#1}% }% @@ -414,7 +501,7 @@ % can be used to query the referenced node's name. % This macro is not defined during node creation. \def\pgfdeclaregenericanchor#1#2{% - \expandafter\def\csname pgf@anchor@generic@#1\endcsname##1{#2}% + \expandafter\def\csname pgf@anchor@generic@#1\endcsname##1{#2}% }% @@ -435,7 +522,10 @@ \def\pgfpointanchor#1#2{% % Ok, check whether #1 is known! \pgfutil@ifundefined{pgf@sh@ns@#1} - {\PackageError{pgf}{No shape named #1 is known}{}% + {\pgfutil@ifundefined{pgf@sh@ns@not yet positionedPGFINTERNAL#1}{% + \pgferror{No shape named #1 is known}}{ + % else, fail silently + }% \pgfpointorigin}% {% \pgf@process{% @@ -500,7 +590,7 @@ \def\pgfpointshapeborder#1#2{% % Ok, check whether #1 is known! \pgfutil@ifundefined{pgf@sh@ns@#1} - {\PackageError{pgf}{No shape named #1 is known}{}% + {\pgferror{No shape named #1 is known}% \pgfpointorigin}% {% \pgf@process{% @@ -536,6 +626,25 @@ } +% Retrieve the list of node parts of a shape +% +% #1 = a macro +% #2 = a shape name +% +% Description: +% +% Stores the list of node parts of a shape #2 in the macro #1. +% +% Example: +% +% \pgfgetnodeparts\mylist{circle split} +% +% This will set \mylist\ to "text,lower" + +\def\pgfgetnodeparts#1#2{% + \expandafter\let\expandafter#1\csname pgf@sh@boxes@#2\endcsname% +} + % Declares a shape type % @@ -605,7 +714,7 @@ \long\def\pgfdeclareshape#1#2{% { - \def\shape@name{#1} + \def\pgf@sm@shape@name{#1} \let\savedanchor=\pgf@sh@savedanchor \let\saveddimen=\pgf@sh@saveddimen \let\savedmacro=\pgf@sh@savedmacro% MW @@ -632,48 +741,48 @@ \anchorborder{\csname pgf@anchor@#1@center\endcsname}% \anchor{text}{\pgfpointorigin}% \nodeparts{text}% - \expandafter\global\expandafter\let\csname pgf@sh@s@\shape@name\endcsname=\pgfutil@empty% + \expandafter\global\expandafter\let\csname pgf@sh@s@\pgf@sm@shape@name\endcsname=\pgfutil@empty% #2 } } \def\pgf@sh@savedanchor#1#2{% - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\shape@name\endcsname{\pgf@sh@resavedanchor{#1}{#2}}} + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\pgf@sh@resavedanchor{#1}{#2}}} \def\pgf@sh@saveddimen#1#2{% - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\shape@name\endcsname{\pgf@sh@resaveddimen{#1}{#2}}} + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\pgf@sh@resaveddimen{#1}{#2}}} \def\pgf@sh@savedmacro#1#2{% MW - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\shape@name\endcsname{\pgf@sh@resavedmacro{#1}{#2}}}% MW -\def\pgf@sh@anchor#1#2{\expandafter\gdef\csname pgf@anchor@\shape@name @#1\endcsname{#2}} + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\pgf@sh@resavedmacro{#1}{#2}}}% MW +\def\pgf@sh@anchor#1#2{\expandafter\gdef\csname pgf@anchor@\pgf@sm@shape@name @#1\endcsname{#2}} \def\pgf@sh@deferredanchor#1#2{% CJ \expandafter\pgfutil@g@addto@macro - \csname pgf@sh@s@\shape@name\endcsname{\pgf@sh@redeferredanchor{#1}{#2}}}% CJ -\def\pgf@sh@anchorborder#1{\expandafter\gdef\csname pgf@anchor@\shape@name @border\endcsname##1{\pgf@process{##1}#1}} -\long\def\pgf@sh@behindbgpath#1{\expandafter\gdef\csname pgf@sh@bbg@\shape@name\endcsname{#1}} -\long\def\pgf@sh@bgpath#1{\expandafter\gdef\csname pgf@sh@bg@\shape@name\endcsname{#1}} -\long\def\pgf@sh@beforebgpath#1{\expandafter\gdef\csname pgf@sh@fbg@\shape@name\endcsname{#1}} -\long\def\pgf@sh@behindfgpath#1{\expandafter\gdef\csname pgf@sh@bfg@\shape@name\endcsname{#1}} -\long\def\pgf@sh@fgpath#1{\expandafter\gdef\csname pgf@sh@fg@\shape@name\endcsname{#1}} -\long\def\pgf@sh@beforefgpath#1{\expandafter\gdef\csname pgf@sg@ffg@\shape@name\endcsname{#1}} -\def\pgf@sh@boxes#1{\expandafter\gdef\csname pgf@sh@boxes@\shape@name\endcsname{#1}} + \csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\pgf@sh@redeferredanchor{#1}{#2}}}% CJ +\def\pgf@sh@anchorborder#1{\expandafter\gdef\csname pgf@anchor@\pgf@sm@shape@name @border\endcsname##1{\pgf@process{##1}#1}} +\long\def\pgf@sh@behindbgpath#1{\expandafter\gdef\csname pgf@sh@bbg@\pgf@sm@shape@name\endcsname{#1}} +\long\def\pgf@sh@bgpath#1{\expandafter\gdef\csname pgf@sh@bg@\pgf@sm@shape@name\endcsname{#1}} +\long\def\pgf@sh@beforebgpath#1{\expandafter\gdef\csname pgf@sh@fbg@\pgf@sm@shape@name\endcsname{#1}} +\long\def\pgf@sh@behindfgpath#1{\expandafter\gdef\csname pgf@sh@bfg@\pgf@sm@shape@name\endcsname{#1}} +\long\def\pgf@sh@fgpath#1{\expandafter\gdef\csname pgf@sh@fg@\pgf@sm@shape@name\endcsname{#1}} +\long\def\pgf@sh@beforefgpath#1{\expandafter\gdef\csname pgf@sh@ffg@\pgf@sm@shape@name\endcsname{#1}} +\def\pgf@sh@boxes#1{\expandafter\gdef\csname pgf@sh@boxes@\pgf@sm@shape@name\endcsname{#1}} \def\pgf@sh@inheritsavedanchors[from=#1]{% - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\shape@name\endcsname{\csname pgf@sh@s@#1\endcsname}} + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\csname pgf@sh@s@#1\endcsname}} \def\pgf@sh@inheritanchor[from=#1]#2{% \edef\pgf@marshal{\global\let\expandafter\noexpand\csname - pgf@anchor@\shape@name @#2\endcsname=\expandafter\noexpand\csname + pgf@anchor@\pgf@sm@shape@name @#2\endcsname=\expandafter\noexpand\csname pgf@anchor@#1@#2\endcsname}% \pgf@marshal% } \def\pgf@sh@inheritanchorborder[from=#1]{% \edef\pgf@marshal{\global\let\expandafter\noexpand\csname - pgf@anchor@\shape@name @border\endcsname=\expandafter\noexpand\csname + pgf@anchor@\pgf@sm@shape@name @border\endcsname=\expandafter\noexpand\csname pgf@anchor@#1@border\endcsname}% \pgf@marshal% } \def\pgf@sh@inheritor#1#2{% \edef\pgf@marshal{\global\let\expandafter\noexpand\csname - pgf@sh@#1@\shape@name\endcsname=\expandafter\noexpand\csname + pgf@sh@#1@\pgf@sm@shape@name\endcsname=\expandafter\noexpand\csname pgf@sh@#1@#2\endcsname}% \pgf@marshal% } @@ -932,6 +1041,15 @@ } +% Special current path start coordinate: +\expandafter\def\csname pgf@sh@ns@current subpath start\endcsname{coordinate} +\expandafter\def\csname pgf@sh@np@current subpath start\endcsname{% + \def\centerpoint{\expandafter\pgfqpoint\pgfsyssoftpath@lastmoveto}% +} +\expandafter\def\csname pgf@sh@nt@current subpath start\endcsname{{1}{0}{0}{1}{0pt}{0pt}} +\expandafter\def\csname pgf@sh@pi@current subpath start\endcsname{\pgfpictureid} + + % Special current bounding box rectangle: \expandafter\def\csname pgf@sh@ns@current bounding box\endcsname{rectangle} @@ -956,8 +1074,8 @@ % Special current page bounding box rectangle: \expandafter\def\csname pgf@sh@ns@current page\endcsname{rectangle} \expandafter\def\csname pgf@sh@np@current page\endcsname{% - \def\southwest{\pgfqpoint{0pt}{0pt}}% - \def\northeast{\pgfqpoint{\paperwidth}{\paperheight}}% + \def\southwest{\pgfpointorigin}% + \def\northeast{\pgfpoint{\pgfsys@thepagewidth}{\pgfsys@thepageheight}}% } \expandafter\def\csname pgf@sh@nt@current page\endcsname{{1}{0}{0}{1}{0pt}{0pt}} \expandafter\def\csname pgf@sh@pi@current page\endcsname{pgfpageorigin} @@ -978,7 +1096,20 @@ \expandafter\gdef\csname pgf@lbb@miny@#1\endcsname{16000pt}% \pgf@size@hookedtrue% \expandafter\def\expandafter\pgf@path@size@hook\expandafter{\pgf@path@size@hook\pgf@lbb@do{#1}} - }% + }, + /pgf/freeze local bounding box/.code={% + {% + \csname pgf@sh@np@#1\endcsname% + \southwest% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \northeast% + \expandafter\xdef\csname pgf@sh@np@#1\endcsname{% + \noexpand\def\noexpand\southwest{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}% + \noexpand\def\noexpand\northeast{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + }% + }% + } } \def\pgf@lbb@do#1{% \ifdim\pgf@size@hook@x<\csname pgf@lbb@minx@#1\endcsname\expandafter\xdef\csname pgf@lbb@minx@#1\endcsname{\the\pgf@size@hook@x}\fi% @@ -1121,7 +1252,7 @@ % % Background path % - \backgroundpath{ + \backgroundpath{% \pgfutil@tempdima=\radius% \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}% \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}% diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulesnakes.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulesnakes.code.tex index 0d3ad5dfdeb..5f6479a1d7b 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulesnakes.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulesnakes.code.tex @@ -7,10 +7,9 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulesnakes.code.tex,v 1.2 2008/01/17 20:09:17 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulesnakes.code.tex,v 1.3 2013/07/15 12:05:34 tantau Exp $ -\PackageWarning{pgf}{Snakes have been superseded by decorations. Use -the module decorations instead of snakes} +\pgfwarning{Snakes have been superseded by decorations. Use the module decorations instead of snakes} \usepgfmodule{decorations} @@ -251,7 +250,7 @@ the module decorations instead of snakes} % \pgfpathsnakealongvector{zig zag}{100pt}{\pgfpolar{30}{1pt}} \def\pgfpathsnakealongvector#1#2#3{% - \pgfutil@ifundefined{pgf@snake@@#1@initial}{\PackageError{pgf}{Undefined snake ``#1''}{}} + \pgfutil@ifundefined{pgf@snake@@#1@initial}{\pgferror{Undefined snake ``#1''}} { \begingroup% keep things local \pgftransformreset% diff --git a/Master/texmf-dist/tex/generic/pgf/rendering/pgfrenderpoints.code.tex b/Master/texmf-dist/tex/generic/pgf/rendering/pgfrenderpoints.code.tex deleted file mode 100644 index 48d36bae8bf..00000000000 --- a/Master/texmf-dist/tex/generic/pgf/rendering/pgfrenderpoints.code.tex +++ /dev/null @@ -1,138 +0,0 @@ -% Copyright 2006 by Till Tantau -% -% This file may be distributed and/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 details. - -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/rendering/pgfrenderpoints.code.tex,v 1.2 2007/03/09 17:49:33 tantau Exp $ - - - - - -% Create a 3D point -% -% #1 = macro name in which the point object should be stored -% #2 to #4 = x-, y- and z-coordinate of the point -% -% Note: -% -% The quick version does not call \setlength and is faster. -% -% Example: -% -% \pgfrenderpointcreate{\pgfpoint{2pt+3cm}{3cm}} - -\def\pgfrenderpointcreate#1#2#3#4{% - \pgfmathsetlength\pgf@xa{#2}% - \pgfmathsetlength\pgf@xb{#3}% - \pgfmathsetlength\pgf@xc{#4}% - \pgfqrenderpointcreate{\the\pgf@xa}{\the\pgf@xb}{\the\pgf@xc}% -} - -\def\pgfqrenderpointcreate#1#2#3#4{% - \edef#1{\pgf@xa=#2\relax\pgf@xb=#3\pgf@xc=#4\relax}% -} - -\def\pgf@render@unpack#1{% - #1% -} - - -% The origin point object -% -% Description: -% -% This object is always the origin. -% - -\pgfqrenderpointcreate\pgfrenderobjorigin{0pt}{0pt}{0pt} - - - - -% Add two 3D vectors -% -% #1 = name of new vector (may be one of the input) -% #2 = name of first vector -% #3 = name of second vector -% -% Description: -% -% The points #2 and #3 are added and the result is stored in #1. If #1 -% equals either #2 or #3, to point is overwritten. -% -% Example: -% -% \pgfrenderpointcreate{\myvec}{1cm}{2cm}{3cm} -% \pgfrenderpointcreate{\offset}{1cm}{0cm}{0cm} -% \pgfrenderpointadd{\myvec}{\myvec}{\offset} - -\def\pgfrenderpointadd#1#2#3{% - \pgf@render@unpack#2% - \pgf@ya=\pgf@xa% - \pgf@yb=\pgf@xb% - \pgf@yc=\pgf@xc% - \pgf@render@unpack#3% - \advance\pgf@xa by\pgf@ya% - \advance\pgf@xb by\pgf@yb% - \advance\pgf@xc by\pgf@yc% - \pgfqrenderpointcreate#1{\the\pgf@xa}{\the\pgf@xb}{\the\pgf@xc}% -} - - -% Scale a 3D vectors -% -% #1 = name of new vector (may be one of the input) -% #2 = scale -% #3 = name of vector to be scaled -% -% Description: -% -% Sets #1 := #2*#3. -% -% Example: -% -% \pgfrenderpointcreate{\myvec}{1cm}{2cm}{3cm} -% \pgfrenderpointscale{\myvec}{2}{\myvec} - -\def\pgfrenderpointscale#1#2#3{% - \pgf@render@unpack#3% - \pgf@xa=#2\pgf@xa% - \pgf@xb=#2\pgf@xb% - \pgf@xc=#2\pgf@xc% - \pgfqrenderpointcreate#1{\the\pgf@xa}{\the\pgf@xb}{\the\pgf@xc}% -} - - - - -% Project a 3D point to 2D -% -% #1 = 3D point object -% -% Description: -% -% This command takes a 3D point object and sets \pgf@x to the x-value -% of the point and \pgf@y to the y-value. -% -% Example: -% -% \pgfpointprojection{\mypoint} - -\def\pgfpointprojection#1{% - \pgf@render@unpack{#1}% - \pgf@x=\pgf@xa% - \pgf@y=\pgf@ya% -} - - - - - - - -\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/rendering/pgfrendertransform.code.tex b/Master/texmf-dist/tex/generic/pgf/rendering/pgfrendertransform.code.tex deleted file mode 100644 index fb6802e9f1c..00000000000 --- a/Master/texmf-dist/tex/generic/pgf/rendering/pgfrendertransform.code.tex +++ /dev/null @@ -1,117 +0,0 @@ -% Copyright 2006 by Till Tantau -% -% This file may be distributed and/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 details. - -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/rendering/pgfrendertransform.code.tex,v 1.1 2006/11/12 14:18:46 tantau Exp $ - - - - -% Create a 3D transformation matrix -% -% #1 = macro name in which the transformation matrix should be stored -% #2 = three comma-separated numbers, representing the first line of -% the matrix. -% #3 = three numbers, representing the second line of the matrix. -% #4 = three numbers, representing the thrid line of the matrix. -% #5 = 3D point object, used for the offset. -% -% Example: -% -% \pgfrendertransformcreate{\mymatrix}{1,0,0}{0,1,0}{0,0,1}{\pgfrenderobjorigin} - -\def\pgfrendertransformcreate#1#2#3#4#5{% - \pgf@render@unpack#5% - \edef#1{{#2}{#3}{#4}{\pgf@xa=\the\pgf@xa\pgf@xb=\the\pgf@xb\pgf@xc=\the\pgf@xc}}% -} - - - -% Apply a 3D transformation matrix to a 3D point -% -% #1 = new point (may be the old point) (#1 := #2*#3) -% #2 = transformation matrix object -% #3 = point to be transformed -% -% Example: -% -% \pgfrendertransform{\newvec}{\mymatrix}{\oldvec} - -\def\pgfrendertransform#1#2#3{% - \pgf@render@unpack#3% - \expandafter\pgf@rendertransform#2% - \pgf@xa=\pgf@ya% - \pgf@xb=\pgf@yb% - \pgf@xc=\pgf@yc% -} - -\def\pgf@rendertransform#1#2#3#4{% - \pgf@@rendertransform\pgf@ya#1\relax% - \pgf@@rendertransform\pgf@yb#2\relax% - \pgf@@rendertransform\pgf@yc#3\relax% - #4% - \advance\pgf@ya by \pgf@xa% - \advance\pgf@yb by \pgf@xb% - \advance\pgf@yc by \pgf@xc% -} - -\def\pgf@@rendertransform#1#2,#3,#4\relax{% - #1=#2\pgf@xa% - \advance#1by#3\pgf@xb% - \advance#1by#4\pgf@xc% -} - - - -% Concatenate two 3D transformation matrices -% -% #1 = new matrix, (#1 := #2*#3) -% #2 = first matrix -% #3 = second matrix -% -% Example: -% -% \pgfrendertransformconcat{\mymatrix}{\rotationmatrix}{\mymatrix} - -\def\pgfrendertransformconcat#1#2#3{% - \expandafter\pgf@render@extract@columns#3% - \pgfrendertransform\pgf@render@temp@a#2\pgf@render@temp@a% - \pgfrendertransform\pgf@render@temp@b#2\pgf@render@temp@b% - \pgfrendertransform\pgf@render@temp@c#2\pgf@render@temp@c% - \pgfrendertransform\pgf@render@temp@d#2\pgf@render@temp@d% - \pgf@render@unpack\pgf@render@temp@a% - \edef\pgf@temp@a{\pgf@sys@tonumber\pgf@xa}% - \edef\pgf@temp@b{\pgf@sys@tonumber\pgf@xb}% - \edef\pgf@temp@c{\pgf@sys@tonumber\pgf@xc}% - \pgf@render@unpack\pgf@render@temp@b% - \edef\pgf@temp@a{\pgf@temp@a,\pgf@sys@tonumber\pgf@xa}% - \edef\pgf@temp@b{\pgf@temp@b,\pgf@sys@tonumber\pgf@xb}% - \edef\pgf@temp@c{\pgf@temp@c,\pgf@sys@tonumber\pgf@xc}% - \pgf@render@unpack\pgf@render@temp@c% - \edef\pgf@temp@a{\pgf@temp@a,\pgf@sys@tonumber\pgf@xa}% - \edef\pgf@temp@b{\pgf@temp@b,\pgf@sys@tonumber\pgf@xb}% - \edef\pgf@temp@c{\pgf@temp@c,\pgf@sys@tonumber\pgf@xc}% - \pgfrendertransformcreate#1{\pgf@temp@a}{\pgf@temp@b}{\pgf@temp@c}{\pgf@render@temp@c}% -} - -\def\pgf@render@extract@columns#1#2#3#4{% - \pgf@@render@extract@columns#1,#2,#3\relax% - \def\pgf@render@temp@d{#4}% -} - -\def\pgf@@render@extract@columns#1,#2,#3,#4,#5,#6,#7,#8,#9\relax{% - \pgfqrenderpointcreate\pgf@render@temp@a{#1pt}{#4pt}{#7pt}% - \pgfqrenderpointcreate\pgf@render@temp@b{#2pt}{#5pt}{#8pt}% - \pgfqrenderpointcreate\pgf@render@temp@c{#3pt}{#6pt}{#9pt}% -} - - - - - -\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf-via-dvi.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf-via-dvi.def index 5cbf2fd66ca..1605a956260 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf-via-dvi.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf-via-dvi.def @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-common-pdf-via-dvi.def,v 1.7 2008/05/19 12:52:49 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-common-pdf-via-dvi.def,v 1.8 2013/07/12 13:52:50 tantau Exp $ % Common driver commands for all drivers that produce pdf via the % detour of a dvi file @@ -23,6 +23,7 @@ % not show anything {\hbox to 0pt{\pgfutil@font@normalfont\pgfutil@selectfont.\hss}}% enforce font change \pgfsys@invoke{0 Tr}% + \pgfsys@invoke{0 J [] 0 d}% reset line cap and dash \wd#1=0pt% \ht#1=0pt% \dp#1=0pt% @@ -41,6 +42,7 @@ \pgflowlevelsynccm% \pgfsys@invoke{q -1 0 0 -1 0 0 cm}% \special{pdf: content -1 0 0 -1 0 0 cm q}% translate to original coordinate system + \pgfsys@invoke{0 J [] 0 d}% reset line cap and dash \wd#1=0pt% \ht#1=0pt% \dp#1=0pt% diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf.def index c48d1c15238..32906ad3b64 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf.def @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-common-pdf.def,v 1.10 2008/05/19 12:52:49 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-common-pdf.def,v 1.13 2013/10/10 12:00:15 tantau Exp $ % Common driver commands for all drivers that produce pdf @@ -63,7 +63,6 @@ % Opacity \def\pgfsys@stroke@opacity#1{% \expandafter\ifx\csname pgf@sys@pdf@so@#1\endcsname\relax% - % Hmm... define... \expandafter\gdef\csname pgf@sys@pdf@so@#1\endcsname{/pgf@CA#1}% \pgfutil@addpdfresource@extgs{/pgf@CA#1 << /CA #1 >>}%<< \fi% @@ -71,13 +70,40 @@ } \def\pgfsys@fill@opacity#1{% \expandafter\ifx\csname pgf@sys@pdf@fo@#1\endcsname\relax% - % Hmm... define... \expandafter\gdef\csname pgf@sys@pdf@fo@#1\endcsname{/pgf@ca#1}% \pgfutil@addpdfresource@extgs{/pgf@ca#1 << /ca #1 >>}%<< \fi% \pgfsysprotocol@literal{\csname pgf@sys@pdf@fo@#1\endcsname\space gs}% } - +\def\pgfsys@blend@mode#1{% + \expandafter\ifx\csname pgf@sys@pdf@bm@#1\endcsname\relax% + \expandafter\let\expandafter\pgf@temp\csname pgf@sys@pdf@blend@mode@map@#1\endcsname% + \expandafter\xdef\csname pgf@sys@pdf@bm@#1\endcsname{/pgf@bm\pgf@temp}% + \ifx\pgf@temp\relax% + \pgferror{Unknown blend mode '#1'}% + \def\pgf@temp{Normal}% + \fi% + \edef\pgf@temp{/pgf@bm\pgf@temp << /BM [ /\pgf@temp ] >>}%<< + \expandafter\pgfutil@addpdfresource@extgs\expandafter{\pgf@temp}% + \fi% + \pgfsysprotocol@literal{\csname pgf@sys@pdf@bm@#1\endcsname\space gs}% +} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@normal\endcsname{Normal} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@multiply\endcsname{Multiply} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@screen\endcsname{Screen} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@overlay\endcsname{Overlay} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@darken\endcsname{Darken} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@lighten\endcsname{Lighten} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@color dodge\endcsname{ColorDodge} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@color burn\endcsname{ColorBurn} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@hard light\endcsname{HardLight} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@soft light\endcsname{SoftLight} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@difference\endcsname{Difference} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@exclusion\endcsname{Exclusion} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@saturation\endcsname{Saturation} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@color\endcsname{Color} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@hue\endcsname{Hue} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@luminosity\endcsname{Luminosity} \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-svg.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-svg.def index fa1cf889bd4..f2edbedf3c9 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-svg.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-svg.def @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-common-svg.def,v 1.21 2009/03/20 10:31:30 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-common-svg.def,v 1.24 2013/08/28 11:00:54 tantau Exp $ % Driver commands for svg @@ -26,13 +26,16 @@ \def\pgf@sys@addtosvgpath#1{\pgfutil@g@addto@macro\pgf@sys@svgpath{#1\space}} \def\pgf@sys@flushsvgpath{\pgfsysprotocol@literal{\pgf@sys@svgpath}\global\let\pgf@sys@svgpath=\pgfutil@empty} \def\pgf@sys@svg@gs#1{% - {\pgfsysprotocol@literal{<g #1>\Hnewline }}\global\advance\pgf@sys@svg@scopecount by1\relax% + {\pgfsysprotocol@literal{<g #1>\pgfsys@svg@newline }}\global\advance\pgf@sys@svg@scopecount by1\relax% } \newcount\pgf@sys@svg@objectcount -\let\Hnewline=\pgfutil@empty -\catcode`\%=12 -\def\pgf@sys@svg@percentchar{%} -\catcode`\%=14 + +{\catcode`\%=12 +\gdef\pgf@sys@svg@percentchar{%} +} +{\catcode`\#=11 +\gdef\pgf@sys@svg@hash{#} +} % Path construction: \def\pgfsys@lineto#1#2{\pgf@sys@addtosvgpath{L }\pgf@sys@svgnum{#1}\pgf@sys@svgnum{#2}} @@ -58,14 +61,14 @@ \pgfsysprotocol@literal{<clipPath id="pgfcp\the\pgf@sys@svg@objectcount"> <path id="pgfpath\the\pgf@sys@svg@objectcount" d="}% \pgf@sys@flushsvgpath% - \pgfsysprotocol@literal{"/>\Hnewline </clipPath>\Hnewline } - \pgfsysprotocol@literal{<use xlink:href="\#pgfpath\the\pgf@sys@svg@objectcount" #1/>\Hnewline }% + \pgfsysprotocol@literal{"/>\pgfsys@svg@newline </clipPath>\pgfsys@svg@newline } + \pgfsysprotocol@literal{<use xlink:href="\#pgfpath\the\pgf@sys@svg@objectcount" #1/>\pgfsys@svg@newline }% \pgf@sys@svg@gs{clip-path="url(\#pgfcp\the\pgf@sys@svg@objectcount)"} \pgf@sys@svg@clipnextfalse% \else% \pgfsysprotocol@literal{<path d="}% \pgf@sys@flushsvgpath% - \pgfsysprotocol@literal{" #1/>\Hnewline } + \pgfsysprotocol@literal{" #1/>\pgfsys@svg@newline } \fi% } \def\pgfsys@stroke{\pgf@sys@svg@possiblyclippedpath{style="fill:none"}} @@ -78,7 +81,7 @@ \pgfsysprotocol@literal{<clipPath id="pgfcp\the\pgf@sys@svg@objectcount"> <path d="}% \pgf@sys@flushsvgpath% - \pgfsysprotocol@literal{"/>\Hnewline </clipPath>\Hnewline } + \pgfsysprotocol@literal{"/>\pgfsys@svg@newline </clipPath>\pgfsys@svg@newline } \pgf@sys@svg@gs{clip-path="url(\#pgfcp\the\pgf@sys@svg@objectcount)"} \pgf@sys@svg@clipnextfalse% \else% @@ -91,7 +94,15 @@ % Transparency: \def\pgfsys@stroke@opacity#1{\pgf@sys@svg@gs{stroke-opacity="#1"}} -\def\pgfsys@fill@opacity#1{\pgf@sys@svg@gs{fill-opacity="#1"}} +\def\pgfsys@fill@opacity#1{\pgf@sys@svg@gs{fill-opacity="#1"}\def\pgf@sys@svg@opacity{#1}} +\def\pgf@sys@svg@opacity{1} +\def\pgfsys@transparencygroupfrombox#1{% + \setbox#1=\hbox{% + \pgfsys@invoke{<g opacity="\pgf@sys@svg@opacity" stroke-opacity="1" fill-opacity="1">\pgfsys@svg@newline }% + \box#1% + \pgfsys@invoke{</g>\pgfsys@svg@newline }% + }% +} % Transformation: \def\pgfsys@transformcm#1#2#3#4#5#6{% @@ -104,11 +115,11 @@ \edef\pgf@sys@svg@thescopecount{\the\pgf@sys@svg@scopecount}% \begingroup% \pgf@sys@svg@scopecount=1\relax% - \pgfsysprotocol@literal{<g>\Hnewline }% + \pgfsysprotocol@literal{<g>\pgfsys@svg@newline }% } \def\pgfsys@endscope{% \loop% - \pgfsysprotocol@literal{</g>\Hnewline }% + \pgfsysprotocol@literal{</g>\pgfsys@svg@newline }% \advance\pgf@sys@svg@scopecount by-1\relax% \ifnum\pgf@sys@svg@scopecount>0\relax% \repeat% @@ -138,8 +149,6 @@ % Color management % -\def\XC@mcolor{\ifpgfpicture\pgfsetcolor{.}\fi} - \def\pgf@sys@svg@color@rgb#1,#2,#3\relax{% {% \pgf@xa=#1pt% @@ -257,7 +266,7 @@ \divide\pgf@x by \c@pgf@counta\relax% \pgf@sys@svg@addtostops{\pgf@sys@tonumber\pgf@x" stop-color="}% \pgf@sys@svg@shading@dorgb#3% - \pgf@sys@svg@addtostops{"/>\noexpand\Hnewline}% + \pgf@sys@svg@addtostops{"/>\noexpand\pgfsys@svg@newline}% } \def\pgf@sys@svg@shading@dorgb#1#2#3{% \pgf@sys@svg@color@rgb#1,#2,#3\relax% @@ -277,9 +286,9 @@ {% \pgf@parsefunc{#3}% \global\advance\pgf@sys@svg@objectcount by1\relax% - \pgf@sys@svg@addtostops{<linearGradient id="pgfsh\the\pgf@sys@svg@objectcount">\noexpand\Hnewline} + \pgf@sys@svg@addtostops{<linearGradient id="pgfsh\the\pgf@sys@svg@objectcount">\noexpand\pgfsys@svg@newline} \pgf@sys@svg@shading@stops% - \pgf@sys@svg@addtostops{</linearGradient>\noexpand\Hnewline}% + \pgf@sys@svg@addtostops{</linearGradient>\noexpand\pgfsys@svg@newline}% \pgf@process{\pgfpoint{\pgf@sys@shading@end@pos}{#2}}% \expandafter\xdef\csname @pgfshading#1!\endcsname{% \def\noexpand\pgf@sys@svg@sh@defs{\noexpand\pgfsysprotocol@literal{\pgf@sys@svg@thestops}}% @@ -287,7 +296,7 @@ width="\pgf@sys@tonumber{\pgf@x}" height="\pgf@sys@tonumber{\pgf@y}" style="fill:url(\noexpand\#pgfsh\the\pgf@sys@svg@objectcount); - stroke:none"/>\noexpand\Hnewline}}% + stroke:none"/>\noexpand\pgfsys@svg@newline}}% \def\noexpand\pgf@sys@svg@pos{\noexpand\pgfpoint{\the\pgf@x}{\the\pgf@y}}% }% }% @@ -308,9 +317,9 @@ \global\advance\pgf@sys@svg@objectcount by1\relax% \pgf@sys@svg@addtostops{<linearGradient id="pgfsh\the\pgf@sys@svg@objectcount" - gradientTransform="rotate(90)">\noexpand\Hnewline} + gradientTransform="rotate(90)">\noexpand\pgfsys@svg@newline} \pgf@sys@svg@shading@stops% - \pgf@sys@svg@addtostops{</linearGradient>\noexpand\Hnewline}% + \pgf@sys@svg@addtostops{</linearGradient>\noexpand\pgfsys@svg@newline}% \pgf@process{\pgfpoint{\pgf@sys@shading@end@pos}{#2}}% \expandafter\xdef\csname @pgfshading#1!\endcsname{% \def\noexpand\pgf@sys@svg@sh@defs{\noexpand\pgfsysprotocol@literal{\pgf@sys@svg@thestops}}% @@ -318,7 +327,7 @@ width="\pgf@sys@tonumber{\pgf@y}" height="\pgf@sys@tonumber{\pgf@x}" style="fill:url(\noexpand\#pgfsh\the\pgf@sys@svg@objectcount); - stroke:none"/>\noexpand\Hnewline}}% + stroke:none"/>\noexpand\pgfsys@svg@newline}}% \def\noexpand\pgf@sys@svg@pos{\noexpand\pgfpoint{\the\pgf@y}{\the\pgf@x}}% }% }% @@ -343,9 +352,9 @@ id="pgfsh\the\pgf@sys@svg@objectcount" fx="\pgf@sys@tonumber\pgf@x" fy="\pgf@sys@tonumber\pgf@y" - >\noexpand\Hnewline} + >\noexpand\pgfsys@svg@newline} \pgf@sys@svg@shading@stops% - \pgf@sys@svg@addtostops{</radialGradient>\noexpand\Hnewline}% + \pgf@sys@svg@addtostops{</radialGradient>\noexpand\pgfsys@svg@newline}% \pgf@xa=\pgf@sys@shading@end@pos% \pgf@xb=2\pgf@xa% \expandafter\xdef\csname @pgfshading#1!\endcsname{% @@ -355,7 +364,7 @@ cy="\pgf@sys@tonumber{\pgf@xa}" r="\pgf@sys@tonumber{\pgf@xa}" style="fill:url(\noexpand\#pgfsh\the\pgf@sys@svg@objectcount); - stroke:none"/>\noexpand\Hnewline}}% + stroke:none"/>\noexpand\pgfsys@svg@newline}}% \def\noexpand\pgf@sys@svg@pos{\noexpand\pgfpoint{\the\pgf@xb}{\the\pgf@xb}}% }% }% @@ -364,6 +373,8 @@ % Patterns +\iffalse % comment until interpage support is available + \def\pgfsys@declarepattern#1#2#3#4#5#6#7#8#9{% % Start building the pattern dictionary: \pgf@xa=#2\relax% @@ -410,6 +421,36 @@ \pgf@sys@svg@gs@color{fill="url(\#pgfpat#1)"}% } +\fi + + + + +% Fadings + +% +% Opacity masks +% +% \def\pgfsys@fadingfrombox#1#2{% +% \setbox#2=\hbox{% +% \pgfsys@invoke{<mask id="pgfmask#1">}% +% \box#2% +% \pgfsys@invoke{</mask>}% +% }% +% \wd#2=0pt% +% \ht#2=0pt% +% \dp#2=0pt% +% \unskip\box#2% +% } +% \def\pgfsys@usefading#1#2#3#4#5#6#7{% +% \pgf@sys@svg@gs@color{mask="url(\#pgfmask#1)"}% +% } + + + +% + +\def\pgfutil@color{\pgfsetcolor} \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvipdfm.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvipdfm.def index 4124784d999..0ad85414779 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvipdfm.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvipdfm.def @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-dvipdfm.def,v 1.19 2008/05/14 16:05:56 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-dvipdfm.def,v 1.21 2013/07/16 16:03:13 tantau Exp $ % Driver commands for dvipdfm @@ -23,6 +23,13 @@ \def\pgfsys@invoke#1{\special{pdf: content Q #1 q}} % ugly, but necessary... +\def\pgfsys@papersize#1#2{% +% \expandafter\gdef\expandafter\pgfsys@atbegindocument% +% \expandafter{\pgfsys@atbegindocument + \special{papersize=#1,#2}% +% } +} + % % Position tracking (needs pdftex >= 1.40.0-alpha-20051205 in dvi mode) diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvipdfmx.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvipdfmx.def index b9669434a4a..a5806aeab78 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvipdfmx.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvipdfmx.def @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-dvipdfmx.def,v 1.3 2009/05/22 07:25:48 jinhwancho Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-dvipdfmx.def,v 1.12 2013/08/28 11:00:54 tantau Exp $ % Driver commands for dvipdfmx % @@ -20,6 +20,7 @@ % \input pgfsys-common-pdf.def + % For unique object name: \newcount\pgfsys@objnum\pgfsys@objnum\@ne @@ -38,41 +39,65 @@ % To avoid this problem, we need to change the color temporarily to another. % % We assume that black is the default color when no color is specified. -\def\start@force@reset@color{% +\def\pgfsys@dvipdfmx@start@force@reset@color{% \special{pdf:bcolor [1]}% \special{pdf:bcolor [0]}% } -\def\stop@force@reset@color{% +\def\pgfsys@dvipdfmx@stop@force@reset@color{% \special{pdf:ecolor}% \special{pdf:ecolor}% } + +\def\pgfsys@dvipdfmx@suspendcontent{% + \special{pdf:code q -1 0 0 -1 0 0 cm q}% + \special{pdf: econtent}% + \special{pdf: bcontent}% + \special{pdf:code -1 0 0 -1 0 0 cm}% + \special{pdf:code q}% translate to original system + \special{pdf: econtent}% +} + +\def\pgfsys@dvipdfmx@unsuspendcontent{% + \special{pdf: bcontent}% + \special{pdf:code Q Q Q}% +} + +\def\pgfsys@hbox#1{% + \pgfsys@beginscope% + \setbox#1=\hbox{\box#1}% + \wd#1=0pt% + \ht#1=0pt% + \dp#1=0pt% + \pgfsys@dvipdfmx@suspendcontent% + \pgfsys@invoke{0 J [] 0 d}% reset line cap and dash + \pgfsys@dvipdfmx@start@force@reset@color% + \box#1% + \pgfsys@dvipdfmx@stop@force@reset@color% + \pgfsys@dvipdfmx@unsuspendcontent% + \pgfsys@endscope% +} + % We cannot use many codes in pgfsys-common-pdf-via-dvi.def. % So it is rewritten here (with some bugs fixed). \def\pgfsys@hboxsynced#1{% - {% - \pgfsys@beginscope% - \setbox\pgf@hbox=\hbox{% - \hskip\pgf@pt@x% - \raise\pgf@pt@y\hbox{% - \pgf@pt@x=0pt% - \pgf@pt@y=0pt% - % The order of `pdf:bcontent' is important here. It should be - % followed by \pgflowlevelsynccm, not reverse order. - \special{pdf:bcontent}% - \pgflowlevelsynccm% - \start@force@reset@color% - \pgfsys@hbox#1% - \stop@force@reset@color% - \special{pdf:econtent}}% - \hss% - }% - \wd\pgf@hbox=0pt% - \ht\pgf@hbox=0pt% - \dp\pgf@hbox=0pt% - \box\pgf@hbox% - \pgfsys@endscope% - }% + \pgfsys@beginscope% + \setbox#1=\hbox{\box#1}% + \wd#1=0pt% + \ht#1=0pt% + \dp#1=0pt% + \pgfsys@dvipdfmx@suspendcontent% + \pgfsys@invoke{0 J [] 0 d}% reset line cap and dash + \pgfsys@dvipdfmx@start@force@reset@color% + \pgf@sys@bp@correct\pgf@pt@x% + \pgf@sys@bp@correct\pgf@pt@y% + \special{pdf:btrans matrix \pgf@pt@aa\space \pgf@pt@ab\space \pgf@pt@ba\space \pgf@pt@bb\space + \pgf@sys@tonumber{\pgf@pt@x} \pgf@sys@tonumber{\pgf@pt@y}}% + \box#1% + \special{pdf:etrans}% + \pgfsys@dvipdfmx@stop@force@reset@color% + \pgfsys@dvipdfmx@unsuspendcontent% + \pgfsys@endscope% } % All text materials between `pdf:bcontent' and `pdf:econtent' are @@ -202,7 +227,7 @@ \def\pgfsys@markposition##1{% \pdfsavepos% \edef\pgf@temp{##1}% - \expandafter\write\expandafter\pgfutil@auxout\expandafter{% + \expandafter\pgfutil@writetoaux\expandafter{% \expandafter\noexpand\expandafter\pgfsyspdfmark\expandafter{\pgf@temp}{\the\pdflastxpos}{\the\pdflastypos}}% } \def\pgfsyspdfmark##1##2##3{% @@ -272,7 +297,7 @@ % Image Mask came from pgfsys-pdftex.def % generic/pgf/basiclayer/pgfcoreimage.code.tex must be modified! \def\pgfsys@defineimage{% width, height, page number - \ifx\includegraphics\relax + \ifx\includegraphics\undefined \ifx\pgf@imagewidth\pgfutil@empty\edef\pgf@imagewidth{1bp}\fi% width? \ifx\pgf@imageheight\pgfutil@empty\edef\pgf@imageheight{1bp}\fi% height? \ifx\pgf@imagepage\pgfutil@empty\else\edef\pgf@imagepage{ page \pgf@imagepage}\fi% @@ -316,18 +341,32 @@ \pgf@sys@bp@correct\pgf@xc% \pgf@sys@bp@correct\pgf@yc% % Now create the pattern object: - \special{pdf:stream @pgf@patternobject@#1 (#8) - << /Type /Pattern - /PatternType 1 - /PaintType \ifnum#9=0 2 \else 1 \fi - /TilingType 1 - /BBox [\pgf@sys@tonumber\pgf@xa\space\pgf@sys@tonumber\pgf@ya\space\pgf@sys@tonumber\pgf@xb\space\pgf@sys@tonumber\pgf@yb] - /XStep \pgf@sys@tonumber\pgf@xc\space - /YStep \pgf@sys@tonumber\pgf@yc\space - /Resources << >> %<< - >>}% - \pgfutil@addpdfresource@patterns{/pgfpat#1\space @pgf@patternobject@#1}% + \pgfsys@dvipdfmx@patternobj{% + \pgfsys@dvipdfmx@stream{@pgfpatternobject#1}{#8}{% + /Type /Pattern + /PatternType 1 + /PaintType \ifnum#9=0 2 \else 1 \fi + /TilingType 1 + /BBox [\pgf@sys@tonumber\pgf@xa\space\pgf@sys@tonumber\pgf@ya\space\pgf@sys@tonumber\pgf@xb\space\pgf@sys@tonumber\pgf@yb] + /XStep \pgf@sys@tonumber\pgf@xc\space + /YStep \pgf@sys@tonumber\pgf@yc\space + /Resources << >> %<< + }% + }% + \pgfutil@addpdfresource@patterns{/pgfpat#1\space @pgfpatternobject#1}% } + +% hook for xdvipdfmx: +\def\pgfsys@dvipdfmx@patternobj#1{% + #1% +}% + +% hook for xdvipdfmx: +\def\pgfsys@dvipdfmx@stream#1#2#3{% + \special{pdf:stream #1 (#2) << #3 >>}% +}% + + \def\pgfsys@setpatternuncolored#1#2#3#4{% \pgfsysprotocol@literal{/pgfprgb cs #2 #3 #4 /pgfpat#1\space scn}% } @@ -356,6 +395,12 @@ \ht#2=0pt% \dp#2=0pt% \box#2% + \special{pdf:put @resources + << + \ifpgf@sys@pdf@extgs@exists /ExtGState @pgfextgs \fi + \ifpgf@sys@pdf@patterns@exists /Pattern @pgfpatterns \fi + \ifpgf@sys@pdf@colorspaces@exists /ColorSpace @pgfcolorspaces \fi + >>}% << \special{pdf:exobj <</Group <</S/Transparency /CS/DeviceGray>> >>}}}\@tempa% \expandafter\xdef\csname pgfsmaskxform@#1\endcsname{\the\pgfsys@objnum}% }% @@ -364,7 +409,7 @@ } \def\pgfsys@usefading#1#2#3#4#5#6#7{% \expandafter\ifx\csname pgfsmaskxform@#1\endcsname\relax% - \PackageError{pgf}{Undefined fading '#1'}{}% + \pgferror{Undefined fading '#1'}% \else% {% \expandafter\ifx\csname pgfsmask@#1\endcsname\relax% @@ -405,7 +450,16 @@ \ht#1=0pt% \dp#1=0pt% \hskip\pgf@picminx bp\box#1\hskip-\pgf@picminx bp% - \special{pdf:exobj <</Group <</S/Transparency>> >>}}}\@tempa% + \special{pdf:put @resources + << + \ifpgf@sys@pdf@extgs@exists /ExtGState @pgfextgs \fi + \ifpgf@sys@pdf@patterns@exists /Pattern @pgfpatterns \fi + \ifpgf@sys@pdf@colorspaces@exists /ColorSpace @pgfcolorspaces \fi + >>}% << + \special{pdf:exobj <</Group << /S /Transparency + /I \ifpgfsys@transparency@group@isolated true \else false \fi + /K \ifpgfsys@transparency@group@knockout true \else false \fi>> >>}% + }}\@tempa% \special{pdf:uxobj @pgftransgroup\the\pgfsys@objnum}% }% \global\advance\pgfsys@objnum\@ne% @@ -421,6 +475,13 @@ \fi \fi +\def\pgfsys@papersize#1#2{% +% \expandafter\gdef\expandafter\pgfsys@atbegindocument%% +% \expandafter{\pgfsys@atbegindocument + \special{papersize=#1,#2}% +% } +} + \endinput %%% Local Variables: diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvips.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvips.def index cec3fa14fda..3847d14a6c8 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvips.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvips.def @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-dvips.def,v 1.20 2008/04/03 17:04:45 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-dvips.def,v 1.23 2013/07/16 16:03:13 tantau Exp $ % Driver commands for dvips @@ -52,7 +52,8 @@ \def\pgfsys@imagesuffixlist{.epsi:.eps:.ps:} \def\pgfsys@papersize#1#2{% - \expandafter\gdef\expandafter\pgfsys@atbegindocument\expandafter{\pgfsys@atbegindocument\special{papersize=#1,#2}}} + \special{papersize=#1,#2}% +}% \expandafter\gdef\expandafter\pgfsys@atbegindocument\expandafter{\pgfsys@atbegindocument\special{papersize=#1,#2}}} \expandafter\gdef\expandafter\pgfsys@atbegindocument\expandafter{\pgfsys@atbegindocument% \pgf@sys@postscript@header{ @@ -74,10 +75,9 @@ /pgfpd{/delta globaldict /pgfdelta get def}bind def % put delta /.setopacityalpha where {pop} {/.setopacityalpha{pop}def} ifelse % install .setopacityalpha /.pgfsetfillopacityalpha{/pgffoa exch def - /pgffill{gsave pgffoa .setopacityalpha fill 1 .setopacityalpha newpath fill grestore}bind def - /pgfeofill{gsave pgffoa .setopacityalpha eofill 1 .setopacityalpha newpath eofill grestore}bind def}bind def - /.pgfsetstrokeopacityalpha{/pgfsoa exch def - /pgfstr{gsave pgfsoa .setopacityalpha stroke grestore}bind def}bind def + /pgffill{gsave pgffoa .setopacityalpha fill 1 .setopacityalpha newpath fill grestore newpath}bind def + /pgfeofill{gsave pgffoa .setopacityalpha eofill 1 .setopacityalpha newpath eofill grestore newpath}bind def}bind def + /.pgfsetstrokeopacityalpha{/pgfsoa exch def /pgfstr{gsave pgfsoa .setopacityalpha stroke grestore newpath}bind def}bind def /pgffoa 1 def /pgfsoa 1 def end @@ -101,7 +101,7 @@ \def\pgfsys@markposition#1{% \pdfsavepos% \edef\pgf@temp{#1}% - \expandafter\write\expandafter\pgfutil@auxout\expandafter{% + \expandafter\pgfutil@writetoaux\expandafter{% \expandafter\noexpand\expandafter\pgfsyspdfmark\expandafter{\pgf@temp}{\the\pdflastxpos}{\the\pdflastypos}}% } diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvisvgm.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvisvgm.def new file mode 100644 index 00000000000..6225c5abc21 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvisvgm.def @@ -0,0 +1,78 @@ +% Copyright 2006 by Till Tantau +% +% This file may be distributed and/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 details. + +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-dvisvgm.def,v 1.3 2013/08/23 09:50:22 tantau Exp $ + + +% Driver commands for dvisvgm + +% +% Load common pdf commands: +% +\input pgfsys-common-svg.def + +\def\pgfsys@invoke#1{{\let\#\pgf@sys@svg@hash\special{dvisvgm:raw #1}}} +\def\pgfsys@beginpicture{\pgfsys@invoke{<g transform="translate({?x},{?y}) scale(1,-1)">}} +\def\pgfsys@endpicture{\pgfsys@invoke{</g>}} + +\def\pgfsys@svg@newline{{?nl}} + + +\def\pgfsys@hbox#1{% + {% + \setbox#1=\hbox{\box#1}% + \wd#1=0pt% + \ht#1=0pt% + \dp#1=0pt% + \pgfsetcolor{.}% + \pgfsys@invoke{<g stroke="none" transform="scale(-1,1) translate({?x},{?y}) scale(-1,-1)">}\box#1\pgfsys@invoke{</g>}% + }% +} + +\def\pgfsys@shadingoutsidepgfpicture#1{% + \begingroup% + #1% + \setbox\pgfpic=\hbox to0pt{% + \pgfsys@beginpicture% + \pgfsys@beginscope% + \pgf@sys@svg@sh@defs% + \pgf@sys@svg@sh% + \pgfsys@endscope% + \pgfsys@endpicture% + \hss% + }% + \pgf@process{\pgf@sys@svg@pos}% + \pgf@picminx=0pt% + \pgf@picminy=0pt% + \pgf@picmaxx=\pgf@x% + \pgf@picmaxy=\pgf@y% + \def\pgf@trimleft@final{0pt}% + \def\pgf@trimright@final{0pt}% + \def\pgf@shift@baseline{0pt}% + \pgfsys@typesetpicturebox\pgfpic% + \endgroup% +} + +\def\pgfsys@shadinginsidepgfpicture#1{% + #1% + \pgf@sys@svg@sh@defs% hmmm.... + \pgf@process{\pgf@sys@svg@pos} + \pgf@xa=-.5\pgf@x% + \pgf@ya=-.5\pgf@y% + \pgfsysprotocol@literal{<g transform="translate(\pgf@sys@tonumber{\pgf@xa},\pgf@sys@tonumber{\pgf@ya})">}% + \pgf@sys@svg@sh% + \pgfsysprotocol@literal{</g>}% +} + +\endinput + + +%%% Local Variables: +%%% mode: latex +%%% End: diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-pdftex.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-pdftex.def index 8627a611077..b9ee92c3622 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-pdftex.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-pdftex.def @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-pdftex.def,v 1.26 2009/05/22 07:25:48 jinhwancho Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-pdftex.def,v 1.33 2013/07/18 10:34:44 tantau Exp $ % Driver commands for pdf @@ -52,8 +52,7 @@ \ifx\pgf@imagepage\pgfutil@empty\else\edef\pgf@imagepage{ page \pgf@imagepage }\fi% \ifx\pdfximage\@undefined% old version of pdflatex \ifx\pgf@imagepage\pgfutil@empty\else% - \PackageWarning{pgf}{Page selection not supported. Ignoring - page selection}% + \pgfwarning{Page selection not supported. Ignoring page selection}% \fi% \setbox\pgfutil@tempboxa=\hbox{% \pdfimage \pgf@imageheight \pgf@imagewidth {\pgf@filename}}% @@ -81,7 +80,7 @@ \pgfmathparse{#2}% \setbox\pgfutil@tempboxa=\hbox to\pgf@max{\vbox to\pgfmathresult pt{\vfil\pgfsys@invoke{/Sh sh}}\hfil}% \pgf@process{\pgfpoint{\pgf@max}{#2}}% - \pdfxform resources {% + \immediate\pdfxform resources {% /Shading << /Sh << /ShadingType 2 /ColorSpace /DeviceRGB /Domain [\pgf@pdfparseddomain] @@ -97,7 +96,7 @@ \pgfmathparse{#2}% \setbox\pgfutil@tempboxa=\hbox to\pgfmathresult pt{\vbox to\pgf@max{\vfil\pgfsys@invoke{/Sh sh}}\hfil}% \pgf@process{\pgfpoint{#2}{\pgf@max}}% - \pdfxform resources {% + \immediate\pdfxform resources {% /Shading << /Sh << /ShadingType 2 /ColorSpace /DeviceRGB /Domain [\pgf@pdfparseddomain] @@ -121,7 +120,7 @@ \pgf@sys@bp@correct{\pgf@y}% \pgf@sys@bp@correct{\pgf@xa}% \pgf@sys@bp@correct{\pgf@ya}% - \pdfxform resources {% + \immediate\pdfxform resources {% /Shading << /Sh << /ShadingType 3 /ColorSpace /DeviceRGB /Domain [\pgf@pdfparseddomain] @@ -218,41 +217,14 @@ } -\def\pgfsys@papersize#1#2{% - \pdfpageheight#2% - \pdfpagewidth#1} - - - % XForm version, crashes ghostview. - %\def\pgfsys@defobject#1#2#3#4{% - % \pgf@process{#2} - % \setbox\pgfobjectbox\hbox{\raise-\pgf@y\hbox{\hskip-\pgf@x\relax#4}} - % \pgf@process{#3} - % \pgf@xa=\pgf@x - % \pgf@ya=\pgf@y - % \pgf@process{#2} - % \advance\pgf@xa by-\pgf@x - % \advance\pgf@ya by-\pgf@y - % \wd\pgfobjectbox=\pgf@xa - % \dp\pgfobjectbox=0pt - % \ht\pgfobjectbox=\pgf@ya - % \pdfxform\pgfobjectbox - % \expandafter\xdef\csname#1\endcsname{\the\pdflastxform} - % \expandafter\xdef\csname pgf@trans#1\endcsname - % {{\pgfget x}{\pgfget y}}} - %\def\pgfsys@useobject#1#2{% - % \setbox\pgfobjectbox\hbox{\pdfrefxform \csname#1\endcsname}% - % \dp\pgfobjectbox=0pt% - % \ht\pgfobjectbox=0pt% - % \wd\pgfobjectbox=0pt% - % \pgfsys@discardpath% - % \pgfsys@beginscope% - % #2% - % \edef\pgf@temp{{1}{0}{0}{1}\csname pgf@trans#1\endcsname}% - % \expandafter\pgfsys@transform\pgf@temp% - % \box\pgfobjectbox% - % \pgfsys@endscope} +\def\pgfsys@papersize#1#2{\pdfpageheight#2\relax\pdfpagewidth#1\relax} +\def\pgfsys@global@papersize#1#2{\global\pdfpageheight#2\relax\global\pdfpagewidth#1\relax} + +\ifx\paperheight\@undefined + \def\pgfsys@thepageheight{\pdfpageheight} + \def\pgfsys@thepagewidth{\pdfpagewidth} +\fi % @@ -261,7 +233,7 @@ \def\pgfsys@markposition#1{% \pdfsavepos% \edef\pgf@temp{#1}% - \expandafter\write\expandafter\pgfutil@auxout\expandafter{% + \expandafter\pgfutil@writetoaux\expandafter{% \expandafter\noexpand\expandafter\pgfsyspdfmark\expandafter{\pgf@temp}{\the\pdflastxpos}{\the\pdflastypos}}% } @@ -274,7 +246,7 @@ \pgf@marshal% } -\def\pgf@sys@pdf@mark@pos@pgfpageorigin{\pgfpointorigin} +\def\pgf@sys@pdf@mark@pos@pgfpageorigin{\pgfqpoint{\hoffset}{\voffset}} % @@ -294,7 +266,7 @@ } \def\pgfsys@usefading#1#2#3#4#5#6#7{% \expandafter\ifx\csname pgfsmaskxform@#1\endcsname\relax% - \PackageError{pgf}{Undefined fading '#1'}{}% + \pgferror{Undefined fading '#1'}% \else% {% \expandafter\ifx\csname pgfsmaks@#1\endcsname\relax% @@ -342,7 +314,9 @@ \def\pgfsys@transparencygroupfrombox#1{% \pgf@sys@pdf@check@resources% \pdfxform - attr { /Group << /S /Transparency >> } %<< + attr { /Group << /S /Transparency + /I \ifpgfsys@transparency@group@isolated true \else false \fi + /K \ifpgfsys@transparency@group@knockout true \else false \fi >> } %<< resources { \pgf@sys@pdf@possible@resources } #1% \setbox#1=\hbox{\pdfrefxform\pdflastxform}% @@ -395,6 +369,10 @@ \pgfutil@addpdfresource@colorspaces{ /pgfprgb [/Pattern /DeviceRGB] } +\def\pgfsys@color@unstacked#1{% + \pdfliteral{\csname\string\color@#1\endcsname}% +} + \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-tex4ht.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-tex4ht.def index 71f819cc2bc..cc5dadb1173 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-tex4ht.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-tex4ht.def @@ -7,11 +7,9 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-tex4ht.def,v 1.23 2010/08/18 12:14:47 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-tex4ht.def,v 1.25 2013/08/06 17:46:08 tantau Exp $ -\RequirePackage{xcolor} - % Driver commands for tex4ht @@ -28,6 +26,11 @@ \newcount\pgf@sys@svg@picnum +\def\pgfsys@pictureboxsynced#1{% + \pgfsys@beginscope\pgflowlevelsynccm\box#1\pgfsys@endscope% +} + + %% %% initial support of Mathml and xhtml inside svg through the svg:foreignelement tag %% @@ -83,49 +86,60 @@ % class="}{\%s}{-\%s}{x-x-\%d}{}{">}{</span>} %} +\def\pgfsys@svg@newline{\Hnewline} + % we don't want tex4ht putting <p> and </p> tags automatically in our svg code and causing invalid xhtml in our svg pictures \newif\ifpgfsys@CssIncluded@\pgfsys@CssIncluded@false \def\pgfsys@beginpicture{% - \EndP\HtmlParOff - \pgfkeys{/tikz/tex4ht node/escape=false}% text only nodes are the default. Advantage : pure svg pictures are the default, nicer for text only nodes. - % Disadvantages : this rendering methods produce more invalid or degraded svg pictures than with the foreignelement tag + \EndP\HtmlParOff + \pgfkeys{/pgf/tex4ht node/escape=false}% + % text only nodes are the default. Advantage : pure svg pictures are + % the default, nicer for text only nodes. + % Disadvantages : this rendering methods produce more invalid or degraded svg pictures than with the foreignelement tag %% we use css to control the display of foreignelement rendered text nodes - \ifpgfsys@CssIncluded@ - \else - \Css{ - .foreignobject {% - line-height:100\%; - font-size:120\%; % this is the trick....a font of size 100% in a box scaled down to half size makes it a half size font. -% you'll have to double the size of things that you want to have a regular size in this half-scaled box though - font-family:STIXgeneral,Times,Symbol,cmr10,CMSY10,CMEX10;% can't wait for the stix font...the cmr10, etc font are available from the mozilla site, times and symbols should be okey - padding:0; - margin:0; -% background-color:\#12ff55; usefull for debugging positioning - text-align:center; % good for centered text nodes...will have to improve that later on...with more integration with tikz options for text nodes - } - }% - \Css{% - math {%, math[mode="inline"] { - vertical-align:baseline; - line-height:100\%; - font-size:100\%; - font-family:STIXGeneral,Times,Symbol, cmr10,cmsy10,cmex10,cmmi10; - font-style: normal; - margin:0; -% background-color:\#99ff99; - padding:0; - }% - }% - \pgfsys@CssIncluded@true - \fi + \ifpgfsys@CssIncluded@ + \else + \Css{ + .foreignobject {% + line-height:100\%; + font-size:120\%; % this is the trick....a font of size 100% in + % a box scaled down to half size makes it a + % half size font. + % you'll have to double the size of things + % that you want to have a regular size in + % this half-scaled box though + font-family:STIXgeneral,Times,Symbol,cmr10,CMSY10,CMEX10;% + % can't wait for the stix font...the cmr10, etc font are + % available from the mozilla site, times and symbols should be + % okey + padding:0; + margin:0; + % background-color:\#12ff55; usefull for debugging positioning + text-align:center; % good for centered text nodes...will have to improve that later on...with more integration with pgf options for text nodes + } + }% + \Css{% + math {%, math[mode="inline"] { + vertical-align:baseline; + line-height:100\%; + font-size:100\%; + font-family:STIXGeneral,Times,Symbol, cmr10,cmsy10,cmex10,cmmi10; + font-style: normal; + margin:0; + % background-color:\#99ff99; + padding:0; + }% + }% + \pgfsys@CssIncluded@true + \fi }% \def\pgfsys@endpicture{% - \HtmlParOn - \par% FIXME : was '\Par' but that seems to be undefined!? + \HtmlParOn + \par% FIXME : was '\Par' but that seems to be undefined!? }% -% this is okey for both rendering methods for text nodes (mtext or foreignelement)... +% this is okay for both rendering methods for text nodes (mtext or foreignelement)... \def\pgfsys@typesetpicturebox#1{% \global\advance\pgf@sys@svg@picnum by 1\relax% % Ok, compute width/height @@ -143,8 +157,7 @@ \pgf@xc=\pgf@x% \pgf@yc=\pgf@y% \pgfsysprotocol@flushcurrentprotocol% - \HCode{<object data="\jobname-\the\pgf@sys@svg@picnum.svg" - width="}% + \HCode{<object data="\jobname-\the\pgf@sys@svg@picnum.svg" width="}% % Calculate pixel coordinates (this does not really make sense, but % we have to do it anyway). Assume 96dpi. \pgf@x=1.3333333\pgf@x% @@ -159,11 +172,11 @@ \pgfsysprotocol@flushcurrentprotocol% \pgfsys@invoke{" type="image/svg+xml"><p>SVG-Viewer needed.</p></object>}% \special{t4ht>\jobname-\the\pgf@sys@svg@picnum.svg}% -%%%%%%%% This is necessary to control the svg through css - \pgfkeys{% - /tikz/tex4ht node/css/.get=\pgfsys@foreignobject@css - }% - \pgfsys@invoke{<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>\Hnewline% added that + %%%%%%%% This is necessary to control the svg through css + \pgfkeys{% + /pgf/tex4ht node/css/.get=\pgfsys@foreignobject@css + }% + \pgfsys@invoke{<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>\Hnewline% added that <?xml-stylesheet href="\pgfsys@foreignobject@css.css" type="text/css"?>\Hnewline}% added that %%%%%%%%%%%%%%% maybee I should add an option to change the css, for the whole picture \pgfsys@invoke{<svg xmlns="http://www.w3.org/2000/svg" @@ -199,23 +212,24 @@ %% we'll use this hbox for the mtext rendering method (the "text only=true" option) \def\pgfsys@hbox#1{% \pgf@x=.5\wd#1% - \ifx\tikz@textcolor\relax% - \else% + \ifx\tikz@textcolor\relax\else\ifx\tikz@textcolor\@undefined\else% \ifx\tikz@textcolor\pgfutil@empty% \pgfsetfillcolor{.}% \else% \pgfsetfillcolor{\tikz@textcolor}% \fi% - \fi% tweak for TikZ + \fi\fi% tweak for TikZ \HCode{<text style="stroke:none" transform="scale(1,-1) translate(\pgf@sys@tonumber{\pgf@x},0)" text-anchor="middle" }% - \ifx\f@size\pgfutil@empty% - \else% - \HCode{ font-size="\f@size"}% - \fi% + \ifpgfutil@format@is@latex% + \ifx\f@size\pgfutil@empty% + \else% + \HCode{ font-size="\f@size"}% + \fi% + \fi% \HCode{>\Hnewline }% \wd#1=0pt% \ht#1=0pt% @@ -230,44 +244,55 @@ %% we have to use some "evil" ^^ tex4ht hackery % tex4ht hackery {% grouping necessary cause we change the catcode of ":" - \catcode`:=11\relax - %%% this is necessary to calculate the size of text nodes with inline maths - % (it is an improvement of tex4ht, got to ask eitan gurary if he could put it in the tex4ht code) - \gdef\DviMathAlt{% - \a:DviMath\leavevmode \MathClass \ht:special{t4ht@(}\hbox\bgroup{\expandafter\ifx\csname ht:everypar\endcsname\relax\expandafter\everypar\else \expandafter\ht:everypar\fi{}\leavevmode\ht:special{t4ht@)}}\DviSend - }% -% these are configures for the foreignelement rendering method of text nodes : we let tex4ht write xhtml and mathml in the svg picture -% - \gdef\pgfsys@foreignobject@configure{% - \Configure{$}{\Configure{@math}{%\a:mathml - display="inline" }\DviMathAlt}{\EndDviMath}{}%%% we REALLY need to use \DviMathAlt here instead of \DviMath see above remark - \Configure{$$}{\Configure{@math}{%\a:mathml - display="block" }\IgnorePar - \ifvmode\else \HCode{<!--tex4ht:inline-->}\fi\EndP - \DviMath}{\EndDviMath\ShowPar\pgfsys@foreignobject@par{\csname HCondtrue\endcsname\noindent} - }{\DisplayMathtrue}% - \Configure{SUB}{\Send{BACK}{<\a:mathml msub><\a:mathml mrow\Hnewline>}% - \Tg</\a:mathml mrow>\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg</\a:mathml mrow>\TG</\a:mathml msub\Hnewline>}% - \Configure{SUP}{\Send{BACK}{<\a:mathml msup><\a:mathml mrow\Hnewline>}% - \Tg</\a:mathml mrow>\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg</\a:mathml mrow>\TG</\a:mathml msup\Hnewline>}% - \Configure{SUBSUP}{\Send{BACK}{<\a:mathml msubsup><\a:mathml mrow\Hnewline>}% - \Tg</\a:mathml mrow>\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg</\a:mathml mrow>\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg</\a:mathml mrow>\TG</\a:mathml msubsup\Hnewline>}% - \Configure{htf}{0}{+}{<span\Hnewline - class="}{\%s}{-\%s}{x-x-\%d}{}{">}{</span>}% - }% - \global\let\pgfsys@foreignobject@par=\par % use this instead of \par -- \Configure is no \long macro (at least in one of the older versions). - -% these are the configures for the mtext rendering method of text nodes : we turn everything into regular character (don't want math modes or subsup) -% and we hope it works (it doesn't if the text nodes aren't simple) - \gdef\pgfsys@mtext@configure{% - % no configures for \(\) and \[\] those might be needed for context or Latex. Let me know ! - \Configure{$$}{}{}{}% no block maths - \Configure{$}{}{}{}%$ no inline maths - \Configure{SUB}{\HCode{<tspan baseline-shift="sub">}}{\HCode{</tspan>}}% - \Configure{SUP}{\HCode{<tspan baseline-shift="sub">}}{\HCode{</tspan>}}% - \Configure{SUBSUP}{}{}{}% not both sub and sup - \Configure{htf} {0}{+}{<tspan font-family="}{\%s}{" font-size="\%s}{}{}{">}{</tspan>}% - }% + \catcode`:=11\relax + %%% this is necessary to calculate the size of text nodes with + %%% inline maths + % (it is an improvement of tex4ht, got to ask eitan gurary if he + % could put it in the tex4ht code) + \gdef\DviMathAlt{% + \a:DviMath\leavevmode \MathClass + \ht:special{t4ht@(}\hbox\bgroup{\expandafter\ifx\csname + ht:everypar\endcsname\relax\expandafter\everypar\else + \expandafter\ht:everypar\fi{}\leavevmode\ht:special{t4ht@)}}\DviSend + }% + % these are configures for the foreignelement rendering method of text nodes : we let tex4ht write xhtml and mathml in the svg picture + % + \gdef\pgfsys@foreignobject@configure{% + \Configure{$}{\Configure{@math}{%\a:mathml + display="inline" }\DviMathAlt}{\EndDviMath}{}%%% we REALLY need to use \DviMathAlt here instead of \DviMath see above remark + \Configure{$$}{\Configure{@math}{%\a:mathml + display="block" }\IgnorePar + \ifvmode\else \HCode{<!--tex4ht:inline-->}\fi\EndP + \DviMath}{\EndDviMath\ShowPar\pgfsys@foreignobject@par{\csname HCondtrue\endcsname\noindent} + }{\DisplayMathtrue}% + \Configure{SUB}{\Send{BACK}{<\a:mathml msub><\a:mathml mrow\Hnewline>}% + \Tg</\a:mathml mrow>\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg</\a:mathml mrow>\TG</\a:mathml msub\Hnewline>}% + \Configure{SUP}{\Send{BACK}{<\a:mathml msup><\a:mathml mrow\Hnewline>}% + \Tg</\a:mathml mrow>\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg</\a:mathml mrow>\TG</\a:mathml msup\Hnewline>}% + \Configure{SUBSUP}{\Send{BACK}{<\a:mathml msubsup><\a:mathml mrow\Hnewline>}% + \Tg</\a:mathml mrow>\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg</\a:mathml mrow>\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg</\a:mathml mrow>\TG</\a:mathml msubsup\Hnewline>}% + \Configure{htf}{0}{+}{<span\Hnewline + class="}{\%s}{-\%s}{x-x-\%d}{}{">}{</span>}% + }% + \global\let\pgfsys@foreignobject@par=\par % use this instead of \par + % -- \Configure is no \long macro (at + % least in one of the older + % versions). + + % these are the configures for the mtext rendering method of text + % nodes : we turn everything into regular character (don't want math + % modes or subsup) + % and we hope it works (it doesn't if the text nodes aren't simple) + \gdef\pgfsys@mtext@configure{% + % no configures for \(\) and \[\] those might be needed for + % context or Latex. Let me know ! + \Configure{$$}{}{}{}% no block maths + \Configure{$}{}{}{}%$ no inline maths + \Configure{SUB}{\HCode{<tspan baseline-shift="sub">}}{\HCode{</tspan>}}% + \Configure{SUP}{\HCode{<tspan baseline-shift="sub">}}{\HCode{</tspan>}}% + \Configure{SUBSUP}{}{}{}% not both sub and sup + \Configure{htf} {0}{+}{<tspan font-family="}{\%s}{" font-size="\%s}{}{}{">}{</tspan>}% + }% }% % a counter to produce unique ids for each text node rendered with foreign element @@ -295,8 +320,8 @@ \def\pgfutil@endminipage{% % same thing here % -% \ifpgfsys@textonly\else\EndP\HtmlParOff\fi - \egroup\egroup +% \ifpgfsys@textonly\else\EndP\HtmlParOff\fi + \egroup\egroup }% @@ -306,71 +331,73 @@ \newdimen\pgf@t % this is the alternate hbox routine that renders text nodes through the foreignobject tag \def\pgfsys@foreignobject@hbox#1{% - % Compute box y translation (x translation is correct). - \pgf@y=-\ht#1\relax - \HCode{<g transform="scale(1,-1) translate(0,\pgf@sys@tonumber{\pgf@y}) % got to translate in y - scale(0.5,0.5)">\Hnewline}% scaling work around (damn dumb browsers !) - % Compute box size (scaled 2 times) - % this is necessary to make the browser scale the font down 50% (the STUPID browsers won't make font-size:50% happen, - % so we have to work around this by making svg scale the things down 50%, doubling the size of the text node frame (i.e. no changement there) - \pgf@x=2\wd#1\relax - \pgf@y=2\ht#1\relax - \advance\pgf@y by 2\dp#1\relax - % this is to adjust the y translation to compensate for the differences between the TeX and the Html models for lines - \setbox\pgfsys@foreignobject@Box=\hbox{abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ - $abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZf_1^1\overline D)_1^1\vec i\vec j$}% - \pgf@t=\ht#1\relax - \advance\pgf@t by -\ht\pgfsys@foreignobject@Box\relax - \pgf@s=\pgf@t\relax - \advance\pgf@s by \dp#1\relax - \advance\pgf@s by -\dp\pgfsys@foreignobject@Box\relax - \ifnum\pgf@s>0\relax - \pgf@s=0pt - \pgf@t=0pt - \else - \advance \pgf@y by -2\pgf@s\relax - \pgf@t=2\pgf@t\relax - \fi - % - \HCode{<foreignObject x="0" y="\pgf@sys@tonumber{\pgf@t}" - width="\pgf@sys@tonumber{\pgf@x}" height="\pgf@sys@tonumber{\pgf@y}">}% - % this is to make use of the css, class and id options through which you can control the way things display - \pgfkeys{% - /tikz/tex4ht node/css/.get=\pgfsys@foreignobject@css,% - /tikz/tex4ht node/class/.get=\pgfsys@foreignobject@class,% - /tikz/tex4ht node/id/.get=\pgfsys@foreignobject@id - }% - \HCode{<head>\Hnewline - <link rel="stylesheet" type="text/css" href="\pgfsys@foreignobject@css.css" />\Hnewline - </head>\Hnewline -% I'll have to look into this, perhaps there are better doctype.... aren't recognised and produces invalid svg pictures -% a workaround (not implemented yet) would be to make them into entities of the svg picture. - <body id="\pgfsys@foreignobject@id" class="\pgfsys@foreignobject@class" xmlns="http://www.w3.org/1999/xhtml" >\Hnewline - <div>\Hnewline - }% - \box#1% - \HCode{% - </div>\Hnewline - </body>\Hnewline - </foreignObject>\Hnewline - }% -% debug positioning not needed but it would be nice to let it there to control things later on -% \HCode{<rect x="0" y="0" width="\pgf@sys@tonumber{\pgf@x}" height="\pgf@sys@tonumber{\pgf@y}" -% style="fill:yellow;stroke:red; fill-opacity:0.5;stroke-opacity:0.5"/>} - \HCode{</g>\Hnewline}% - \global\advance\pgf@sys@svg@nodenum by 1\relax + % Compute box y translation (x translation is correct). + \pgf@y=-\ht#1\relax + \HCode{<g transform="scale(1,-1) translate(0,\pgf@sys@tonumber{\pgf@y}) % got to translate in y + scale(0.5,0.5)">\Hnewline}% scaling work around (damn dumb browsers !) + % Compute box size (scaled 2 times) + % this is necessary to make the browser scale the font down 50% (the STUPID browsers won't make font-size:50% happen, + % so we have to work around this by making svg scale the things down 50%, doubling the size of the text node frame (i.e. no changement there) + \pgf@x=2\wd#1\relax + \pgf@y=2\ht#1\relax + \advance\pgf@y by 2\dp#1\relax + % this is to adjust the y translation to compensate for the differences between the TeX and the Html models for lines + \setbox\pgfsys@foreignobject@Box=\hbox{abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + $abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZf_1^1\overline D)_1^1\vec i\vec j$}% + \pgf@t=\ht#1\relax + \advance\pgf@t by -\ht\pgfsys@foreignobject@Box\relax + \pgf@s=\pgf@t\relax + \advance\pgf@s by \dp#1\relax + \advance\pgf@s by -\dp\pgfsys@foreignobject@Box\relax + \ifnum\pgf@s>0\relax + \pgf@s=0pt + \pgf@t=0pt + \else + \advance \pgf@y by -2\pgf@s\relax + \pgf@t=2\pgf@t\relax + \fi + % + \HCode{<foreignObject x="0" y="\pgf@sys@tonumber{\pgf@t}" + width="\pgf@sys@tonumber{\pgf@x}" height="\pgf@sys@tonumber{\pgf@y}">}% + % this is to make use of the css, class and id options through which you can control the way things display + \pgfkeys{% + /pgf/tex4ht node/css/.get=\pgfsys@foreignobject@css,% + /pgf/tex4ht node/class/.get=\pgfsys@foreignobject@class,% + /pgf/tex4ht node/id/.get=\pgfsys@foreignobject@id + }% + \HCode{<head>\Hnewline + <link rel="stylesheet" type="text/css" href="\pgfsys@foreignobject@css.css" />\Hnewline + </head>\Hnewline + % I'll have to look into this, perhaps there are better + % doctype.... aren't recognised and produces invalid svg + % pictures a workaround (not implemented yet) would be to make + % them into entities of the svg picture. + <body id="\pgfsys@foreignobject@id" class="\pgfsys@foreignobject@class" xmlns="http://www.w3.org/1999/xhtml" >\Hnewline + <div>\Hnewline + }% + \box#1% + \HCode{% + </div>\Hnewline + </body>\Hnewline + </foreignObject>\Hnewline + }% + % debug positioning not needed but it would be nice to let it there to control things later on + % \HCode{<rect x="0" y="0" width="\pgf@sys@tonumber{\pgf@x}" height="\pgf@sys@tonumber{\pgf@y}" + % style="fill:yellow;stroke:red; fill-opacity:0.5;stroke-opacity:0.5"/>} + \HCode{</g>\Hnewline}% + \global\advance\pgf@sys@svg@nodenum by 1\relax }% % the options and the code that controls it all (switches between \pgfsys@mtext@hbox and \pgfsys@foreignelement@hbox) \pgfkeys{% - /tikz/.cd, - tex4ht node/escape/.is choice, - tex4ht node/escape/false/.code={\let\pgfsys@hbox\pgfsys@mtext@hbox\pgfsys@mtext@configure\pgfsys@textonlytrue}, - tex4ht node/escape/true/.code={\let\pgfsys@hbox\pgfsys@foreignobject@hbox\pgfsys@foreignobject@configure\pgfsys@textonlyfalse}, - tex4ht node/css/.initial=\jobname, - tex4ht node/class/.initial=foreignobject, - tex4ht node/id/.initial=\jobname\the\pgf@sys@svg@picnum-\the\pgf@sys@svg@nodenum + /pgf/.cd, + tex4ht node/escape/.is choice, + tex4ht node/escape/false/.code={\let\pgfsys@hbox\pgfsys@mtext@hbox\pgfsys@mtext@configure\pgfsys@textonlytrue}, + tex4ht node/escape/true/.code={\let\pgfsys@hbox\pgfsys@foreignobject@hbox\pgfsys@foreignobject@configure\pgfsys@textonlyfalse}, + tex4ht node/css/.initial=\jobname, + tex4ht node/class/.initial=foreignobject, + tex4ht node/id/.initial=\jobname\the\pgf@sys@svg@picnum-\the\pgf@sys@svg@nodenum }% @@ -426,19 +453,26 @@ \pgfsysprotocol@literal{</g>\Hnewline}% } -% Protect against color.4ht evil meddling with xcolor: -\let\pgf@xcolor@declaredcolor=\@declaredcolor -\let\pgf@xcolor@undeclaredcolor=\@undeclaredcolor + +\ifpgfutil@format@is@latex + % Protect against color.4ht evil meddling with xcolor: + \RequirePackage{xcolor} + \let\pgf@xcolor@declaredcolor=\@declaredcolor + \let\pgf@xcolor@undeclaredcolor=\@undeclaredcolor +\fi \AtBeginDocument{ \let\pgfsys@invoke=\pgfsys@body@invoke \let\pgfsys@shadingoutsidepgfpicture=\pgfsys@body@shadingoutsidepgfpicture \let\pgfsys@shadinginsidepgfpicture=\pgfsys@body@shadinginsidepgfpicture - \let\pgf@texht@declaredcolor=\@declaredcolor - \let\pgf@texht@undeclaredcolor=\@undeclaredcolor - \def\@declaredcolor{\ifpgfpicture\expandafter\pgf@xcolor@declaredcolor\else\expandafter\pgf@texht@declaredcolor\fi} - \def\@undeclaredcolor{\ifpgfpicture\expandafter\pgf@xcolor@undeclaredcolor\else\expandafter\pgf@texht@undeclaredcolor\fi} - %\ConfigureEnv{pgfpicture}{}{}{}{} there is no environment in plain TeX and this produces errors + \ifpgfutil@format@is@latex + \let\pgf@texht@declaredcolor=\@declaredcolor + \let\pgf@texht@undeclaredcolor=\@undeclaredcolor + \def\@declaredcolor{\ifpgfpicture\expandafter\pgf@xcolor@declaredcolor\else\expandafter\pgf@texht@declaredcolor\fi} + \def\@undeclaredcolor{\ifpgfpicture\expandafter\pgf@xcolor@undeclaredcolor\else\expandafter\pgf@texht@undeclaredcolor\fi} + \fi + \def\pgfutil@color{\pgfsetcolor} + % \ConfigureEnv{pgfpicture}{}{}{}{} there is no environment in plain TeX and this produces errors % this might be needed for context or latex though....let me know ! }% diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-textures.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-textures.def index 5e3aa27258c..0645fb8c51f 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-textures.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-textures.def @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-textures.def,v 1.5 2007/12/12 16:57:17 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-textures.def,v 1.6 2011/05/13 10:16:37 tantau Exp $ % Driver commands for textures driver @@ -71,10 +71,12 @@ pgffoa .setopacityalpha}bind def% save /.setopacityalpha where {pop} {/.setopacityalpha{pop}def} ifelse % install .setopacityalpha /.pgfsetfillopacityalpha{/pgffoa exch def - /pgffill{gsave pgffoa .setopacityalpha fill 1 .setopacityalpha newpath fill grestore}bind def - /pgfeofill{gsave pgffoa .setopacityalpha eofill1 .setopacityalpha newpath eofill grestore}bind def}bind def + /pgffill{gsave pgffoa .setopacityalpha fill 1 .setopacityalpha + newpath fill grestore newpath}bind def + /pgfeofill{gsave pgffoa .setopacityalpha eofill1 + .setopacityalpha newpath eofill grestore newpath}bind def}bind def /.pgfsetstrokeopacityalpha{/pgfsoa exch def - /pgfstr{gsave pgfsoa .setopacityalpha stroke grestore}bind def}bind def + /pgfstr{gsave pgfsoa .setopacityalpha stroke grestore newpath}bind def}bind def /pgffoa 1 def /pgfsoa 1 def } diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-vtex.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-vtex.def index 742b4a6fef3..5014f48beba 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-vtex.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-vtex.def @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-vtex.def,v 1.8 2007/12/12 16:57:17 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-vtex.def,v 1.10 2013/07/15 12:05:34 tantau Exp $ % Driver commands for vtex @@ -47,7 +47,7 @@ \def\pgf@sys@vtex@@setcolor#1#2#3#4#5{% \pgfsysps@color@resetnow% \expandafter\ifx\csname pgfsys@color@#4\endcsname\relax% - \PackageError{pgfbase}{Unsupported color model `#4'. Sorry}{}% + \pgferror{Unsupported color model `#4'. Sorry}% \else% \edef\pgf@colmarshal{\expandafter\noexpand\csname pgfsys@color@#4\endcsname}% \pgf@uncomma#5,,% @@ -92,6 +92,13 @@ } } +% vtex commands for changing the paper size +\def\pgfsys@papersize#1#2{\mediawidth#1\mediaheight#2} + + + + + \endinput %%% Local Variables: diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-xetex.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-xetex.def index feaa7f77bae..9d13ae1ae70 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-xetex.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-xetex.def @@ -7,44 +7,68 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-xetex.def,v 1.3 2010/02/16 10:56:09 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-xetex.def,v 1.9 2013/07/16 16:03:13 tantau Exp $ -% Driver commands for dvipdfm +\input pgfsys-dvipdfmx.def -% -% Load common pdf and pdf in dvi commands: -% -\input pgfsys-common-pdf.def -\input pgfsys-common-pdf-via-dvi.def +\def\pgfsys@dvipdfmx@patternobj#1{% + % I have NO idea why this is necessary for xdvipdfmx - but without + % it, it crashes. + \pgfutil@insertatbegincurrentpagefrombox{#1}% +}% -% -% dvipdfmx-specific stuff: -% +% XeTeX supports pdftex commands for paper size +\def\pgfsys@papersize#1#2{% + \pdfpageheight#2% + \pdfpagewidth#1} + +\def\pgfsys@global@papersize#1#2{% + \global\pdfpageheight#2% + \global\pdfpagewidth#1} + -\def\pgfsys@invoke#1{\special{pdf:literal direct #1 }} +% Xetex does not support interpolate and not mask +\def\pgfsys@defineimage{% width, height, page number + \ifx\includegraphics\undefined + \ifx\pgf@imagewidth\pgfutil@empty\edef\pgf@imagewidth{1bp}\fi% width? + \ifx\pgf@imageheight\pgfutil@empty\edef\pgf@imageheight{1bp}\fi% height? + \ifx\pgf@imagepage\pgfutil@empty\else\edef\pgf@imagepage{ page \pgf@imagepage}\fi% + \ifx\pgf@imageinterpolate\pgfutil@empty\else\edef\pgf@imageinterpolate{ /Interpolate\space\pgf@imageinterpolate}\fi% + \ifx\pgf@imagemask\pgfutil@empty\else\xdef\pgf@imagemask{ /SMask @\pgf@imagemask}\fi% + \edef\pgf@image{\noexpand\hbox to \pgf@imagewidth{\vbox to \pgf@imageheight{\vfil\special{pdf:image width \pgf@imagewidth\space height \pgf@imageheight\space\pgf@imagepage\space(\pgf@filename) <<\pgf@imageinterpolate\pgf@imagemask\space>>}}\hfil}}% + \else + \ifx\pgf@imagewidth\pgfutil@empty\else\edef\pgf@imagewidth{width=\pgf@imagewidth,}\fi% + \ifx\pgf@imageheight\pgfutil@empty\else\edef\pgf@imageheight{height=\pgf@imageheight,}\fi% + \ifx\pgf@imagepage\pgfutil@empty\else\edef\pgf@imagepage{page=\pgf@imagepage,}\fi% + \edef\pgf@image{\noexpand\includegraphics[\pgf@imageheight\pgf@imagewidth\pgf@imagepage]{\pgf@filename}}% + \fi% +} + +% XeTeX supports position tracking, now +\def\pgfsys@markposition#1{% + \pdfsavepos% + \edef\pgf@temp{#1}% + \expandafter\pgfutil@writetoaux\expandafter{% + \expandafter\noexpand\expandafter\pgfsyspdfmark\expandafter{\pgf@temp}{\the\pdflastxpos}{\the\pdflastypos}}% +} +\def\pgfsyspdfmark#1#2#3{% + \expandafter\gdef\csname pgf@sys@pdf@mark@pos@#1\endcsname{\pgfqpoint{#2sp}{#3sp}}% +} -\ifx\XeTeXversion\@undefined - \PackageError{pgfsys}{XeTeX is not running, but it should. Somehow - the wrong driver got selected}{} -\fi +\def\pgfsys@getposition#1#2{% + \edef\pgf@marshal{\let\noexpand#2=\expandafter\noexpand\csname pgf@sys@pdf@mark@pos@#1\endcsname}% + \pgf@marshal% +} +\def\pgf@sys@pdf@mark@pos@pgfpageorigin{\pgfqpoint{2\hoffset}{0pt}} -% -% Position tracking always on -% -\pgf@sys@pdf@dvi@tracker +\ifx\paperheight\@undefined +\else + \pdfpagewidth\paperwidth + \pdfpageheight\paperheight % this is to work around a positioning problem in xetex. +\fi -% -% Page size stuff -% -\def\pgfsys@papersize#1#2{% - \pdfpageheight#2% - \pdfpagewidth#1} \endinput - -%%% Local Variables: -%%% mode: latex -%%% End: diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys.code.tex b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys.code.tex index 3cd39c48645..63a1aac41a5 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys.code.tex,v 1.37 2010/06/30 13:06:37 ludewich Exp $ +\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys.code.tex,v 1.47 2013/11/30 11:35:10 ludewich Exp $ % Load key mechanism @@ -17,6 +17,10 @@ \pgfkeys{/pgf/.is family} \def\pgfset{\pgfqkeys{/pgf}} +% This is if is needed *very* early +\newif\ifpgfpicture + + % % The following conversion functions are used to convert from TeX % dimensions to postscript/pdf points. @@ -66,6 +70,28 @@ \newcount\c@pgf@countc \newcount\c@pgf@countd +\newtoks\t@pgf@toka +\newtoks\t@pgf@tokb +\newtoks\t@pgf@tokc + +% Ensure that math registers are the same (math is broken in case it +% is loaded first) +\let\pgfmath@x\pgf@x +\let\pgfmath@xa\pgf@xa +\let\pgfmath@xb\pgf@xb +\let\pgfmath@xc\pgf@xc + +\let\pgfmath@y\pgf@y +\let\pgfmath@ya\pgf@ya +\let\pgfmath@yb\pgf@yb +\let\pgfmath@yc\pgf@yc + +\let\c@pgfmath@counta\c@pgf@counta +\let\c@pgfmath@countb\c@pgf@countb +\let\c@pgfmath@countc\c@pgf@countc +\let\c@pgfmath@countd\c@pgf@countd + + % The following \if decides, whether even-odd filling and clipping is % to be used or normal the non-zero winding number rule. See the @@ -96,8 +122,7 @@ \expandafter\ifx\csname pgf@sys@fail@#1\endcsname\pgfutil@empty% \else% \expandafter\global\expandafter\let\csname pgf@sys@fail@#1\endcsname=\pgfutil@empty% - \PackageWarning{pgf}{% - Your graphic driver \pgfsysdriver\space does not support #1. This warning is given only once}% + \pgfwarning{Your graphic driver \pgfsysdriver\space does not support #1. This warning is given only once}% \fi% } @@ -131,33 +156,31 @@ % \def\pgfsys@moveto#1#2{\pgf@sys@fail{path constructions}} -% This command is used to start a path at a specific point (#1bp,#2bp) -% or to move the current point of the current path to (#1bp,#2bp) +% This command is used to start a path at a specific point (#1,#2) +% or to move the current point of the current path to (#1,#2) % without drawing anything upon stroking (the current path is % `interrupted'). % -% Here (and in the following) the coordinates are in TeX's big points -% (bp), unless the coordinate system has been scaled. A big point is -% 1/72 inches. Note that TeX's point pt is 1/72.27 inches. +% The arguments must be dimensions (like |10pt|). % % Example: % -% \pgfsys@moveto{10}{10} -% \pgfsys@lineto{0}{0} +% \pgfsys@moveto{10pt}{10pt} +% \pgfsys@lineto{0pt}{0pt} % \pgfsys@stroke % -% This will draw a line from (10bp,10bp) to the origin of the picture. +% This will draw a line from (10pt,10pt) to the origin of the picture. \def\pgfsys@lineto#1#2{\pgf@sys@fail{path constructions}} -% Continue the current path to (#1bp,#2bp) with a line. +% Continue the current path to (#1,#2) with a line. \def\pgfsys@curveto#1#2#3#4#5#6{\pgf@sys@fail{path constructions}} -% Continue the current path with a bezier curver to (#5bp,#6bp). The -% control points of the curve are at (#1bp,#2bp) and (#3bp,#4bp). +% Continue the current path with a bezier curver to (#5,#6). The +% control points of the curve are at (#1,#2) and (#3,#4). \def\pgfsys@rect#1#2#3#4{\pgf@sys@fail{path constructions}} % Append a rectangle to the current path whose lower left corner is at -% (#1bp,#2bp) and whose width/height is given by (#3bp,#4bp). +% (#1,#2) and whose width/height is given by (#3,#4). % % This command can be `mapped back' to moveto and lineto commands, but % it is included since pdf has a special, quick version of this command. @@ -306,7 +329,7 @@ % % \def\pgfsys@setlinewidth#1{\pgf@sys@fail{setting the line width}} -% Sets the width of lines, when stroked, to #1bp. +% Sets the width of lines, when stroked, to #1. \def\pgfsys@buttcap{\pgf@sys@fail{setting the line cap}} % Sets the cap to a butt cap. See \pgfsys@stroke. @@ -331,22 +354,21 @@ % Sets the join to a bevel join. See \pgfsys@stroke. \def\pgfsys@setdash#1#2{\pgf@sys@fail{setting the dashing pattern}} -% Sets the dashing patter. #1 should be a list of lengths given in big -% points (bp) separated by spaces. #2 should be a single value given -% in bp. +% Sets the dashing patter. #1 should be a list of lengths separated by +% spaces. #2 should be a single dimension. % % The list of values in #1 is used to determine the lengths of the % `on' phases of the dashing and of the `off' phases. For example, if -% #1 is `3 4', then the dashing pattern is `3bp on followed by 4bp -% off, followed by 3bp on, followed by 4bp off, and so on'. A pattern -% of `.5 4 3 1.5' means `.5bp on, 4bp off, 3bp on, 1.5bp off, .5bp on, +% #1 is `3pt 4pt', then the dashing pattern is `3pt on followed by 4pt +% off, followed by 3pt on, followed by 4pt off, and so on'. A pattern +% of `.5pt 4pt 3pt 1.5pt' means `.5pt on, 4pt off, 3pt on, 1.5pt off, .5pt on, % ...'. If the number of entries is odd, the last one is used twice, -% so `3' means `3bp on, 3bp off, 3bp on, 3bp off,...'. An empty list +% so `3pt' means `3pt on, 3pt off, 3pt on, 3pt off,...'. An empty list % means `always on'. % % The second argument determines the `phase' of the pattern. For -% example, for a pattern of `3 4' and a phase of `1', the pattern -% would start: `2bp on, 4bp off, 3bp on, 4bp off, 3bp on, 4bp off...'. +% example, for a pattern of `3pt 4pt' and a phase of `1pt', the pattern +% would start: `2pt on, 4pt off, 3pt on, 4pt off, 3pt on, 4pt off...'. @@ -509,6 +531,17 @@ % overlap will be darker than the rest. By comparison, if the circles % are part of a transparency group, the overlap will get the same % color as the rest. +% +% The following settings modify the bevahiour of a transparency group: + +\newif\ifpgfsys@transparency@group@isolated +\newif\ifpgfsys@transparency@group@knockout + + +\def\pgfsys@blend@mode#1{\pgf@sys@fail{blend mode}} +% Sets the current blend mode. See the PDF specification for details +% on blend modes. + \def\pgfsys@definemask{\pgf@sys@fail{image masks}} % This command declares a mask for usage with images. It works similar @@ -631,12 +664,36 @@ % Page size stuff % % + \def\pgfsys@papersize#1#2{\pgf@sys@fail{papersize}} -% This command sets the paper size in a portable way. +% This command sets the paper size in a portable way. It tries to do +% so "locally" for the current page, but what really happens depends +% strongly on the driver. For instance, dvips will use whatever is +% used with the first call to this command that is part of the +% shipped-out document and will ignore all other uses. In contrast, +% pdftex will use the current value of the papersize for each page +% and, additionally, setting the papersize is local to the current TeX +% group. +% #1 = width +% #2 = height + +\def\pgfsys@global@papersize#1#2{\pgfsys@papersize{#1}{#2}} +% This command does the same as the papersize command, only for +% drivers that support this, \global is used to set the papersize. % #1 = width % #2 = height +\ifx\paperheight\@undefined + \def\pgfsys@thepageheight{\the\vsize} % this is wrong, but I do not + % know how to compute the page height + % in plain tex. + \def\pgfsys@thepagewidth{\the\hsize} +\else + \def\pgfsys@thepageheight{\paperheight} + \def\pgfsys@thepagewidth{\paperwidth} +\fi + % % @@ -705,7 +762,7 @@ \def\pgfsys@transformshift#1#2{\pgfsys@transformcm{1}{0}{0}{1}{#1}{#2}} % This command will change the origin of the low-level coordinate -% system to (#1bp,#2bp). +% system to (#1,#2). \def\pgfsys@transformxyscale#1#2{\pgfsys@transformcm{#1}{0}{0}{#2}{0bp}{0bp}} % This command will scale the low-level coordinate system (and @@ -739,6 +796,20 @@ % transformation cm. This will ensure that hyperlinks ``survive'' at % least translations. +\def\pgfsys@pictureboxsynced#1{% + {% + \setbox0=\hbox{\pgfsys@beginpicture\box#1\pgfsys@endpicture}% + \pgfsys@hboxsynced0% + }% +} +% Basically, this should do the same as doing a (scoped) low level sync +% followed by inserting the box #1 directly into the output +% stream. However, the default implementation uses \pgfsys@hboxsynced +% in conjunction with \pgfsys@beginpicture to ensure that, if +% possible, hyperlinks survive in pdfs. Drivers that are sensitive to +% picture-in-picture scopes shuold replace this implementation by +% \pgfsys@beginscope\pgflowlevelsynccm\box#1\pgfsys@endscope + \def\pgfsys@beginpicture{} % Called at the beginning of a pgfpicture. Used to setup things. @@ -835,7 +906,9 @@ {% \pgfsysprotocol@setcurrentprotocol\pgfutil@empty% \pgfsysprotocol@bufferedtrue% + \pgfsys@beginscope% #4% + \pgfsys@endscope% \pgfsysprotocol@getcurrentprotocol\pgfsys@@temp% \expandafter\global\expandafter\let\csname #1\endcsname=\pgfsys@@temp% }% @@ -897,9 +970,9 @@ \input pgf.cfg -\PackageInfo{pgfsys}{Driver file for pgf: \pgfsysdriver} +\immediate\write-1{Driver file for pgf: \pgfsysdriver} \pgfutil@InputIfFileExists{\pgfsysdriver}{}{% - \PackageError{pgfsys}{Driver file ``\pgfsysdriver'' not found.}{}} + \pgferror{Driver file ``\pgfsysdriver'' not found.}} diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsyssoftpath.code.tex b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsyssoftpath.code.tex index 96fe6db490a..0b6310873ab 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsyssoftpath.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsyssoftpath.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsyssoftpath.code.tex,v 1.7 2008/07/18 19:06:58 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsyssoftpath.code.tex,v 1.9 2013/09/09 10:05:41 tantau Exp $ % This package provides the pgf system path abstraction layer. This @@ -52,7 +52,7 @@ % buffers are flushed. % % Because of this buffering, it is imperative that the main path is -% accessed only vie appropriate interface macros. +% accessed only via appropriate interface macros. @@ -141,33 +141,31 @@ % Add a moveto element to the current path \def\pgfsyssoftpath@moveto#1#2{% - \edef\pgfsyssoftpath@temp{{% - \noexpand\pgfsyssoftpath@movetotoken{#1}{#2}% - }}% - \expandafter\pgfsyssoftpath@addtocurrentpath\pgfsyssoftpath@temp% + \edef\pgfsyssoftpath@coord{{#1}{#2}}% + \expandafter\pgfsyssoftpath@addtocurrentpath\expandafter{\expandafter\pgfsyssoftpath@movetotoken\pgfsyssoftpath@coord}% \ifpgfsyssoftpathmovetorelevant% - \xdef\pgfsyssoftpath@lastmoveto{{#1}{#2}}% + \global\let\pgfsyssoftpath@lastmoveto\pgfsyssoftpath@coord% \fi% } % Add a lineto element to the current path \def\pgfsyssoftpath@lineto#1#2{% - \edef\pgfsyssoftpath@temp{{% - \noexpand\pgfsyssoftpath@linetotoken{#1}{#2}% - }}% - \expandafter\pgfsyssoftpath@addtocurrentpath\pgfsyssoftpath@temp% + \edef\pgfsyssoftpath@coord{{#1}{#2}}% + \expandafter\pgfsyssoftpath@addtocurrentpath\expandafter{\expandafter\pgfsyssoftpath@linetotoken\pgfsyssoftpath@coord}% } + % Add curveto elements to the current path \def\pgfsyssoftpath@curveto#1#2#3#4#5#6{% \edef\pgfsyssoftpath@temp{{% - \noexpand\pgfsyssoftpath@curvetosupportatoken{#1}{#2}% - \noexpand\pgfsyssoftpath@curvetosupportbtoken{#3}{#4}% - \noexpand\pgfsyssoftpath@curvetotoken{#5}{#6}% - }}% + \noexpand\pgfsyssoftpath@curvetosupportatoken{#1}{#2}% + \noexpand\pgfsyssoftpath@curvetosupportbtoken{#3}{#4}% + \noexpand\pgfsyssoftpath@curvetotoken{#5}{#6}% + }}% \expandafter\pgfsyssoftpath@addtocurrentpath\pgfsyssoftpath@temp% } + % Add rectanlge elements to the current path \def\pgfsyssoftpath@rect#1#2#3#4{% \edef\pgfsyssoftpath@temp{{% @@ -179,18 +177,13 @@ % Add closepath element to the current path \def\pgfsyssoftpath@closepath{% - \edef\pgfsyssoftpath@temp{{% - \noexpand\pgfsyssoftpath@closepathtoken\pgfsyssoftpath@lastmoveto% - }}% - \expandafter\pgfsyssoftpath@addtocurrentpath\pgfsyssoftpath@temp% + \expandafter\pgfsyssoftpath@addtocurrentpath\expandafter{\expandafter\pgfsyssoftpath@closepathtoken\pgfsyssoftpath@lastmoveto}% } % Add special element to the current path \def\pgfsyssoftpath@specialround#1#2{% - \edef\pgfsyssoftpath@temp{{% - \noexpand\pgfsyssoftpath@specialroundtoken{#1}{#2}% - }}% - \expandafter\pgfsyssoftpath@addtocurrentpath\pgfsyssoftpath@temp% + \edef\pgfsyssoftpath@temp{{#1}{#2}}% + \expandafter\pgfsyssoftpath@addtocurrentpath\expandafter{\expandafter\pgfsyssoftpath@specialroundtoken\pgfsyssoftpath@temp}% } % Marshallers @@ -200,6 +193,8 @@ \def\pgfsyssoftpath@curvetosupportatoken#1#2#3#4#5#6#7#8{\pgfsys@curveto{#1}{#2}{#4}{#5}{#7}{#8}} \def\pgfsyssoftpath@closepathtoken#1#2{\pgfsys@closepath} \let\pgfsyssoftpath@specialroundtoken=\pgfutil@gobbletwo +\def\pgfsyssoftpath@curvetosupportbtoken#1#2{curvetotokenb} % make sure this this \ifx-equal only to itself +\def\pgfsyssoftpath@curvetotoken#1#2{curvetotoken}% make sure this this \ifx-equal only to itself \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/utilities/pgffor.code.tex b/Master/texmf-dist/tex/generic/pgf/utilities/pgffor.code.tex index d31ddedfe26..e984ca06315 100644 --- a/Master/texmf-dist/tex/generic/pgf/utilities/pgffor.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/utilities/pgffor.code.tex @@ -7,17 +7,23 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/utilities/pgffor.code.tex,v 1.18 2010/03/23 14:47:45 vibrovski Exp $ +\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/utilities/pgffor.code.tex,v 1.25 2013/12/13 11:40:27 tantau Exp $ +% pgfmath is needed +\input pgfmath.code.tex \newdimen\pgffor@iter \newdimen\pgffor@skip \newif\ifpgffor@continue -\let\pgffor@beginhook=\pgfutil@empty -\let\pgffor@endhook=\pgfutil@empty -\let\pgffor@afterhook=\pgfutil@empty +\def\pgffor@reset@hooks{% + \let\pgffor@beginhook=\relax% + \let\pgffor@endhook=\relax% + \let\pgffor@afterhook=\relax% +} +\pgffor@reset@hooks + % Stack emulation % @@ -133,20 +139,20 @@ } \def\pgffor@iterate{% - % Must do all of these in case the internal stack is used. - \let\pgffor@last=\pgfutil@empty% + % Must do all of these in case the internal stack is used. + \let\pgffor@last=\pgfutil@empty% \let\pgffor@prevlast=\pgfutil@empty% \let\pgffor@dotsend=\pgfutil@empty% - \let\pgffor@dots@pre=\pgfutil@empty% - \let\pgffor@dots@post=\pgfutil@empty% - % - \expandafter\pgffor@scan\pgffor@values} + \let\pgffor@dots@pre=\pgfutil@empty% + \let\pgffor@dots@post=\pgfutil@empty% + % + \expandafter\pgffor@scan\pgffor@values} \def\pgffor@stop{\pgffor@stop}% \def\pgffor@dots{...}% \def\pgffor@scan{\pgfutil@ifnextchar({\pgffor@scanround}{\pgffor@scanone}} -\def\pgffor@scanround(#1)#2,{\def\pgffor@value{(#1)}\pgffor@scanned} +\def\pgffor@scanround(#1)#2,{\def\pgffor@value{(#1)#2}\pgffor@scanned} \def\pgffor@scanone#1,{\def\pgffor@value{#1}\pgffor@scanned} @@ -215,7 +221,7 @@ \pgffor@assign@before@code% \fi% % - \expandafter\pgffor@beginhook\pgffor@body\pgffor@endhook% + \expandafter\expandafter\expandafter\pgffor@reset@hooks\expandafter\pgffor@beginhook\expandafter\pgffor@body\pgffor@endhook% % Execute assign after code. \ifx\pgffor@assign@after@code\pgfutil@empty% \else% @@ -373,7 +379,7 @@ \pgffor@assign@before@code% \fi% % - \expandafter\pgffor@beginhook\pgffor@body\pgffor@endhook% + \expandafter\expandafter\expandafter\pgffor@reset@hooks\expandafter\pgffor@beginhook\expandafter\pgffor@body\pgffor@endhook% % % Perform assignments after loop body. \ifx\pgffor@assign@after@code\pgfutil@empty% @@ -448,23 +454,21 @@ % Convert the number in the macro passed as #1 to a-z or A-Z. \pgfutil@tempcnta=#1\relax% \ifnum\pgfutil@tempcnta>95\relax% - \advance\pgfutil@tempcnta by-96% - \expandafter\def\expandafter#1\expandafter% - {\pgffor@alpha\pgfutil@tempcnta}% + \advance\pgfutil@tempcnta by-96\relax% + \edef#1{\pgffor@alpha\pgfutil@tempcnta}% \else% - \advance\pgfutil@tempcnta by-64% - \expandafter\def\expandafter#1\expandafter% - {\pgffor@Alpha\pgfutil@tempcnta}% + \advance\pgfutil@tempcnta by-64 % + \edef#1{\pgffor@Alpha\pgfutil@tempcnta}% \fi% } \def\pgffor@Alpha#1{% - \ifcase#1\or A\or B\or C\or D\or E\or F\or G\or H\or I\or J\or K\or L\or M% + \ifcase#1\relax\or A\or B\or C\or D\or E\or F\or G\or H\or I\or J\or K\or L\or M% \or N\or O\or P\or Q\or R\or S\or T\or U\or V\or W\or X\or Y\or Z\else?\fi% } \def\pgffor@alpha#1{% - \ifcase#1\or a\or b\or c\or d\or e\or f\or g\or h\or i\or j\or k\or l\or m% + \ifcase#1\relax\or a\or b\or c\or d\or e\or f\or g\or h\or i\or j\or k\or l\or m% \or n\or o\or p\or q\or r\or s\or t\or u\or v\or w\or x\or y\or z\else?\fi% } @@ -482,12 +486,12 @@ \begingroup% \escapechar=-1\relax% \expandafter\pgffor@@addiftotoks\string#1\pgffor@stop} -\def\pgffor@@addiftotoks#1#2#3#4#5\pgffor@stop{% +\def\pgffor@@addiftotoks#1#2#3#4\pgffor@stop{% \endgroup - \csname if#4#5\endcsname% - \expandafter\def\expandafter\pgffor@tokstemp\expandafter{\csname#4#5true\endcsname}% + \csname if#3#4\endcsname% + \expandafter\def\expandafter\pgffor@tokstemp\expandafter{\csname#3#4true\endcsname}% \else% - \expandafter\def\expandafter\pgffor@tokstemp\expandafter{\csname#4#5false\endcsname}% + \expandafter\def\expandafter\pgffor@tokstemp\expandafter{\csname#3#4false\endcsname}% \fi% \pgffor@@addcstotoks% } @@ -520,28 +524,32 @@ \let\pgffor@remember@expanded=\pgfutil@empty \def\pgffor@default@endgroup{% - \ifx\pgffor@assign@once@code\pgfutil@empty% - \else% - \global\edef\pgffor@remember@once@expanded{\pgffor@remember@once@code}% - \fi% - \ifx\pgffor@remember@code\pgfutil@empty% - \else% - \global\edef\pgffor@remember@expanded{\pgffor@remember@code}% - \fi% - \endgroup% - % - \ifx\pgffor@remember@once@expanded\pgfutil@empty% - \else% - \pgffor@remember@once@expanded% - \let\pgffor@assign@once@code=\pgfutil@empty% - \global\let\pgffor@remember@once@expanded=\pgfutil@empty% - \fi% - % - \ifx\pgffor@remember@expanded\pgfutil@empty% - \else% - \pgffor@remember@expanded% - \global\let\pgffor@remember@expanded=\pgfutil@empty% - \fi% + \ifx\pgffor@remember@once@code\pgfutil@empty + \else + \xdef\pgffor@remember@once@expanded{\pgffor@remember@once@code}% + \fi + \ifx\pgffor@remember@code\pgfutil@empty + \else + \xdef\pgffor@remember@expanded{\pgffor@remember@code}% + \fi + \endgroup + % + \ifx\pgffor@remember@once@expanded\pgfutil@empty + \else + \pgffor@remember@once@expanded% + % \let\pgffor@assign@once@code=\pgfutil@empty % Not needed anymore? (CJ) + \global\let\pgffor@remember@once@expanded=\pgfutil@empty + \fi + \ifx\pgffor@assign@once@code\pgfutil@empty + \else + \global\let\pgffor@assign@once@code=\pgfutil@empty + \fi + % + \ifx\pgffor@remember@expanded\pgfutil@empty + \else + \pgffor@remember@expanded% + \global\let\pgffor@remember@expanded=\pgfutil@empty + \fi } \let\pgffor@begingroup=\pgffor@default@begingroup diff --git a/Master/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex b/Master/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex index 86e0499ded7..3d79735459d 100644 --- a/Master/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex @@ -25,8 +25,14 @@ % This is useful: +\newif\ifpgfkeys@csname@test% + +\def\pgfkeys@ifcsname#1\endcsname#2\else#3\fi{% + \pgfkeys@csname@testfalse% + \expandafter\ifx\csname#1\endcsname\relax\else\expandafter\ifx\csname#1\endcsname\@undefined\else\pgfkeys@csname@testtrue\fi\fi% + \ifpgfkeys@csname@test#2\else#3\fi% +}% -\def\pgfkeys@ifcsname#1\endcsname#2\else#3\fi{\expandafter\ifx\csname#1\endcsname\relax#3\else#2\fi}% \ifx\eTeXrevision\undefined% \else% \expandafter\let\expandafter\pgfkeys@ifcsname\csname ifcsname\endcsname% @@ -37,7 +43,7 @@ % This also: \ifx\PackageError\undefined - \def\pgfkeys@error#1{\immediate\write-1{Package pgfkeys: Error! #1.}}% + \def\pgfkeys@error#1{\errmessage{Package pgfkeys Error: #1.}}% \else \def\pgfkeys@error#1{\PackageError{pgfkeys}{#1}{}}% \fi @@ -180,10 +186,10 @@ % for handled keys). \long\def\pgfkeysifassignable#1#2#3{% \pgfkeysifdefined{#1}% - {#2} - {\pgfkeysifdefined{#1/.@cmd}% - {#2}% - {#3}}% + {#2} + {\pgfkeysifdefined{#1/.@cmd}% + {#2}% + {#3}}% }% @@ -286,14 +292,37 @@ \expandafter\pgfkeys@normal% \fi% } -\long\def\pgfkeys@normal#1,{% +\newif\ifpgfkeys@syntax@handlers +\def\pgfkeys@normal{% + \ifpgfkeys@syntax@handlers% + \expandafter\pgfkeys@syntax@handlers% + \else% + \expandafter\pgfkeys@@normal% + \fi% +} +\def\pgfkeys@syntax@handlers{\pgf@keys@utilifnextchar\relax\pgfkeys@syntax@@handlers\pgfkeys@syntax@@handlers}%get rid of spaces +\def\pgfkeys@syntax@@handlers{\futurelet\pgfkeys@first@char\pgfkeys@syntax@handlers@test} +\def\pgfkeys@syntax@handlers@test{% + \pgfkeysgetvalue{/handlers/first char syntax/\meaning\pgfkeys@first@char}\pgfkeys@the@handler% + \ifx\pgfkeys@the@handler\relax% + \expandafter\pgfkeys@@normal% + \else% + \expandafter\pgfkeys@use@handler% + \fi% +} +\long\def\pgfkeys@use@handler#1,{% + \pgfkeys@the@handler{#1}% + \pgfkeys@parse% +} + +\long\def\pgfkeys@@normal#1,{% \pgfkeys@unpack#1=\pgfkeysnovalue=\pgfkeys@stop% \pgfkeys@parse% } \def\pgfkeys@cleanup\pgfkeys@mainstop{} \def\pgfkeys@mainstop{\pgfkeys@mainstop} % equals only itself -\def\pgfkeys@novalue{} % equals only itself +\def\pgfkeys@novalue{} \def\pgfkeysnovalue{\pgfkeys@novalue} % equals only itself \def\pgfkeysnovalue@text{\pgfkeysnovalue} \def\pgfkeysvaluerequired{\pgfkeysvaluerequired} % equals only itself @@ -312,7 +341,8 @@ {}% no default, so leave it \fi% \ifx\pgfkeyscurrentvalue\pgfkeysvaluerequired% - \pgfkeysvalueof{/errors/value required/.@cmd}\pgfkeyscurrentkey\pgfkeyscurrentvalue\pgfeov% + \def\pgf@marshal{\pgfkeysvalueof{/errors/value required/.@cmd}}% + \expandafter\pgf@marshal\expandafter{\pgfkeyscurrentkey}{}\pgfeov% \else% \pgfkeys@case@one% \fi% @@ -356,30 +386,30 @@ \pgfkeys@split@path% \pgfkeysifdefined{/handlers/\pgfkeyscurrentname/.@cmd}{% \pgfkeys@ifexecutehandler{% - \pgfkeysgetvalue{/handlers/\pgfkeyscurrentname/.@cmd}{\pgfkeys@code}% + \pgfkeysgetvalue{/handlers/\pgfkeyscurrentname/.@cmd}{\pgfkeys@code}% \expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov - }{% + }{% % this here is necessary: /my search path/key/.code % won't be called, so \pgfkeyscurrentpath == '/my search path/key' % -> it should be one directory higher! We want to invoke the - % .unknown handler in - % '/my search path' - % - % Idea: - % set - % - path := '/my search path' - % - name := 'key/.code' - % - key = '/my search path/key/.code' - \let\pgfkeys@temp=\pgfkeyscurrentkey - \let\pgfkeys@tempb=\pgfkeyscurrentname + % .unknown handler in + % '/my search path' + % + % Idea: + % set + % - path := '/my search path' + % - name := 'key/.code' + % - key = '/my search path/key/.code' + \let\pgfkeys@temp=\pgfkeyscurrentkey + \let\pgfkeys@tempb=\pgfkeyscurrentname \edef\pgfkeyscurrentkey{\pgfkeyscurrentpath}% \pgfkeys@split@path% - \let\pgfkeyscurrentkey=\pgfkeys@temp - \edef\pgfkeyscurrentname{\pgfkeyscurrentname/\pgfkeys@tempb}% - \pgfkeys@unknown - }% + \let\pgfkeyscurrentkey=\pgfkeys@temp + \edef\pgfkeyscurrentname{\pgfkeyscurrentname/\pgfkeys@tempb}% + \pgfkeys@unknown + }% }{% - \pgfkeys@unknown + \pgfkeys@unknown }% } @@ -394,37 +424,31 @@ \else % implement the 'only existing' feature here: \pgfkeysifdefined{\pgfkeyscurrentpath}{#1}{% - \pgfkeysifdefined{\pgfkeyscurrentpath/.@cmd}{#1}{#2}% + \pgfkeysifdefined{\pgfkeyscurrentpath/.@cmd}{#1}{#2}% }{}% \fi% }% \def\pgfkeys@ifexecutehandler@handlefullorexisting#1#2{% \ifpgfkeysaddeddefaultpath \pgfkeys@ifcsname pgfk@excpt@\pgfkeyscurrentname\endcsname% -%\message{ifexecutehandler(\pgfkeyscurrentkeyRAW, path \pgfkeysdefaultpath): '\pgfkeyscurrentname' is an exception; processing it (on \pgfkeyscurrentpath).}% #1% ok, this particular key handler is known and be processed in any case (for example .try) \else % implement the 'only existing' feature here: \pgfkeysifdefined{\pgfkeyscurrentpath}{% -%\message{ifexecutehandler(\pgfkeyscurrentkeyRAW, path \pgfkeysdefaultpath): '\pgfkeyscurrentpath' does exist. Executing '\pgfkeyscurrentname'.}% - #1% - }{% - \pgfkeysifdefined{\pgfkeyscurrentpath/.@cmd}{% -%\message{ifexecutehandler(\pgfkeyscurrentkeyRAW, path \pgfkeysdefaultpath): '\pgfkeyscurrentpath/.@cmd' does exist. Executing '\pgfkeyscurrentname'.}% - #1% - }{% -%\message{ifexecutehandler(\pgfkeyscurrentkeyRAW, path \pgfkeysdefaultpath): '\pgfkeyscurrentpath' does NOT exist. Skipping '\pgfkeyscurrentname'.}% - #2% - }% - }% + #1% + }{% + \pgfkeysifdefined{\pgfkeyscurrentpath/.@cmd}{% + #1% + }{% + #2% + }% + }% \fi% \else -%\message{ifexecutehandler(\pgfkeyscurrentkeyRAW, path \pgfkeysdefaultpath): Fully qualified key provided. Executing '\pgfkeyscurrentname'.}% #1% ok, always true if the USER explicitly provided the full key path. \fi }% -\def\pgfkeysaddhandlyonlyexistingexception#1{\expandafter\def\csname pgfk@excpt@#1\endcsname{1}}% - +\def\pgfkeysaddhandleonlyexistingexception#1{\expandafter\def\csname pgfk@excpt@#1\endcsname{1}}% \def\pgfkeys@unknown{% \pgfkeysifdefined{\pgfkeyscurrentpath/.unknown/.@cmd}% @@ -579,10 +603,12 @@ \long\def\pgfkeysdef#1#2{% \long\def\pgfkeys@temp##1\pgfeov{#2}% \pgfkeyslet{#1/.@cmd}{\pgfkeys@temp}% + \pgfkeyssetvalue{#1/.@body}{#2}% } \long\def\pgfkeysedef#1#2{% \long\edef\pgfkeys@temp##1\pgfeov{#2}% \pgfkeyslet{#1/.@cmd}{\pgfkeys@temp}% + \pgfkeyssetvalue{#1/.@body}{#2}% } @@ -628,27 +654,27 @@ % % defnargs: % \pgfkeysdefnargs{/a}{2}{1=`#1', 2=`#2'} % \pgfkeys{ -% /a= -% {1} -% {2} +% /a= +% {1} +% {2} % } % ->defnargs: 1=`1', 2=`2' % % defargs: % \pgfkeysdefargs{/b}{#1#2}{1=`#1', 2=`#2'} % \pgfkeys{ -% /b= -% {1} -% {2} +% /b= +% {1} +% {2} % } % ->defargs: 1=`1', 2=` 2' (note the space!) % % defargs: % \pgfkeysdefargs{/b}{#1#2}{1=`#1', 2=`#2'} % \pgfkeys{ -% /b= -% {1}% -% {2} +% /b= +% {1}% +% {2} % } % ->defargs: 1=`1', 2=`2' %-------------------------------------------------- @@ -656,32 +682,30 @@ \long\def\pgfkeysedefnargs#1#2#3{\pgfkeysdefnargs@{#1}{#2}{#3}{\edef}}% \long\def\pgfkeysdefnargs@#1#2#3#4{% \ifcase#2\relax - \pgfkeyssetvalue{#1/.@args}{}% + \pgfkeyssetvalue{#1/.@args}{}% \or - \pgfkeyssetvalue{#1/.@args}{##1}% + \pgfkeyssetvalue{#1/.@args}{##1}% \or - \pgfkeyssetvalue{#1/.@args}{##1##2}% + \pgfkeyssetvalue{#1/.@args}{##1##2}% \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3}% + \pgfkeyssetvalue{#1/.@args}{##1##2##3}% \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4}% + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4}% \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5}% + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5}% \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6}% + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6}% \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6}% + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7}% \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7}% + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8}% \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8##9}% + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8##9}% \else - \pgfkeys@error{\string\pgfkeysdefnargs: expected <= 9 arguments, got #2}% + \pgfkeys@error{\string\pgfkeysdefnargs: expected <= 9 arguments, got #2}% \fi \pgfkeysgetvalue{#1/.@args}\pgfkeys@tempargs - \def\pgfkeys@temp{\expandafter#4\csname pgfk@#1/.@@body\endcsname}% + \def\pgfkeys@temp{\expandafter\long\expandafter#4\csname pgfk@#1/.@@body\endcsname}% \expandafter\pgfkeys@temp\pgfkeys@tempargs{#3}% % eliminate the \pgfeov at the end such that TeX gobbles spaces % by using @@ -712,34 +736,37 @@ % Find out, whether with args or not. \pgfkeysifdefined{\pgfkeyscurrentpath/.@args}% {% Yes, so add to body and reuse args - \pgfkeysaddvalue{\pgfkeyscurrentpath/.@body}{#1}{#2}% - % Redefine code - {% - \pgfkeysgetvalue{\pgfkeyscurrentpath/.@args}{\pgfkeys@tempargs}% - \pgfkeysgetvalue{\pgfkeyscurrentpath/.@body}{\pgfkeys@tempbody}% - \def\pgfkeys@marshal{\expandafter\gdef\expandafter\pgfkeys@global@temp\pgfkeys@tempargs}% - \expandafter\pgfkeys@marshal\expandafter{\pgfkeys@tempbody}% - }% + \pgfkeysaddvalue{\pgfkeyscurrentpath/.@body}{#1}{#2}% + % Redefine code + {% + \pgfkeysgetvalue{\pgfkeyscurrentpath/.@args}{\pgfkeys@tempargs}% + \pgfkeysgetvalue{\pgfkeyscurrentpath/.@body}{\pgfkeys@tempbody}% + \def\pgfkeys@marshal{\expandafter\gdef\expandafter\pgfkeys@global@temp\pgfkeys@tempargs}% + \expandafter\pgfkeys@marshal\expandafter{\pgfkeys@tempbody}% + }% \pgfkeysifdefined{\pgfkeyscurrentpath/.@@body}{% - % support for \pgfkeysndefargs: - \pgfkeyslet{\pgfkeyscurrentpath/.@@body}{\pgfkeys@global@temp}% - }{% - % support for \pgfkeysdefargs: + % support for \pgfkeysndefargs: + \pgfkeyslet{\pgfkeyscurrentpath/.@@body}{\pgfkeys@global@temp}% + }{% + % support for \pgfkeysdefargs: \pgfkeyslet{\pgfkeyscurrentpath/.@cmd}{\pgfkeys@global@temp}% - }% + }% }% {% % No, so single argument (simple \pgfkeysdef). Redefine accordingly. + \edef\pgf@expanded@path{\pgfkeyscurrentpath}% {% \toks0{#1}% - \pgfkeysifdefined{\pgfkeyscurrentpath/.@cmd}% - {\pgfkeys@temptoks\expandafter\expandafter\expandafter{\csname pgfk@\pgfkeyscurrentpath/.@cmd\endcsname##1\pgfeov}}% - {\pgfkeys@temptoks{}}% + \pgfkeysifdefined{\pgf@expanded@path/.@cmd}% + {\expandafter\expandafter\expandafter\pgfkeys@temptoks\expandafter\expandafter\expandafter{\csname pgfk@\pgf@expanded@path/.@body\endcsname}}% + {\expandafter\pgfkeys@temptoks\expandafter{\expandafter\pgfkeyssetvalue\expandafter{\pgf@expanded@path}{##1}}}% \toks1{#2}% \xdef\pgfkeys@global@temp{\the\toks0 \the\pgfkeys@temptoks \the\toks1 }% }% - \expandafter\def\expandafter\pgfkeys@temp\expandafter##\expandafter1\expandafter\pgfeov\expandafter{\pgfkeys@global@temp}% - \pgfkeyslet{\pgfkeyscurrentpath/.@cmd}\pgfkeys@temp% + \def\pgf@temp{\pgfkeyssetvalue{\pgf@expanded@path/.@body}}% + \expandafter\pgf@temp\expandafter{\pgfkeys@global@temp}% + \expandafter\long\expandafter\def\expandafter\pgfkeys@temp\expandafter##\expandafter1\expandafter\pgfeov\expandafter{\pgfkeys@global@temp}% + \pgfkeyslet{\pgf@expanded@path/.@cmd}\pgfkeys@temp% }% } \pgfkeys{/handlers/.prefix code/.code=\pgfkeys{\pgfkeyscurrentpath/.add code={#1}{}}}% @@ -780,7 +807,8 @@ {% \ifx\pgfkeyscurrentvalue\pgfkeysnovalue@text% \else% - \pgfkeysvalueof{/errors/value forbidden/.@cmd}\pgfkeyscurrentkey\pgfkeyscurrentvalue\pgfeov% + \def\pgf@marshal{\pgfkeysvalueof{/errors/value forbidden/.@cmd}}% + \expandafter\expandafter\expandafter\pgf@marshal\expandafter\expandafter\expandafter{\expandafter\pgfkeyscurrentkey\expandafter}\expandafter{\pgfkeyscurrentvalue}\pgfeov% \fi% }{}}} @@ -799,23 +827,32 @@ \pgfkeys@ifcsname#1#2\endcsname% \csname#1#2\endcsname% \else% - \pgfkeysvalueof{/errors/boolean expected/.@cmd}\pgfkeyscurrentkey{#2}\pgfeov% + \def\pgf@marshal{\pgfkeysvalueof{/errors/boolean expected/.@cmd}}% + \expandafter\pgf@marshal\expandafter{\pgfkeyscurrentkey}{#2}\pgfeov% \fi } \pgfkeys{/handlers/.is choice/.code=% \pgfkeys{% \pgfkeyscurrentpath/.cd,% - .code=\expandafter\pgfkeysalso\expandafter{\pgfkeyscurrentkey/##1}, - .unknown/.style={/errors/unknown choice value=\pgfkeyscurrentkey\pgfkeyscurrentvalue}}} + .code=\def\pgfkeys@was@choice{##1}\expandafter\pgfkeysalso\expandafter{\pgfkeyscurrentkey/##1}, + .unknown/.code={% + \def\pgf@marshal{\pgfkeysvalueof{/errors/unknown choice value/.@cmd}}% + {\expandafter\expandafter\expandafter\pgf@marshal\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgfkeys@pathtoks\expandafter}\expandafter{\pgfkeys@was@choice}\pgfeov}% + }% + }% +} % Repeatedly setting a key \pgfkeys{/handlers/.list/.code=% {% + \ifx\foreach\@undefined% + \pgfkeys@error{You need to load the pgffor package to use the .list key syntax.}% + \fi% % Use foreach to unfold the list - \let\pgf@keys@temp=\pgfutil@empty% + \def\pgf@keys@temp{}% \foreach \pgf@keys@key in{#1}% {\expandafter\expandafter\expandafter\gdef% \expandafter\expandafter\expandafter\pgf@keys@temp% @@ -825,10 +862,16 @@ \expandafter\expandafter\expandafter{\expandafter\pgf@keys@list@path\expandafter}\pgf@keys@temp\pgf@stop% }% } -\def\pgf@keys@do@list#1{\pgfutil@ifnextchar\bgroup{\pgf@keys@do@list@item{#1}}\pgfutil@gobble} +\def\pgf@keys@do@list#1{\pgf@keys@utilifnextchar\bgroup{\pgf@keys@do@list@item{#1}}\pgf@keys@gobble} \def\pgf@keys@do@list@item#1#2{\pgfkeysalso{#1={#2}}\pgf@keys@do@list{#1}} +% Forwarding + +\pgfkeys{/handlers/.forward to/.code=% + \pgfkeys{\pgfkeyscurrentpath/.add code={}{\pgfkeys{#1={##1}}}} +} + % Inspection handlers @@ -836,6 +879,9 @@ \pgfkeys{/handlers/.show code/.code=\pgfkeysgetvalue{\pgfkeyscurrentpath/.@cmd}{\pgfkeysshower}\show\pgfkeysshower} % inspect the body of the command +% First char syntax handlers +\pgfkeys{/handlers/first char syntax/.is if=pgfkeys@syntax@handlers} + % Path handling % Prepares the .unknown handler used by '.search also'. @@ -844,22 +890,23 @@ \global\def\pgfkeys@global@temp##1\pgfeov{}% \pgfkeys@searchalso@parse#1,\pgfkeys@mainstop {% - \toks0=\expandafter{\pgfkeys@global@temp##1\pgfeov}% - \toks1={\def\pgfutilnext{\pgfkeysvalueof{/handlers/.unknown/.@cmd}##1\pgfeov}\pgfutilnext}% - \xdef\pgfkeys@global@temp{% - \noexpand\ifpgfkeysaddeddefaultpath - \noexpand\pgfkeyssuccessfalse - \noexpand\let\noexpand\pgfkeys@searchalso@name=\noexpand\pgfkeyscurrentkeyRAW - \the\toks0 % one or more /.try things; one for each path. The last element won't have a /.try - %\noexpand\ifpgfkeyssuccess - %\noexpand\else - % \the\toks1 % invoke /handlers/.unknown handler - %\noexpand\fi - \noexpand\else - \the\toks1 % invoke /handlers/.unknown handler - \noexpand\fi - }% - \expandafter\gdef\expandafter\pgfkeys@global@temp\expandafter##\expandafter1\expandafter\pgfeov\expandafter{\pgfkeys@global@temp}% + \toks0=\expandafter{\pgfkeys@global@temp##1\pgfeov}% + \toks1={\pgfkeysalso{/handlers/.unknown/.@cmd/.expand once=\pgfkeys@searchalso@temp@value}}% + \xdef\pgfkeys@global@temp{% + \noexpand\def\noexpand\pgfkeys@searchalso@temp@value{####1}% + \noexpand\ifpgfkeysaddeddefaultpath + \noexpand\pgfkeyssuccessfalse + \noexpand\let\noexpand\pgfkeys@searchalso@name=\noexpand\pgfkeyscurrentkeyRAW + \the\toks0 % one or more /.try things; one for each path. The last element won't have a /.try + %\noexpand\ifpgfkeyssuccess + %\noexpand\else + % \the\toks1 % invoke /handlers/.unknown handler + %\noexpand\fi + \noexpand\else + \the\toks1 % invoke /handlers/.unknown handler + \noexpand\fi + }% + \expandafter\gdef\expandafter\pgfkeys@global@temp\expandafter##\expandafter1\expandafter\pgfeov\expandafter{\pgfkeys@global@temp}% }% }% @@ -876,36 +923,36 @@ \pgfkeys@spdef\pgfkeys@temp{#1}% {% \toks0=\expandafter{\pgfkeys@global@temp##1\pgfeov}% - \toks1=\expandafter{\pgfkeys@temp}% - \toks2={##1}% - \xdef\pgfkeys@global@temp{% - \the\toks0 % the space is important! - \noexpand\ifpgfkeyssuccess\noexpand\else - \noexpand\pgfqkeys{\the\toks1 }{\noexpand\pgfkeys@searchalso@name - \ifx\pgfkeys@searchalso@nexttok\pgfkeys@mainstop\else/.try\fi={\the\toks2 }}% - \noexpand\fi}% - \expandafter\gdef\expandafter\pgfkeys@global@temp\expandafter##\expandafter1\expandafter\pgfeov\expandafter{\pgfkeys@global@temp}% + \toks1=\expandafter{\pgfkeys@temp}% + \xdef\pgfkeys@global@temp{% + \the\toks0 % the space is important! + \noexpand\ifpgfkeyssuccess\noexpand\else + \noexpand\pgfqkeys{\the\toks1 }{\noexpand\pgfkeys@searchalso@name + \ifx\pgfkeys@searchalso@nexttok\pgfkeys@mainstop\else/.try\fi /.expand once=\noexpand\pgfkeys@searchalso@temp@value}% + \noexpand\fi}% + \expandafter\gdef\expandafter\pgfkeys@global@temp\expandafter##\expandafter1\expandafter\pgfeov\expandafter{\pgfkeys@global@temp}% }% \pgfkeys@searchalso@parse#2% } \pgfkeys{% - /handlers/.is family/.code=\pgfkeys{\pgfkeyscurrentpath/.ecode=\edef\noexpand\pgfkeysdefaultpath{\pgfkeyscurrentpath/}},% - /handlers/.cd/.code=\edef\pgfkeysdefaultpath{\pgfkeyscurrentpath/},% - /handlers/.search also/.code={% - \pgfkeys@searchalso@prepare@unknown@handler{#1}% + /handlers/.is family/.code=\pgfkeys{\pgfkeyscurrentpath/.ecode=\edef\noexpand\pgfkeysdefaultpath{\pgfkeyscurrentpath/}},% + /handlers/.cd/.code=\edef\pgfkeysdefaultpath{\pgfkeyscurrentpath/},% + /handlers/.search also/.code={% + \pgfkeys@searchalso@prepare@unknown@handler{#1}% %\message{I prepared the '\pgfkeyscurrentpath/.unknown' handler \meaning\pgfkeys@global@temp\space for '#1'.}% - \pgfkeyslet{\pgfkeyscurrentpath/.unknown/.@cmd}{\pgfkeys@global@temp}% - } + \pgfkeyslet{\pgfkeyscurrentpath/.unknown/.@cmd}{\pgfkeys@global@temp}% + } }% % Value expansion \pgfkeys{/handlers/.expand once/.code=\expandafter\pgfkeys@exp@call\expandafter{#1}} +\pgfkeys{/handlers/.expand two once/.code 2 args=\expandafter\expandafter\expandafter\pgfkeys@exp@call\expandafter\expandafter\expandafter{\expandafter#1\expandafter}\expandafter{#2}} \pgfkeys{/handlers/.expand twice/.code=\expandafter\expandafter\expandafter\pgfkeys@exp@call\expandafter\expandafter\expandafter{#1}} \pgfkeys{/handlers/.expanded/.code=\edef\pgfkeys@temp{#1}\expandafter\pgfkeys@exp@call\expandafter{\pgfkeys@temp}} -\def\pgfkeys@exp@call#1{\pgfkeysalso{\pgfkeyscurrentpath={#1}}} +\long\def\pgfkeys@exp@call#1{\pgfkeysalso{\pgfkeyscurrentpath={#1}}} % Try to set a key and do nothing if not define @@ -938,20 +985,20 @@ {% \pgfkeys@split@path% \pgfkeysifdefined{/handlers/\pgfkeyscurrentname/.@cmd}{% - % in the standard configuration, this check here is redundand - % because pgfkeys@ifexecutehandler === true. - % It is only interesting for 'handle only existing'. + % in the standard configuration, this check here is redundand + % because pgfkeys@ifexecutehandler === true. + % It is only interesting for 'handle only existing'. \pgfkeys@ifexecutehandler{% - \pgfkeysgetvalue{/handlers/\pgfkeyscurrentname/.@cmd}{\pgfkeys@code}% + \pgfkeysgetvalue{/handlers/\pgfkeyscurrentname/.@cmd}{\pgfkeys@code}% \expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov \pgfkeyssuccesstrue% - }{% - \pgfkeyssuccessfalse - }% }{% - \pgfkeyssuccessfalse + \pgfkeyssuccessfalse }% - }% + }{% + \pgfkeyssuccessfalse + }% + }% }% } @@ -962,49 +1009,111 @@ % Errors -\pgfkeys{/errors/boolean expected/.code 2 args=\pgfkeys@error{% - Boolean parameter of key '#1' must be 'true' or 'false', not - '#2'. I am going to ignore it}} -\pgfkeys{/errors/value required/.code 2 args=\pgfkeys@error{% - The key '#1' requires a value. I am going to ignore this key}{}} -\pgfkeys{/errors/value forbidden/.code 2 args=\pgfkeys@error{% - You may not specify a value for the key '#1'. I am going to ignore - the value '#2' that you provided}} -\pgfkeys{/errors/unknown choice value/.code 2 args=\pgfkeys@error{% - Choice '\pgfkeyscurrentname' unknown in key - '\pgfkeyscurrentpath'. I am going to ignore this key}} -\pgfkeys{/errors/unknown key/.code 2 args=\pgfkeys@error{% - I do not know the key '#1' and I am going to ignore it. Perhaps - you misspelled it}} +\pgfkeys{ + /errors/boolean expected/.code 2 args=% + { + \toks1={#1} + \toks2={#2} + \pgfkeys@error{% + Boolean parameter of key '\the\toks1' must be 'true' or 'false', not + '\the\toks2'. I am going to ignore it% + } + }, + /errors/value required/.code 2 args=% + { + \toks1={#1} + \pgfkeys@error{% + The key '\the\toks1' requires a value. I am going to ignore this + key% + } + }, + /errors/value forbidden/.code 2 args=% + { + \toks1={#1} + \toks2={#2} + \pgfkeys@error{% + You may not specify a value for the key '\the\toks1'. I am going to ignore + the value '\the\toks2' that you provided% + } + }, + /errors/unknown choice value/.code 2 args=% + { + \toks1={#1} + \toks2={#2} + \pgfkeys@error{% + Choice '\the\toks2' unknown in choice key '\the\toks1'. I am + going to ignore this key% + } + }, + /errors/unknown key/.code 2 args=% + { + \toks1={#1} + \toks2={#2} + \def\pgf@temp{#2}% + \pgfkeys@error{% + I do not know the key '\the\toks1'\ifx\pgf@temp\pgfkeysnovalue@text\space\else, to which you passed + '\the\toks2', \fi and I am going to ignore it. Perhaps you + misspelled it% + } + } +} \pgfkeys{/handlers/.unknown/.code=% {% - \let\pgfkeys@orig@key=\pgfkeyscurrentkey% - \pgfkeysalso{/errors/unknown key=\pgfkeys@orig@key{}}% - } + \def\pgf@marshal{\pgfkeysvalueof{/errors/unknown key/.@cmd}}% + {\expandafter\expandafter\expandafter\pgf@marshal\expandafter\expandafter\expandafter{\expandafter\pgfkeyscurrentkey\expandafter}\expandafter{\pgfkeyscurrentvalue}\pgfeov}% + }% } \pgfkeys{ - /handler config/.is choice, - /handler config/all/.code={% - \let\pgfkeys@case@three=\pgfkeys@case@three@handleall - \let\pgfkeys@ifexecutehandler=\pgfkeys@ifexecutehandler@handleall - }, - /handler config/only existing/.code={% - \let\pgfkeys@case@three=\pgfkeys@case@three@handle@restricted - \let\pgfkeys@ifexecutehandler=\pgfkeys@ifexecutehandler@handleonlyexisting - }, - /handler config/full or existing/.code={% - \let\pgfkeys@case@three=\pgfkeys@case@three@handle@restricted - \let\pgfkeys@ifexecutehandler=\pgfkeys@ifexecutehandler@handlefullorexisting - }, - /handler config/only existing/add exception/.code={\pgfkeysaddhandlyonlyexistingexception{#1}}, + /handler config/.is choice, + /handler config/all/.code={% + \let\pgfkeys@case@three=\pgfkeys@case@three@handleall + \let\pgfkeys@ifexecutehandler=\pgfkeys@ifexecutehandler@handleall + }, + /handler config/only existing/.code={% + \let\pgfkeys@case@three=\pgfkeys@case@three@handle@restricted + \let\pgfkeys@ifexecutehandler=\pgfkeys@ifexecutehandler@handleonlyexisting + }, + /handler config/full or existing/.code={% + \let\pgfkeys@case@three=\pgfkeys@case@three@handle@restricted + \let\pgfkeys@ifexecutehandler=\pgfkeys@ifexecutehandler@handlefullorexisting + }, + /handler config/only existing/add exception/.code={\pgfkeysaddhandleonlyexistingexception{#1}}, }% -\pgfkeysaddhandlyonlyexistingexception{.cd}% -\pgfkeysaddhandlyonlyexistingexception{.try}% -\pgfkeysaddhandlyonlyexistingexception{.retry}% -\pgfkeysaddhandlyonlyexistingexception{.lastretry}% -\pgfkeysaddhandlyonlyexistingexception{.unknown}% +\pgfkeysaddhandleonlyexistingexception{.cd}% +\pgfkeysaddhandleonlyexistingexception{.try}% +\pgfkeysaddhandleonlyexistingexception{.retry}% +\pgfkeysaddhandleonlyexistingexception{.lastretry}% +\pgfkeysaddhandleonlyexistingexception{.unknown}% +\pgfkeysaddhandleonlyexistingexception{.expand once}% +\pgfkeysaddhandleonlyexistingexception{.expand two once}% +\pgfkeysaddhandleonlyexistingexception{.expand twice}% +\pgfkeysaddhandleonlyexistingexception{.expanded}% + + +% Utilities for self-containment +\def\pgf@keys@gobble#1{} +\long\def\pgf@keys@utilifnextchar#1#2#3{% + \let\pgf@keys@utilreserved@d=#1% + \def\pgf@keys@utilreserved@a{#2}% + \def\pgf@keys@utilreserved@b{#3}% + \futurelet\pgf@keys@utillet@token\pgf@keys@utilifnch} +\def\pgf@keys@utilifnch{% + \ifx\pgf@keys@utillet@token\pgf@keys@utilsptoken + \let\pgf@keys@utilreserved@c\pgf@keys@utilxifnch + \else + \ifx\pgf@keys@utillet@token\pgf@keys@utilreserved@d + \let\pgf@keys@utilreserved@c\pgf@keys@utilreserved@a + \else + \let\pgf@keys@utilreserved@c\pgf@keys@utilreserved@b + \fi + \fi + \pgf@keys@utilreserved@c} +{% + \def\:{\global\let\pgf@keys@utilsptoken= } \: + \def\:{\pgf@keys@utilxifnch} \expandafter\gdef\: {\futurelet\pgf@keys@utillet@token\pgf@keys@utilifnch} +} \input pgfkeysfiltered.code.tex diff --git a/Master/texmf-dist/tex/generic/pgf/utilities/pgfkeysfiltered.code.tex b/Master/texmf-dist/tex/generic/pgf/utilities/pgfkeysfiltered.code.tex index c46e418ddad..ef7411da924 100644 --- a/Master/texmf-dist/tex/generic/pgf/utilities/pgfkeysfiltered.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/utilities/pgfkeysfiltered.code.tex @@ -132,7 +132,7 @@ % #1: old value of default path. % #2: key-value-list. -\def\pgfkeysfiltered@@install#1#2{% +\long\def\pgfkeysfiltered@@install#1#2{% \pgfkeys@install@filter@and@invoke{% \let\pgfkeysdefaultpath\pgfkeys@root% \pgfkeys@parse#2,\pgfkeys@mainstop% @@ -162,7 +162,7 @@ } % #1 = options -\long\long\def\pgfkeysalsofiltered#1{% +\long\def\pgfkeysalsofiltered#1{% \pgfkeys@install@filter@and@invoke{\pgfkeysalso{#1}}% }% @@ -922,7 +922,7 @@ % #1 the code to invoke after init and before cleanup -\def\pgfkeys@install@filter@and@invoke#1{% +\long\def\pgfkeys@install@filter@and@invoke#1{% \ifpgfkeysfilteringisactive \pgfkeys@error{Sorry, nested calls to key filtering routines are not allowed. (reason: It is not possible to properly restore the previous filtering state after returning from the nested call)}% \fi diff --git a/Master/texmf-dist/tex/generic/pgf/utilities/pgfrcs.code.tex b/Master/texmf-dist/tex/generic/pgf/utilities/pgfrcs.code.tex index 6a0a1be016d..4f9d167e7bb 100644 --- a/Master/texmf-dist/tex/generic/pgf/utilities/pgfrcs.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/utilities/pgfrcs.code.tex @@ -15,10 +15,8 @@ % prints out a message to the log. -%\def\pgfversion{2.00-cvs} -%\def\pgftypesetversion{\oldstylenums{2}.\oldstylenums{00}--\textsc{cvs}} -\def\pgfversion{2.10} -\def\pgftypesetversion{\oldstylenums{2}.\oldstylenums{10}} +\def\pgfversion{3.0.0} +\def\pgftypesetversion{\oldstylenums{3}.\oldstylenums{0}.\oldstylenums{0}} \ifx\pgfrcsloaded\undefined @@ -89,9 +87,13 @@ \def\ProvidesFile#1[#2]{\wlog{Loading file #1 version #2.}} \fi -\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/utilities/pgfrcs.code.tex,v 1.24 2010/10/25 20:57:06 ludewich Exp $ +\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/utilities/pgfrcs.code.tex,v 1.28 2013/12/20 14:44:47 tantau Exp $ \catcode`\@=\pgfrcsatcode \fi + +% Local Variables: +% coding: undecided-unix +% End: diff --git a/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-common-lists.tex b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-common-lists.tex new file mode 100644 index 00000000000..26529cd5e37 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-common-lists.tex @@ -0,0 +1,159 @@ +% Copyright 2013 by Christian Feuersaenger +% +% This file may be distributed and/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 details. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 +% +% This list here is a general re-implementation of the list used in +% the PGF system layer. +% It employs two collect-buffers to reduce the runtime. +% +% - It has preasymptotical runtime O(N), but is O(N^2) asymptotically. +% - It requires only 5 macros per list. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Usage: +% \pgfapplistnewempty\macro +\def\pgfapplistnewempty#1{% + \expandafter\let\csname pgfapp@#1\endcsname=\pgfutil@empty + \expandafter\let\csname pgfapp@#1@smallbuf\endcsname=\pgfutil@empty + \expandafter\let\csname pgfapp@#1@bigbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfapp@#1@smallbuf@c\endcsname{0}% + \expandafter\def\csname pgfapp@#1@bigbuf@c\endcsname{0}% +}% + +% #1: the item to append +% #2: the list as macro name +\long\def\pgfapplistpushback#1\to#2{% + \begingroup + \c@pgf@counta=\csname pgfapp@#2@smallbuf@c\endcsname\relax + \advance\c@pgf@counta by1 + \xdef\pgf@glob@TMPa{\the\c@pgf@counta}% + \endgroup + \expandafter\let\csname pgfapp@#2@smallbuf@c\endcsname=\pgf@glob@TMPa + \ifnum\csname pgfapp@#2@smallbuf@c\endcsname<40 + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfapp@#2@smallbuf\endcsname#1}% + \expandafter\edef\csname pgfapp@#2@smallbuf\endcsname{\the\t@pgf@toka}% + \else + \pgfapplistpushback@smallbufoverfl{#1}{#2}% + \fi +}% +\long\def\pgfapplistpushback@smallbufoverfl#1#2{% + \begingroup + \c@pgf@counta=\csname pgfapp@#2@bigbuf@c\endcsname\relax + \advance\c@pgf@counta by1 + \xdef\pgf@glob@TMPa{\the\c@pgf@counta}% + \endgroup + \expandafter\let\csname pgfapp@#2@bigbuf@c\endcsname=\pgf@glob@TMPa + % + \ifnum\csname pgfapp@#2@bigbuf@c\endcsname<30 + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfapp@#2@bigbuf\endcsname}% + \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfapp@#2@smallbuf\endcsname#1}% + \expandafter\edef\csname pgfapp@#2@bigbuf\endcsname{\the\t@pgf@toka\the\t@pgf@tokb}% + \expandafter\let\csname pgfapp@#2@smallbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfapp@#2@smallbuf@c\endcsname{0}% + \else% + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfapp@#2\endcsname}% + \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfapp@#2@bigbuf\endcsname}% + \t@pgf@tokc=\expandafter\expandafter\expandafter{\csname pgfapp@#2@smallbuf\endcsname#1}% + \expandafter\edef\csname pgfapp@#2\endcsname{\the\t@pgf@toka\the\t@pgf@tokb\the\t@pgf@tokc}% + \expandafter\let\csname pgfapp@#2@smallbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfapp@#2@smallbuf@c\endcsname{0}% + \expandafter\let\csname pgfapp@#2@bigbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfapp@#2@bigbuf@c\endcsname{0}% + \fi% +}% +\def\pgfapplist@flushbuffers#1{% + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfapp@#1\endcsname}% + \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfapp@#1@bigbuf\endcsname}% + \t@pgf@tokc=\expandafter\expandafter\expandafter{\csname pgfapp@#1@smallbuf\endcsname}% + \expandafter\edef\csname pgfapp@#1\endcsname{\the\t@pgf@toka\the\t@pgf@tokb\the\t@pgf@tokc}% + \expandafter\let\csname pgfapp@#1@smallbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfapp@#1@smallbuf@c\endcsname{0}% + \expandafter\let\csname pgfapp@#1@bigbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfapp@#1@bigbuf@c\endcsname{0}% +}% + +\def\pgfapplistlet#1=#2{% + \pgfapplist@flushbuffers{#2}% + \expandafter\let\expandafter#1\csname pgfapp@#2\endcsname +}% + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% A variant of applist which has the same runtime requirements, but +% does PUSH FRONT only. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +% Usage: +% \pgfprependlistnewempty{list} +\def\pgfprependlistnewempty#1{% + \expandafter\let\csname pgfpPRP@#1\endcsname=\pgfutil@empty + \expandafter\let\csname pgfpPRP@#1@smallbuf\endcsname=\pgfutil@empty + \expandafter\let\csname pgfpPRP@#1@bigbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfpPRP@#1@smallbuf@c\endcsname{0}% + \expandafter\def\csname pgfpPRP@#1@bigbuf@c\endcsname{0}% +}% + +% #1: the item to append +% #2: the list as macro name +\long\def\pgfprependlistpushfront#1\to#2{% + \begingroup + \c@pgf@counta=\csname pgfpPRP@#2@smallbuf@c\endcsname\relax + \advance\c@pgf@counta by1 + \xdef\pgf@glob@TMPa{\the\c@pgf@counta}% + \endgroup + \expandafter\let\csname pgfpPRP@#2@smallbuf@c\endcsname=\pgf@glob@TMPa + \ifnum\csname pgfpPRP@#2@smallbuf@c\endcsname<40 + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfpPRP@#2@smallbuf\endcsname}% + \t@pgf@tokb={#1}% + \expandafter\edef\csname pgfpPRP@#2@smallbuf\endcsname{\the\t@pgf@tokb\the\t@pgf@toka}% + \else + \pgfprependlistpushfront@smallbufoverfl{#1}{#2}% + \fi +}% +\long\def\pgfprependlistpushfront@smallbufoverfl#1#2{% + \begingroup + \c@pgf@counta=\csname pgfpPRP@#2@bigbuf@c\endcsname\relax + \advance\c@pgf@counta by1 + \xdef\pgf@glob@TMPa{\the\c@pgf@counta}% + \endgroup + \expandafter\let\csname pgfpPRP@#2@bigbuf@c\endcsname=\pgf@glob@TMPa + % + \ifnum\csname pgfpPRP@#2@bigbuf@c\endcsname<30 + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfpPRP@#2@bigbuf\endcsname}% + \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfpPRP@#2@smallbuf\endcsname}% + \t@pgf@tokc={#1}% + \expandafter\edef\csname pgfpPRP@#2@bigbuf\endcsname{\the\t@pgf@tokc\the\t@pgf@tokb\the\t@pgf@toka}% + \expandafter\let\csname pgfpPRP@#2@smallbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfpPRP@#2@smallbuf@c\endcsname{0}% + \else% + \pgfprependlist@flushbuffers{#2}% + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfpPRP@#2\endcsname}% + \t@pgf@tokb={#1}% + \expandafter\edef\csname pgfpPRP@#2\endcsname{\the\t@pgf@tokb\the\t@pgf@toka}% + \fi% +}% +\def\pgfprependlist@flushbuffers#1{% + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfpPRP@#1\endcsname}% + \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfpPRP@#1@bigbuf\endcsname}% + \t@pgf@tokc=\expandafter\expandafter\expandafter{\csname pgfpPRP@#1@smallbuf\endcsname}% + \expandafter\edef\csname pgfpPRP@#1\endcsname{\the\t@pgf@tokc\the\t@pgf@tokb\the\t@pgf@toka}% + \expandafter\let\csname pgfpPRP@#1@smallbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfpPRP@#1@smallbuf@c\endcsname{0}% + \expandafter\let\csname pgfpPRP@#1@bigbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfpPRP@#1@bigbuf@c\endcsname{0}% +}% +\def\pgfprependlistlet#1=#2{% + \pgfprependlist@flushbuffers{#2}% + \expandafter\let\expandafter#1\csname pgfpPRP@#2\endcsname +}% diff --git a/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-common.tex b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-common.tex index 7b3c34a0510..cdf0cfe821d 100644 --- a/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-common.tex +++ b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-common.tex @@ -27,17 +27,40 @@ \catcode`\@=11\relax +% Which format is loaded? +\newif\ifpgfutil@format@is@latex +\newif\ifpgfutil@format@is@plain +\newif\ifpgfutil@format@is@context + + % Simple stuff -\long\def\pgfutil@ifundefined#1{% +% \pgfutil@ifundefined{<macro name with backslash>} +% {<is undefined code>}{<is defined code>} +% +% This will let #1 to \relax if it undefined. +% +% This macro is expandable. +\def\pgfutil@ifundefined#1{% \expandafter\ifx\csname#1\endcsname\relax \expandafter\pgfutil@firstoftwo \else \expandafter\pgfutil@secondoftwo \fi} -\def\pgfutil@firstofone#1{#1} -\def\pgfutil@firstoftwo#1#2{#1} -\def\pgfutil@secondoftwo#1#2{#2} + +% A variant of \pgfutil@ifundefined which will NOT let #1 to \relax it +% is undefined. However, this macro is not expandable. +\def\pgfutil@IfUndefined#1{% + \begingroup\expandafter\expandafter\expandafter\endgroup + \expandafter\ifx\csname#1\endcsname\relax + \expandafter\pgfutil@firstoftwo + \else + \expandafter\pgfutil@secondoftwo + \fi +} +\long\def\pgfutil@firstofone#1{#1} +\long\def\pgfutil@firstoftwo#1#2{#1} +\long\def\pgfutil@secondoftwo#1#2{#2} \def\pgfutil@empty{} \def\pgfutil@gobble@until@relax#1\relax{} \def\pgfutil@gobble#1{} @@ -51,6 +74,7 @@ \xdef#1{\the\pgfutil@toks@}% \endgroup} \newif\ifpgfutil@tempswa +\newif\ifpgfutil@tempswb % pgfutil@ifnextchar @@ -111,12 +135,13 @@ \expandafter\pgfutil@fornoop \else #4\relax\expandafter\pgfutil@iforloop\fi#2\@@#3{#4}} \def\pgfutil@tfor#1:={\pgfutil@tf@r#1 } -\long\def\pgfutil@tf@r#1#2\do#3{\def\pgfutil@fortmp{#2}\ifx\pgfutil@fortmp\space\else +\long\def\pgfutil@tf@r#1#2\do#3{\def\pgfutil@fortmp{#2}\ifx\pgfutil@fortmp\pgfutil@space\else \pgfutil@tforloop#2\pgfutil@nil\pgfutil@nil\@@#1{#3}\fi} \long\def\pgfutil@tforloop#1#2\@@#3#4{\def#3{#1}\ifx #3\pgfutil@nnil \expandafter\pgfutil@fornoop \else #4\relax\expandafter\pgfutil@tforloop\fi#2\@@#3{#4}} +\def\pgfutil@space{ } % pgfutil@IfFileExists @@ -170,6 +195,19 @@ \let\pgfutil@insertatbegincurrentpage=\relax +% Ragged left and ragged right + +\def\pgfutil@raggedright{\rightskip\z@ plus2em \spaceskip.3333em \xspaceskip.5em\relax} +\def\pgfutil@raggedleft{\leftskip\z@ plus2em \rightskip\z@ \spaceskip.3333em \xspaceskip.5em\parfillskip0pt\relax} + + +% Error Messages +\def\pgfutil@packageerror#1#2#3{\errhelp{#3}\errmessage{Package #1 Error: #2}} +\def\pgfutil@packagewarning#1#2{\immediate\write17{Package #1: Warning! #2.}} +\def\pgferror#1{\pgfutil@packageerror{pgf}{#1}{}} +\def\pgfwarning#1{\pgfutil@packagewarning{pgf}{#1}} + + % Library files inclusion @@ -196,20 +234,28 @@ \def\use@@pgflibrary#1{% \edef\pgf@list{#1}% \pgfutil@for\pgf@temp:=\pgf@list\do{% - \expandafter\pgfkeys@spdef\expandafter\pgf@temp\expandafter{\pgf@temp}% - \ifx\pgf@temp\pgfutil@empty - \else - \expandafter\ifx\csname pgf@library@\pgf@temp @loaded\endcsname\relax% - \expandafter\let\csname pgf@library@\pgf@temp @loaded\endcsname=\pgfutil@empty% - \expandafter\edef\csname pgf@library@#1@atcode\endcsname{\the\catcode`\@} - \expandafter\edef\csname pgf@library@#1@barcode\endcsname{\the\catcode`\|} - \catcode`\@=11 - \catcode`\|=12 - \input pgflibrary\pgf@temp.code.tex - \catcode`\@=\csname pgf@library@#1@atcode\endcsname - \catcode`\|=\csname pgf@library@#1@barcode\endcsname - \fi% - \fi + \expandafter\pgfkeys@spdef\expandafter\pgf@temp\expandafter{\pgf@temp}% + \ifx\pgf@temp\pgfutil@empty + \else + \expandafter\ifx\csname pgf@library@\pgf@temp @loaded\endcsname\relax% + \expandafter\let\csname pgf@library@\pgf@temp @loaded\endcsname=\pgfutil@empty% + \expandafter\edef\csname pgf@library@#1@atcode\endcsname{\the\catcode`\@} + \expandafter\edef\csname pgf@library@#1@barcode\endcsname{\the\catcode`\|} + \expandafter\edef\csname pgf@library@#1@dollarcode\endcsname{\the\catcode`\$} + \catcode`\@=11 + \catcode`\|=12 + \catcode`\$=3 + \pgfutil@InputIfFileExists{pgflibrary\pgf@temp.code.tex}{}{% + \pgferror{I did not find the pgf library + '\pgf@temp'. I looked for the file named + pgflibrary\pgf@temp.code.tex, but could not find it in in + the current texmf trees.} + }% + \catcode`\@=\csname pgf@library@#1@atcode\endcsname + \catcode`\|=\csname pgf@library@#1@barcode\endcsname + \catcode`\$=\csname pgf@library@#1@dollarcode\endcsname + \fi% + \fi }% } @@ -240,11 +286,14 @@ \expandafter\let\csname pgf@module@\pgf@temp @loaded\endcsname=\pgfutil@empty% \expandafter\edef\csname pgf@module@#1@atcode\endcsname{\the\catcode`\@} \expandafter\edef\csname pgf@module@#1@barcode\endcsname{\the\catcode`\|} + \expandafter\edef\csname pgf@module@#1@dollarcode\endcsname{\the\catcode`\$} \catcode`\@=11 \catcode`\|=12 + \catcode`\$=3 \input pgfmodule\pgf@temp.code.tex \catcode`\@=\csname pgf@module@#1@atcode\endcsname \catcode`\|=\csname pgf@module@#1@barcode\endcsname + \catcode`\$=\csname pgf@module@#1@dollarcode\endcsname \fi% }% } @@ -258,8 +307,6 @@ % Guess the driver: % -\def\pgfutil@guessdriver{\edef\pgfsysdriver{pgfsys-\Gin@driver}} - \begingroup \catcode`\"=12 \edef\pgf@loc@TMPa{"}% @@ -461,4 +508,51 @@ \let\pgfutil@write=\write \let\pgfutil@read=\read +% curtesy for latex: +\let\pgfutil@protect\relax + + +% new tempdims: +\newdimen\pgfutil@tempdima +\newdimen\pgfutil@tempdimb + + +% luatex stuff +% We assume luatex version > 0.39: +% - \directlua <general text> will work +% - \directlua is the only luatex primitive that we can assume +% accessible without being prefixed by the format via +% tex.enableprimitives. +% Ideas taken from the ifluatex package (Heiko Oberdiek) +\let\pgfutil@ifluatex\iffalse +\begingroup\expandafter\expandafter\expandafter\endgroup +\expandafter\ifx\csname directlua\endcsname\relax +\else + \expandafter\let\csname pgfutil@ifluatex\expandafter\endcsname + \csname iftrue\endcsname +\fi + +\pgfutil@ifluatex + \let\pgfutil@directlua\directlua + \pgfutil@directlua{% + tex.enableprimitives('pgfutil@',{'luaescapestring'})} +\else + \def\pgfutil@directlua#1{} + \def\pgfutil@luaescapestring#1{} +\fi +% End of luatex stuff + +% Advances a number stored in a macro and writes the result back into +% the macro. +% #1 is a macro containing a number. +\def\pgfutil@advancestringcounter#1{% + \begingroup + \c@pgf@counta=#1\relax + \advance\c@pgf@counta by1 + \edef#1{\the\c@pgf@counta}% + \pgfmath@smuggleone#1% + \endgroup +}% +\input pgfutil-common-lists.tex + \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-context.def b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-context.def index 202778f5802..22c2a291417 100644 --- a/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-context.def +++ b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-context.def @@ -1,4 +1,4 @@ -% Copyright 2006, 2011 by Till Tantau +% Copyright 2006 by Till Tantau % % This file may be distributed and/or modified % @@ -8,6 +8,7 @@ % See the file doc/generic/pgf/licenses/LICENSE for more details. +\pgfutil@format@is@contexttrue % The aux files, needed for reading back coordinates @@ -16,6 +17,7 @@ \csname newwrite\endcsname\pgfutil@auxout \csname openout\endcsname\pgfutil@auxout\jobname.pgf } +\def\pgfutil@writetoaux#1{\write\pgfutil@auxout{#1}} % XColor-like support for ConTeXt @@ -138,23 +140,30 @@ \def\pgfutil@emu@select#1#2#3#4#5{#5} - +% The cmyk part is from Joseph Wright. +% See tex.stackexchange.com/questions/27952/cmyk-context-colors-in-tikz \def\pgfutil@registercolor#1{% \edef\pgf@temp{\PDFcolor{#1}}% - \edef\pgf@marshal{\noexpand\pgfutil@in@{ g}{\pgf@temp}}% - \pgf@marshal% - \ifpgfutil@in@% - \expandafter\pgfutil@context@parse@gray\pgf@temp\pgf@stop{#1}% - \else% - \edef\pgf@marshal{\noexpand\pgfutil@in@{ rg}{\pgf@temp}}% - \pgf@marshal% - \ifpgfutil@in@% - \expandafter\pgfutil@context@parse@rgb\pgf@temp\pgf@stop{#1}% - \else% - \PackageError{pgf}{Color #1 has an unsupported color model.}{}% - \pgfutil@definecolor{#1}{gray}{0} - \fi% - \fi% + \edef\pgf@marshal{\noexpand\pgfutil@in@{rg}{\pgf@temp}}% + \pgf@marshal + \ifpgfutil@in@ + \expandafter\pgfutil@context@parse@rgb\pgf@temp\pgf@stop{#1}% + \else + \edef\pgf@marshal{\noexpand\pgfutil@in@{g}{\pgf@temp}}% + \pgf@marshal + \ifpgfutil@in@ + \expandafter\pgfutil@context@parse@gray\pgf@temp\pgf@stop{#1}% + \else + \edef\pgf@marshal{\noexpand\pgfutil@in@{k}{\pgf@temp}}% + \pgf@marshal + \ifpgfutil@in@ + \expandafter\pgfutil@context@parse@cmyk\pgf@temp\pgf@stop{#1}% + \else + \pgferror{Color #1 has an unsupported color model.}% + \pgfutil@definecolor{#1}{gray}{0}% + \fi + \fi + \fi } \def\pgfutil@context@parse@gray#1 g#2\pgf@stop#3{% @@ -165,6 +174,15 @@ \pgfutil@definecolor{#5}{rgb}{#1,#2,#3} } +\def\pgfutil@context@parse@cmyk#1 #2 #3 #4k#5\pgf@stop #6{% + \pgfutil@definecolor{#6}{cmyk}{#1,#2,#3,#4}% +} + +\def\pgfutil@emu@cmyk#1#2,#3,#4,#5\@nil{% + \expandafter\def\csname\string\color@#1\endcsname + {\xcolor@{}{}{cmyk}{#2,#3,#4,#5}}% +} + % Make this command available in general: \let\colorlet=\pgfutil@colorlet @@ -253,12 +271,18 @@ \newbox\pgfutil@tempboxa -\newdimen\pgfutil@tempdima -\newdimen\pgfutil@tempdimb - \newbox \pgfutil@voidb@x \newtoks \pgfutil@toks@ +\let\pgfmath@tempdima\pgfutil@tempdima +\let\pgfmath@tempdima\pgfutil@tempdima +\let\pgfmath@tempcnta\pgfutil@tempcnta +\let\pgfmath@tempcntb\pgfutil@tempcntb + +% From LaTeX +\newskip\pgfutil@flushglue +\pgfutil@flushglue=0pt plus 1fil + % Module stuff \def\pgfutil@usemodule#1{\usemodule[#1]} @@ -332,9 +356,9 @@ % The following is still messy and needs to be cleanup up (everything % prefixed by pgfutil@): -\def\PackageInfo#1#2{} -\def\PackageWarning#1#2{\immediate\write17{Package #1: Warning! #2.}}% -\def\PackageError#1#2#3{\immediate\write17{Package #1: Error! #2.}}% +%\def\PackageInfo#1#2{} +%\def\PackageWarning#1#2{\immediate\write17{Package #1: Warning! #2.}}% +%\def\PackageError#1#2#3{\immediate\write17{Package #1: Error! #2.}}% \long\def\AtBeginDocument#1{#1}% \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-latex.def b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-latex.def index f9681aa4a56..c990a3730a4 100644 --- a/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-latex.def +++ b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-latex.def @@ -10,12 +10,21 @@ \catcode`\@=11\relax +\pgfutil@format@is@latextrue + \let\pgfutil@auxout=\@auxout +\def\pgfutil@writetoaux#1{\if@filesw\write\pgfutil@auxout{#1}\fi} + \let\pgfutil@tempcnta=\@tempcnta \let\pgfutil@tempcntb=\@tempcntb \let\pgfutil@voidb@x=\voidb@x \let\pgfutil@toks@=\toks@ +\let\pgfutil@packageerror=\PackageError +\let\pgfutil@packagewarning=\PackageWarning + +\def\pgfutil@protect{\protect} + \def\pgfutil@definecolor{\definecolor} \def\pgfutil@color{\color} @@ -38,6 +47,11 @@ \pgf@next{#2}{#3}% } +\let\pgfutil@raggedleft\raggedleft +\let\pgfutil@raggedright\raggedright + +\let\pgfutil@flushglue=\@flushglue + \def\pgfutil@font@tiny{\tiny} \def\pgfutil@font@scriptsize{\scriptsize} \def\pgfutil@font@footnotesize{\footnotesize} @@ -59,13 +73,30 @@ \let\pgfutil@tempboxa=\@tempboxa -\let\pgfutil@tempdima=\@tempdima -\let\pgfutil@tempdimb=\@tempdimb +\let\pgfmath@tempdima\pgfutil@tempdima +\let\pgfmath@tempdima\pgfutil@tempdima +\let\pgfmath@tempcnta\pgfutil@tempcnta +\let\pgfmath@tempcntb\pgfutil@tempcntb -\AtEndDocument{\the\pgfutil@everybye} + +\AtBeginDocument{\AtEndDocument{\par\vfil\penalty-10000\relax\the\pgfutil@everybye}} \def\pgfutil@insertatbegincurrentpagefrombox#1{% - \global\setbox\pgfutil@abb\hbox{\unhbox\pgfutil@abb#1}% + \edef\pgf@temp{\the\wd\pgfutil@abb}% + \global\setbox\pgfutil@abb\hbox{% + \unhbox\pgfutil@abb + % + % the order in which \pgfutil@insertatbegincurrentpagefrombox + % matters unless we make the following -shift! + % To see this, consider writing two such statements. The second + % one will (naturally) be placed more to the right, although there + % is no apparent reason why it should. + % + % CF observed problems when placing patterns in XObjects without + % this skip (dvipdfmx driver for pgfplots shader=interp) + \hskip-\pgf@temp\relax + #1% + }% } \newbox\pgfutil@abb% \def\pgfutil@insertatbegincurrentpage#1{% @@ -82,14 +113,14 @@ % Add at begin page stuff \setbox\@cclv=\vbox{% \setbox\z@=\hbox{\pgfutil@abe\unhbox\pgfutil@abb\pgfutil@abc\global\let\pgfutil@abc\pgfutil@empty}% - \wd\z@=\z@ - \ht\z@=\z@ - \dp\z@=\z@ - \box\z@ + \wd\z@=\z@% + \ht\z@=\z@% + \dp\z@=\z@% + \box\z@% % if TeX changes into vertical mode, it inserts \parskip and % \lineskip. Disable it here: - \nointerlineskip - \ifvbox\@cclv \unvbox\@cclv \else\hsize=\wd\@cclv \unhbox\@cclv \fi% + \nointerlineskip% + \ifvbox\@cclv \unvbox\@cclv \else\hsize=\wd\@cclv \noindent\unhbox\@cclv \fi% %\box\@cclv % using \box instead of \unhbox or \unvbox % has the advantage that glue settings won't be @@ -98,4 +129,30 @@ }% } +% Preview hack: preview.sty hacks into \shipout (which is ok), but +% does not honour everyshi.sty (which is not ok). This causes everyshi +% material to get lost. + +\AtBeginDocument{ + \@ifpackageloaded{preview}{% + % Ok, package loaded. Swap definitions of everyshi.sty's shipout + % and preview.sty's shipout: + \let\pgf@temp\pr@shipout% This is the original shipout + \let\pr@shipout\@EveryShipout@Shipout% This is what preview.sty should call + \let\@EveryShipout@Org@Shipout\pgf@temp% Everyshi should now use the original one + }{}% +} + + +% Guess the driver: + +\def\pgfutil@guessdriver{ + \ifx\HCode\@undefined% + \edef\pgfsysdriver{pgfsys-\Gin@driver}% should be right + \else% + \def\pgfsysdriver{pgfsys-tex4ht.def}% should be right + \fi% +} + + \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-plain.def b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-plain.def index c09cf21fe0f..31d0d21d10c 100644 --- a/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-plain.def +++ b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-plain.def @@ -9,6 +9,7 @@ +\pgfutil@format@is@plaintrue % The aux files, needed for reading back coordinates @@ -17,7 +18,7 @@ \csname newwrite\endcsname\pgfutil@auxout \csname openout\endcsname\pgfutil@auxout\jobname.pgf } - +\def\pgfutil@writetoaux#1{\write\pgfutil@auxout{#1}} % XColor-like support for plain TeX @@ -147,7 +148,7 @@ \def\pgfutil@minipage[#1]#2{% \hbox to#2\bgroup% \hsize=#2\relax% - \vbox\bgroup\leavevmode% + \vbox\bgroup\noindent% } \def\pgfutil@endminipage{\egroup\egroup} @@ -159,14 +160,18 @@ \ifx\pdfoutput\relax\alloc@0\count\countdef\insc@unt\pdfoutput\fi \def\pgfutil@guessdriver{ - \ifcase\pdfoutput% - \ifx\XeTeXversion\@undefined - \def\pgfsysdriver{pgfsys-dvips.def}% hopefully - \else - \def\pgfsysdriver{pgfsys-xetex.def}% should be right - \fi + \ifx\HCode\@undefined% + \ifcase\pdfoutput% + \ifx\XeTeXversion\@undefined + \def\pgfsysdriver{pgfsys-dvips.def}% hopefully + \else + \def\pgfsysdriver{pgfsys-xetex.def}% should be right + \fi + \else% + \def\pgfsysdriver{pgfsys-pdftex.def}% should be right + \fi% \else% - \def\pgfsysdriver{pgfsys-pdftex.def}% should be right + \def\pgfsysdriver{pgfsys-tex4ht.def}% should be right \fi% } @@ -206,9 +211,14 @@ \newbox\pgfutil@tempboxa -\newdimen\pgfutil@tempdima -\newdimen\pgfutil@tempdimb +\let\pgfmath@tempdima\pgfutil@tempdima +\let\pgfmath@tempdima\pgfutil@tempdima +\let\pgfmath@tempcnta\pgfutil@tempcnta +\let\pgfmath@tempcntb\pgfutil@tempcntb +% From LaTeX +\newskip\pgfutil@flushglue +\pgfutil@flushglue=0pt plus 1fil % Module stuff @@ -228,8 +238,7 @@ -% Hack shipout. Should perhaps use atbegshi? Not in standard distribution, currently... -% Code inspired (but patched...) from everyshi.sty: +% Hack shipout. Now use atbegshi \def\pgfutil@insertatbegincurrentpagefrombox#1{% \global\setbox\pgfutil@abb\hbox{\unhbox\pgfutil@abb#1}% @@ -244,39 +253,34 @@ } \let\pgfutil@abe\pgfutil@empty% -\def\pgfutil@@EveryShipout@Shipout{% - \afterassignment\pgfutil@@EveryShipout@Test - \setbox255= % -} -\def\pgfutil@@EveryShipout@Test{% - \ifvoid\@cclv\relax - \aftergroup\pgfutil@EveryShipout@Output - \else - \pgfutil@EveryShipout@Output - \fi% -} -\def\pgfutil@EveryShipout@Output{% - \setbox255=\vbox{% - \setbox0=\hbox{\pgfutil@abe\unhbox\pgfutil@abb\pgfutil@abc\global\let\pgfutil@abc\pgfutil@empty}% - \wd0=0pt% - \ht0=0pt% - \dp0=0pt% - \box0% - \unvbox255% - }% - \pgfutil@@EveryShipout@Org@Shipout\box\@cclv% -} -\let\pgfutil@@EveryShipout@Org@Shipout\shipout -\let\shipout\pgfutil@@EveryShipout@Shipout - - +% Code by Heiko Oberdiek on ctt +\input atbegshi.sty\relax +\AtBeginShipout{% + \setbox\AtBeginShipoutBox=\vbox{% + \setbox0=\hbox{% + \begingroup + \pgfutil@abe + \unhbox\pgfutil@abb + \pgfutil@abc + \global\let\pgfutil@abc\pgfutil@empty + \endgroup + }% + \wd0=0pt\relax + \ht0=0pt\relax + \dp0=0pt\relax + \box0 % + \nointerlineskip + \box\AtBeginShipoutBox + }% +}% +% End of HO code % The following is still messy and needs to be cleanup up (everything % prefixed by pgfutil@): -\def\PackageInfo#1#2{} -\def\PackageWarning#1#2{\immediate\write17{Package #1: Warning! #2.}}% -\def\PackageError#1#2#3{\immediate\write17{Package #1: Error! #2.}}% +%\def\PackageInfo#1#2{} +%\def\PackageWarning#1#2{\immediate\write17{Package #1: Warning! #2.}}% +%\def\PackageError#1#2#3{\immediate\write17{Package #1: Error! #2.}}% \long\def\AtBeginDocument#1{#1}% \endinput diff --git a/Master/texmf-dist/tex/latex/pgf/basiclayer/pgf.sty b/Master/texmf-dist/tex/latex/pgf/basiclayer/pgf.sty index ad5c9b2ad4f..22eb6a92941 100644 --- a/Master/texmf-dist/tex/latex/pgf/basiclayer/pgf.sty +++ b/Master/texmf-dist/tex/latex/pgf/basiclayer/pgf.sty @@ -10,7 +10,7 @@ \RequirePackage{pgfrcs} -\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/latex/pgf/basiclayer/pgf.sty,v 1.12 2008/01/15 17:17:22 tantau Exp $ +\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/latex/pgf/basiclayer/pgf.sty,v 1.14 2013/12/18 15:01:45 tantau Exp $ \def\pgf@draft{} \DeclareOption{draft}{\def\pgf@draft{\pgf@draftmodetrue}} diff --git a/Master/texmf-dist/tex/latex/pgf/doc/pgfmanual.pdflinks.code.tex b/Master/texmf-dist/tex/latex/pgf/doc/pgfmanual.pdflinks.code.tex index e507d30e85c..ba9ed33e243 100644 --- a/Master/texmf-dist/tex/latex/pgf/doc/pgfmanual.pdflinks.code.tex +++ b/Master/texmf-dist/tex/latex/pgf/doc/pgfmanual.pdflinks.code.tex @@ -82,6 +82,9 @@ /pdflinks/codeexample links/.is if=pgfmanualprettyenabled, /pdflinks/codeexample links/.default=true, % + % How to render a hyperlink + /pdflinks/render hyperlink/.code=#1, + % % whenever an unqualified key is found, the following key prefix % list is tried to find a match. /pdflinks/search key prefixes in/.initial={/tikz/,/pgf/}, @@ -123,6 +126,12 @@ /pdflinks/internal link prefix/.initial=pgf, } +\begingroup + \catcode`\_=12 + \gdef\pgfmanualpdf@underscore{_}% + \catcode`\ =13\relax\gdef\pgfmanualpdf@install@active@space{\def {\space}}% +\endgroup + \gdef\pgfmanualpdf@installreplacements{% \def\marg##1{{##1}}% \def\oarg##1{[##1]}% @@ -132,10 +141,15 @@ \def\\{\textbackslash}% \def\space{:}% \edef\ {\space}% + \edef\SPACE{\` \relax}% + \ifnum\the\catcode`\ =13 % + \pgfmanualpdf@install@active@space + \fi \edef\#{}% \def\printanat{@}% \def\protect{}% \def\textasciicircum{o}% + \def\_{\pgfmanualpdf@underscore}% \expandafter\edef\pgfmanual@verb@activebar{\pgfmanual@verb@bar}% }% @@ -216,7 +230,11 @@ \fi \expandafter\gdef\csname pgfd@lbl@\pgfmanualpdflabel@@\endcsname{w}% 1. remember the label AND remember that we "w"rote it into the pdf. \edef\pgfmanualpdflabel@@{\pgfkeysvalueof{/pdflinks/internal link prefix}.\pgfmanualpdflabel@@}% - \expandafter\hypertarget\expandafter{\pgfmanualpdflabel@@}{#2}% + \ifvmode% + \expandafter\hypertarget\expandafter{\pgfmanualpdflabel@@}{#2}% + \else% + {\setbox0=\hbox{\raise1em\hbox{\expandafter\hypertarget\expandafter{\pgfmanualpdflabel@@}{}}}\ht0=0pt\box0}#2% + \fi% \else #2% \fi @@ -262,7 +280,7 @@ }% \def\pgfmanualpdfref@#1#2{% \pgfkeysgetvalue{/pdflinks/internal link prefix}\pgfmanual@temp - \expandafter\hyperlink\expandafter{\pgfmanual@temp.#1}{#2}% + \expandafter\hyperlink\expandafter{\pgfmanual@temp.#1}{\pgfkeysvalueof{/pdflinks/render hyperlink/.@cmd}{#2}\pgfeov}% \ifpgfmanualshowlabels \pgfkeysvalueof{/pdflinks/show labels code/.@cmd}{#1}\pgfeov \fi diff --git a/Master/texmf-dist/tex/latex/pgf/doc/pgfmanual.prettyprinter.code.tex b/Master/texmf-dist/tex/latex/pgf/doc/pgfmanual.prettyprinter.code.tex index 85482fedaaf..3c4f5c28fbc 100644 --- a/Master/texmf-dist/tex/latex/pgf/doc/pgfmanual.prettyprinter.code.tex +++ b/Master/texmf-dist/tex/latex/pgf/doc/pgfmanual.prettyprinter.code.tex @@ -191,6 +191,10 @@ % #1: the coordinate system name (*without* the leading brace). % The leading brace must be re-inserted by this style. /codeexample/prettyprint/point with cs/.code 2 args={(#1:#2},% + % + % The font / color command to use for comments. Will be set at + % the beginning of a comment + /codeexample/prettyprint/comment font/.initial=,% % the same with specialised code: %/codeexample/prettyprint/point with cs/<CS NAME>/.code 2 args={(#1:#2},% % @@ -285,12 +289,12 @@ % \def\pgfmanual@pretty@installcommenthandler{% \expandafter\def\pgfmanual@pretty@activepercent{% - \begingroup + \begingroup% \pgfmanualprettycommentactivetrue \expandafter\let\pgfmanual@pretty@activenl=\pgfmanual@pretty@recoveraftercomment \expandafter\def\pgfmanual@pretty@activepercent{\%}% - %\tt - \% % + \pgfkeysvalueof{/codeexample/prettyprint/comment font}%\tt + \%% }% }% \def\pgfmanual@pretty@recoveraftercomment{% diff --git a/Master/texmf-dist/tex/latex/pgf/frontendlayer/libraries/tikzlibraryexternal.code.tex b/Master/texmf-dist/tex/latex/pgf/frontendlayer/libraries/tikzlibraryexternal.code.tex index 9fe775dc8a8..c3000401b0b 100644 --- a/Master/texmf-dist/tex/latex/pgf/frontendlayer/libraries/tikzlibraryexternal.code.tex +++ b/Master/texmf-dist/tex/latex/pgf/frontendlayer/libraries/tikzlibraryexternal.code.tex @@ -22,9 +22,19 @@ % It replaces \tikzpicture/ \endtikzpicture and \tikz and invokes \beginpgfgraphicnamed ... \endpgfgraphicnamed % commands if necessary. +% load this package in order to get \pdf@mdfivesum . +% \pdf@mdfivesum is available for pdftex and lualatex and computes the +% md5 sum. Note that pdftex has \pdfmdfivesum, but lualatex does not +% have it. +\usepackage{pdftexcmds} + % source generic implementation: \input tikzexternalshared.code.tex +\pgfutil@IfUndefined{pdf@mdfivesum}{}{% + \let\tikzexternal@mdfivesum=\pdf@mdfivesum +}% + \def\tikzexternal@TEXDIALECT@begpicture{\begin{tikzpicture}} \def\tikzexternal@TEXDIALECT@endpicture{\end{tikzpicture}}% @@ -52,6 +62,7 @@ \noexpand\endgroup \noexpand#1{\the\t@tikzexternal@tmpa}% }% + \t@tikzexternal@tmpa={}% release memory. \else \t@tikzexternal@tmpa=\expandafter{\the\t@tikzexternal@tmpa #2\end{#3}}% \def\tikzexternal@TEXDIALECT@collectpicture@next{% @@ -61,8 +72,30 @@ }% \def\tikzexternal@laTeX@collect@until@end@tikzpicturetikzpicturestring{tikzpicture}% +\def\tikzexternal@handle@landscape{% + \ltx@ifpackageloaded{pdflscape}{% + % Work around a bug in conjunction with pdflscape and + % external: without this optimize-away-instruction, the + % externalized image would be rotated - and it will be rotated + % once more again when it is included. + % + % if we "optimize it away", the landscape stuff will be + % omitted. I hope this is enough... might not be entirely + % fool-proof; perhaps we need to set it to \relax. For now, it + % will probably do the job + \tikzset{ + external/.cd, + optimize command away=\landscape, + optimize command away=\endlandscape + }% + }{% + }% +}% + \AtBeginDocument{% \pgfutil@ifundefined{tikzexternalrealjob}{% \global\let\tikzexternalrealjob=\jobname }{}% + \tikzexternal@handle@landscape }% + diff --git a/Master/texmf-dist/tex/latex/pgf/math/pgfmath.sty b/Master/texmf-dist/tex/latex/pgf/math/pgfmath.sty index b8092306e25..f079db528ea 100644 --- a/Master/texmf-dist/tex/latex/pgf/math/pgfmath.sty +++ b/Master/texmf-dist/tex/latex/pgf/math/pgfmath.sty @@ -7,6 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. +\RequirePackage{pgfrcs,pgfkeys} \input{pgfmath.code.tex} \endinput diff --git a/Master/texmf-dist/tex/latex/pgf/systemlayer/pgfsys.sty b/Master/texmf-dist/tex/latex/pgf/systemlayer/pgfsys.sty index 2e2eab766e2..6f9c2b8b932 100644 --- a/Master/texmf-dist/tex/latex/pgf/systemlayer/pgfsys.sty +++ b/Master/texmf-dist/tex/latex/pgf/systemlayer/pgfsys.sty @@ -9,6 +9,10 @@ \RequirePackage{pgfrcs} +\DeclareOption{dvisvgm}{\def\pgfsysdriver{pgfsys-dvisvgm.def}} + +\ProcessOptions + \input{pgfsys.code.tex} \input{pgfsyssoftpath.code.tex} \input{pgfsysprotocol.code.tex} diff --git a/Master/texmf-dist/tex/latex/pgf/utilities/pgffor.sty b/Master/texmf-dist/tex/latex/pgf/utilities/pgffor.sty index dc04e9aeea2..c0de8c134ad 100644 --- a/Master/texmf-dist/tex/latex/pgf/utilities/pgffor.sty +++ b/Master/texmf-dist/tex/latex/pgf/utilities/pgffor.sty @@ -9,6 +9,7 @@ \RequirePackage{pgfrcs} \RequirePackage{pgfkeys} +\RequirePackage{pgfmath} \input{pgffor.code.tex} diff --git a/Master/texmf-dist/tex/latex/pgf/utilities/pgfpages.sty b/Master/texmf-dist/tex/latex/pgf/utilities/pgfpages.sty index 9e1ebc3035e..2144e9c7005 100644 --- a/Master/texmf-dist/tex/latex/pgf/utilities/pgfpages.sty +++ b/Master/texmf-dist/tex/latex/pgf/utilities/pgfpages.sty @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesPackage{pgfpages}[2004/11/05 ver 0.01] +\ProvidesPackage{pgfpages}[2011/01/05 ver 0.02] \RequirePackage{pgfcore,calc} @@ -790,10 +790,11 @@ \else% \pgflowlevel{\pgftransformyscale{\csname pgfpages@p@\the\pgf@cpn @yscale\endcsname}}% \fi% + \pgfscope% \expandafter\ifx\csname pgfpages@p@\the\pgf@cpn @rotation\endcsname\relax% - \pgfscope% \else% - \pgflowlevel{\pgftransformrotate{\csname pgfpages@p@\the\pgf@cpn @rotation\endcsname}}% + \pgflowlevel{\pgftransformrotate{\csname + pgfpages@p@\the\pgf@cpn @rotation\endcsname}}% \fi% \pgfutil@tempdima=\csname pgfpages@p@\the\pgf@cpn @width\endcsname\relax% \pgfutil@tempdimb=\csname pgfpages@p@\the\pgf@cpn @height\endcsname\relax% @@ -855,11 +856,14 @@ \@parboxrestore% \pgfpages@originalshipout% \vbox{\hbox{% - \hskip-1in% - \vbox to \pgfphysicalheight{% - \vss\box\pgfpages@shipoutbox% - \vskip1in% - }}}% + \pgfsetupphysicalpagesizes% + \hskip-1in% + \vbox to \pgfphysicalheight{% + \vss\box\pgfpages@shipoutbox% + \vskip1in% + }}% + \pgfsetupphysicalpagesizes% + }% \endgroup% } @@ -896,8 +900,13 @@ % \pgfhookintoshipout \newcommand\pgfhookintoshipout{ - \let\pgfpages@originalshipout=\shipout - \let\shipout=\pgfpages@interceptshipout + \ifx\CROP@shipout\undefined + \let\pgfpages@originalshipout=\shipout + \let\shipout=\pgfpages@interceptshipout + \else + \let\pgfpages@originalshipout=\CROP@shipout + \let\CROP@shipout=\pgfpages@interceptshipout + \fi } \def\pgfpages@interceptshipout{% @@ -1005,37 +1014,15 @@ % \pgfsetupphysicalpagesizes \newcommand\pgfsetupphysicalpagesizes{% - % The following code was send to me by Rolf Niepraschk - \ifx\Gin@driver\pgfutil@empty\else% - \filename@parse{\Gin@driver}\@tempswafalse% - \def\reserved@a{dvips}% - \ifx\filename@base\reserved@a\@tempswatrue\fi% - \def\reserved@a{dvipdfm}% - \ifx\filename@base\reserved@a\@tempswatrue\fi% - \if@tempswa% - \AtBeginDvi{% - \special{papersize=\the\pgfphysicalwidth,\the\pgfphysicalheight}}% - \fi% - \def\reserved@a{pdftex}% - \ifx\filename@base\reserved@a - \pdfpagewidth\pgfphysicalwidth\pdfpageheight\pgfphysicalheight% - \fi% - \def\reserved@a{vtex}% - \ifx\filename@base\reserved@a - \mediawidth\pgfphysicalwidth\mediaheight\pgfphysicalheight% - \fi% - \fi + \pgfsys@global@papersize{\the\pgfphysicalwidth}{\the\pgfphysicalheight}% } % % Start/End setup % -\AtBeginDocument -{ - \pgfhookintoshipout - \pgfsetupphysicalpagesizes -} +\pgfhookintoshipout + \AtEndDocument { \clearpage diff --git a/Master/tlpkg/bin/tlpkginfo b/Master/tlpkg/bin/tlpkginfo index c037265ce36..2f1829e61db 100755 --- a/Master/tlpkg/bin/tlpkginfo +++ b/Master/tlpkg/bin/tlpkginfo @@ -303,6 +303,9 @@ sub prepare { } elsif ($pkg eq "hfoldsty") { $tds_path = glob ("$CTAN/fonts/hfoldsty/hfoldsty-v*.zip"); + } elsif ($pkg eq "pgf") { + $tds_path = glob ("$CTAN/install/graphics/pgf/base/pgf.tds.zip"); + # ...and except for files in latex-tds... } elsif ($pkg =~ /^($latex_tds_pkgs)$/) { if ($pkg =~ /^($amslatex_tds_pkgs)$/) { diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds index 4d7b442015c..c975941f59b 100755 --- a/Master/tlpkg/libexec/ctan2tds +++ b/Master/tlpkg/libexec/ctan2tds @@ -757,7 +757,7 @@ chomp ($Build = `cd $Master/../Build/source && pwd`); 'persian-hm-ftx',"die 'skipping, legality?'", #"&MAKEflatten", 'persian-hm-xbs',"die 'skipping, legality?'", #"&MAKEflatten", 'persian-modern',"&MAKEflatten", - 'pgf', "&MAKEcopy", +# 'pgf', "&MAKEcopy", 'pgothic', "die 'skipping, use bookhands'", 'phaistos', "&MAKEflatten", 'philosophers-imprint', "die 'skipping, use philosophersimprint'", @@ -5563,8 +5563,8 @@ sub POSTpedigreeperl { sub POSTpgf { print "POST$package - mv generic,latex,... directories\n"; - &SYSTEM ("cd $DEST && mkdir tex && mv context generic latex plain tex"); - &SYSTEM ("$RM $DEST/README"); +# &SYSTEM ("cd $DEST && mkdir tex && mv context generic latex plain tex"); +# &SYSTEM ("$RM $DEST/README"); } sub POSTpgfplots { |