├── .gitignore ├── AUTHORS ├── CHANGES ├── LICENSE ├── MANIFEST.in ├── docs ├── Makefile ├── changelog.rst ├── common.inc ├── conf.py ├── customization_guide.rst ├── docgraphs │ ├── balls.dot │ ├── ex1.dot │ ├── ex1b.dot │ ├── ex2.dot │ ├── ex3.dot │ ├── ex4.dot │ ├── lblstyle.dot │ ├── nodesize.dot │ ├── pgfarrows.dot │ ├── preproc1.dot │ ├── pstarrows.dot │ ├── simple.dot │ ├── simplelbl.dot │ ├── topaths1.dot │ └── valignmode1.dot ├── img │ ├── balls.pdf │ ├── balls.png │ ├── consistent.pdf │ ├── consistent.png │ ├── dot2texiex1.pdf │ ├── dot2texiex1.png │ ├── dot2texiex2.pdf │ ├── dot2texiex2.png │ ├── ex1.png │ ├── ex1bcomb.png │ ├── ex1comb.pdf │ ├── ex1comb.png │ ├── ex1def.png │ ├── ex1gstyle.pdf │ ├── ex1gstyle.png │ ├── ex1huge.pdf │ ├── ex1huge.png │ ├── ex2.pdf │ ├── ex2.png │ ├── fsm1.pdf │ ├── fsm1.png │ ├── lblstyle.pdf │ ├── lblstyle.png │ ├── nodewidth1.pdf │ ├── nodewidth1.png │ ├── nodewidth2.pdf │ ├── nodewidth2.png │ ├── pgfarrows.pdf │ ├── pgfarrows.png │ ├── pgfsimple.png │ ├── pgftikzsimple.pdf │ ├── pgftikzsimple.png │ ├── preproc1a.pdf │ ├── preproc1a.png │ ├── preproc1b.pdf │ ├── preproc1b.png │ ├── pstarrows.pdf │ ├── pstarrows.png │ ├── texmode.pdf │ ├── texmode.png │ ├── texmodeb.pdf │ ├── texmodeb.png │ ├── tikzedgelabels.pdf │ ├── tikzedgelabels.png │ ├── tikzsimple.png │ ├── topaths1.pdf │ ├── topaths1.png │ ├── valignmode0.pdf │ ├── valignmode0.png │ ├── valignmode1.pdf │ ├── valignmode1.png │ ├── valignmode2.pdf │ ├── valignmode2.png │ ├── valignmode3.pdf │ └── valignmode3.png ├── index.rst ├── installation_guide.rst ├── license.rst ├── make.bat ├── module_guide.rst ├── tipsandtricks.rst └── usage_guide.rst ├── dot2tex ├── __init__.py ├── __main__.py ├── base.py ├── dot2tex.py ├── dotparsing.py ├── pgfformat.py ├── pstricksformat.py └── utils.py ├── examples ├── automata.dot ├── balls.dot ├── distances.dot ├── dotarrows.dot ├── dropshadows.dot ├── ex1.dot ├── graphanndtti.tex ├── graphofgraphs.dot ├── gvcols.tex ├── latexmarkup.dot ├── pgfarrows.dot ├── pgfsnakes.dot ├── poltab.dot ├── pstarrows.dot ├── showpoints.dot ├── sportsbracket.dot ├── subgraphs.dot ├── tank.dot ├── tikzautomata.dot ├── tikzshapes.dot └── transp.dot ├── readme.md ├── setup.py └── tests ├── experimental ├── test_buildexamples.py ├── test_comparedotparsing.py ├── test_graphparsing.py └── test_multirender.py ├── test_dot2tex.py ├── test_dotparsing.py └── testgraphs ├── autosize.dot ├── clust.dot ├── colors.dot ├── compassports.dot ├── concentrate.dot ├── d2topts.dot ├── dot2tikznodeshapesmapping.dot ├── escstr.dot ├── invis.dot ├── latin1.dot ├── markup.dot ├── markup2.dot ├── multilines.dot ├── nodenames.dot ├── parsetests ├── ids.dot ├── multilines.dot ├── quoting.dot └── subgraphs.dot ├── pststyles.dot ├── specialchars.dot ├── styles.dot ├── transp.dot └── utf8.dot /.gitignore: -------------------------------------------------------------------------------- 1 | # use glob syntax. 2 | syntax: glob 3 | 4 | *.pyc 5 | *.egg-info* 6 | *.log 7 | _* 8 | *.aux 9 | *.log 10 | *.bbl 11 | *.out 12 | *.pyc 13 | *.bak 14 | *.toc 15 | *.nav 16 | *.snm 17 | *.blg 18 | *.dvi 19 | *.idx 20 | *.ind 21 | *.nlo 22 | *.synctex.gz 23 | *.orig 24 | *.table 25 | *.gnuplot 26 | Thumbs.db 27 | .DS_Store 28 | tests/tmp/* 29 | tests/exrender/* 30 | build/* 31 | dist/* 32 | venv/* 33 | .idea/* 34 | 35 | !*.py 36 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Dot2tex is written and maintained by Kjell Magne Fauske. The dot language parser is mainly written 2 | by Michael Krause. 3 | 4 | Patches and suggestions 5 | ``````````````````````` 6 | 7 | - Nicolas Thiery 8 | - Peter Collingbourne 9 | - Michael Krause 10 | - Ero Carrera 11 | - Michael Niedermair 12 | - Ioannis Filippidis 13 | - Travis Scrimshaw 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /CHANGES: -------------------------------------------------------------------------------- 1 | dot2tex change log 2 | ================== 3 | 4 | Here you can see the full list of changes between each dot2tex release. 5 | 6 | 2.12.dev 7 | -------- 8 | 9 | - Major code refactoring 10 | 11 | 2.11.3 12 | ------ 13 | 14 | Released 2019-03-31 15 | 16 | - Ignore multiline edge labels during preprocessing (issue #27) 17 | - Fixed parsing of DOT IDs. Numerals can now be used as node IDs. 18 | - Fixed issue #64. Remove \ characters from drawsting. 19 | 20 | 2.11.2 21 | ------ 22 | 23 | - Added support for the circle node shape. Thanks to Alexander Hagen for the pull request. 24 | - Fix Popen issue on windows 10 when calling latex. The --autosize option is now working again. 25 | 26 | 2.11.1 27 | ------ 28 | 29 | Released 2019-03-15 30 | 31 | - Fix bug in setup.py entry_points. 32 | 33 | 2.11.0 34 | ------ 35 | 36 | Released 2019-03-15 37 | 38 | - Added support for Python 3! Thanks Travis Scrimshaw! 39 | - Various bug fixes. 40 | 41 | 2.10.dev 42 | -------- 43 | 44 | Not released 45 | 46 | - Convert input file to output file only if latter is outdated. Can be overridden by the new 47 | --force command line option. 48 | - Replaced deprecated opt parse with argparse. 49 | - Python 2.7.x is now a requirement (due to the use of the argparse module) 50 | 51 | 2.9.1 52 | ----- 53 | 54 | Not released 55 | 56 | - Preprocessing head and tail labels now works in the ``duplicate`` mode. 57 | - Added support for preprocessing head and tail labels (pstricks). 58 | - Relaxed syntax for including external dot files. Comments are now allowed after ``\input{}``. 59 | - All xdot coordinates are now parsed as float (issue #31). 60 | - Added the svgnames option when loading xcolor in the default templates (issue #25). 61 | 62 | 2.9.0 63 | ----- 64 | 65 | Released 2014-05-16. 66 | 67 | - Added support for preprocessing head and tail label (pgf and tikz). 68 | - Graphviz arrow styles are now mapped to corresponding PGF/TikZ arrows. 69 | - Project is now hosted on GitHub. 70 | - Numbers are now outputted as floats. Some versions of Graphviz uses scientific notation 71 | for small numbers. TeX does not handle that well [issue #11]. 72 | - Added support for more Graphviz node shapes when using the tikz output format: 73 | square, diamond, trapezium and star. 74 | - Fixed compatibility issue with Pyparsing 2.0.1. 75 | - Fixed a bug in preprocessing triggered by using the ``--styleonly`` option 76 | with the tikz output format. 77 | - The number of sides in the hexagon tikz shape is now correct. Thanks to Jean Pichon for 78 | reporting this. 79 | - Added support for the point shape when using the TikZ output format. 80 | - Node labels are no longer shown when the node shape is point and the output 81 | format is TikZ. 82 | - Fixed issue 14. Parsing of dimension data from the TeX-log is now 83 | more robust and the ``--autosize`` option should now work in Cygwin. 84 | - Added the ``--progoptions`` option for passing options to the graph layout program. 85 | - Documentation is now built using Sphinx 86 | - Cleaned up internal error handling. 87 | - When dot2tex fails to parse a graph, dot2tex will now raise an exception 88 | and quit. In previous versions dot2tex attempted to run the graph through 89 | Graphviz first. 90 | - Log handlers are no longer configured when using dot2tex as a library. 91 | - Fixed [issue 20]. ``format=positions`` no longer fails if node coordinates 92 | are floats. Thanks to Nicolas Thiery for reporting this bug. 93 | - Fixed several bugs in the parsing of ID numerals. The bug caused labels 94 | like ``label="1.2.3.4"`` to be interpreted as ``label=1.2`` [issue 17]. 95 | Thanks to Vsevolod for reporting this. 96 | - ``stdout`` is now properly restored after parsing dot data. Thanks to Nicolas Thiery 97 | for the patch. 98 | - Parentheses, ``()``, in tikz node names are now replaced with ``{}``. Parentheses are not valid 99 | characters in node names. Thanks DamienJadeDuff for reporting this. 100 | 101 | 2.8.7 102 | ----- 103 | 104 | Released 2009-10-05. 105 | 106 | - Edges with no edge points are now properly handled. 107 | - Added the ``positions`` output format that returns a dictionary with node 108 | names as keys and (x, y) tuples as values. Works only when called as a module. 109 | Feature suggested by Nicolas Thiery. 110 | - Fixed handling of ``stderr`` when creating xdot data. Thanks to Nicolas Thiery 111 | for reporting this bug. 112 | - Exceptions are now caught when accessing invalid win32 registry keys. 113 | Updated Graphviz registry key. 114 | Thanks Andreas Frische for reporting this. 115 | - Fixed templates so that crop code is not inserted when preprocessing the graph. 116 | 117 | 118 | 2.8.6 119 | ----- 120 | 121 | Released 2009-07-09. 122 | 123 | - Added the ``--pgf118`` option for generating code compatible with PGF 1.18 and 124 | earlier. 125 | - Fixed a bug in handling of the special ``d2toptions`` attribute. It was read 126 | even when commented out. Thanks Misha Aizatulin for reporting this. 127 | - Fixed label alignment issues when using recent versions of Graphviz. 128 | - Silenced os.popen3 deprecation warning in Python 2.6. 129 | - Fixed bug in handling of d2toption when dot2tex was used as a module. 130 | 131 | 132 | 2.8.5 133 | ----- 134 | 135 | Released 2009-03-02 136 | 137 | - Updated TikZ/PGF templates to use ``line join=bevel`` instead of 138 | ``join=bevel``. The name of the option was changed in PGF 2.0 and ``join`` 139 | is now used by TikZ's chain library. The change will break PGF 1.18 140 | compatibility. 141 | - Unquoted unicode strings are now correctly parsed. 142 | 143 | 144 | 2.8.4 145 | ----- 146 | 147 | Released 2008-09-23. 148 | 149 | - Fixed a really stupid bug in the quoting of the Graphviz binaries. 150 | The code in the 2.8.3 release did not quote the binaries at all. 151 | Thanks Peter Collingbourne for spotting this! 152 | 153 | 2.8.3 154 | ----- 155 | 156 | - File paths to the Graphviz executables are now quoted. This solves 157 | an issue with paths containing spaces. Thanks Pedro Teixeira and 158 | Mateusz for reporting this. 159 | - Fixed a template typo. Dot2tex looks for the ``<>``, 160 | but ``<>`` is used in the documentation. Now both 161 | versions can be used. 162 | - Added ``--cache`` command line option. If caching is enabled, dot2tex 163 | will check if the input graph has been processed before. If it has 164 | not changed the graph will not be converted (not documented yet). 165 | 166 | 2.8.2 167 | ----- 168 | 169 | - Fixed a parsing bug in the detection of output format in cases like:: 170 | 171 | dot2tex --preproc example.dot | dot2tex 172 | 173 | Thanks Peter Collingbourne for the patch! 174 | - Removed obsolete shebang line from dot2tex.py 175 | 176 | 177 | 2.8.1 178 | ----- 179 | 180 | - Fixed a severe bug in the preprocessing code for the tikz output format. 181 | 182 | 2.8.0 183 | ----- 184 | 185 | Released 2008-05-05. 186 | 187 | - Node names are now filtered to ensure that they are valid TikZ node names. 188 | - Correct fill and stroke color is now set when using the tikz and pst output formats. 189 | - Invisible nodes now generate zero-size coordinates when using the tikz 190 | output format. This allows drawing edges to/from invisible nodes. 191 | - Added dropshadows.dot and sportsbracket.dot examples. 192 | - Concentrated edges are now supported in the pgf and pstricks output formats. 193 | - The dot parser now correctly parses quoted string like:: 194 | 195 | label="A \"quote\"" 196 | label="\n\nA" 197 | 198 | - The dot parser now supports concatenation of double quoted strings using 199 | the + character. Example:: 200 | 201 | a [label="partA" + "partB" + "partC"]; 202 | 203 | - Added support for edge compass points when using the tikz output format. 204 | Example: ``a.n -> b.e`` is translated to ``\draw (a.north) ... (b.east)`` 205 | - The external pydot module has been replaced with a custom version 206 | of the pydot's dot parser. Available in the dotparsing.py file. 207 | - Added support for file input. If the input data contains the line 208 | ``\input{filename.dot}`` 209 | filename.dot will be loaded and processed. (Thanks Kim Sullivan for the idea) 210 | - Added interface for using dot2tex as a library. Example:: 211 | 212 | import dot2tex 213 | testgraph="digraph G {a_1-> a_2 -> a_3 -> a_1;}" 214 | texcode = dot2tex.dot2tex(testgraph,format='tikz',crop=True) 215 | 216 | 217 | 2.7.0 218 | ----- 219 | 220 | Released 2007-12-10. 221 | 222 | - Added the ``--codeonly`` option. When this option is used, only draw 223 | commands are generated. Intended for use with the dot2texi package. 224 | - Minor improvements to the documentation. 225 | - Added ``graphanndtti.tex`` example. 226 | 227 | 2.6.1 228 | ----- 229 | 230 | - Fixed missing header in the file dot2tex/dotex 231 | - Fixed various typos in the documentation 232 | 233 | 2.6.0 234 | ----- 235 | 236 | Released 2007-09-14. 237 | 238 | - Added the ``--autosize`` option. Equivalent to:: 239 | 240 | > dot2tex --preproc ex.dot | dot2tex 241 | 242 | - Added the ``--prog`` option for choosing between dot, neato, circo, towpi 243 | and fdp, when the input is in plain dot format. 244 | - Added the special ``d2toptions`` graph attribute. Allows you to specify 245 | dot2tex options in command line format. 246 | - Added a dot2tex wrapper script and changed setup.py to make it fully 247 | compatible with both setuptools and distutils. A dot2tex module will 248 | now be put in the site-packages directory and a wrapper script in the 249 | scripts directory. 250 | - Fixed typo in error message. 251 | - Added ``--runtests`` option to run doc tests (experimental). 252 | - Fixed issue with wrong template when both the --preview and --figonly 253 | options were used. 254 | 255 | 2.5.0 256 | ----- 257 | 258 | Released 2007-07-28. 259 | 260 | - Added the TikZ output format (``-f tikz``) 261 | - Added the ``lblstyle`` attribute for styling graph, node and edge labels. 262 | (PGF and TikZ only) 263 | - Added the ``--tikzedgelabels`` option for placing edge labels without 264 | using xdot edge label information (tikz and pgf output format only). 265 | - Added a topath edge attribute for using TikZ' to paths (tikz and 266 | pgf only). 267 | - Information about the selected output format is now stored in the graph 268 | generated in preprocessing mode. No longer necessary to specify an 269 | output format in the final run. 270 | - Edges with the same source and dest are now handled correctly in 271 | preprocessing mode. Only the edge defined last was preprocessed. 272 | - Added the ``--nodeoptions`` and ``--edgeoptions`` options and corresponding 273 | ``d2tnodeoptions`` and ``d2tedgeoptions`` graph attribute (tikz only). 274 | - Added the ``exstyle`` attribute. Ignored in preprocessing mode. (pgf and 275 | tikz only) 276 | 277 | 2.0.3 278 | ----- 279 | 280 | - Special TeX char escape code rewritten. Now works as intended. 281 | The ``$`` character was not properly escaped. 282 | - Added ``&`` to list of special characters. 283 | 284 | 285 | 2.0.2 286 | ----- 287 | 288 | - Fixed a severe bug in the interpretation of color attributes in edges. 289 | Colors were not reset after a change to a single edge color. 290 | 291 | 2.0.1 292 | ----- 293 | 294 | - Node margins are now interpreted correctly for nodes with size < minsize. 295 | - Nodes now grow correctly to fit labels when size > minsize 296 | - Updated documentation with an example on how to change node sizes. 297 | 298 | 2.0.0 299 | ----- 300 | 301 | Released 2007-04-23 302 | 303 | - Fixed a number of preprocessing bug related to how node attributes are 304 | interpreted. 305 | - Added automata.dot example. 306 | - Changed the name of the ``--preview`` option to ``--crop``. 307 | - Added the --preproc option for preprocessing labels with preview.sty. 308 | - Added the --debug option. Writes detailed debug information to dot2tex.log. 309 | - The ^ char is now properly escaped. 310 | - Default PGF/TikZ template now requires PGF v >= 1.09. 311 | - Added new template tags to support preprocessing mode. 312 | - Templates for preprocessing, output and figonly mode can now be put 313 | in the same file. 314 | - Added the ``--alignstr`` option. 315 | - Added the ``--valignmode`` option. 316 | - Added the ``--usepdflatex`` option. 317 | 318 | 1.5.0 319 | ----- 320 | 321 | Released 2006-10-22 322 | 323 | - Added a few more helpfull error messages. 324 | - Added the ``--figonly`` option. 325 | - The ``$`` character is now properly escaped. 326 | - Fixed a few issues when converting between Graphviz to backend styles. 327 | - Fixed scoping issues when drawing edges in duplicate mode. 328 | - Added more intelligent detection of xdot input. Older versions of 329 | Graphviz does not include the ``xdotversion`` attribute in the 330 | output. 331 | - Styles are now transfered to the PSTricks and PGF/TikZ backend. 332 | - Added a force straight line option to avoid using curves for 333 | straight edges. 334 | - PGF/TikZ is now set as the default backend. 335 | - Fixed a line ending issue in data converted internally to the xdot format. 336 | - Added the ``-V`` version command line switch 337 | - Added the ``--encoding`` option 338 | - Added option for switching node and graph draw order. 339 | - Fixed bug in PGF/TikZ color handling 340 | - Added the ``--preview`` option to crop graphs 341 | - Added ``--figpreamble`` and ``--figpostamble`` options and graph attributes. 342 | - Added ``--docpreamble`` option and ``d2tdocpreamble`` graph attribute 343 | - Added ``--graphstyle`` option 344 | - Added ``--gvcols`` option 345 | - Changed default PGF/TikZ arrow type to >=latex' 346 | 347 | 1.0.1 348 | ----- 349 | 350 | - Fixed bug in gvcols.tex 351 | 352 | 1.0.0 353 | ----- 354 | 355 | Released 2006-09-10 356 | 357 | - First public release. 358 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019, Kjell Magne Fauske 2 | 3 | The dot parser is copyright (c) 2004-2014 Michael Krause and Ero Carrera 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to 7 | deal in the Software without restriction, including without limitation the 8 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9 | sell copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include docs * 2 | recursive-exclude docs *.pyc 3 | recursive-exclude docs *.pyo 4 | include CHANGES LICENSE AUTHORS readme.md 5 | include examples/*.dot 6 | include examples/*dtti.tex 7 | include tests/testgraphs/*.dot 8 | prune tests/testgraphs/*/*.dot 9 | include tests/testgraphs/parsetests/*.dot 10 | include tests/test_comparedotparsing.py 11 | include tests/test_multirender.py 12 | include tests/test_buildexamples.py 13 | include tests/test_dot2tex.py 14 | prune examples/*dot2tex-fig* 15 | include examples/gvcols.tex 16 | prune docs/_build 17 | 18 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # Internal variables. 11 | PAPEROPT_a4 = -D latex_paper_size=a4 12 | PAPEROPT_letter = -D latex_paper_size=letter 13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 14 | 15 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest 16 | 17 | help: 18 | @echo "Please use \`make ' where is one of" 19 | @echo " html to make standalone HTML files" 20 | @echo " dirhtml to make HTML files named index.html in directories" 21 | @echo " singlehtml to make a single large HTML file" 22 | @echo " pickle to make pickle files" 23 | @echo " json to make JSON files" 24 | @echo " htmlhelp to make HTML files and a HTML help project" 25 | @echo " qthelp to make HTML files and a qthelp project" 26 | @echo " devhelp to make HTML files and a Devhelp project" 27 | @echo " epub to make an epub" 28 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 29 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 30 | @echo " text to make text files" 31 | @echo " man to make manual pages" 32 | @echo " changes to make an overview of all changed/added/deprecated items" 33 | @echo " linkcheck to check all external links for integrity" 34 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 35 | 36 | clean: 37 | -rm -rf $(BUILDDIR)/* 38 | 39 | html: 40 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 41 | @echo 42 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 43 | 44 | dirhtml: 45 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 46 | @echo 47 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 48 | 49 | singlehtml: 50 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 51 | @echo 52 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 53 | 54 | pickle: 55 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 56 | @echo 57 | @echo "Build finished; now you can process the pickle files." 58 | 59 | json: 60 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 61 | @echo 62 | @echo "Build finished; now you can process the JSON files." 63 | 64 | htmlhelp: 65 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 66 | @echo 67 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 68 | ".hhp project file in $(BUILDDIR)/htmlhelp." 69 | 70 | qthelp: 71 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 72 | @echo 73 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 74 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 75 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/dot2tex.qhcp" 76 | @echo "To view the help file:" 77 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/dot2tex.qhc" 78 | 79 | devhelp: 80 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 81 | @echo 82 | @echo "Build finished." 83 | @echo "To view the help file:" 84 | @echo "# mkdir -p $$HOME/.local/share/devhelp/dot2tex" 85 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/dot2tex" 86 | @echo "# devhelp" 87 | 88 | epub: 89 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 90 | @echo 91 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 92 | 93 | latex: 94 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 95 | @echo 96 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 97 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 98 | "(use \`make latexpdf' here to do that automatically)." 99 | 100 | latexpdf: 101 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 102 | @echo "Running LaTeX files through pdflatex..." 103 | make -C $(BUILDDIR)/latex all-pdf 104 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 105 | 106 | text: 107 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 108 | @echo 109 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 110 | 111 | man: 112 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 113 | @echo 114 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 115 | 116 | changes: 117 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 118 | @echo 119 | @echo "The overview file is in $(BUILDDIR)/changes." 120 | 121 | linkcheck: 122 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 123 | @echo 124 | @echo "Link check complete; look for any errors in the above output " \ 125 | "or in $(BUILDDIR)/linkcheck/output.txt." 126 | 127 | doctest: 128 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 129 | @echo "Testing of doctests in the sources finished, look at the " \ 130 | "results in $(BUILDDIR)/doctest/output.txt." 131 | -------------------------------------------------------------------------------- /docs/changelog.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../CHANGES -------------------------------------------------------------------------------- /docs/common.inc: -------------------------------------------------------------------------------- 1 | .. _CTAN: http://www.ctan.org/tex-archive/help/Catalogue/entries/dot2tex.html 2 | .. _easy_install: https://pypi.python.org/pypi/setuptools 3 | .. _Graphviz: http://www.graphviz.org/ 4 | .. _PSTricks: http://tug.org/PSTricks/main.cgi/ 5 | .. _PGF/TikZ: http://www.ctan.org/pkg/pgf 6 | .. _MIT: http://opensource.org/licenses/mit-license.php 7 | .. _Python: https://www.python.org 8 | .. _pyparsing: http://pyparsing.wikispaces.com/ 9 | .. _pydot: https://pypi.python.org/pypi/pydot 10 | .. _preview: http://www.ctan.org/pkg/preview 11 | .. _preview-latex: http://www.gnu.org/software/auctex/preview-latex.html 12 | .. _AUCTeX: http://www.gnu.org/software/auctex/ 13 | .. _dot2texi: http://www.ctan.org/pkg/dot2texi 14 | .. _pip: https://pypi.python.org/pypi/pip -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # dot2tex documentation build configuration file, created by 4 | # sphinx-quickstart on Thu Apr 21 19:55:14 2011. 5 | # 6 | # This file is execfile()d with the current directory set to its containing dir. 7 | # 8 | # Note that not all possible configuration values are present in this 9 | # autogenerated file. 10 | # 11 | # All configuration values have a default; values that are commented out 12 | # serve to show the default. 13 | 14 | import sys, os 15 | 16 | # If extensions (or modules to document with autodoc) are in another directory, 17 | # add these directories to sys.path here. If the directory is relative to the 18 | # documentation root, use os.path.abspath to make it absolute, like shown here. 19 | #sys.path.insert(0, os.path.abspath('.')) 20 | 21 | # -- General configuration ----------------------------------------------------- 22 | 23 | # If your documentation needs a minimal Sphinx version, state it here. 24 | #needs_sphinx = '1.0' 25 | 26 | # Add any Sphinx extension module names here, as strings. They can be extensions 27 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 28 | extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.ifconfig'] 29 | 30 | # Add any paths that contain templates here, relative to this directory. 31 | templates_path = ['_templates'] 32 | 33 | # The suffix of source filenames. 34 | source_suffix = '.rst' 35 | 36 | # The encoding of source files. 37 | #source_encoding = 'utf-8-sig' 38 | 39 | # The master toctree document. 40 | master_doc = 'index' 41 | 42 | # General information about the project. 43 | project = u'dot2tex' 44 | copyright = u'2019, Kjell Magne Fauske' 45 | 46 | # The version info for the project you're documenting, acts as replacement for 47 | # |version| and |release|, also used in various other places throughout the 48 | # built documents. 49 | # 50 | # The short X.Y version. 51 | version = '2.12.dev' 52 | # The full version, including alpha/beta/rc tags. 53 | release = '2.12.dev' 54 | 55 | # The language for content autogenerated by Sphinx. Refer to documentation 56 | # for a list of supported languages. 57 | #language = None 58 | 59 | # There are two options for replacing |today|: either, you set today to some 60 | # non-false value, then it is used: 61 | #today = '' 62 | # Else, today_fmt is used as the format for a strftime call. 63 | #today_fmt = '%B %d, %Y' 64 | 65 | # List of patterns, relative to source directory, that match files and 66 | # directories to ignore when looking for source files. 67 | exclude_patterns = ['_build'] 68 | 69 | # The reST default role (used for this markup: `text`) to use for all documents. 70 | #default_role = None 71 | 72 | # If true, '()' will be appended to :func: etc. cross-reference text. 73 | #add_function_parentheses = True 74 | 75 | # If true, the current module name will be prepended to all description 76 | # unit titles (such as .. function::). 77 | #add_module_names = True 78 | 79 | # If true, sectionauthor and moduleauthor directives will be shown in the 80 | # output. They are ignored by default. 81 | #show_authors = False 82 | 83 | # The name of the Pygments (syntax highlighting) style to use. 84 | pygments_style = 'sphinx' 85 | 86 | # A list of ignored prefixes for module index sorting. 87 | #modindex_common_prefix = [] 88 | 89 | 90 | # -- Options for HTML output --------------------------------------------------- 91 | 92 | # The theme to use for HTML and HTML Help pages. See the documentation for 93 | # a list of builtin themes. 94 | html_theme = 'default' 95 | 96 | # Theme options are theme-specific and customize the look and feel of a theme 97 | # further. For a list of options available for each theme, see the 98 | # documentation. 99 | #html_theme_options = {} 100 | 101 | # Add any paths that contain custom themes here, relative to this directory. 102 | #html_theme_path = [] 103 | 104 | # The name for this set of Sphinx documents. If None, it defaults to 105 | # " v documentation". 106 | #html_title = None 107 | 108 | # A shorter title for the navigation bar. Default is the same as html_title. 109 | #html_short_title = None 110 | 111 | # The name of an image file (relative to this directory) to place at the top 112 | # of the sidebar. 113 | #html_logo = None 114 | 115 | # The name of an image file (within the static path) to use as favicon of the 116 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 117 | # pixels large. 118 | #html_favicon = None 119 | 120 | # Add any paths that contain custom static files (such as style sheets) here, 121 | # relative to this directory. They are copied after the builtin static files, 122 | # so a file named "default.css" will overwrite the builtin "default.css". 123 | html_static_path = ['_static'] 124 | 125 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 126 | # using the given strftime format. 127 | #html_last_updated_fmt = '%b %d, %Y' 128 | 129 | # If true, SmartyPants will be used to convert quotes and dashes to 130 | # typographically correct entities. 131 | #html_use_smartypants = True 132 | 133 | # Custom sidebar templates, maps document names to template names. 134 | #html_sidebars = {} 135 | 136 | # Additional templates that should be rendered to pages, maps page names to 137 | # template names. 138 | #html_additional_pages = {} 139 | 140 | # If false, no module index is generated. 141 | #html_domain_indices = True 142 | 143 | # If false, no index is generated. 144 | #html_use_index = True 145 | 146 | # If true, the index is split into individual pages for each letter. 147 | #html_split_index = False 148 | 149 | # If true, links to the reST sources are added to the pages. 150 | #html_show_sourcelink = True 151 | 152 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 153 | #html_show_sphinx = True 154 | 155 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 156 | #html_show_copyright = True 157 | 158 | # If true, an OpenSearch description file will be output, and all pages will 159 | # contain a tag referring to it. The value of this option must be the 160 | # base URL from which the finished HTML is served. 161 | #html_use_opensearch = '' 162 | 163 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 164 | #html_file_suffix = None 165 | 166 | # Output file base name for HTML help builder. 167 | htmlhelp_basename = 'dot2texdoc' 168 | 169 | 170 | # -- Options for LaTeX output -------------------------------------------------- 171 | 172 | # The paper size ('letter' or 'a4'). 173 | #latex_paper_size = 'letter' 174 | 175 | # The font size ('10pt', '11pt' or '12pt'). 176 | #latex_font_size = '10pt' 177 | 178 | # Grouping the document tree into LaTeX files. List of tuples 179 | # (source start file, target name, title, author, documentclass [howto/manual]). 180 | latex_documents = [ 181 | ('index', 'dot2tex.tex', u'dot2tex Documentation', 182 | u'Kjell Magne Fauske', 'manual'), 183 | ] 184 | 185 | # The name of an image file (relative to this directory) to place at the top of 186 | # the title page. 187 | #latex_logo = None 188 | 189 | # For "manual" documents, if this is true, then toplevel headings are parts, 190 | # not chapters. 191 | #latex_use_parts = False 192 | 193 | # If true, show page references after internal links. 194 | #latex_show_pagerefs = False 195 | 196 | # If true, show URL addresses after external links. 197 | #latex_show_urls = False 198 | 199 | # Additional stuff for the LaTeX preamble. 200 | #latex_preamble = '' 201 | 202 | # Documents to append as an appendix to all manuals. 203 | #latex_appendices = [] 204 | 205 | # If false, no module index is generated. 206 | #latex_domain_indices = True 207 | 208 | 209 | # -- Options for manual page output -------------------------------------------- 210 | 211 | # One entry per manual page. List of tuples 212 | # (source start file, name, description, authors, manual section). 213 | man_pages = [ 214 | ('index', 'dot2tex', u'dot2tex Documentation', 215 | [u'Kjell Magne Fauske'], 1) 216 | ] 217 | 218 | 219 | # Example configuration for intersphinx: refer to the Python standard library. 220 | intersphinx_mapping = {'python': ('http://docs.python.org/', None)} 221 | -------------------------------------------------------------------------------- /docs/docgraphs/balls.dot: -------------------------------------------------------------------------------- 1 | // This graph uses special PGF/TikZ styles to create some interesting 2 | // visual effects. To get the snaked edges run dot2tex with the -s option 3 | // to force straight edges. Example 4 | // $ fdp -Txdot balls.dot | dot2tex -s > balls.tex 5 | graph G { 6 | node [shape=circle, fixedsize=True, width="0.2", style="ball color = green", label=""]; 7 | edge [style="snake=zigzag, green"]; 8 | a_1 -- c -- a_2; 9 | c [style="ball color=black"]; 10 | edge [style="snake=snake, blue", color=red]; 11 | node [style="ball color = red", label=""]; 12 | a_3 -- c -- a_4 --a_3; 13 | } -------------------------------------------------------------------------------- /docs/docgraphs/ex1.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | a_1-> a_2 -> a_3 -> a_1; 3 | } -------------------------------------------------------------------------------- /docs/docgraphs/ex1b.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | node [shape=circle]; 3 | a_1-> a_2 -> a_3 -> a_1; 4 | } -------------------------------------------------------------------------------- /docs/docgraphs/ex2.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | a_1 [texlbl="$\frac{\gamma}{x^2}$"]; 3 | a_1-> a_2 -> a_3 -> a_1; 4 | } -------------------------------------------------------------------------------- /docs/docgraphs/ex3.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | start; 3 | end; 4 | node [texmode="math"]; 5 | a_1; 6 | a_2; 7 | start -> a_1 -> a_2 -> end; 8 | } -------------------------------------------------------------------------------- /docs/docgraphs/ex4.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | a_1 [texlbl="$\frac{\gamma}{2x^2+y^3}$"]; 3 | a_1 -> a_2 -> a_3 -> a_1 4 | node [texmode="math"]; 5 | a_1 -> b_1 -> b_2 -> a_3; 6 | b_1 [label="\\frac{\\gamma}{x^2}"]; 7 | node [texmode="verbatim"] 8 | b_4 [label="\\beta"] 9 | a_3 -> b_4 -> a_1; 10 | } -------------------------------------------------------------------------------- /docs/docgraphs/lblstyle.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | node [shape=circle]; 3 | a -> b [label="label",lblstyle="draw=red,cross out"]; 4 | b -> c [label="test",lblstyle="below=0.5cm,rotate=20,fill=blue!20"]; 5 | a [label="aa",lblstyle="blue"]; 6 | b [lblstyle="font=\Huge"]; 7 | c [label="ccc", lblstyle="red,rotate=90"]; 8 | rankdir=LR; 9 | label="Graph label"; 10 | lblstyle="draw,fill=red!20"; 11 | } -------------------------------------------------------------------------------- /docs/docgraphs/nodesize.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | node [shape=rectangle]; 3 | a_1 [margin="0"]; // will have no effect 4 | a_2 [margin="0.7,0.4"]; 5 | a_3 [width="2",height="1"]; 6 | a_1-> a_2 -> a_3 -> a_1; 7 | } -------------------------------------------------------------------------------- /docs/docgraphs/pgfarrows.dot: -------------------------------------------------------------------------------- 1 | // Examples of PGF/TikZ style arrows. See chapter 14.1 in the PGF/TikZ manual 2 | // for all availale arrow styles. 3 | // To generate this graph you can write: 4 | // $ circo -Txdot pgfarrows.dot | dot2tex.py > pgfarrows.tex 5 | digraph G { 6 | graph [mindist=0.5]; 7 | node [texmode="math", fixedsize=true, shape=circle, width=0.4, style="fill=green!20"]; 8 | c -> n_1 [style="-stealth"]; 9 | c -> n_2 [style="-to"]; 10 | c -> n_3 [style="-latex"]; 11 | c -> n_4 [style="-diamond"]; 12 | c -> n_5 [style="-o"]; 13 | c -> n_6 [style="{-]}"]; 14 | c -> n_7 [style="-triangle 90"]; 15 | c -> n_8 [style="-hooks"]; 16 | c -> n_9 [style="->>"]; 17 | c [style="fill=red!80"]; 18 | } -------------------------------------------------------------------------------- /docs/docgraphs/preproc1.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | node [shape=circle]; 3 | a_1 [texlbl="$x^2+\frac{\sin y}{y^2+\cos \beta}+\gamma_3$"]; 4 | a_1 -> a_2 [label=" ", texlbl="$x_1+x_3^2+z+c+v~~$"]; 5 | a_2 -> a_1; 6 | } -------------------------------------------------------------------------------- /docs/docgraphs/pstarrows.dot: -------------------------------------------------------------------------------- 1 | // Examples of Pstricks style arrows. 2 | // To generate this graph you can write: 3 | // $ circo -Txdot pstarrows.dot | dot2tex.py -fpst > pstarrows.tex 4 | digraph G { 5 | d2tdocpreamble="\usepackage{pstricks-add}"; 6 | graph [mindist=0.5]; 7 | node [texmode="math", fixedsize=true, shape=circle, width=0.4]; 8 | c -> n_1 [style="arrows=->"]; 9 | c -> n_2 [style="arrows=->>"]; 10 | c -> n_3 [style="arrows=-<"]; 11 | c -> n_4 [style="arrows=-*"]; 12 | c -> n_5 [style="arrows=-{]}"]; 13 | c -> n_6 [style="arrows=-o"]; 14 | c -> n_7 [style="arrows=-H"]; 15 | } -------------------------------------------------------------------------------- /docs/docgraphs/simple.dot: -------------------------------------------------------------------------------- 1 | graph G { 2 | mindist = 0.5; 3 | node [shape="circle"]; 4 | a -- b -- c -- a; 5 | } -------------------------------------------------------------------------------- /docs/docgraphs/simplelbl.dot: -------------------------------------------------------------------------------- 1 | graph G { 2 | mindist = 0.5; 3 | node [shape="circle"]; 4 | d2tfigpreamble = "\tikzstyle{mystyle}=[fill=blue!20]"; 5 | edge [lblstyle="mystyle"]; 6 | a -- b [label="ab"]; 7 | b -- c [label="bc"]; 8 | c -- a [label="ca"]; 9 | } -------------------------------------------------------------------------------- /docs/docgraphs/topaths1.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | mindist = 0.5; 3 | node [shape="circle"]; 4 | a -> b [topath="bend right"]; 5 | c -> b [topath="bend left"]; 6 | c -> a [topath="out=10,in=-90"]; 7 | b -> b [topath="loop above"]; 8 | } -------------------------------------------------------------------------------- /docs/docgraphs/valignmode1.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | node [fontsize=10]; 3 | node0 [label="{left|right}", shape=record]; 4 | node1 [shape=rectangle, label="node 1"]; 5 | node0 -> node1; 6 | rankdir=LR; 7 | } -------------------------------------------------------------------------------- /docs/img/balls.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/balls.pdf -------------------------------------------------------------------------------- /docs/img/balls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/balls.png -------------------------------------------------------------------------------- /docs/img/consistent.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/consistent.pdf -------------------------------------------------------------------------------- /docs/img/consistent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/consistent.png -------------------------------------------------------------------------------- /docs/img/dot2texiex1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/dot2texiex1.pdf -------------------------------------------------------------------------------- /docs/img/dot2texiex1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/dot2texiex1.png -------------------------------------------------------------------------------- /docs/img/dot2texiex2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/dot2texiex2.pdf -------------------------------------------------------------------------------- /docs/img/dot2texiex2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/dot2texiex2.png -------------------------------------------------------------------------------- /docs/img/ex1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/ex1.png -------------------------------------------------------------------------------- /docs/img/ex1bcomb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/ex1bcomb.png -------------------------------------------------------------------------------- /docs/img/ex1comb.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/ex1comb.pdf -------------------------------------------------------------------------------- /docs/img/ex1comb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/ex1comb.png -------------------------------------------------------------------------------- /docs/img/ex1def.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/ex1def.png -------------------------------------------------------------------------------- /docs/img/ex1gstyle.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/ex1gstyle.pdf -------------------------------------------------------------------------------- /docs/img/ex1gstyle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/ex1gstyle.png -------------------------------------------------------------------------------- /docs/img/ex1huge.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/ex1huge.pdf -------------------------------------------------------------------------------- /docs/img/ex1huge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/ex1huge.png -------------------------------------------------------------------------------- /docs/img/ex2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/ex2.pdf -------------------------------------------------------------------------------- /docs/img/ex2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/ex2.png -------------------------------------------------------------------------------- /docs/img/fsm1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/fsm1.pdf -------------------------------------------------------------------------------- /docs/img/fsm1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/fsm1.png -------------------------------------------------------------------------------- /docs/img/lblstyle.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/lblstyle.pdf -------------------------------------------------------------------------------- /docs/img/lblstyle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/lblstyle.png -------------------------------------------------------------------------------- /docs/img/nodewidth1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/nodewidth1.pdf -------------------------------------------------------------------------------- /docs/img/nodewidth1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/nodewidth1.png -------------------------------------------------------------------------------- /docs/img/nodewidth2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/nodewidth2.pdf -------------------------------------------------------------------------------- /docs/img/nodewidth2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/nodewidth2.png -------------------------------------------------------------------------------- /docs/img/pgfarrows.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/pgfarrows.pdf -------------------------------------------------------------------------------- /docs/img/pgfarrows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/pgfarrows.png -------------------------------------------------------------------------------- /docs/img/pgfsimple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/pgfsimple.png -------------------------------------------------------------------------------- /docs/img/pgftikzsimple.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/pgftikzsimple.pdf -------------------------------------------------------------------------------- /docs/img/pgftikzsimple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/pgftikzsimple.png -------------------------------------------------------------------------------- /docs/img/preproc1a.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/preproc1a.pdf -------------------------------------------------------------------------------- /docs/img/preproc1a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/preproc1a.png -------------------------------------------------------------------------------- /docs/img/preproc1b.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/preproc1b.pdf -------------------------------------------------------------------------------- /docs/img/preproc1b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/preproc1b.png -------------------------------------------------------------------------------- /docs/img/pstarrows.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/pstarrows.pdf -------------------------------------------------------------------------------- /docs/img/pstarrows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/pstarrows.png -------------------------------------------------------------------------------- /docs/img/texmode.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/texmode.pdf -------------------------------------------------------------------------------- /docs/img/texmode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/texmode.png -------------------------------------------------------------------------------- /docs/img/texmodeb.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/texmodeb.pdf -------------------------------------------------------------------------------- /docs/img/texmodeb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/texmodeb.png -------------------------------------------------------------------------------- /docs/img/tikzedgelabels.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/tikzedgelabels.pdf -------------------------------------------------------------------------------- /docs/img/tikzedgelabels.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/tikzedgelabels.png -------------------------------------------------------------------------------- /docs/img/tikzsimple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/tikzsimple.png -------------------------------------------------------------------------------- /docs/img/topaths1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/topaths1.pdf -------------------------------------------------------------------------------- /docs/img/topaths1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/topaths1.png -------------------------------------------------------------------------------- /docs/img/valignmode0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/valignmode0.pdf -------------------------------------------------------------------------------- /docs/img/valignmode0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/valignmode0.png -------------------------------------------------------------------------------- /docs/img/valignmode1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/valignmode1.pdf -------------------------------------------------------------------------------- /docs/img/valignmode1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/valignmode1.png -------------------------------------------------------------------------------- /docs/img/valignmode2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/valignmode2.pdf -------------------------------------------------------------------------------- /docs/img/valignmode2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/valignmode2.png -------------------------------------------------------------------------------- /docs/img/valignmode3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/valignmode3.pdf -------------------------------------------------------------------------------- /docs/img/valignmode3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/docs/img/valignmode3.png -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | dot2tex - A Graphviz to LaTeX converter 2 | ======================================= 3 | 4 | :Author: Kjell Magne Fauske 5 | :Version: 2.12.dev 6 | :Licence: MIT_ 7 | 8 | 9 | The purpose of dot2tex is to give graphs generated by Graphviz_ a more LaTeX 10 | friendly look and feel. This is accomplished by converting xdot output from 11 | Graphviz_ to a series of PSTricks_ or `PGF/TikZ`_ commands. This approach allows: 12 | 13 | * Typesetting labels with LaTeX, allowing mathematical notation 14 | * Using native PSTricks and PGF/TikZ commands for drawing arrows 15 | * Using backend specific styles to customize the output 16 | 17 | 18 | User's guide 19 | ============ 20 | 21 | .. toctree:: 22 | :maxdepth: 2 23 | :numbered: 24 | 25 | installation_guide 26 | usage_guide 27 | customization_guide 28 | tipsandtricks 29 | module_guide 30 | 31 | 32 | Additional notes 33 | ================ 34 | 35 | .. toctree:: 36 | :maxdepth: 2 37 | 38 | Change log 39 | license 40 | 41 | 42 | Acknowledgements 43 | ================ 44 | 45 | The dot parser used by dot2tex is based on code from the pydot_ project. 46 | 47 | 48 | Indices and tables 49 | ================== 50 | 51 | * :ref:`genindex` 52 | * :ref:`modindex` 53 | * :ref:`search` 54 | 55 | .. include:: common.inc -------------------------------------------------------------------------------- /docs/installation_guide.rst: -------------------------------------------------------------------------------- 1 | Installation guide 2 | ================== 3 | 4 | Dependencies 5 | ------------ 6 | 7 | The following software and modules are required to run dot2tex: 8 | 9 | - Python_ 2.7 or 3.x. 10 | - pyparsing_. Version 1.4.8 or later is recommended. 11 | - Graphviz_. A recent version is required. 12 | - preview_. A LaTeX package for extracting parts of a document. A free-standing part of the `preview-latex`_/`AUCTeX`_ bundle. 13 | - `PGF/TikZ`_ version 2.0 or later. 14 | 15 | Users have reported problems using dot2tex with old versions of pyparsing and Graphviz. 16 | 17 | A natural companion to dot2tex is `the dot2texi LaTeX package `_ for embedding graphs directly in your LaTeX source code. 18 | 19 | 20 | Using pip or easy_install 21 | ------------------------- 22 | 23 | The easiest way to install dot2tex is to use `pip`_ (recommended) or `easy_install`_:: 24 | 25 | $ pip install dot2tex 26 | 27 | or `easy_install`_:: 28 | 29 | $ easy_install dot2tex 30 | 31 | If you are on Linux or Mac OS X you may have to call `pip`_ or `easy_install`_ using ``sudo``:: 32 | 33 | $ sudo pip install dot2tex 34 | 35 | The commands will locate dot2tex and download it automatically. Note that documentation and examples are not installed by default. `Pip` and `easy_install`_ will also create a wrapper script or EXE file for you and install dependencies if necessary. 36 | 37 | 38 | .. _download: https://pypi.python.org/pypi/dot2tex#downloads 39 | 40 | Binary packages 41 | --------------- 42 | 43 | Binary packages are available for Debian_ and OpenSUSE_. 44 | 45 | 46 | From source 47 | ----------- 48 | 49 | Download a zip or a tarball from the download_ page. Unpack the file to a directory and run ``python`` on the ``setup.py`` file:: 50 | 51 | $ python setup.py install 52 | 53 | This will create a dot2tex module in your Python modue directory and a wrapper script in your ``SCRIPTS`` directory. Note that a few warnings will be displayed. You can safely ignore them. The warnings are shown because there is some extra information in the ``setup.py`` file that distutils does not understand. 54 | 55 | 56 | Development version 57 | ------------------- 58 | 59 | The development version of ``dot2tex`` is `hosted on GitHub `_. To get the code you can use the following command:: 60 | 61 | git clone https://github.com/kjellmf/dot2tex.git 62 | 63 | .. _Debian: http://packages.qa.debian.org/d/dot2tex.html 64 | .. _OpenSUSE: https://build.opensuse.org/package/show/home:jimfunk/dot2tex 65 | 66 | 67 | .. include:: common.inc -------------------------------------------------------------------------------- /docs/license.rst: -------------------------------------------------------------------------------- 1 | License 2 | ======= 3 | 4 | Dot2tex is licensed under the MIT licence. It basically means that you can do whatever you want with it 5 | as long as you keep the copyright license in all copies or substantial portions of the software. See :ref:`below ` 6 | for details. 7 | 8 | Authors 9 | ------- 10 | 11 | .. include:: ../AUTHORS 12 | 13 | .. _license_details: 14 | 15 | The dot2tex license 16 | ------------------- 17 | 18 | .. include:: ../LICENSE -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | if "%SPHINXBUILD%" == "" ( 6 | set SPHINXBUILD=sphinx-build 7 | ) 8 | set BUILDDIR=_build 9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . 10 | if NOT "%PAPER%" == "" ( 11 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 12 | ) 13 | 14 | if "%1" == "" goto help 15 | 16 | if "%1" == "help" ( 17 | :help 18 | echo.Please use `make ^` where ^ is one of 19 | echo. html to make standalone HTML files 20 | echo. dirhtml to make HTML files named index.html in directories 21 | echo. singlehtml to make a single large HTML file 22 | echo. pickle to make pickle files 23 | echo. json to make JSON files 24 | echo. htmlhelp to make HTML files and a HTML help project 25 | echo. qthelp to make HTML files and a qthelp project 26 | echo. devhelp to make HTML files and a Devhelp project 27 | echo. epub to make an epub 28 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 29 | echo. text to make text files 30 | echo. man to make manual pages 31 | echo. changes to make an overview over all changed/added/deprecated items 32 | echo. linkcheck to check all external links for integrity 33 | echo. doctest to run all doctests embedded in the documentation if enabled 34 | goto end 35 | ) 36 | 37 | if "%1" == "clean" ( 38 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 39 | del /q /s %BUILDDIR%\* 40 | goto end 41 | ) 42 | 43 | if "%1" == "html" ( 44 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 45 | if errorlevel 1 exit /b 1 46 | echo. 47 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 48 | goto end 49 | ) 50 | 51 | if "%1" == "dirhtml" ( 52 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 53 | if errorlevel 1 exit /b 1 54 | echo. 55 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 56 | goto end 57 | ) 58 | 59 | if "%1" == "singlehtml" ( 60 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml 61 | if errorlevel 1 exit /b 1 62 | echo. 63 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. 64 | goto end 65 | ) 66 | 67 | if "%1" == "pickle" ( 68 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 69 | if errorlevel 1 exit /b 1 70 | echo. 71 | echo.Build finished; now you can process the pickle files. 72 | goto end 73 | ) 74 | 75 | if "%1" == "json" ( 76 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 77 | if errorlevel 1 exit /b 1 78 | echo. 79 | echo.Build finished; now you can process the JSON files. 80 | goto end 81 | ) 82 | 83 | if "%1" == "htmlhelp" ( 84 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 85 | if errorlevel 1 exit /b 1 86 | echo. 87 | echo.Build finished; now you can run HTML Help Workshop with the ^ 88 | .hhp project file in %BUILDDIR%/htmlhelp. 89 | goto end 90 | ) 91 | 92 | if "%1" == "qthelp" ( 93 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 94 | if errorlevel 1 exit /b 1 95 | echo. 96 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 97 | .qhcp project file in %BUILDDIR%/qthelp, like this: 98 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\dot2tex.qhcp 99 | echo.To view the help file: 100 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\dot2tex.ghc 101 | goto end 102 | ) 103 | 104 | if "%1" == "devhelp" ( 105 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp 106 | if errorlevel 1 exit /b 1 107 | echo. 108 | echo.Build finished. 109 | goto end 110 | ) 111 | 112 | if "%1" == "epub" ( 113 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub 114 | if errorlevel 1 exit /b 1 115 | echo. 116 | echo.Build finished. The epub file is in %BUILDDIR%/epub. 117 | goto end 118 | ) 119 | 120 | if "%1" == "latex" ( 121 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 122 | if errorlevel 1 exit /b 1 123 | echo. 124 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 125 | goto end 126 | ) 127 | 128 | if "%1" == "text" ( 129 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text 130 | if errorlevel 1 exit /b 1 131 | echo. 132 | echo.Build finished. The text files are in %BUILDDIR%/text. 133 | goto end 134 | ) 135 | 136 | if "%1" == "man" ( 137 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man 138 | if errorlevel 1 exit /b 1 139 | echo. 140 | echo.Build finished. The manual pages are in %BUILDDIR%/man. 141 | goto end 142 | ) 143 | 144 | if "%1" == "changes" ( 145 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 146 | if errorlevel 1 exit /b 1 147 | echo. 148 | echo.The overview file is in %BUILDDIR%/changes. 149 | goto end 150 | ) 151 | 152 | if "%1" == "linkcheck" ( 153 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 154 | if errorlevel 1 exit /b 1 155 | echo. 156 | echo.Link check complete; look for any errors in the above output ^ 157 | or in %BUILDDIR%/linkcheck/output.txt. 158 | goto end 159 | ) 160 | 161 | if "%1" == "doctest" ( 162 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 163 | if errorlevel 1 exit /b 1 164 | echo. 165 | echo.Testing of doctests in the sources finished, look at the ^ 166 | results in %BUILDDIR%/doctest/output.txt. 167 | goto end 168 | ) 169 | 170 | :end 171 | -------------------------------------------------------------------------------- /docs/module_guide.rst: -------------------------------------------------------------------------------- 1 | .. _using-dot2tex-as-a-module: 2 | 3 | Using dot2tex as a module 4 | ========================= 5 | 6 | It is possible to load dot2tex as a module for use in other Python programs. Here is a basic example: 7 | 8 | .. sourcecode:: python 9 | 10 | import dot2tex 11 | testgraph = """ 12 | digraph G { 13 | a -> b -> c -> a; 14 | } 15 | """ 16 | texcode = dot2tex.dot2tex(testgraph, format='tikz', crop=True) 17 | 18 | The ``dot2tex`` function is the main interface: 19 | 20 | .. sourcecode:: python 21 | 22 | dot2tex(dotsource,**kwargs) 23 | 24 | It takes the following input arguments: 25 | 26 | ====================== =================================================== 27 | Argument Description 28 | ====================== =================================================== 29 | ``dotsource`` A string containing a DOT or XDOT graph. 30 | ``**kwargs`` An arbitrary number of conversion options passed as 31 | keyword arguments 32 | ====================== =================================================== 33 | 34 | The function returns the resulting LaTeX code as a string. 35 | 36 | The supported options are the same as the :ref:`command line options ` (long version). Here are a few examples: 37 | 38 | .. sourcecode:: python 39 | 40 | import dot2tex as d2t 41 | texcode = d2t.dot2tex(testgraph, format='tikz', crop=True) 42 | texcode = d2t.dot2tex(testgraph, preproc=True,figonly=True) 43 | texcode = d2t.dot2tex(testgraph, debug=True) 44 | 45 | Option values are either strings or booleans. Note that some of the command line options are not relevant when using dot2tex as a module. 46 | 47 | To specify a template you can use the ``template`` option like this: 48 | 49 | .. sourcecode:: python 50 | 51 | import dot2tex 52 | mytemplate = "<>" 53 | texcode = dot2tex.dot2tex(graph, template = mytemplate) 54 | 55 | 56 | .. _module-debugging: 57 | 58 | Debugging 59 | --------- 60 | 61 | You can set ``debug=True`` to create a detailed log useful for debugging. To retrieve the content of the log you can use the ``get_logstream`` function. It will return a ``StringIO`` instance. You can then use the ``getvalue()`` class method to get the actual text. Example: 62 | 63 | .. sourcecode:: python 64 | 65 | import dot2tex 66 | texcode = dot2tex.dot2tex(testgraph, debug=True) 67 | logstream = dot2tex.get_logstream() 68 | print logstream.getvalue() 69 | 70 | 71 | .. _positions-output-format: 72 | 73 | The ``positions`` output format 74 | ------------------------------- 75 | 76 | When you use dot2tex as a module you have access to the special ``positions`` output format if you use ``format=positions``. 77 | The ``dot2tex`` function will then return dictionary with node name as key and a (x, y) tuple with the 78 | center position of the node as value: 79 | 80 | .. sourcecode:: python 81 | 82 | >>> import dot2tex 83 | >>> testgraph = """ 84 | ... digraph G { 85 | ... a -> b -> c -> a; 86 | ... } 87 | """ 88 | >>> dot2tex.dot2tex(testgraph, format='positions') 89 | {'a': [54, 162], 'b': [27, 90], 'c': [54, 18]} 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /docs/tipsandtricks.rst: -------------------------------------------------------------------------------- 1 | Tips and tricks 2 | =============== 3 | 4 | Fonts 5 | ----- 6 | 7 | No font information in the DOT file is preserved by dot2tex. However, there are several ways of modifying the generated LaTeX code to achieve some control of fonts and font sizes. 8 | 9 | - Modifying the templates. 10 | - Using the ``d2tdocpreamble`` and ``d2tfigpreamble`` attributes or command line options. 11 | - Using the ``lblstyle`` attribute. 12 | 13 | To increase the font size you can for instance insert a ``\Huge`` command in the figure preamble:: 14 | 15 | $ dot2tex -tmath --figpreamble="\Huge" ex1.dot > ex1huge.tex 16 | 17 | .. figure:: img/ex1huge.* 18 | :alt: Setting label font size to \Huge 19 | 20 | Debugging 21 | --------- 22 | 23 | When making your own templates it is easy to make mistakes, and LaTeX markup in graphs may fail to compile. To make it easier to find errors, invoke dot2tex with the ``--debug`` option:: 24 | 25 | $ dot2tex --preproc --debug test.dot 26 | 27 | A dot2tex.log file will then be generated with detailed information. In the log file you will find the generated LaTeX code, as well as well as the compilation log. 28 | 29 | Be consistent 30 | ------------- 31 | 32 | Be aware of differences between the template you use for preprocessing and code used to generate final output. This is especially important if you use the ``--figonly`` option and include the code in a master document. If a 10pt font is used during preprocessing, the result may not be optimal if a 12pt font is used in the final output. 33 | 34 | Example. A graph is generated with:: 35 | 36 | $ dot2tex --preproc -tmath --nominsize ex1.dot > ex1tmp.dot 37 | 38 | Running through dot2tex again with:: 39 | 40 | $ dot2tex --figpreamble="\Huge" ex1tmp.dot > ex1huge.tex 41 | 42 | gives labels that do not fit properly inside the nodes. 43 | 44 | .. figure:: img/consistent.* 45 | :alt: Inconsistence between preproc mode and output mode 46 | 47 | Postprocessing 48 | -------------- 49 | 50 | The output from Graphviz and dot2tex is not perfect. Manual adjustments are sometimes necessary to get the right results for use in a publication. For final and cosmetic adjustments, it is often easier to edit the generated code than to hack the dot source. This is especially true when using the ``tikz`` output format. 51 | 52 | Use the special graph attributes 53 | -------------------------------- 54 | 55 | Dot2tex has many options for customizing the output. Sometimes is is impractical or boring to type the various options at the command line each time you want to create the graph. To avoid this, you can use the special graph attributes. The ``d2toptions`` attribute is handy because it is interpreted as command line options. 56 | 57 | So instead of typing:: 58 | 59 | $ dot2tex -tikz -tmath --tikzedgelabels ex1.dot 60 | 61 | each time, use ``d2toptions`` like this: 62 | 63 | :: 64 | 65 | digraph G { 66 | d2toptions ="-tikz -tmath --tikzedgelabels"; 67 | ... 68 | } 69 | 70 | 71 | 72 | .. _use-tikz-format: 73 | 74 | Use the tikz output format for maximum flexibility 75 | -------------------------------------------------- 76 | 77 | The difference between the ``pgf`` and ``tikz`` output formats is best shown with an example. Consider the following graph: 78 | 79 | :: 80 | 81 | graph G { 82 | mindist = 0.5; 83 | node [shape=circle]; 84 | a -- b -- c -- a; 85 | } 86 | 87 | Rendering the graph using ``circo`` and the ``pgf`` and ``tikz`` output formats:: 88 | 89 | $ circo -Txdot simple.dot | dot2tex -tmath -fpgf -s 90 | $ circo -Txdot simple.dot | dot2tex -tmath -ftikz -s 91 | 92 | gives visually different graphs: 93 | 94 | .. figure:: img/pgftikzsimple.* 95 | :alt: Difference between pgf and tikz output format 96 | 97 | However, the main difference is in the generated code. Here is the ``pgf`` output: 98 | 99 | .. sourcecode:: latex 100 | 101 | % Edge: a -- b 102 | \draw [] (19bp,38bp) -- (19bp,60bp); 103 | % Edge: b -- c 104 | \draw [] (35bp,70bp) -- (55bp,58bp); 105 | % Edge: c -- a 106 | \draw [] (55bp,40bp) -- (35bp,28bp); 107 | % Node: a 108 | \begin{scope} 109 | \pgfsetstrokecolor{black} 110 | \draw (19bp,19bp) ellipse (18bp and 19bp); 111 | \draw (19bp,19bp) node {$a$}; 112 | \end{scope} 113 | % Node: b 114 | \begin{scope} 115 | \pgfsetstrokecolor{black} 116 | \draw (19bp,79bp) ellipse (18bp and 19bp); 117 | \draw (19bp,79bp) node {$b$}; 118 | \end{scope} 119 | % Node: c 120 | \begin{scope} 121 | \pgfsetstrokecolor{black} 122 | \draw (71bp,49bp) ellipse (18bp and 19bp); 123 | \draw (71bp,49bp) node {$c$}; 124 | \end{scope} 125 | 126 | Compare the above code with the ``tikz`` output: 127 | 128 | .. sourcecode:: latex 129 | 130 | \node (a) at (19bp,19bp) [draw,circle,] {$a$}; 131 | \node (b) at (19bp,79bp) [draw,circle,] {$b$}; 132 | \node (c) at (71bp,49bp) [draw,circle,] {$c$}; 133 | \draw [] (a) -- (b); 134 | \draw [] (b) -- (c); 135 | \draw [] (c) -- (a); 136 | 137 | The code is much more compact and it is quite easy to modify the graph. 138 | 139 | .. _dot2texi_package: 140 | 141 | The dot2texi LaTeX package 142 | -------------------------- 143 | 144 | The dot2texi package allows you to embed DOT graphs directly in you LaTeX document. The package will automatically run ``dot2tex`` for you and include the generated code. Example: 145 | 146 | .. sourcecode:: latex 147 | 148 | \documentclass{article} 149 | \usepackage{dot2texi} 150 | 151 | \usepackage{tikz} 152 | \usetikzlibrary{shapes,arrows} 153 | 154 | \begin{document} 155 | \begin{dot2tex}[neato,options=-tmath] 156 | digraph G { 157 | node [shape="circle"]; 158 | a_1 -> a_2 -> a_3 -> a_4 -> a_1; 159 | } 160 | \end{dot2tex} 161 | 162 | \end{document} 163 | 164 | When the above code is run through LaTeX, the following will happen is shell escape is enabled: 165 | 166 | - The graph is written to file. 167 | - ``dot2tex`` is run on the DOT file. 168 | - The generated code is included in the document. 169 | 170 | The whole process is completely automated. The generated graph will look like this: 171 | 172 | .. figure:: img/dot2texiex1.* 173 | :alt: Graph generated with dot2texi 174 | 175 | The ``codeonly`` option is useful in conjunction with ``dot2texi``, especially when used with the ``tikz`` output format. Here is an example that shows how to annotate a graph: 176 | 177 | .. sourcecode:: latex 178 | 179 | \documentclass{article} 180 | \usepackage{tikz} 181 | \usetikzlibrary{arrows,shapes} 182 | \usepackage{dot2texi} 183 | \begin{document} 184 | % Define layers 185 | \pgfdeclarelayer{background} 186 | \pgfdeclarelayer{foreground} 187 | \pgfsetlayers{background,main,foreground} 188 | 189 | % The scale option is useful for adjusting spacing between nodes. 190 | % Note that this works best when straight lines are used to connect 191 | % the nodes. 192 | \begin{tikzpicture}[>=latex',scale=0.8] 193 | % set node style 194 | \tikzstyle{n} = [draw,shape=circle,minimum size=2em, 195 | inner sep=0pt,fill=red!20] 196 | \begin{dot2tex}[dot,tikz,codeonly,styleonly,options=-s -tmath] 197 | digraph G { 198 | node [style="n"]; 199 | A_1 -> B_1; A_1 -> B_2; A_1 -> B_3; 200 | B_1 -> C_1; B_1 -> C_2; 201 | B_2 -> C_2; B_2 -> C_3; 202 | B_3 -> C_3; B_3 -> C_4; 203 | } 204 | \end{dot2tex} 205 | % annotations 206 | \node[left=1em] at (C_1.west) (l3) {Level 3}; 207 | \node at (l3 |- B_1) (l2){Level 2}; 208 | \node at (l3 |- A_1) (l1) {Level 1}; 209 | % Draw lines to separate the levels. First we need to calculate 210 | % where the middle is. 211 | \path (l3) -- coordinate (l32) (l2) -- coordinate (l21) (l1); 212 | \draw[dashed] (C_1 |- l32) -- (l32 -| C_4); 213 | \draw[dashed] (C_1 |- l21) -- (l21 -| C_4); 214 | \draw[<->,red] (A_1) to[out=-120,in=90] (C_2); 215 | % Highlight the A_1 -> B_1 -> C_2 path. Use layers to draw 216 | % behind everything. 217 | \begin{pgfonlayer}{background} 218 | \draw[rounded corners=2em,line width=3em,blue!20,cap=round] 219 | (A_1.center) -- (B_1.west) -- (C_2.center); 220 | \end{pgfonlayer} 221 | \end{tikzpicture} 222 | \end{document} 223 | 224 | .. figure:: img/dot2texiex2.* 225 | :alt: Annotated graph 226 | 227 | .. note:: 228 | 229 | If you don't want to include the dot directly in your document, you can use the ``\input{..}`` command. See the section :ref:`external_dot_files` for more details. 230 | -------------------------------------------------------------------------------- /docs/usage_guide.rst: -------------------------------------------------------------------------------- 1 | =========== 2 | Usage guide 3 | =========== 4 | 5 | .. _invoking-dot2tex: 6 | 7 | Invoking dot2tex from the command line 8 | ====================================== 9 | 10 | Syntax:: 11 | 12 | dot2tex [options] [inputfile] 13 | 14 | 15 | Input data is read from standard input if no input file is specified. Output is written to standard output unless a destination file is set with the ``-o`` option. 16 | 17 | Dot2tex can also be loaded as a module for use in other Python program. See the section :ref:`using-dot2tex-as-a-module` for more details. 18 | 19 | Dot2tex relies on the `xdot format`_ generated by Graphviz. Dot2tex will automatically run ``dot`` on the input data if it is in the plain dot format. If you want to use other layout tools like ``neato`` and ``circo``, use the ``--prog`` option. You can pass options to the layout program with the ``--progoptions`` option. 20 | 21 | .. _xdot format: http://www.graphviz.org/doc/info/output.html#d:xdot 22 | 23 | A few examples on how to invoke dot2tex: 24 | 25 | Read a file from standard input and write the result to the file ``test.tex``:: 26 | 27 | $ dot -Txdot test.dot | dot2tex > test.tex 28 | $ neato -Txdot -Gstart=rand test.dot | dot2tex > test.tex 29 | 30 | Load ``test.dot``, convert it to xdot format and output the resulting graph using the ``tikz`` output format to ``testpgf.tex``:: 31 | 32 | $ dot2tex -ftikz test.dot > testtikz.tex 33 | 34 | The same as above, but use neato for graph layout:: 35 | 36 | $ dot2tex --prog=neato -ftikz test.dot > testneato.tex 37 | 38 | 39 | .. admonition:: Invoking dot2tex 40 | 41 | If you are on Windows and have installed dot2tex from source, you have to type ``python dot2tex`` to invoke the program. 42 | 43 | 44 | 45 | 46 | 47 | .. _command-line-options: 48 | 49 | Command line options 50 | ==================== 51 | 52 | The following options are available: 53 | 54 | -h, --help 55 | Display help message. 56 | -f fmt, --format fmt 57 | Set output format. The following values of `fmt` are supported: 58 | 59 | ``pgf`` 60 | PGF/TikZ. Default. 61 | ``pstricks`` or ``pst`` 62 | Use PSTricks. 63 | ``tikz`` 64 | TikZ format. 65 | 66 | -t mode, --texmode mode 67 | Text mode. Specify how text is converted. 68 | 69 | ``verbatim`` 70 | Text is displayed with all special TeX chars escaped (default). 71 | ``math`` 72 | Output all text in math mode $$. 73 | ``raw`` 74 | Output text without any processing. 75 | 76 | Note that you can locally override the text mode by assigning a special ``texlbl`` attribute to a graph element, or by using the ``texmode`` attribute. See :ref:`labels` for details. 77 | 78 | -s, --straightedges 79 | Draw edges using straight lines. Graphviz uses bezier curves to draw straight edges. Use this option to force the use of line to operations instead of curves. Does not work in ``duplicate`` mode. 80 | 81 | -o filename, --output filename 82 | Write output to file. 83 | 84 | -d, --duplicate 85 | Duplicate the xdot output. Uses the drawing information embedded in the xdot output to draw nodes and edges. 86 | 87 | --template filename 88 | Use template from file. See the :ref:`templates` section for more details. 89 | 90 | -V, --version 91 | Print version information and exit. 92 | 93 | -w, --switchdraworder 94 | Switch drawing order of nodes and edges. By default edges are drawn before nodes. 95 | 96 | -c, --crop 97 | Use ``preview.sty`` to crop the graph. Currently only implemented for the ``pgf`` and ``tikz`` output format. 98 | 99 | --figonly 100 | Output the graph without a document preamble. Useful if the graph is to be included in a master document. 101 | 102 | --codeonly 103 | Output only the drawing commands, without wrapping it in a ``tikzpicture`` or ``pspicture`` environment. Useful when used with the dot2texi package. 104 | 105 | --preproc 106 | Preprocess the graph through LaTeX using the preview_ package. Will generate a new dot file where the height and widths of nodes and edge labels are set based on the results from preview_. 107 | 108 | --autosize 109 | Preprocess the graph and run Graphviz on the output. Equivalent to:: 110 | 111 | $ dot2tex --preproc ex1.dot | dot2tex 112 | 113 | --prog program 114 | Set graph layout program to use when the input is in plain dot format. Allowed values: 115 | 116 | - ``dot`` (default) 117 | - ``neato`` 118 | - ``circo`` 119 | - ``fdp`` 120 | - ``twopi`` 121 | 122 | --progoptions options 123 | Pass options to graph layout program. 124 | 125 | --usepdflatex 126 | Use pdflatex instead of latex for preprocessing the graph. 127 | 128 | --nominsize 129 | Ignore minimum node sizes during preprocessing. 130 | 131 | --valignmode mode 132 | Vertical alignment of node labels, where ``mode`` can have the values: 133 | 134 | ``center`` 135 | Labels are placed in the middle of the node (default). 136 | ``dot`` 137 | Use the coordinate given by the xdot output from Graphviz. 138 | 139 | (``pgf`` and ``pstricks`` only) 140 | 141 | --alignstr 142 | Used to pass a default alignment string to the PSTricks ``\rput`` command:: 143 | 144 | \rput[alignstr] ... 145 | 146 | Only works for the PSTricks format. PGF/TikZ users can instead pass an ``anchor=...`` style using the ``graphstyle`` option. 147 | 148 | --tikzedgelabels 149 | Bypass Graphviz' edge label placement and use PGF/TikZ instead (``tikz`` and ``pgf`` formats only). 150 | 151 | --styleonly 152 | Use TikZ only styles when drawing nodes. No ``draw`` or ``shape`` option is added (``tikz`` format only). 153 | 154 | --nodeoptions tikzoptions 155 | Wrap node code in a ``scope`` environment with ``tikzoptions`` as parameter (``tikz`` format only). 156 | 157 | --edgeoptions tikzoptions 158 | Wrap edge code in a ``scope`` environment with ``tikzoptions`` as parameter (``tikz`` format only). 159 | 160 | --debug 161 | Write detailed debug information to the file dot2tex.log in the current directory. 162 | 163 | --pgf118 164 | Generate code compatible with PGF 1.18 and earlier. 165 | 166 | --pgf210 167 | Generate code compatible with PGF 2.10. 168 | 169 | The following options are used by the output :ref:`templates `. 170 | 171 | -e encoding, --encoding encoding 172 | Set text encoding. Supported encodings are: 173 | 174 | - ``utf8`` 175 | - ``latin1`` 176 | 177 | --docpreamble TeXcode 178 | Insert TeX code in the document preamble. 179 | 180 | --figpreamble TeXcode 181 | Insert TeX code in the figure preamble. 182 | 183 | --figpostamble TeXcode 184 | Insert TeX code in the figure postamble. 185 | 186 | --graphstyle style 187 | Sets the ``<>`` tag. 188 | 189 | --margin margin 190 | Set margin around the graph when using ``preview.sty``. ``margin`` must be a valid TeX unit. By default ``margin`` is set to ``0pt``. 191 | 192 | .. _output-formats: 193 | 194 | Output formats 195 | ============== 196 | 197 | The output format is specified with the ``-f fmt`` or ``--format fmt`` command line option. The following output formats 198 | are available form the command line. Additionally there is a special :ref:`positions output format ` only available when 199 | using dot2tex as Python module. 200 | 201 | .. _output-fomat-pgf: 202 | 203 | PGF 204 | --- 205 | 206 | This is the default output format. Generates code for the `Portable Graphics Format`_ (PGF) package . Mixes both PGF and TikZ commands. 207 | 208 | .. _Portable Graphics Format: http://www.ctan.org/pkg/pgf 209 | 210 | .. _output-fomat-pstricks: 211 | 212 | PSTricks 213 | -------- 214 | 215 | Generates code for the PSTricks_ package. 216 | 217 | .. _output-fomat-tikz: 218 | 219 | TikZ 220 | ---- 221 | 222 | The ``tikz`` output format also uses the PGF and TikZ package. However, it relies on TikZ node and edge mechanisms to draw nodes and edges, instead of using the drawing information provided by Graphviz. This allows much tighter integration with TikZ and in some cases prettier results. 223 | 224 | Advantages of the ``tikz`` format: 225 | 226 | - The generated code is very compact and clean. 227 | - Easy to modify the output. 228 | - Labels will fit inside nodes without preprocessing. 229 | - Full access to the power of PGF and TikZ. 230 | 231 | You can find more details in the section: :ref:`use-tikz-format`. 232 | 233 | .. note:: The ``tikz`` output format requires detailed knowledge of the PGF and TikZ package. Some of Graphviz' features will not work with this output format. 234 | 235 | .. _labels: 236 | 237 | Labels 238 | ====== 239 | 240 | The main purpose of dot2tex is to allow text and labels to be typeset by LaTeX. Labels are treated differently according to the current TeX mode: 241 | 242 | ``verbatim`` 243 | Text is displayed with all special TeX chars escaped (default). 244 | ``math`` 245 | Output all text in math mode $$. 246 | ``raw`` 247 | Output text without any processing. 248 | 249 | The TeX mode can be set on the command line using the ``-t`` option. It can also be set locally in a graph by using the special ``texmode`` attribute. 250 | 251 | You can also use the special ``texlbl`` attribute on a graph element, which is interpreted as ``raw`` TeX string. If a ``texlbl`` attribute is found, it will be used regardless of the current TeX mode. It also has precedence over the ``label`` attribute. 252 | 253 | .. note:: The ``\`` character needs to be escaped with ``\\`` if used in the ``label`` attribute. 254 | 255 | Note that only position and alignment information is converted. Any font information is lost. This may result in some odd behavior. Some tweaking may be necessary to get it right. See the section :ref:`vertical-label-alignment` for tips. 256 | 257 | .. note:: If you use ``texlbl`` for edges, you have to provide a dummy ``label`` attribute. Otherwise Graphviz will not generate the necessary code for placing edge labels. 258 | 259 | Label examples 260 | -------------- 261 | 262 | Consider the following graph: 263 | 264 | :: 265 | 266 | digraph G { 267 | a_1-> a_2 -> a_3 -> a_1; 268 | } 269 | 270 | Converting the graph using:: 271 | 272 | $ dot2tex -tmath ex1.dot > ex1.tex 273 | 274 | gives the result shown in the left hand side of the figure below. The default rendering is shown to the right. Using the ``raw`` mode will result in a compilation error because of the underscore character. 275 | 276 | .. figure:: img/ex1comb.* 277 | :alt: Difference between math and verbatim mode 278 | 279 | Example of using ``texlbl``: 280 | 281 | :: 282 | 283 | digraph G { 284 | a_1 [texlbl="$\frac{\gamma}{x^2}$"]; 285 | a_1-> a_2 -> a_3 -> a_1; 286 | } 287 | 288 | .. figure:: img/ex2.* 289 | :alt: Using the special texlbl attribute 290 | 291 | Example of using the ``texmode`` attribute: 292 | 293 | :: 294 | 295 | digraph G { 296 | a_1 [texlbl="$\frac{\gamma}{2x^2+y^3}$"]; 297 | a_1 -> a_2 -> a_3 -> a_1 298 | node [texmode="math"]; 299 | a_1 -> b_1 -> b_2 -> a_3; 300 | b_1 [label="\\frac{\\gamma}{x^2}"]; 301 | node [texmode="verbatim"] 302 | b_4 [label="\\beta"] 303 | a_3 -> b_4 -> a_1; 304 | } 305 | 306 | .. figure:: img/texmode.* 307 | :alt: Using the special texmode attribute 308 | 309 | The above example shows two important things: 310 | 311 | - The backslash ``\`` character needs to be written as ``\\`` in the ``label`` attribute. 312 | - Using LaTeX markup in the ``label`` attribute gives oversized nodes. A workaround is to use the ``texlbl`` attribute, and manually pad the ``label`` attribute to an appropriate length. A much better solution is to use the ``--preproc`` option. 313 | 314 | Preprocessing the above graph with:: 315 | 316 | $ dot2tex --preproc ex4.dot | dot2tex > ex4.tex 317 | 318 | gives correctly sized nodes: 319 | 320 | .. figure:: img/texmodeb.* 321 | :alt: Preprocessing the graph to get correct node sizes. 322 | 323 | Read more about preprocessing in the `Preprocessing graphs`_ section. 324 | 325 | .. _vertical-label-alignment: 326 | 327 | Vertical label alignment 328 | ------------------------ 329 | 330 | Dot2tex relies on the xdot format for drawing nodes and placing node labels. The fonts that Graphviz and LaTeX use are different, so using the label coordinates from Graphviz does not always give good results. Dot2tex's default behavior is to place node labels in the middle of the node. However, you can change this behavior by setting the ``valignmode`` option to ``dot``. Labels will then be placed using the coordinates supplied by Graphviz. 331 | 332 | Here is an example graph where it is necessary to use the ``valignmode`` option: 333 | 334 | :: 335 | 336 | digraph G { 337 | node0 [label="{left|right}", shape=record]; 338 | node1 [shape=rectangle, label="node 1"]; 339 | node0 -> node1; 340 | rankdir=LR; 341 | } 342 | 343 | For record nodes dot2tex has to use Graphviz coordinates. This is shown in the following figure rendered with:: 344 | 345 | $ dot2tex valign.dot 346 | 347 | .. figure:: img/valignmode0.* 348 | :alt: Vertical alignment for record shapes 349 | 350 | To get the same vertical alignment for both nodes, you can use:: 351 | 352 | $ dot2tex --valignmode=dot valign.dot 353 | 354 | .. figure:: img/valignmode1.* 355 | :alt: Vertical alignment with --valignmode=dot 356 | 357 | Now the labels are aligned, but the labels are still placed too low. The reason for this is that both PSTricks and PGF by default centers text vertically on the current coordinate. The alignment point should in this case be set to the baseline. For PGF/TikZ you can use the ``--graphstyle`` option like this:: 358 | 359 | $ dot2tex --valignmode=dot --graphstyle="anchor=base" valign.dot 360 | 361 | PSTricks users have to use the ``--alingstr`` option:: 362 | 363 | $ dot2tex --valignmode=dot --alignstr=B valign.dot 364 | 365 | .. figure:: img/valignmode2.* 366 | :alt: blabla 367 | 368 | The result is better, but to get even better alignment you have to change the node font size. Graphviz' default font size is 14pt, which is larger than the typical 10pt or 11pt used in LaTeX documents. By changing the node font size to 10pt we can trick Graphviz to give us a better alignment: 369 | 370 | :: 371 | 372 | digraph G { 373 | node [fontsize=10]; 374 | node0 [label="{left|right}", shape=record]; 375 | node1 [shape=rectangle, label="node 1"]; 376 | node0 -> node1; 377 | rankdir=LR; 378 | } 379 | 380 | .. figure:: img/valignmode3.* 381 | :alt: blabla 382 | 383 | 384 | .. _preprocessing-graphs: 385 | 386 | Preprocessing graphs 387 | ==================== 388 | 389 | A problem with using LaTeX for typesetting node and edge labels, is that Graphviz does not know the sizes of the resulting labels. To circumvent this problem, you can use the ``--preproc`` or ``--autosize`` option. The following will then happen: 390 | 391 | 1. Node and edge labels are extracted and the corresponding LaTeX markup is saved to a temporary file. 392 | 2. The file is typeset with LaTeX and information about sizes is extracted using the preview_ package. 393 | 3. A new dot file is created where node and edge label sizes are set using the dot language's ``width`` and ``height`` attributes. 394 | 4. The generated graph can now be processed using Graphviz and dot2tex. Label sizes will now correspond with the output from LaTeX. 395 | 396 | Widths and heights of nodes are handled the in same way as Graphviz does it. The ``width`` and ``height`` attributes set the minimum size of the node. If label size + margins is larger that the minimum size, the node size will grow accordingly. Default values are width=0.75in and height=0.5in. 397 | 398 | Node margins are set using the `margin`_ attribute. This also works for edge labels. ``margin==value`` sets both the horizontal and vertical margin to ``value``, ``margin=="hvalue,vvalue"`` sets the horizontal and vertical margins respectively. 399 | 400 | .. note:: All sizes are given in inches. 401 | 402 | If you do not want a minimum node size, you can use the '--nominsize' option. Dot2tex will then use size of label + margins as node size. 403 | 404 | Nodes with ``fixedsize=True`` attributes are not processed. 405 | 406 | Limitations: 407 | 408 | - Does not work for HTML-labels 409 | - Does not work for record-based nodes 410 | 411 | .. _preprocessing-examples: 412 | 413 | Examples 414 | -------- 415 | 416 | Consider the following graph: 417 | 418 | :: 419 | 420 | digraph G { 421 | node [shape=circle]; 422 | a_1 [texlbl="$x^2+\frac{\sin y}{y^2+\cos \beta}+\gamma_3$"]; 423 | a_1 -> a_2 [label=" ", texlbl="$x_1+x_3^2+z+c+v~~$"]; 424 | a_2 -> a_1; 425 | } 426 | 427 | Rendered with:: 428 | 429 | $ dot2tex -tmath example.dot > example.tex 430 | 431 | the graph will look like this: 432 | 433 | .. figure:: img/preproc1a.* 434 | :alt: Graph with oversized edge and node labels 435 | 436 | You could improve the result by adding a longer ``label`` attribute or setting a fixed width. A better solution is to preprocess the graph like this:: 437 | 438 | $ dot2tex -tmath --preproc example.dot > exampletmp.dot 439 | $ dot2tex exampletmp.dot > example.tex 440 | 441 | You can also chain the commands:: 442 | 443 | $ dot2tex -tmath --preproc example.dot | dot2tex > example.tex 444 | 445 | A shorter alternative is:: 446 | 447 | $ dot2tex -tmath --autosize example.dot > example.tex 448 | 449 | The resulting graph now has correctly sized nodes and edge labels: 450 | 451 | .. figure:: img/preproc1b.* 452 | :alt: Graph with preprocessed labels 453 | 454 | Modifying node sizes using the ``widht/height`` and ``margin`` attributes can be a bit counterintuitive. A few examples will hopefully make it clearer: 455 | 456 | :: 457 | 458 | digraph G { 459 | node [shape=rectangle]; 460 | a_1 [margin="0"]; 461 | a_2 [margin="0.7,0.4"]; 462 | a_3 [width="2",height="1"]; 463 | a_1-> a_2 -> a_3 -> a_1; 464 | } 465 | 466 | Processing the graph with:: 467 | 468 | $ dot2tex -tmath --preproc example.dot | dot2tex > example.tex 469 | 470 | gives 471 | 472 | .. figure:: img/nodewidth1.* 473 | :alt: Graph with preprocessed labels 474 | 475 | Setting the margin of ``a_1`` to 0 has no effect because of the minimum node width. Processing the graph with:: 476 | 477 | $ dot2tex -tmath --preproc --nominsize example.dot | dot2tex > example.tex 478 | 479 | gives a different graph, where only label widths and margins affect the node sizes: 480 | 481 | .. figure:: img/nodewidth2.* 482 | :alt: Graph with preprocessed labels 483 | 484 | 485 | .. _margin: http://graphviz.org/doc/info/attrs.html#d:margin 486 | 487 | 488 | .. include:: common.inc 489 | 490 | -------------------------------------------------------------------------------- /dot2tex/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """Convert graphviz graphs to LaTeX-friendly formats 4 | 5 | Various tools for converting graphs generated by the graphviz library 6 | to formats for use with LaTeX. 7 | 8 | Copyright (c) 2006-2014, Kjell Magne Fauske 9 | 10 | """ 11 | 12 | # Copyright (c) 2006-2014, Kjell Magne Fauske 13 | # 14 | # Permission is hereby granted, free of charge, to any person obtaining a copy 15 | # of this software and associated documentation files (the "Software"), to 16 | # deal in the Software without restriction, including without limitation the 17 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 18 | # sell copies of the Software, and to permit persons to whom the Software is 19 | # furnished to do so, subject to the following conditions: 20 | # 21 | # The above copyright notice and this permission notice shall be included in 22 | # all copies or substantial portions of the Software. 23 | # 24 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 29 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 30 | # IN THE SOFTWARE. 31 | 32 | __author__ = 'Kjell Magne Fauske' 33 | __license__ = 'MIT' 34 | 35 | from . import dot2tex as d2t 36 | from pyparsing import ParseException 37 | 38 | __version__ = d2t.__version__ 39 | 40 | import logging 41 | 42 | 43 | class _NullHandler(logging.Handler): 44 | def emit(self, record): 45 | pass 46 | 47 | _h = _NullHandler() 48 | logging.getLogger("dot2tex").addHandler(_h) 49 | 50 | 51 | def get_logstream(): 52 | return None 53 | 54 | 55 | def dot2tex(dotsource, **kwargs): 56 | """Process dotsource and return LaTeX code 57 | 58 | Conversion options can be specified as keyword options. Example: 59 | dot2tex(data,format='tikz',crop=True) 60 | 61 | """ 62 | return d2t.convert_graph(dotsource, **kwargs) 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /dot2tex/__main__.py: -------------------------------------------------------------------------------- 1 | from .dot2tex import main 2 | 3 | if __name__ == '__main__': 4 | main() 5 | -------------------------------------------------------------------------------- /dot2tex/pstricksformat.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from .base import DotConvBase 4 | from .utils import smart_float, tikzify 5 | 6 | log = logging.getLogger("dot2tex") 7 | 8 | PSTRICKS_TEMPLATE = r"""\documentclass{standalone} 9 | % <> 10 | \usepackage[x11names,svgnames]{xcolor} 11 | \usepackage[<>]{inputenc} 12 | \usepackage{graphicx} 13 | \usepackage{pstricks} 14 | \usepackage{amsmath} 15 | <>% 16 | \usepackage[active,auctex]{preview} 17 | <>% 18 | <>% 19 | <>% 20 | 21 | 22 | \begin{document} 23 | <>% 24 | <>% 25 | <>% 26 | <>% 27 | 28 | % Start of code 29 | \begin{pspicture}[linewidth=1bp<>]<> 30 | \pstVerb{2 setlinejoin} % set line join style to 'mitre' 31 | <>% 32 | <> 33 | <>% 34 | \end{pspicture} 35 | % End of code 36 | <>% 37 | \end{document} 38 | % 39 | <> 40 | \begin{pspicture}[linewidth=1bp<>]<> 41 | \pstVerb{2 setlinejoin} % set line join style to 'mitre' 42 | <>% 43 | <> 44 | <>% 45 | \end{pspicture} 46 | <> 47 | % 48 | <> 49 | <>% 50 | <> 51 | <>% 52 | <> 53 | """ 54 | 55 | 56 | class Dot2PSTricksConv(DotConvBase): 57 | """PSTricks converter backend""" 58 | 59 | def __init__(self, options=None): 60 | DotConvBase.__init__(self, options) 61 | if not self.template: 62 | self.template = PSTRICKS_TEMPLATE 63 | self.styles = dict( 64 | dotted="linestyle=dotted", 65 | dashed="linestyle=dashed", 66 | bold="linewidth=2pt", 67 | solid="", 68 | filled="", 69 | ) 70 | 71 | def do_graphtmp(self): 72 | self.pencolor = "" 73 | self.fillcolor = "" 74 | self.color = "" 75 | self.body += '{\n' 76 | DotConvBase.do_graph(self) 77 | self.body += '}\n' 78 | 79 | def draw_ellipse(self, drawop, style=None): 80 | op, x, y, w, h = drawop 81 | s = "" 82 | if op == 'E': 83 | if style: 84 | style = style.replace('filled', '') 85 | stylestr = 'fillstyle=solid' 86 | else: 87 | stylestr = "" 88 | 89 | if style: 90 | if stylestr: 91 | stylestr += ',' + style 92 | else: 93 | stylestr = style 94 | 95 | s += r" \psellipse[%s](%sbp,%sbp)(%sbp,%sbp)\n" % (stylestr, smart_float(x), smart_float(y), 96 | # w+self.linewidth,h+self.linewidth) 97 | smart_float(w), smart_float(h)) 98 | 99 | return s 100 | 101 | def draw_polygon(self, drawop, style=None): 102 | op, points = drawop 103 | pp = ['(%sbp,%sbp)' % (smart_float(p[0]), smart_float(p[1])) for p in points] 104 | stylestr = "" 105 | if op == 'P': 106 | if style: 107 | style = style.replace('filled', '') 108 | stylestr = "fillstyle=solid" 109 | if style: 110 | if stylestr: 111 | stylestr += ',' + style 112 | else: 113 | stylestr = style 114 | 115 | s = r" \pspolygon[%s]%s\n" % (stylestr, "".join(pp)) 116 | return s 117 | 118 | def draw_polyline(self, drawop, style=None): 119 | op, points = drawop 120 | pp = ['(%sbp,%sbp)' % (smart_float(p[0]), smart_float(p[1])) for p in points] 121 | s = r" \psline%s\n" % "".join(pp) 122 | return s 123 | 124 | def draw_bezier(self, drawop, style=None): 125 | op, points = drawop 126 | pp = [] 127 | for point in points: 128 | pp.append("(%sbp,%sbp)" % (smart_float(point[0]), smart_float(point[1]))) 129 | 130 | arrowstyle = "" 131 | return r" \psbezier{%s}%s\n" % (arrowstyle, "".join(pp)) 132 | 133 | def draw_text(self, drawop, style=None): 134 | if len(drawop) == 7: 135 | c, x, y, align, w, text, valign = drawop 136 | else: 137 | c, x, y, align, w, text = drawop 138 | valign = "" 139 | if align == "-1": 140 | alignstr = 'l' # left aligned 141 | elif align == "1": 142 | alignstr = 'r' # right aligned 143 | else: 144 | alignstr = "" # centered (default) 145 | if alignstr or valign: 146 | alignstr = '[' + alignstr + valign + ']' 147 | s = " \\rput%s(%sbp,%sbp){%s}\n" % (alignstr, smart_float(x), smart_float(y), text) 148 | return s 149 | 150 | def set_color(self, drawop): 151 | c, color = drawop 152 | color = self.convert_color(color) 153 | s = "" 154 | if c == 'c': 155 | # set pen color 156 | if self.pencolor != color: 157 | self.pencolor = color 158 | s = r" \psset{linecolor=%s}\n" % color 159 | else: 160 | return "" 161 | elif c == 'C': 162 | # set fill color 163 | if self.fillcolor != color: 164 | self.fillcolor = color 165 | s = r" \psset{fillcolor=%s}\n" % color 166 | else: 167 | return "" 168 | elif c == 'cC': 169 | if self.color != color: 170 | self.color = color 171 | self.pencolor = self.fillcolor = color 172 | s = r" \psset{linecolor=%s}\n" % color 173 | else: 174 | log.warning('Unhandled color: %s', drawop) 175 | return s 176 | 177 | def set_style(self, drawop): 178 | c, style = drawop 179 | psstyle = self.styles.get(style, "") 180 | if psstyle: 181 | return r" \psset{%s}\n" % psstyle 182 | else: 183 | return "" 184 | 185 | def filter_styles(self, style): 186 | filtered_styles = [] 187 | for item in style.split(','): 188 | keyval = item.strip() 189 | if keyval.find('setlinewidth') < 0: 190 | filtered_styles.append(keyval) 191 | return ', '.join(filtered_styles) 192 | 193 | def start_node(self, node): 194 | self.pencolor = "" 195 | self.fillcolor = "" 196 | self.color = "" 197 | return "{%\n" 198 | 199 | def end_node(self, node): 200 | return "}%\n" 201 | 202 | def start_edge(self): 203 | self.pencolor = "" 204 | self.fillcolor = "" 205 | return "{%\n" 206 | 207 | def end_edge(self): 208 | return "}%\n" 209 | 210 | def start_graph(self, graph): 211 | self.pencolor = "" 212 | self.fillcolor = "" 213 | self.color = "" 214 | return "{\n" 215 | 216 | def end_graph(self, node): 217 | return "}\n" 218 | 219 | def draw_edge(self, edge): 220 | s = "" 221 | if edge.attr.get('style', '') in ['invis', 'invisible']: 222 | return "" 223 | edges = self.get_edge_points(edge) 224 | for arrowstyle, points in edges: 225 | if arrowstyle == '--': 226 | arrowstyle = '' 227 | color = getattr(edge, 'color', '') 228 | if self.color != color: 229 | if color: 230 | s += self.set_color(('c', color)) 231 | else: 232 | # reset to default color 233 | s += self.set_color(('c', 'black')) 234 | pp = [] 235 | for point in points: 236 | p = point.split(',') 237 | pp.append("(%sbp,%sbp)" % (smart_float(p[0]), smart_float(p[1]))) 238 | 239 | edgestyle = edge.attr.get('style', '') 240 | styles = [] 241 | if arrowstyle: 242 | styles.append('arrows=%s' % arrowstyle) 243 | if edgestyle: 244 | edgestyles = [self.styles.get(key.strip(), key.strip()) 245 | for key in edgestyle.split(',') if key] 246 | styles.extend(edgestyles) 247 | if styles: 248 | stylestr = ",".join(styles) 249 | else: 250 | stylestr = "" 251 | if not self.options.get('straightedges'): 252 | s += r" \psbezier[%s]%s\n" % (stylestr, "".join(pp)) 253 | else: 254 | s += r" \psline[%s]%s%s\n" % (stylestr, pp[0], pp[-1]) 255 | # s += " \psbezier[%s]{%s}%s\n" % (stylestr, arrowstyle,"".join(pp)) 256 | ## if edge.label: 257 | ## x,y = edge.lp.split(',') 258 | ## #s += "\\rput(%s,%s){%s}\n" % (x,y,edge.label) 259 | return s 260 | 261 | def init_template_vars(self): 262 | DotConvBase.init_template_vars(self) 263 | # Put a ',' before <> 264 | graphstyle = self.templatevars.get('<>', '') 265 | if graphstyle: 266 | graphstyle = graphstyle.strip() 267 | if not graphstyle.startswith(','): 268 | graphstyle = ',' + graphstyle 269 | self.templatevars['<>'] = graphstyle 270 | 271 | 272 | PSTRICKSN_TEMPLATE = r"""\documentclass{standalone} 273 | % <> 274 | \usepackage[x11names, svgnames]{xcolor} 275 | \usepackage[<>]{inputenc} 276 | \usepackage{graphicx} 277 | \usepackage{pst-all} 278 | \usepackage[a3paper,landscape]{geometry} 279 | \usepackage{amsmath} 280 | <>% 281 | \usepackage[active,auctex]{preview} 282 | <>% 283 | <>% 284 | <>% 285 | 286 | 287 | \begin{document} 288 | <>% 289 | <>% 290 | <>% 291 | <>% 292 | 293 | % Start of code 294 | \begin{pspicture}[linewidth=1bp<>]<> 295 | \pstVerb{2 setlinejoin} % set line join style to 'mitre' 296 | <>% 297 | <> 298 | <>% 299 | \end{pspicture} 300 | % End of code 301 | <>% 302 | \end{document} 303 | % 304 | <> 305 | \begin{pspicture}[linewidth=1bp<>]<> 306 | \pstVerb{2 setlinejoin} % set line join style to 'mitre' 307 | <>% 308 | <> 309 | <>% 310 | \end{pspicture} 311 | <> 312 | % 313 | <> 314 | <>% 315 | <> 316 | <>% 317 | <> 318 | """ 319 | 320 | 321 | class Dot2PSTricksNConv(Dot2PSTricksConv): 322 | """A backend that utilizes the node and edge mechanism of PSTricks-Node""" 323 | 324 | def __init__(self, options=None): 325 | options = options or {} 326 | # to connect nodes they have to defined. Therefore we have to ensure 327 | # that code for generating nodes is outputted first. 328 | options['switchdraworder'] = True 329 | options['flattengraph'] = True 330 | options['rawdim'] = True 331 | self.template = PSTRICKSN_TEMPLATE 332 | Dot2PSTricksConv.__init__(self, options) 333 | 334 | def output_node_comment(self, node): 335 | # With the node syntax comments are unnecessary 336 | return "" 337 | 338 | def do_nodes(self): 339 | s = "" 340 | for node in self.nodes: 341 | self.currentnode = node 342 | 343 | psshadeoption = getattr(node, 'psshadeoption', '') 344 | psshape = getattr(node, 'psshape', '') 345 | 346 | # detect node type, if psshape is not set 347 | if len(psshape) == 0: 348 | shape = getattr(node, 'shape', 'ellipse') 349 | # box -> psframebox 350 | # circle -> pscirclebox 351 | # rectangle -> psframebox 352 | psshape = "psframebox" 353 | if shape == "circle": 354 | psshape = "pscirclebox" 355 | if shape == "ellipse": 356 | psshape = "psovalbox" 357 | if shape == "triangle": 358 | psshape = "pstribox" 359 | # TODO incomplete 360 | 361 | width = getattr(node, 'width', '1') 362 | height = getattr(node, 'height', '1') 363 | psbox = getattr(node, 'psbox', 'false') 364 | 365 | color = getattr(node, 'color', '') 366 | fillcolor = getattr(node, 'fillcolor', '') 367 | 368 | if len(color) > 0: 369 | psshadeoption = "linecolor=" + color + "," + psshadeoption 370 | if len(fillcolor) > 0: 371 | psshadeoption = "fillcolor=" + fillcolor + "," + psshadeoption 372 | 373 | style = getattr(node, 'style', '') 374 | if len(style) > 0: 375 | if style == "dotted": 376 | psshadeoption = "linestyle=dotted," + psshadeoption 377 | if style == "dashed": 378 | psshadeoption = "linestyle=dashed," + psshadeoption 379 | if style == "solid": 380 | psshadeoption = "linestyle=solid," + psshadeoption 381 | if style == "bold": 382 | psshadeoption = "linewidth=2pt," + psshadeoption 383 | 384 | pos = getattr(node, 'pos') 385 | if not pos: 386 | continue 387 | x, y = pos.split(',') 388 | label = self.get_label(node) 389 | pos = "%sbp,%sbp" % (smart_float(x), smart_float(y)) 390 | # TODO style 391 | 392 | sn = "" 393 | sn += self.output_node_comment(node) 394 | sn += self.start_node(node) 395 | if psbox == "false": 396 | sn += "\\rput(%s){\\rnode{%s}{\\%s[%s]{%s}}}\n" % \ 397 | (pos, tikzify(node.name), psshape, psshadeoption, label) 398 | else: 399 | sn += "\\rput(%s){\\rnode{%s}{\\%s[%s]{\\parbox[c][%sin][c]{%sin}{\\centering %s}}}}\n" % \ 400 | (pos, tikzify(node.name), psshape, psshadeoption, height, width, label) 401 | sn += self.end_node(node) 402 | s += sn 403 | self.body += s 404 | 405 | def do_edges(self): 406 | s = "" 407 | for edge in self.edges: 408 | s += self.draw_edge(edge) 409 | self.body += s 410 | 411 | def draw_edge(self, edge): 412 | s = "" 413 | edges = self.get_edge_points(edge) 414 | for arrowstyle, points in edges: 415 | # styles = [] 416 | psarrow = getattr(edge, 'psarrow', '') 417 | 418 | if len(psarrow) == 0: 419 | stylestr = '-' 420 | else: 421 | stylestr = psarrow 422 | 423 | psedge = getattr(edge, 'psedge', 'ncline') 424 | psedgeoption = getattr(edge, 'psedgeoption', '') 425 | 426 | color = getattr(edge, 'color', '') 427 | fillcolor = getattr(edge, 'fillcolor', '') 428 | 429 | if len(color) > 0: 430 | psedgeoption = "linecolor=" + color + "," + psedgeoption 431 | if len(fillcolor) > 0: 432 | psedgeoption = "fillcolor=" + fillcolor + "," + psedgeoption 433 | 434 | style = getattr(edge, 'style', '') 435 | if len(style) > 0: 436 | if style == "dotted": 437 | psedgeoption = "linestyle=dotted," + psedgeoption 438 | if style == "dashed": 439 | psedgeoption = "linestyle=dashed," + psedgeoption 440 | if style == "solid": 441 | psedgeoption = "linestyle=solid," + psedgeoption 442 | if style == "bold": 443 | psedgeoption = "linewidth=2pt," + psedgeoption 444 | 445 | pslabel = getattr(edge, 'pslabel', 'ncput') 446 | pslabeloption = getattr(edge, 'pslabeloption', '') 447 | label = getattr(edge, 'label', '') 448 | headlabel = getattr(edge, 'headlabel', '') 449 | taillabel = getattr(edge, 'taillabel', '') 450 | 451 | src = tikzify(edge.get_source()) 452 | dst = tikzify(edge.get_destination()) 453 | s = "\\%s[%s]{%s}{%s}{%s}\n" % (psedge, psedgeoption, stylestr, src, dst) 454 | if len(label) != 0: 455 | s += "\\%s[%s]{%s}\n" % (pslabel, pslabeloption, label) 456 | if len(headlabel) != 0: 457 | pslabelhead = 'npos=0.8,' + pslabeloption 458 | s += "\\%s[%s]{%s}\n" % (pslabel, pslabelhead, headlabel) 459 | if len(taillabel) != 0: 460 | pslabeltail = 'npos=0.2,' + pslabeloption 461 | s += "\\%s[%s]{%s}\n" % (pslabel, pslabeltail, taillabel) 462 | return s 463 | 464 | def start_node(self, node): 465 | return "" 466 | 467 | def end_node(self, node): 468 | return "" 469 | -------------------------------------------------------------------------------- /dot2tex/utils.py: -------------------------------------------------------------------------------- 1 | from . import dotparsing 2 | 3 | # Inch to bp conversion factor 4 | INCH2BP = 72.0 5 | SPECIAL_CHARS = ['$', '\\', '%', '_', '#', '{', r'}', '^', '&'] 6 | SPECIAL_CHARS_REPLACE = [r'\$', r'$\backslash$', r'\%', r'\_', r'\#', 7 | r'\{', r'\}', r'\^{}', r'\&'] 8 | charmap = dict(zip(SPECIAL_CHARS, SPECIAL_CHARS_REPLACE)) 9 | 10 | 11 | def mreplace(s, chararray, newchararray): 12 | for a, b in zip(chararray, newchararray): 13 | s = s.replace(a, b) 14 | return s 15 | 16 | 17 | def escape_texchars(string): 18 | r"""Escape the special LaTeX-chars %{}_^ 19 | 20 | Examples: 21 | 22 | >>> escape_texchars('10%') 23 | '10\\%' 24 | >>> escape_texchars('%{}_^\\$') 25 | '\\%\\{\\}\\_\\^{}$\\backslash$\\$' 26 | """ 27 | return "".join([charmap.get(c, c) for c in string]) 28 | 29 | 30 | def tikzify(s): 31 | if s.strip(): 32 | return mreplace(s, r'\,:.()', '-+_*{}') 33 | else: 34 | return "d2tnn%i" % (len(s) + 1) 35 | 36 | 37 | def nsplit(seq, n=2): 38 | """Split a sequence into pieces of length n 39 | 40 | If the length of the sequence isn't a multiple of n, the rest is discarded. 41 | Note that nsplit will strings into individual characters. 42 | 43 | Examples: 44 | >>> nsplit('aabbcc') 45 | [('a', 'a'), ('b', 'b'), ('c', 'c')] 46 | >>> nsplit('aabbcc',n=3) 47 | [('a', 'a', 'b'), ('b', 'c', 'c')] 48 | 49 | # Note that cc is discarded 50 | >>> nsplit('aabbcc',n=4) 51 | [('a', 'a', 'b', 'b')] 52 | """ 53 | return [xy for xy in zip(*[iter(seq)] * n)] 54 | 55 | 56 | def chunks(s, cl): 57 | """Split a string or sequence into pieces of length cl and return an iterator""" 58 | for i in range(0, len(s), cl): 59 | yield s[i:i + cl] 60 | 61 | 62 | def replace_tags(template, tags, tagsreplace): 63 | """Replace occurrences of tags with tagsreplace 64 | 65 | Example: 66 | >>> replace_tags('a b c d',('b','d'),{'b':'bbb','d':'ddd'}) 67 | 'a bbb c ddd' 68 | """ 69 | s = template 70 | for tag in tags: 71 | replacestr = tagsreplace.get(tag, '') 72 | if not replacestr: 73 | replacestr = '' 74 | s = s.replace(tag, replacestr) 75 | return s 76 | 77 | 78 | def getboolattr(item, key, default): 79 | if str(getattr(item, key, '')).lower() == 'true': 80 | return True 81 | else: 82 | return False 83 | 84 | 85 | def smart_float(number): 86 | if type(number) is str: # handle newlines 87 | number = number.strip('\\\r\n') 88 | number_as_string = "%s" % float(number) 89 | if 'e' in number_as_string: 90 | return "%.4f" % float(number) 91 | else: 92 | return number_as_string 93 | 94 | 95 | def is_multiline_label(drawobject): 96 | # https://graphviz.gitlab.io/_pages/doc/info/attrs.html#k:escString 97 | if getattr(drawobject, "texlbl", None): 98 | return False 99 | 100 | label = getattr(drawobject, "label", "") 101 | return any(x in label for x in [r"\n", r"\l", r"\r"]) 102 | 103 | 104 | class EndOfGraphElement(object): 105 | def __init__(self): 106 | pass 107 | 108 | 109 | def get_all_graph_elements(graph, l=None): 110 | """Return all nodes and edges, including elements in subgraphs""" 111 | if not l: 112 | l = [] 113 | outer = True 114 | l.append(graph) 115 | else: 116 | outer = False 117 | for element in graph.allitems: 118 | if isinstance(element, dotparsing.DotSubGraph): 119 | l.append(element) 120 | get_all_graph_elements(element, l) 121 | else: 122 | l.append(element) 123 | 124 | if outer: 125 | return l 126 | else: 127 | l.append(EndOfGraphElement()) -------------------------------------------------------------------------------- /examples/automata.dot: -------------------------------------------------------------------------------- 1 | /* 2 | :Title: State machine 3 | :Tags: PGF, Preproc 4 | 5 | This state machine is `based on an example`_ from the PGF and TikZ manual. 6 | The original looks much better. For small graphs you usually 7 | get better looking results by drawing them manually. 8 | 9 | .. _based on an example: http://www.fauskes.net/pgftikzexamples/state-machine/ 10 | 11 | Generated with:: 12 | 13 | $ dot2tex -tmath --autosize --crop automata.dot > automata.tex 14 | 15 | 16 | */ 17 | digraph automata { 18 | rankdir=LR; 19 | node [shape=circle]; 20 | edge [style=">=stealth',shorten >=1pt"]; 21 | q_a [shape=doublecircle]; 22 | q_a -> q_b [label="0,1,L"]; 23 | q_b -> q_b [label="1,1,L"]; 24 | q_b -> q_c [label="0,1,L"]; 25 | q_c -> q_e [label="1,0,R"]; 26 | q_e -> q_a [label="1,0,R"]; 27 | q_a -> q_c [label="1,1,R"]; 28 | q_c -> q_d [label="0,1,L"]; 29 | q_d -> q_d [label="1,1,R"]; 30 | q_d -> q_a [label="0,1,R"]; 31 | } 32 | -------------------------------------------------------------------------------- /examples/balls.dot: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | :Title: Snaked edges 4 | :Tags: PGF 5 | 6 | This graph uses special `PGF/TikZ`_ styles to create some interesting 7 | visual effects. To get the snaked edges run dot2tex with the ``-s`` option 8 | to force straight edges. 9 | 10 | Generated with:: 11 | 12 | $ dot2tex -s --prog fdp balls.dot > balls.tex 13 | 14 | .. _PGF/TikZ: http://www.ctan.org/tex-archive/help/Catalogue/entries/pgf.html 15 | */ 16 | graph G { 17 | node [shape=circle, fixedsize=True, width="0.2", style="ball color = green", label=""]; 18 | edge [style="snake=zigzag, green"]; 19 | a_1 -- c -- a_2; 20 | c [style="ball color=black"]; 21 | edge [style="snake=snake, blue", color=red]; 22 | node [style="ball color = red", label=""]; 23 | a_3 -- c -- a_4 --a_3; 24 | } -------------------------------------------------------------------------------- /examples/distances.dot: -------------------------------------------------------------------------------- 1 | /* 2 | :Title: Distances 3 | :Tags: TikZ, tikzedgelabels 4 | 5 | Generated with:: 6 | 7 | $ circo -Txdot distances.dot | dot2tex --crop --tikzedgelabels -ftikz -tmath -s > distances.tex 8 | 9 | */ 10 | graph G { 11 | node [shape=circle,fixedsize = true,width=0.1,style="fill=blue!20"]; 12 | edge [lblstyle="fill=black!10,inner sep=1pt,sloped"]; 13 | K -- F [label="120"]; 14 | H -- S [label="650"]; 15 | H -- M [label="780"]; 16 | D -- B [label="490"]; 17 | D -- M [label="600"]; 18 | B -- M [label="580"]; 19 | H -- N [label="600"]; 20 | F -- H [label="490"]; 21 | S -- B [label="630"]; 22 | S -- N [label="210"]; 23 | S -- M [label="230"]; 24 | F --M [label="100"]; 25 | } -------------------------------------------------------------------------------- /examples/dotarrows.dot: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | :Title: Graphviz arrows 4 | :Tags: PGF 5 | 6 | Shows how Graphviz arrows are mapped to PGF/TikZ arrows 7 | 8 | Generated with:: 9 | 10 | $ dot2tex --prog=circo -s -ftikz dotarrows.dot > dotarrows.tex 11 | 12 | */ 13 | digraph G { 14 | graph [mindist=0.5]; 15 | node [texmode="math", shape=circle, style="circle, fill=green!20"]; 16 | edge [lblstyle="above,sloped"]; 17 | d2ttikzedgelabels=true; 18 | c -> n_1 [arrowhead="normal", label="normal"]; 19 | c -> n_2 [arrowhead="inv", label="inv"]; 20 | c -> n_3 [arrowhead="dot", label="dot"]; 21 | c -> n_4 [arrowhead="invdot", label="invdot"]; 22 | c -> n_5 [arrowhead="odot", label="odot"]; 23 | c -> n_6 [arrowhead="invodot", label="invodot"]; 24 | c -> n_7 [arrowhead="none", label="none"]; 25 | c -> n_8 [arrowhead="tee", label="tee"]; 26 | c -> n_9 [arrowhead="empty", label="empty"]; 27 | c -> "n_{10}" [arrowhead="invempty", label="invempty"]; 28 | c -> "n_{11}" [arrowhead="diamond", label="diamond"]; 29 | c -> "n_{12}" [arrowhead="odiamond", label="odiamond"]; 30 | c -> "n_{13}" [arrowhead="ediamond", label="ediamond"]; 31 | c -> "n_{14}" [arrowhead="crow", label="crow"]; 32 | c -> "n_{15}" [arrowhead="box", label="box"]; 33 | c -> "n_{16}" [arrowhead="obox", label="obox"]; 34 | c -> "n_{17}" [arrowhead="open", label="open"]; 35 | c -> "n_{18}" [arrowhead="halfopen", label="halfopen"]; 36 | c -> "n_{19}" [arrowhead="vee", label="vee"]; 37 | c -> "n_{20}" [arrowhead="circle", label="circle"]; 38 | c [style="fill=red!80"]; 39 | } -------------------------------------------------------------------------------- /examples/dropshadows.dot: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | :Title: Node drop shadows 4 | :Tags: TikZ 5 | 6 | 7 | The ``tikz`` output format is highly customizable thanks to TikZ' powerful 8 | style options. In this example drop shadows have been added to all the nodes. 9 | 10 | **Note**: This example requires PGF 2.00 or later. Download the PDF to fully see 11 | the drop shadow effect. The bitmap rendering does not render transparency well. 12 | 13 | 14 | Generated with:: 15 | 16 | $ dot2tex -ftikz --prog neato -s --crop dropshadows.dot > dropshadows.tex 17 | 18 | 19 | */ 20 | graph G { 21 | d2tdocpreamble = "\usetikzlibrary{shadows}"; 22 | node [shape=circle,style="fill=red!20,circular drop shadow"]; 23 | "Node A" -- {"Node B"; "Node C"}; 24 | "Node B" -- {"Node E"; "Node G"}; 25 | "Node C" -- "Node D"; 26 | "Node D" -- {"Node F"; "Node H"}; 27 | "Node E" -- {"Node F"; "Node H"; "Node G"}; 28 | } 29 | -------------------------------------------------------------------------------- /examples/ex1.dot: -------------------------------------------------------------------------------- 1 | /* 2 | :Title: Basic example 3 | :Tags: PGF 4 | 5 | A basic example. 6 | 7 | Generated with:: 8 | 9 | $ dot2tex --preproc -tmath ex1.dot | dot2tex > ex1.tex 10 | 11 | */ 12 | 13 | digraph G { 14 | a_1-> a_2 -> a_3 -> a_1; 15 | } -------------------------------------------------------------------------------- /examples/graphanndtti.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage{tikz} 3 | \usetikzlibrary{arrows,shapes} 4 | \usepackage{dot2texi} 5 | \begin{document} 6 | % Define layers 7 | \pgfdeclarelayer{background} 8 | \pgfdeclarelayer{foreground} 9 | \pgfsetlayers{background,main,foreground} 10 | 11 | % The scale option is useful for adjusting spacing between nodes. 12 | % Note that this works best when straight lines are used to connect 13 | % the nodes. 14 | \begin{tikzpicture}[>=latex',scale=0.8] 15 | % set node style 16 | \tikzstyle{n} = [draw,shape=circle,minimum size=2em, 17 | inner sep=0pt,fill=red!20] 18 | \begin{dot2tex}[dot,tikz,codeonly,styleonly,options=-s -tmath] 19 | digraph G { 20 | node [style="n"]; 21 | A_1 -> B_1; A_1 -> B_2; A_1 -> B_3; 22 | B_1 -> C_1; B_1 -> C_2; 23 | B_2 -> C_2; B_2 -> C_3; 24 | B_3 -> C_3; B_3 -> C_4; 25 | } 26 | \end{dot2tex} 27 | % annotations 28 | \node[left=1em] at (C_1.west) (l3) {Level 3}; 29 | \node at (l3 |- B_1) (l2){Level 2}; 30 | \node at (l3 |- A_1) (l1) {Level 1}; 31 | % Draw lines to separate the levels. First we need to calculate 32 | % where the middle is. 33 | \path (l3) -- coordinate (l32) (l2) -- coordinate (l21) (l1); 34 | \draw[dashed] (C_1 |- l32) -- (l32 -| C_4); 35 | \draw[dashed] (C_1 |- l21) -- (l21 -| C_4); 36 | \draw[<->,red] (A_1) to[out=-120,in=90] (C_2); 37 | % Highlight the A_1 -> B_1 -> C_2 path. Use layers to draw 38 | % behind everything. 39 | \begin{pgfonlayer}{background} 40 | \draw[rounded corners=2em,line width=3em,blue!20,cap=round] 41 | (A_1.center) -- (B_1.west) -- (C_2.center); 42 | \end{pgfonlayer} 43 | \end{tikzpicture} 44 | \end{document} -------------------------------------------------------------------------------- /examples/graphofgraphs.dot: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | :Title: Graph of graphs 4 | :Tags: PGF 5 | 6 | This example shows that node content is not limited to text and math. 7 | You can for instance insert graphics and create this weird graph of graphs. 8 | Download the PDF and zoom in to see the details. 9 | 10 | Generated with:: 11 | 12 | $ neato -Txdot graphofgraphs.dot | dot2tex --crop -fpgf > graphofgraphs.tex 13 | 14 | */ 15 | digraph G { 16 | graph [mindist=0.5]; 17 | node [shape=plaintext, height=0.5]; 18 | edge [style="black!50, thin,-to"]; 19 | a_1 [texlbl="\raisebox{-.4\height}{\includegraphics[height=30bp]{balls.pdf}}"]; 20 | a_2 [texlbl="\raisebox{-.4\height}{\includegraphics[height=30bp]{pgfsnakes.pdf}}"]; 21 | a_3 [texlbl="\raisebox{-.4\height}{\includegraphics[height=30bp]{pgfarrows.pdf}}"]; 22 | a_4 [texlbl="\raisebox{-.4\height}{\includegraphics[height=30bp]{poltab.pdf}}"]; 23 | a_5 [texlbl="\raisebox{-.4\height}{\includegraphics[height=30bp]{subgraphs.pdf}}"]; 24 | a_1-> a_2 -> a_3 -> a_4 -> a_5 -> a_1; 25 | a_2 -> a_5; 26 | } -------------------------------------------------------------------------------- /examples/gvcols.tex: -------------------------------------------------------------------------------- 1 | \def\rangeHSB{255} 2 | \preparecolorset{HSB}{}{}{% 3 | aliceblue,147,15,255;% 4 | antiquewhite,24,35,250;% 5 | antiquewhite1,23,36,255;% 6 | antiquewhite2,23,36,238;% 7 | antiquewhite3,23,36,205;% 8 | antiquewhite4,24,34,139;% 9 | aquamarine,113,128,255;% 10 | aquamarine1,113,128,255;% 11 | aquamarine2,113,128,238;% 12 | aquamarine3,113,128,205;% 13 | aquamarine4,113,128,139;% 14 | azure,127,15,255;% 15 | azure1,127,15,255;% 16 | azure2,127,15,238;% 17 | azure3,127,14,205;% 18 | azure4,127,14,139;% 19 | beige,42,26,245;% 20 | bisque,23,58,255;% 21 | bisque1,23,58,255;% 22 | bisque2,23,58,238;% 23 | bisque3,22,58,205;% 24 | bisque4,23,58,139;% 25 | black,0,0,0;% 26 | blanchedalmond,25,49,255;% 27 | blue,170,255,255;% 28 | blue1,170,255,255;% 29 | blue2,170,255,238;% 30 | blue3,170,255,205;% 31 | blue4,170,255,139;% 32 | blueviolet,192,206,226;% 33 | brown,0,190,165;% 34 | brown1,0,191,255;% 35 | brown2,0,191,238;% 36 | brown3,0,191,205;% 37 | brown4,0,190,139;% 38 | burlywood,23,99,222;% 39 | burlywood1,23,100,255;% 40 | burlywood2,23,99,238;% 41 | burlywood3,23,99,205;% 42 | burlywood4,23,99,139;% 43 | cadetblue,128,103,160;% 44 | cadetblue1,131,103,255;% 45 | cadetblue2,131,102,238;% 46 | cadetblue3,131,103,205;% 47 | cadetblue4,131,102,139;% 48 | chartreuse,63,255,255;% 49 | chartreuse1,63,255,255;% 50 | chartreuse2,63,255,238;% 51 | chartreuse3,63,255,205;% 52 | chartreuse4,63,255,139;% 53 | chocolate,17,218,210;% 54 | chocolate1,17,219,255;% 55 | chocolate2,17,219,238;% 56 | chocolate3,17,218,205;% 57 | chocolate4,17,220,139;% 58 | coral,11,175,255;% 59 | coral1,7,169,255;% 60 | coral2,6,169,238;% 61 | coral3,6,169,205;% 62 | coral4,6,168,139;% 63 | cornflowerblue,154,147,237;% 64 | cornsilk,33,34,255;% 65 | cornsilk1,33,34,255;% 66 | cornsilk2,34,35,238;% 67 | cornsilk3,34,34,205;% 68 | cornsilk4,35,34,139;% 69 | crimson,246,231,220;% 70 | cyan,127,255,255;% 71 | cyan1,127,255,255;% 72 | cyan2,127,255,238;% 73 | cyan3,127,255,205;% 74 | cyan4,127,255,139;% 75 | darkgoldenrod,30,239,184;% 76 | darkgoldenrod1,30,240,255;% 77 | darkgoldenrod2,30,240,238;% 78 | darkgoldenrod3,30,240,205;% 79 | darkgoldenrod4,30,240,139;% 80 | darkgreen,85,255,100;% 81 | darkkhaki,39,110,189;% 82 | darkolivegreen,58,142,107;% 83 | darkolivegreen1,58,143,255;% 84 | darkolivegreen2,58,143,238;% 85 | darkolivegreen3,58,143,205;% 86 | darkolivegreen4,58,143,139;% 87 | darkorange,23,255,255;% 88 | darkorange1,21,255,255;% 89 | darkorange2,21,255,238;% 90 | darkorange3,21,255,205;% 91 | darkorange4,21,255,139;% 92 | darkorchid,198,192,204;% 93 | darkorchid1,198,193,255;% 94 | darkorchid2,198,192,238;% 95 | darkorchid3,198,192,205;% 96 | darkorchid4,198,192,139;% 97 | darksalmon,10,121,233;% 98 | darkseagreen,85,61,188;% 99 | darkseagreen1,85,62,255;% 100 | darkseagreen2,85,62,238;% 101 | darkseagreen3,85,62,205;% 102 | darkseagreen4,85,62,139;% 103 | darkslateblue,175,143,139;% 104 | darkslategray,127,103,79;% 105 | darkslategray1,127,104,255;% 106 | darkslategray2,127,103,238;% 107 | darkslategray3,127,104,205;% 108 | darkslategray4,127,104,139;% 109 | darkslategrey,127,103,79;% 110 | darkturquoise,128,255,209;% 111 | darkviolet,199,255,211;% 112 | deeppink,232,235,255;% 113 | deeppink1,232,235,255;% 114 | deeppink2,232,235,238;% 115 | deeppink3,232,235,205;% 116 | deeppink4,231,236,139;% 117 | deepskyblue,138,255,255;% 118 | deepskyblue1,138,255,255;% 119 | deepskyblue2,138,255,238;% 120 | deepskyblue3,138,255,205;% 121 | deepskyblue4,138,255,139;% 122 | dimgray,0,0,105;% 123 | dimgrey,0,0,105;% 124 | dodgerblue,148,225,255;% 125 | dodgerblue1,148,225,255;% 126 | dodgerblue2,148,225,238;% 127 | dodgerblue3,148,225,205;% 128 | dodgerblue4,148,225,139;% 129 | firebrick,0,206,178;% 130 | firebrick1,0,207,255;% 131 | firebrick2,0,207,238;% 132 | firebrick3,0,207,205;% 133 | firebrick4,0,207,139;% 134 | floralwhite,28,15,255;% 135 | forestgreen,85,192,139;% 136 | gainsboro,0,0,220;% 137 | ghostwhite,170,7,255;% 138 | gold,35,255,255;% 139 | gold1,35,255,255;% 140 | gold2,35,255,238;% 141 | gold3,35,255,205;% 142 | gold4,35,255,139;% 143 | goldenrod,30,217,218;% 144 | goldenrod1,30,218,255;% 145 | goldenrod2,30,218,238;% 146 | goldenrod3,30,218,205;% 147 | goldenrod4,30,218,139;% 148 | gray,0,0,192;% 149 | gray0,0,0,0;% 150 | gray1,0,0,3;% 151 | gray10,0,0,26;% 152 | gray100,0,0,255;% 153 | gray11,0,0,28;% 154 | gray12,0,0,31;% 155 | gray13,0,0,33;% 156 | gray14,0,0,36;% 157 | gray15,0,0,38;% 158 | gray16,0,0,41;% 159 | gray17,0,0,43;% 160 | gray18,0,0,46;% 161 | gray19,0,0,48;% 162 | gray2,0,0,5;% 163 | gray20,0,0,51;% 164 | gray21,0,0,54;% 165 | gray22,0,0,56;% 166 | gray23,0,0,59;% 167 | gray24,0,0,61;% 168 | gray25,0,0,64;% 169 | gray26,0,0,66;% 170 | gray27,0,0,69;% 171 | gray28,0,0,71;% 172 | gray29,0,0,74;% 173 | gray3,0,0,8;% 174 | gray30,0,0,77;% 175 | gray31,0,0,79;% 176 | gray32,0,0,82;% 177 | gray33,0,0,84;% 178 | gray34,0,0,87;% 179 | gray35,0,0,89;% 180 | gray36,0,0,92;% 181 | gray37,0,0,94;% 182 | gray38,0,0,97;% 183 | gray39,0,0,99;% 184 | gray4,0,0,10;% 185 | gray40,0,0,102;% 186 | gray41,0,0,105;% 187 | gray42,0,0,107;% 188 | gray43,0,0,110;% 189 | gray44,0,0,112;% 190 | gray45,0,0,115;% 191 | gray46,0,0,117;% 192 | gray47,0,0,120;% 193 | gray48,0,0,122;% 194 | gray49,0,0,125;% 195 | gray5,0,0,13;% 196 | gray50,0,0,127;% 197 | gray51,0,0,130;% 198 | gray52,0,0,133;% 199 | gray53,0,0,135;% 200 | gray54,0,0,138;% 201 | gray55,0,0,140;% 202 | gray56,0,0,143;% 203 | gray57,0,0,145;% 204 | gray58,0,0,148;% 205 | gray59,0,0,150;% 206 | gray6,0,0,15;% 207 | gray60,0,0,153;% 208 | gray61,0,0,156;% 209 | gray62,0,0,158;% 210 | gray63,0,0,161;% 211 | gray64,0,0,163;% 212 | gray65,0,0,166;% 213 | gray66,0,0,168;% 214 | gray67,0,0,171;% 215 | gray68,0,0,173;% 216 | gray69,0,0,176;% 217 | gray7,0,0,18;% 218 | gray70,0,0,179;% 219 | gray71,0,0,181;% 220 | gray72,0,0,184;% 221 | gray73,0,0,186;% 222 | gray74,0,0,189;% 223 | gray75,0,0,191;% 224 | gray76,0,0,194;% 225 | gray77,0,0,196;% 226 | gray78,0,0,199;% 227 | gray79,0,0,201;% 228 | gray8,0,0,20;% 229 | gray80,0,0,204;% 230 | gray81,0,0,207;% 231 | gray82,0,0,209;% 232 | gray83,0,0,212;% 233 | gray84,0,0,214;% 234 | gray85,0,0,217;% 235 | gray86,0,0,219;% 236 | gray87,0,0,222;% 237 | gray88,0,0,224;% 238 | gray89,0,0,227;% 239 | gray9,0,0,23;% 240 | gray90,0,0,229;% 241 | gray91,0,0,232;% 242 | gray92,0,0,235;% 243 | gray93,0,0,237;% 244 | gray94,0,0,240;% 245 | gray95,0,0,242;% 246 | gray96,0,0,245;% 247 | gray97,0,0,247;% 248 | gray98,0,0,250;% 249 | gray99,0,0,252;% 250 | green,85,255,255;% 251 | green1,85,255,255;% 252 | green2,85,255,238;% 253 | green3,85,255,205;% 254 | green4,85,255,139;% 255 | greenyellow,59,208,255;% 256 | grey,0,0,192;% 257 | grey0,0,0,0;% 258 | grey1,0,0,3;% 259 | grey10,0,0,26;% 260 | grey100,0,0,255;% 261 | grey11,0,0,28;% 262 | grey12,0,0,31;% 263 | grey13,0,0,33;% 264 | grey14,0,0,36;% 265 | grey15,0,0,38;% 266 | grey16,0,0,41;% 267 | grey17,0,0,43;% 268 | grey18,0,0,46;% 269 | grey19,0,0,48;% 270 | grey2,0,0,5;% 271 | grey20,0,0,51;% 272 | grey21,0,0,54;% 273 | grey22,0,0,56;% 274 | grey23,0,0,59;% 275 | grey24,0,0,61;% 276 | grey25,0,0,64;% 277 | grey26,0,0,66;% 278 | grey27,0,0,69;% 279 | grey28,0,0,71;% 280 | grey29,0,0,74;% 281 | grey3,0,0,8;% 282 | grey30,0,0,77;% 283 | grey31,0,0,79;% 284 | grey32,0,0,82;% 285 | grey33,0,0,84;% 286 | grey34,0,0,87;% 287 | grey35,0,0,89;% 288 | grey36,0,0,92;% 289 | grey37,0,0,94;% 290 | grey38,0,0,97;% 291 | grey39,0,0,99;% 292 | grey4,0,0,10;% 293 | grey40,0,0,102;% 294 | grey41,0,0,105;% 295 | grey42,0,0,107;% 296 | grey43,0,0,110;% 297 | grey44,0,0,112;% 298 | grey45,0,0,115;% 299 | grey46,0,0,117;% 300 | grey47,0,0,120;% 301 | grey48,0,0,122;% 302 | grey49,0,0,125;% 303 | grey5,0,0,13;% 304 | grey50,0,0,127;% 305 | grey51,0,0,130;% 306 | grey52,0,0,133;% 307 | grey53,0,0,135;% 308 | grey54,0,0,138;% 309 | grey55,0,0,140;% 310 | grey56,0,0,143;% 311 | grey57,0,0,145;% 312 | grey58,0,0,148;% 313 | grey59,0,0,150;% 314 | grey6,0,0,15;% 315 | grey60,0,0,153;% 316 | grey61,0,0,156;% 317 | grey62,0,0,158;% 318 | grey63,0,0,161;% 319 | grey64,0,0,163;% 320 | grey65,0,0,166;% 321 | grey66,0,0,168;% 322 | grey67,0,0,171;% 323 | grey68,0,0,173;% 324 | grey69,0,0,176;% 325 | grey7,0,0,18;% 326 | grey70,0,0,179;% 327 | grey71,0,0,181;% 328 | grey72,0,0,184;% 329 | grey73,0,0,186;% 330 | grey74,0,0,189;% 331 | grey75,0,0,191;% 332 | grey76,0,0,194;% 333 | grey77,0,0,196;% 334 | grey78,0,0,199;% 335 | grey79,0,0,201;% 336 | grey8,0,0,20;% 337 | grey80,0,0,204;% 338 | grey81,0,0,207;% 339 | grey82,0,0,209;% 340 | grey83,0,0,212;% 341 | grey84,0,0,214;% 342 | grey85,0,0,217;% 343 | grey86,0,0,219;% 344 | grey87,0,0,222;% 345 | grey88,0,0,224;% 346 | grey89,0,0,227;% 347 | grey9,0,0,23;% 348 | grey90,0,0,229;% 349 | grey91,0,0,232;% 350 | grey92,0,0,235;% 351 | grey93,0,0,237;% 352 | grey94,0,0,240;% 353 | grey95,0,0,242;% 354 | grey96,0,0,245;% 355 | grey97,0,0,247;% 356 | grey98,0,0,250;% 357 | grey99,0,0,252;% 358 | honeydew,85,15,255;% 359 | honeydew1,85,15,255;% 360 | honeydew2,85,15,238;% 361 | honeydew3,85,14,205;% 362 | honeydew4,85,14,139;% 363 | hotpink,233,150,255;% 364 | hotpink1,234,145,255;% 365 | hotpink2,235,141,238;% 366 | hotpink3,236,135,205;% 367 | hotpink4,234,148,139;% 368 | indianred,0,140,205;% 369 | indianred1,0,148,255;% 370 | indianred2,0,148,238;% 371 | indianred3,0,149,205;% 372 | indianred4,0,148,139;% 373 | indigo,194,255,130;% 374 | ivory,42,15,255;% 375 | ivory1,42,15,255;% 376 | ivory2,42,15,238;% 377 | ivory3,42,14,205;% 378 | ivory4,42,14,139;% 379 | khaki,38,106,240;% 380 | khaki1,39,112,255;% 381 | khaki2,39,112,238;% 382 | khaki3,39,111,205;% 383 | khaki4,39,111,139;% 384 | lavender,170,20,250;% 385 | lavenderblush,240,15,255;% 386 | lavenderblush1,240,15,255;% 387 | lavenderblush2,239,15,238;% 388 | lavenderblush3,240,14,205;% 389 | lavenderblush4,239,14,139;% 390 | lawngreen,64,255,252;% 391 | lemonchiffon,38,49,255;% 392 | lemonchiffon1,38,49,255;% 393 | lemonchiffon2,37,50,238;% 394 | lemonchiffon3,38,49,205;% 395 | lemonchiffon4,39,49,139;% 396 | lightblue,137,63,230;% 397 | lightblue1,138,64,255;% 398 | lightblue2,138,64,238;% 399 | lightblue3,138,63,205;% 400 | lightblue4,137,64,139;% 401 | lightcoral,0,119,240;% 402 | lightcyan,127,31,255;% 403 | lightcyan1,127,31,255;% 404 | lightcyan2,127,31,238;% 405 | lightcyan3,127,31,205;% 406 | lightcyan4,127,31,139;% 407 | lightgoldenrod,35,115,238;% 408 | lightgoldenrod1,35,116,255;% 409 | lightgoldenrod2,35,115,238;% 410 | lightgoldenrod3,35,115,205;% 411 | lightgoldenrod4,35,115,139;% 412 | lightgoldenrodyellow,42,40,250;% 413 | lightgray,0,0,211;% 414 | lightgrey,0,0,211;% 415 | lightpink,248,73,255;% 416 | lightpink1,249,81,255;% 417 | lightpink2,248,81,238;% 418 | lightpink3,249,80,205;% 419 | lightpink4,249,80,139;% 420 | lightsalmon,12,132,255;% 421 | lightsalmon1,12,132,255;% 422 | lightsalmon2,11,132,238;% 423 | lightsalmon3,12,133,205;% 424 | lightsalmon4,12,133,139;% 425 | lightseagreen,125,209,178;% 426 | lightskyblue,143,117,250;% 427 | lightskyblue1,143,79,255;% 428 | lightskyblue2,143,79,238;% 429 | lightskyblue3,142,79,205;% 430 | lightskyblue4,143,78,139;% 431 | lightslateblue,175,143,255;% 432 | lightslategray,148,56,153;% 433 | lightslategrey,148,56,153;% 434 | lightsteelblue,151,52,222;% 435 | lightsteelblue1,151,53,255;% 436 | lightsteelblue2,151,53,238;% 437 | lightsteelblue3,151,53,205;% 438 | lightsteelblue4,150,53,139;% 439 | lightyellow,42,31,255;% 440 | lightyellow1,42,31,255;% 441 | lightyellow2,42,31,238;% 442 | lightyellow3,42,31,205;% 443 | lightyellow4,42,31,139;% 444 | limegreen,85,192,205;% 445 | linen,21,20,250;% 446 | magenta,212,255,255;% 447 | magenta1,212,255,255;% 448 | magenta2,212,255,238;% 449 | magenta3,212,255,205;% 450 | magenta4,212,255,139;% 451 | maroon,239,185,176;% 452 | maroon1,228,203,255;% 453 | maroon2,228,203,238;% 454 | maroon3,228,204,205;% 455 | maroon4,228,203,139;% 456 | mediumaquamarine,113,128,205;% 457 | mediumblue,170,255,205;% 458 | mediumorchid,204,152,211;% 459 | mediumorchid1,203,153,255;% 460 | mediumorchid2,203,153,238;% 461 | mediumorchid3,203,153,205;% 462 | mediumorchid4,203,154,139;% 463 | mediumpurple,183,124,219;% 464 | mediumpurple1,183,125,255;% 465 | mediumpurple2,183,125,238;% 466 | mediumpurple3,183,125,205;% 467 | mediumpurple4,183,124,139;% 468 | mediumseagreen,103,169,179;% 469 | mediumslateblue,176,143,238;% 470 | mediumspringgreen,111,255,250;% 471 | mediumturquoise,125,167,209;% 472 | mediumvioletred,228,228,199;% 473 | midnightblue,170,198,112;% 474 | mintcream,106,9,255;% 475 | mistyrose,4,30,255;% 476 | mistyrose1,4,30,255;% 477 | mistyrose2,4,30,238;% 478 | mistyrose3,3,29,205;% 479 | mistyrose4,5,29,139;% 480 | moccasin,26,73,255;% 481 | navajowhite,25,81,255;% 482 | navajowhite1,25,81,255;% 483 | navajowhite2,25,82,238;% 484 | navajowhite3,25,82,205;% 485 | navajowhite4,25,82,139;% 486 | navy,170,255,128;% 487 | navyblue,170,255,128;% 488 | oldlace,27,23,253;% 489 | olivedrab,56,192,142;% 490 | olivedrab1,56,193,255;% 491 | olivedrab2,56,192,238;% 492 | olivedrab3,56,192,205;% 493 | olivedrab4,56,192,139;% 494 | orange,27,255,255;% 495 | orange1,27,255,255;% 496 | orange2,27,255,238;% 497 | orange3,27,255,205;% 498 | orange4,27,255,139;% 499 | orangered,11,255,255;% 500 | orangered1,11,255,255;% 501 | orangered2,11,255,238;% 502 | orangered3,11,255,205;% 503 | orangered4,11,255,139;% 504 | orchid,214,123,218;% 505 | orchid1,214,124,255;% 506 | orchid2,214,124,238;% 507 | orchid3,214,124,205;% 508 | orchid4,213,124,139;% 509 | palegoldenrod,38,72,238;% 510 | palegreen,85,100,251;% 511 | palegreen1,85,101,255;% 512 | palegreen2,85,100,238;% 513 | palegreen3,85,100,205;% 514 | palegreen4,85,100,139;% 515 | paleturquoise,127,67,238;% 516 | paleturquoise1,127,68,255;% 517 | paleturquoise2,127,68,238;% 518 | paleturquoise3,127,68,205;% 519 | paleturquoise4,127,67,139;% 520 | palevioletred,241,124,219;% 521 | palevioletred1,241,125,255;% 522 | palevioletred2,241,125,238;% 523 | palevioletred3,241,125,205;% 524 | palevioletred4,241,124,139;% 525 | papayawhip,26,41,255;% 526 | peachpuff,20,70,255;% 527 | peachpuff1,20,70,255;% 528 | peachpuff2,19,69,238;% 529 | peachpuff3,19,69,205;% 530 | peachpuff4,20,69,139;% 531 | peru,20,176,205;% 532 | pink,247,63,255;% 533 | pink1,245,73,255;% 534 | pink2,245,73,238;% 535 | pink3,245,74,205;% 536 | pink4,245,73,139;% 537 | plum,212,70,221;% 538 | plum1,212,68,255;% 539 | plum2,212,68,238;% 540 | plum3,212,68,205;% 541 | plum4,212,67,139;% 542 | powderblue,132,59,230;% 543 | purple,196,221,240;% 544 | purple1,191,207,255;% 545 | purple2,192,207,238;% 546 | purple3,192,207,205;% 547 | purple4,192,207,139;% 548 | red,0,255,255;% 549 | red1,0,255,255;% 550 | red2,0,255,238;% 551 | red3,0,255,205;% 552 | red4,0,255,139;% 553 | rosybrown,0,61,188;% 554 | rosybrown1,0,62,255;% 555 | rosybrown2,0,62,238;% 556 | rosybrown3,0,62,205;% 557 | rosybrown4,0,62,139;% 558 | royalblue,159,181,225;% 559 | royalblue1,159,183,255;% 560 | royalblue2,159,183,238;% 561 | royalblue3,159,182,205;% 562 | royalblue4,159,183,139;% 563 | saddlebrown,17,220,139;% 564 | salmon,4,138,250;% 565 | salmon1,9,150,255;% 566 | salmon2,9,150,238;% 567 | salmon3,9,150,205;% 568 | salmon4,9,150,139;% 569 | sandybrown,19,154,244;% 570 | seagreen,103,170,139;% 571 | seagreen1,103,171,255;% 572 | seagreen2,103,171,238;% 573 | seagreen3,103,171,205;% 574 | seagreen4,103,170,139;% 575 | seashell,17,16,255;% 576 | seashell1,17,16,255;% 577 | seashell2,18,17,238;% 578 | seashell3,18,17,205;% 579 | seashell4,18,16,139;% 580 | sienna,13,183,160;% 581 | sienna1,13,184,255;% 582 | sienna2,13,184,238;% 583 | sienna3,13,184,205;% 584 | sienna4,13,185,139;% 585 | skyblue,139,108,235;% 586 | skyblue1,144,120,255;% 587 | skyblue2,144,120,238;% 588 | skyblue3,144,120,205;% 589 | skyblue4,145,119,139;% 590 | slateblue,175,143,205;% 591 | slateblue1,175,144,255;% 592 | slateblue2,175,144,238;% 593 | slateblue3,175,144,205;% 594 | slateblue4,175,144,139;% 595 | slategray,148,56,144;% 596 | slategray1,149,56,255;% 597 | slategray2,149,56,238;% 598 | slategray3,148,57,205;% 599 | slategray4,149,56,139;% 600 | slategrey,148,56,144;% 601 | snow,0,5,255;% 602 | snow1,0,5,255;% 603 | snow2,0,5,238;% 604 | snow3,0,4,205;% 605 | snow4,0,3,139;% 606 | springgreen,106,255,255;% 607 | springgreen1,106,255,255;% 608 | springgreen2,106,255,238;% 609 | springgreen3,106,255,205;% 610 | springgreen4,106,255,139;% 611 | steelblue,146,155,180;% 612 | steelblue1,146,156,255;% 613 | steelblue2,146,156,238;% 614 | steelblue3,146,156,205;% 615 | steelblue4,147,155,139;% 616 | tan,24,84,210;% 617 | tan1,20,176,255;% 618 | tan2,20,176,238;% 619 | tan3,20,176,205;% 620 | tan4,20,176,139;% 621 | thistle,212,29,216;% 622 | thistle1,212,30,255;% 623 | thistle2,212,30,238;% 624 | thistle3,212,29,205;% 625 | thistle4,212,29,139;% 626 | tomato,6,184,255;% 627 | tomato1,6,184,255;% 628 | tomato2,6,184,238;% 629 | tomato3,6,184,205;% 630 | tomato4,6,185,139;% 631 | transparent,42,0,255;% 632 | turquoise,123,182,224;% 633 | turquoise1,129,255,255;% 634 | turquoise2,129,255,238;% 635 | turquoise3,129,255,205;% 636 | turquoise4,129,255,139;% 637 | violet,212,115,238;% 638 | violetred,227,215,208;% 639 | violetred1,235,193,255;% 640 | violetred2,235,192,238;% 641 | violetred3,235,192,205;% 642 | violetred4,235,192,139;% 643 | wheat,27,68,245;% 644 | wheat1,27,69,255;% 645 | wheat2,27,68,238;% 646 | wheat3,27,68,205;% 647 | wheat4,27,67,139;% 648 | white,0,0,255;% 649 | whitesmoke,0,0,245;% 650 | yellow,42,255,255;% 651 | yellow1,42,255,255;% 652 | yellow2,42,255,238;% 653 | yellow3,42,255,205;% 654 | yellow4,42,255,139;% 655 | yellowgreen,56,192,205} -------------------------------------------------------------------------------- /examples/latexmarkup.dot: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | :Title: LaTeX markup 4 | :Tags: PGF 5 | 6 | */ 7 | digraph G { 8 | node [fontcolor=red]; 9 | subgraph cluster0 { 10 | node [style=filled,color=white, texmode=math]; 11 | style=filled; 12 | color=lightgrey; 13 | a_0 -> a_1 -> a_2 -> a_3; 14 | label="latex"; 15 | texlbl="\LaTeX"; 16 | } 17 | subgraph cluster1 { 18 | node [style=filled, texmode=math, fontcolor=red]; 19 | b_0 -> b_1 -> b_2 -> b_3; 20 | label = "process #2"; 21 | color=blue 22 | } 23 | start -> a_0; 24 | start -> b_0; 25 | a_1 -> b_3; 26 | b_2 -> a_3; 27 | a_3 -> a_0; 28 | a_3 -> end; 29 | b_3 -> end; 30 | start [shape=diamond, texlbl="${\frac{\sqrt{\gamma+\beta}}{x^2+y^2}}$"]; 31 | end [shape=Msquare]; 32 | } -------------------------------------------------------------------------------- /examples/pgfarrows.dot: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | :Title: PGF and TikZ arrows 4 | :Tags: PGF 5 | 6 | Examples of PGF/TikZ style arrows. See chapter 14.1 in the PGF/TikZ manual 7 | for all availale arrow styles. 8 | 9 | Generated with:: 10 | 11 | $ dot2tex --prog=circo pgfarrows.dot > pgfarrows.tex 12 | 13 | */ 14 | digraph G { 15 | graph [mindist=0.5]; 16 | node [texmode="math", fixedsize=true, shape=circle, width=0.4, style="fill=green!20"]; 17 | c -> n_1 [style="-stealth", label="stealth"]; 18 | c -> n_2 [style="-to", label="to"]; 19 | c -> n_3 [style="-latex", label="latex"]; 20 | c -> n_4 [style="-diamond", label="diamond"]; 21 | c -> n_5 [style="-o", label="o"]; 22 | c -> n_6 [style="{-]}", label="]"]; 23 | c -> n_7 [style="-triangle 90", label="triangle 90"]; 24 | c -> n_8 [style="-hooks", label="hooks"]; 25 | c -> n_9 [style="->>", texmode="math", label=">>"]; 26 | c [style="fill=red!80"]; 27 | } -------------------------------------------------------------------------------- /examples/pgfsnakes.dot: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | :Title: PGF snakes 4 | :Tags: PGF 5 | 6 | Examples of PGF/TikZ snake line styles. See chapter 14.2 in the PGF/TikZ 7 | manual for all availale snake styles. Note that the snake styles requires 8 | line operations, so you have to use the ``-s`` option. 9 | 10 | Generated with:: 11 | 12 | $ dot2tex -fpgf -s --prog circo pgfsnakes.dot > pgfsnakes.tex 13 | 14 | */ 15 | graph G { 16 | graph [mindist=0.5]; 17 | node [texmode="math", fixedsize=true, shape=circle, width=0.4, style="fill=green!20"]; 18 | c -- n_1 [style="snake=zigzag"]; 19 | c -- n_2 [style="snake=saw"]; 20 | c -- n_3 [style="snake=expanding waves, segment angle=10"]; 21 | c -- n_4 [style="snake=snake"]; 22 | c -- n_5 [style="snake=coil, segment amplitude=6pt"]; 23 | c -- n_6 [style="snake=brace"]; 24 | c -- n_7 [style="snake=triangles"]; 25 | c [style="fill=red!80"]; 26 | } -------------------------------------------------------------------------------- /examples/poltab.dot: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | :Tags: PGF, Preproc 4 | 5 | This example graph was contributed by Teresa Gomez-Diaz, and shows 6 | that the ``texlbl`` attriute can contain arbitrary LaTeX markup. 7 | 8 | Generated with:: 9 | 10 | $ dot2tex -tmath --autosize poltab.dot > poltab.tex 11 | 12 | 13 | */ 14 | digraph G { 15 | rankdir=LR; 16 | node [shape=plaintext]; 17 | a_1 [texlbl="$\begin{array}{l} \fbox{1}\fbox{1} \end{array}$"]; 18 | a_2 [texlbl="$\frac{1}{q} \begin{array}{l} \fbox{2}\fbox{1} \end{array} + \begin{array}{l} \fbox{1}\fbox{2} \end{array}$"]; 19 | a_3 [texlbl="$(q+\frac{1}{q}) \begin{array}{l} \fbox{2}\fbox{2} \end{array}$"]; 20 | 21 | a_4 [texlbl="$\frac{1}{q} \frac{1}{z_1} \begin{array}{l} \fbox{1}\fbox{2} \end{array} + \frac{1}{z_2}\begin{array}{l} \fbox{2}\fbox{1} \end{array}$"]; 22 | 23 | { rank=same; a_1; a_2; a_3;} 24 | { nodesep =1; a_2; a_4;} 25 | 26 | a_1 -> a_2 [label="f_1" ]; 27 | a_2 -> a_3 [label="f_1" ]; 28 | a_1 -> a_4 [label="f_0" dir=back]; 29 | a_3 -> a_4 [label="f_0" ]; 30 | 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /examples/pstarrows.dot: -------------------------------------------------------------------------------- 1 | /* 2 | :Title: PSTricks arrows 3 | :Tags: PSTricks 4 | 5 | Examples of Pstricks style arrows. 6 | To generate this graph you can write:: 7 | 8 | $ circo -Txdot pstarrows.dot | dot2tex -fpst > pstarrows.tex 9 | 10 | */ 11 | digraph G { 12 | d2tdocpreamble="\usepackage{pstricks-add}"; 13 | graph [mindist=0.5]; 14 | node [texmode="math", fixedsize=true, shape=circle, width=0.4, style="linecolor=red, fillcolor=white"]; 15 | edge [color="blue"]; 16 | c -> n_1 [style="arrows=->", texmode="math", label=">"]; 17 | c -> n_2 [style="arrows=->>", texmode="math", label=">>"]; 18 | c -> n_3 [style="arrows=-<", texmode="math", label="<"]; 19 | c -> n_4 [style="arrows=-*", texmode="math", label="*"]; 20 | c -> n_5 [style="arrows=-{]}", texmode="math", label="]"]; 21 | edge [color="red"]; 22 | c -> n_6 [style="arrows=-o", texmode="math", label="o"]; 23 | c -> n_7 [style="arrows=-H", texmode="math", label="H"]; 24 | c -> n_8 [style="arrows=->, nArrowsA=5", texmode="math"]; 25 | } -------------------------------------------------------------------------------- /examples/showpoints.dot: -------------------------------------------------------------------------------- 1 | /* 2 | :Title: Control points 3 | :Tags: PSTricks 4 | 5 | This example uses the ``showpoints`` PSTricks style to show the 6 | control points of the edge curves. 7 | 8 | Generated with:: 9 | 10 | $ dot2tex -fpst showpoints.dot > showpoints.tex 11 | 12 | 13 | */ 14 | digraph G { 15 | size = "8,8"; 16 | {rank=min S8 S24 S1 S35 S30} 17 | {rank=max T8 T24 T1 T35 T30} 18 | edge [exstyle="showpoints=true, linecolor=red"]; 19 | node [style="fillstyle=solid"]; 20 | S8 -> 9; 21 | S24 -> 27; 22 | S24 -> 25; 23 | S1 -> 10; 24 | S1 -> 2; 25 | S35 -> 36; 26 | S35 -> 43; 27 | S30 -> 31; 28 | S30 -> 33; 29 | 9 -> 42; 30 | 9 -> T1; 31 | 25 -> T1; 32 | 25 -> 26; 33 | 27 -> T24; 34 | 2 -> 3; 35 | 2 -> 16; 36 | 2 -> 17; 37 | 2 -> T1; 38 | 2 -> 18; 39 | 10 -> 11; 40 | 10 -> 14; 41 | 10 -> T1; 42 | 10 -> 13; 43 | 10 -> 12; 44 | 31 -> T1; 45 | 31 -> 32; 46 | 33 -> T30; 47 | 33 -> 34; 48 | 42 -> 4; 49 | 26 -> 4; 50 | 3 -> 4; 51 | 16 -> 15; 52 | 17 -> 19; 53 | 18 -> 29; 54 | 11 -> 4; 55 | 14 -> 15; 56 | 37 -> 39; 57 | 37 -> 41; 58 | 37 -> 38; 59 | 37 -> 40; 60 | 13 -> 19; 61 | 12 -> 29; 62 | 43 -> 38; 63 | 43 -> 40; 64 | 36 -> 19; 65 | 32 -> 23; 66 | 34 -> 29; 67 | 39 -> 15; 68 | 41 -> 29; 69 | 38 -> 4; 70 | 40 -> 19; 71 | 4 -> 5; 72 | 19 -> 21; 73 | 19 -> 20; 74 | 19 -> 28; 75 | 5 -> 6; 76 | 5 -> T35; 77 | 5 -> 23; 78 | 21 -> 22; 79 | 20 -> 15; 80 | 28 -> 29; 81 | 6 -> 7; 82 | 15 -> T1; 83 | 22 -> 23; 84 | 22 -> T35; 85 | 29 -> T30; 86 | 7 -> T8; 87 | 23 -> T24; 88 | 23 -> T1; 89 | } 90 | -------------------------------------------------------------------------------- /examples/sportsbracket.dot: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | :Title: Orthogonal edges 4 | :Tags: PGF, topath 5 | 6 | 7 | This example is adapted from an example posted by Ryan Schmidt to the `graphviz-interest`_ mailing 8 | list. Graphviz currently does not support orthogonal edges. However, 9 | with dot2tex you can use the ``topath`` attribute to create custom edges. 10 | 11 | Here is the definition of the ``fork horizontal`` to-path. It uses the powerful 12 | *coordinate calculations* feature introduced in PGF 2.00. 13 | 14 | .. sourcecode:: latex 15 | 16 | ... 17 | \usetikzlibrary{calc} 18 | ... 19 | \tikzstyle{fork horizontal} =[to path={ 20 | -| ($(\tikztostart)!0.5!(\tikztotarget)$) |- (\tikztotarget) \tikztonodes}] 21 | 22 | 23 | **Note**: This example requires PGF 2.00 or later. 24 | 25 | Generated with:: 26 | 27 | $ dot2tex --crop sportsbracket.dot > sportsbracket.tex 28 | 29 | .. _graphviz-interest: https://mailman.research.att.com/pipermail/graphviz-interest/2008q2/thread.html#5129 30 | 31 | */ 32 | digraph G { 33 | // Put our custom fork horizontal to path in the document preamble 34 | d2tdocpreamble = "\usetikzlibrary{calc}\ 35 | \tikzstyle{fork horizontal} =[to path={\ 36 | -| ($(\tikztostart)!0.5!(\tikztotarget)$) |- (\tikztotarget) \tikztonodes}]"; 37 | rankdir=LR 38 | node [shape=box, width=2] 39 | 40 | graph [size="8.5,11" label="NCAA Men's Basketball: 2008 Tournament"] 41 | 42 | 11 [label="North Carolina"] 43 | 12 [label="Mount St. Mary's"] 44 | 13 [label="Indiana"] 45 | 14 [label="Arkansas"] 46 | 15 [label="Notre Dame"] 47 | 16 [label="George Mason"] 48 | 17 [label="Washington St."] 49 | 18 [label="Winthrop"] 50 | 19 [label="Oklahoma"] 51 | 110 [label="St. Joseph's"] 52 | 111 [label="Louisville"] 53 | 112 [label="Boise St."] 54 | 113 [label="Butler"] 55 | 114 [label="South Alabama"] 56 | 115 [label="Tennessee"] 57 | 116 [label="American"] 58 | 21 [label="North Carolina"] 59 | 22 [label="Arkansas"] 60 | 23 [label="Notre Dame"] 61 | 24 [label="Washington St."] 62 | 25 [label="Oklahoma"] 63 | 26 [label="Louisville"] 64 | 27 [label="Butler"] 65 | 28 [label="Tennessee"] 66 | 31 [label="North Carolina"] 67 | 32 [label="Washington St."] 68 | 33 [label="Louisville"] 69 | 34 [label="Tennessee"] 70 | 41 [label="North Carolina"] 71 | 42 [label="Louisville"] 72 | 51 [label="North Carolina"] 73 | // Use the custom 'fork horizontal' to path defined above 74 | edge [topath="fork horizontal"]; 75 | 11:e->21:w 76 | 12:e->21:w 77 | 13:e->22:w 78 | 14:e->22:w 79 | 15:e->23:w 80 | 16:e->23:w 81 | 17:e->24:w 82 | 18:e->24:w 83 | 19:e->25:w 84 | 110:e->25:w 85 | 111:e->26:w 86 | 112:e->26:w 87 | 113:e->27:w 88 | 114:e->27:w 89 | 115:e->28:w 90 | 116:e->28:w 91 | 21:e->31:w 92 | 22:e->31:w 93 | 23:e->32:w 94 | 24:e->32:w 95 | 25:e->33:w 96 | 26:e->33:w 97 | 27:e->34:w 98 | 28:e->34:w 99 | 31:e->41:w 100 | 32:e->41:w 101 | 33:e->42:w 102 | 34:e->42:w 103 | 41:e->51:w 104 | 42:e->51:w 105 | 106 | edge [style=invis] 107 | rank=same {11->12->13->14->15->16->17->18->19->110->111->112->113->114->115->116} 108 | } 109 | -------------------------------------------------------------------------------- /examples/subgraphs.dot: -------------------------------------------------------------------------------- 1 | /* 2 | :Title: Styled subgraphs 3 | :Tags: PGF, Preproc 4 | 5 | This example shows how subgraphs can be styled using PGF/TikZ styles. 6 | Note that version 1.09 or higher of PGF/TikZ is required. 7 | 8 | Generated with:: 9 | 10 | $ dot2tex -tmath --autosize --crop subgraphs.dot > subgraphs.tex 11 | 12 | */ 13 | digraph G { 14 | d2tdocpreamble="\usetikzlibrary{patterns}"; 15 | size="6,6"; 16 | node [style="fill=blue!40"]; 17 | node [shape=circle, width=0.4]; 18 | a -> b -> c; 19 | graph [style="rounded corners, shade"]; 20 | 21 | subgraph cluster0 { 22 | graph [style="pattern color=red, pattern=bricks, rounded corners"]; 23 | node [style = "fill=blue, semitransparent"]; 24 | x_0 -> y_0; 25 | x_0 -> z_0; 26 | } 27 | 28 | subgraph cluster1 { 29 | graph [style="snake=snake, fill=green!20"]; 30 | node [style = "fill=red!20"]; 31 | edge [style="->>"]; 32 | x_1 -> y_1; 33 | x_1 -> z_1; 34 | } 35 | 36 | subgraph cluster2 { 37 | node [style=" "]; 38 | x_2 -> y_2; 39 | x_2 -> z_2; 40 | } 41 | 42 | a -> x_0; 43 | b -> x_1; 44 | b -> x_2; 45 | a -> z_2; 46 | c -> z_1; 47 | } 48 | -------------------------------------------------------------------------------- /examples/tank.dot: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | :Title: Two tank system 4 | :Tags: PGF 5 | 6 | This graph shows the structural model of a two tank system. 7 | 8 | Generated with:: 9 | 10 | $ dot2tex -fpgf tank.dot > tank.tex 11 | 12 | */ 13 | graph G { 14 | node[shape=doublecircle, fixedsize=true, width=0.4]; 15 | graph [style="rounded corners"]; 16 | subgraph cluster0 { 17 | style = "red, fill=blue!20,rounded corners"; 18 | label = "Tank 1"; 19 | node [texmode="math"] 20 | c_1--q_L; c_1--h_1; 21 | c_2--q_P; c_2--h_1; 22 | c_3--q_L; c_3--q_P; c_3--dh_1; 23 | d_4--dh_1;d_4--h_1; 24 | dh_1 [label="\\dot{h}_1"]; 25 | } 26 | 27 | subgraph cluster1{ 28 | label = "Pipe"; 29 | node [texmode="math"] 30 | c_5--h_1; c_5--q_12; 31 | q_12 [label="q_{12}"]; 32 | } 33 | 34 | c_5--h_2; 35 | c_3--q_12; 36 | c_6--q_12; 37 | 38 | subgraph cluster2{ 39 | label = "Tank 2"; 40 | node [texmode="math"] 41 | c_6--dh_2;c_6--q_2; 42 | d_7--dh_2; d_7--h_2; 43 | c_8--h_2;c_8--q_2; 44 | c_m--q_2; 45 | dh_2 [label="\\dot{h}_2"]; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /examples/tikzautomata.dot: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | :Title: Automata 4 | :Tags: TikZ, topath, tikzedgelabels 5 | 6 | An example of how to use TikZ' automata libray and to paths to 7 | create a pretty state machine. 8 | 9 | Generated with:: 10 | 11 | $ neato -Txdot tikzautomata.dot | dot2tex -ftikz > tikzautomata.tex 12 | 13 | */ 14 | digraph G { 15 | d2ttikzedgelabels = true; 16 | d2tstyleonly = true; 17 | d2tdocpreamble = "\usetikzlibrary{automata}"; 18 | d2tfigpreamble = "\tikzstyle{every state}= \ 19 | [draw=blue!50,very thick,fill=blue!20]"; 20 | node [style="state"]; 21 | edge [lblstyle="auto",topath="bend left"]; 22 | A [style="state, initial"]; 23 | A -> B [label=2]; 24 | A -> D [label=7]; 25 | B -> A [label=1]; 26 | B -> B [label=3,topath="loop above"]; 27 | B -> C [label=4]; 28 | C -> F [label=5]; 29 | F -> B [label=8]; 30 | F -> D [label=7]; 31 | D -> E [label=2]; 32 | E -> A [label="1,6"]; 33 | F [style="state,accepting"]; 34 | } -------------------------------------------------------------------------------- /examples/tikzshapes.dot: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | :Title: TikZ node shapes 4 | :Tags: TikZ, tikzedgelabels 5 | 6 | This example shows some of special `TikZ node shapes`_ that are available when using 7 | the ``tikz`` output format. 8 | 9 | Generated with:: 10 | 11 | $ dot2tex -ftikz --prog circo -s tikzshapes.dot > tikzshapes.tex 12 | 13 | 14 | .. _TikZ node shapes: http://www.fauskes.net/pgftikzexamples/node-shapes/ 15 | 16 | */ 17 | graph G { 18 | graph [mindist=0.5]; 19 | node [style="fill=green!20",texmode=math]; 20 | edge [lblstyle="above,sloped"]; 21 | d2ttikzedgelabels=true; 22 | c [style=circle]; 23 | n_1 [lblstyle=diamond]; 24 | n_2 [lblstyle=star]; 25 | n_3 [lblstyle="forbidden sign"]; 26 | n_4 [lblstyle="circle split", texlbl="$n$ \nodepart{lower} $4$"]; 27 | n_5 [lblstyle="cross out"]; 28 | n_6 [lblstyle="strike out"]; 29 | n_7 [lblstyle="regular polygon,regular polygon sides=7"]; 30 | c -- n_1 [label="diamond"]; 31 | c -- n_2 [label="star"]; 32 | c -- n_3 [label="forbidden sign"]; 33 | c -- n_4 [label="circle split"]; 34 | c -- n_5 [label="cross out"]; 35 | c -- n_6 [label="strike out"]; 36 | c -- n_7 [label="regular polygon"]; 37 | c [style="fill=red!80"]; 38 | } -------------------------------------------------------------------------------- /examples/transp.dot: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | :Title: Node transparency 4 | :Tags: PGF 5 | 6 | Example of node transparency. 7 | Based on the graph on http://www.graphviz.org/Gallery/undirected/transparency.html 8 | 9 | The overlapping nodes are achieved with:: 10 | 11 | $ dot2tex --prog neato -fpgf transp.dot > transp.tex 12 | 13 | */ 14 | graph G { 15 | node [style=filled, fillcolor="#00ff005f"] 16 | 1 -- 30 [f=1]; 17 | 1 -- 40 [f=14]; 18 | 8 -- 46 [f=1]; 19 | 8 -- 16 [f=18]; 20 | 10 -- 25 [f=1]; 21 | 10 -- 19 [f=5]; 22 | 10 -- 33 [f=1]; 23 | 12 -- 8 [f=1]; 24 | 12 -- 36 [f=5]; 25 | 12 -- 17 [f=16]; 26 | 13 -- 38 [f=1]; 27 | 13 -- 24 [f=19]; 28 | 24 -- 49 [f=1]; 29 | 24 -- 13 [f=1]; 30 | 24 -- 47 [f=12]; 31 | 24 -- 12 [f=19]; 32 | 25 -- 27 [f=1]; 33 | 25 -- 12 [f=1]; 34 | 27 -- 12 [f=1]; 35 | 27 -- 14 [f=8]; 36 | 29 -- 10 [f=1]; 37 | 29 -- 8 [f=17]; 38 | 30 -- 24 [f=1]; 39 | 30 -- 44 [f=15]; 40 | 38 -- 29 [f=1]; 41 | 38 -- 35 [f=15]; 42 | 2 -- 42 [f=2]; 43 | 2 -- 35 [f=3]; 44 | 2 -- 11 [f=19]; 45 | 14 -- 18 [f=2]; 46 | 14 -- 24 [f=15]; 47 | 14 -- 38 [f=18]; 48 | 18 -- 49 [f=2]; 49 | 18 -- 47 [f=20]; 50 | 26 -- 41 [f=2]; 51 | node [style=filled fillcolor="#ff00005f"] 52 | 26 -- 42 [f=15]; 53 | 31 -- 39 [f=2]; 54 | 31 -- 47 [f=17]; 55 | 31 -- 25 [f=14]; 56 | 37 -- 26 [f=2]; 57 | 37 -- 16 [f=14]; 58 | 39 -- 50 [f=2]; 59 | 39 -- 14 [f=2]; 60 | 39 -- 18 [f=17]; 61 | 39 -- 47 [f=10]; 62 | 41 -- 31 [f=2]; 63 | 41 -- 8 [f=16]; 64 | 42 -- 44 [f=2]; 65 | 42 -- 29 [f=12]; 66 | 44 -- 37 [f=2]; 67 | 44 -- 32 [f=15]; 68 | 3 -- 20 [f=2]; 69 | 3 -- 28 [f=19]; 70 | 6 -- 45 [f=2]; 71 | 6 -- 28 [f=10]; 72 | 9 -- 6 [f=2]; 73 | 9 -- 16 [f=1]; 74 | node [style=filled fillcolor="#0000ff5f"] 75 | 15 -- 16 [f=2]; 76 | 15 -- 48 [f=2]; 77 | 16 -- 50 [f=2]; 78 | 16 -- 32 [f=14]; 79 | 16 -- 39 [f=8]; 80 | 20 -- 33 [f=2]; 81 | 33 -- 9 [f=2]; 82 | 33 -- 46 [f=3]; 83 | 33 -- 48 [f=17]; 84 | 45 -- 15 [f=2]; 85 | 4 -- 17 [f=4]; 86 | 4 -- 15 [f=6]; 87 | 4 -- 12 [f=16]; 88 | 17 -- 21 [f=4]; 89 | 19 -- 35 [f=4]; 90 | 19 -- 15 [f=9]; 91 | 19 -- 43 [f=4]; 92 | 21 -- 19 [f=4]; 93 | 21 -- 50 [f=4]; 94 | 23 -- 36 [f=4]; 95 | 34 -- 23 [f=4]; 96 | 34 -- 24 [f=11]; 97 | 35 -- 34 [f=4]; 98 | 35 -- 16 [f=6]; 99 | 35 -- 18 [f=16]; 100 | 36 -- 46 [f=4]; 101 | 5 -- 7 [f=1]; 102 | 5 -- 36 [f=6]; 103 | 7 -- 32 [f=1]; 104 | 7 -- 11 [f=2]; 105 | 7 -- 14 [f=17]; 106 | 11 -- 40 [f=1]; 107 | 11 -- 50 [f=1]; 108 | 22 -- 46 [f=1]; 109 | 28 -- 43 [f=1]; 110 | 28 -- 8 [f=18]; 111 | 32 -- 28 [f=1]; 112 | 32 -- 39 [f=13]; 113 | 32 -- 42 [f=15]; 114 | 40 -- 22 [f=1]; 115 | 40 -- 47 [f=1]; 116 | 43 -- 11 [f=1]; 117 | 43 -- 17 [f=19]; 118 | } 119 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | dot2tex - A Graphviz to LaTeX converter 2 | ======================================= 3 | 4 | > [!WARNING] 5 | > This project is no longer being maintained. I have tried to find a new maintainer for the project with no luck. 6 | > If you are interested, feel free to reach out. See https://github.com/xyz2tex/dot2tex/issues/58 for details. 7 | 8 | License: MIT (See LICENSE for details.) 9 | 10 | Version: 2.12.dev 11 | 12 | URL: https://github.com/xyz2tex/dot2tex 13 | 14 | Documentation: http://dot2tex.readthedocs.org/ 15 | 16 | Dot2tex is a tool for converting graphs rendered by Graphviz to formats 17 | that can be used with LaTeX. 18 | 19 | Installation 20 | ============ 21 | 22 | Before you install dot2tex you have to have a working Python environment 23 | installed on your system. Dot2tex works with Python 2.7 and Python 3. In addition 24 | you'll need the following modules: 25 | 26 | * [pyparsing](https://github.com/pyparsing/pyparsing). A recent version is required. 27 | Older version like for instance 1.3.2 does not work with dot2tex. 28 | * [preview](http://www.ctan.org/tex-archive/help/Catalogue/entries/preview.html) 29 | A stand-alone part of the preview-latex/AUCTeX bundle. 30 | Required for preprocessing graphs with LaTeX. 31 | * PGF/TikZ 2.0 or later required. 32 | 33 | Note. If you have dot2tex version 2.5.0 or older installed, please remove the old 34 | version of the dot2tex.py file in your SCRIPTS directory before you install the 35 | latest dot2tex version. Otherwise the new dot2tex wrapper script will try to load 36 | the dot2tex.py as a module. 37 | 38 | Using pip 39 | --------- 40 | 41 | The easiest way to install dot2tex is to use [pip][]: 42 | 43 | $ pip install dot2tex 44 | 45 | The command will locate dot2tex and download it automatically along with dependencies. Note that 46 | documentation and examples are not installed by default. 47 | 48 | [pip]: http://www.pip-installer.org/en/latest/# 49 | 50 | Binary packages 51 | --------------- 52 | 53 | Binary packages are available for [Debian][] and [OpenSUSE][]. 54 | 55 | [Debian]: http://packages.qa.debian.org/d/dot2tex.html 56 | [OpenSUSE]: http://download.opensuse.org/repositories/home:/jimfunk/ 57 | 58 | From source 59 | ----------- 60 | 61 | Download a zip or a tarball from the download_ page. Unpack the file to a directory and run ``python`` on the ``setup.py`` 62 | file: 63 | 64 | $ python setup.py install 65 | 66 | This will create a dot2tex module in your Python module directory and a wrapper 67 | script in your ``SCRIPTS`` directory. Note that a few warnings will be 68 | displayed. You can safely ignore them. The warnings are shown because there is 69 | some extra information in the ``setup.py`` file that distutils does not understand. 70 | 71 | 72 | Development version 73 | ------------------- 74 | 75 | The development version of ``dot2tex`` is [available on GitHub](https://github.com/kjellmf/dot2tex). 76 | 77 | Contribute 78 | ========== 79 | 80 | - Issue tracker: https://github.com/kjellmf/dot2tex/issues 81 | - Source code: https://github.com/kjellmf/dot2tex 82 | 83 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from setuptools import setup 3 | 4 | setup(name='dot2tex', 5 | version='2.12.dev', 6 | description='A Graphviz to LaTeX converter', 7 | long_description="""\ 8 | The purpose of dot2tex is to give graphs generated by the graph layout tool 9 | Graphviz_, a more LaTeX friendly look and feel. This is accomplished by: 10 | 11 | - Using native PSTricks_ and `PGF/TikZ`_ commands for drawing arrows, 12 | edges and nodes. 13 | - Typesetting labels with LaTeX, allowing mathematical notation. 14 | - Using backend specific styles to customize the output. 15 | 16 | .. _Graphviz: http://www.graphviz.org/ 17 | .. _PSTricks: http://tug.org/PSTricks/main.cgi/ 18 | .. _PGF/TikZ: http://www.ctan.org/tex-archive/help/Catalogue/entries/pgf.html 19 | """, 20 | author='Kjell Magne Fauske', 21 | author_email='kjellmf@gmail.com', 22 | url="https://github.com/kjellmf/dot2tex", 23 | packages=['dot2tex'], 24 | classifiers=[ 25 | 'Development Status :: 4 - Beta', 26 | 'Environment :: Console', 27 | 'Intended Audience :: Science/Research', 28 | 'License :: OSI Approved :: MIT License', 29 | 'Natural Language :: English', 30 | 'Operating System :: OS Independent', 31 | 'Programming Language :: Python :: 2', 32 | 'Programming Language :: Python :: 2.7', 33 | 'Programming Language :: Python :: 3', 34 | 'Programming Language :: Python :: 3.5', 35 | 'Programming Language :: Python :: 3.6', 36 | 'Programming Language :: Python :: 3.7', 37 | 'Topic :: Scientific/Engineering :: Visualization', 38 | 'Topic :: Text Processing :: Markup :: LaTeX', 39 | 'Topic :: Utilities', 40 | ], 41 | install_requires=['pyparsing', 'setuptools'], 42 | entry_points={ 43 | 'console_scripts': [ 44 | 'dot2tex = dot2tex.dot2tex:main', 45 | ] 46 | 47 | } 48 | ) 49 | -------------------------------------------------------------------------------- /tests/experimental/test_buildexamples.py: -------------------------------------------------------------------------------- 1 | """ 2 | Script to build the the dot2tex examples. 3 | """ 4 | 5 | import re, os, shutil, glob, sys, logging 6 | 7 | from os.path import join, basename, splitext, normpath, abspath 8 | 9 | # intitalize logging module 10 | log = logging.getLogger("test_graphparser") 11 | console = logging.StreamHandler() 12 | console.setLevel(logging.WARNING) 13 | # set a format which is simpler for console use 14 | formatter = logging.Formatter('%(levelname)-8s %(message)s') 15 | # tell the handler to use this format 16 | console.setFormatter(formatter) 17 | log.addHandler(console) 18 | 19 | BASE_DIR = join(abspath(os.path.dirname(__file__)), "") 20 | DEST_DIR = join(BASE_DIR, 'exrender/') 21 | EXAMPLES_DIR = normpath(abspath(join(BASE_DIR, "../../examples/"))) 22 | 23 | 24 | def copyifnewer(source, dest): 25 | """Copy source to dest if dest is older than source or doesn't exists""" 26 | copy = False 27 | # Check that dest exists. Create dir if necessary 28 | if os.path.exists(dest): 29 | # get source's and dest's timpestamps 30 | source_ts = os.path.getmtime(source) 31 | dest_ts = os.path.getmtime(dest) 32 | # compare timestamps 33 | if source_ts > dest_ts: copy = True 34 | else: 35 | copy = True 36 | dir = os.path.dirname(dest) 37 | if dir != '' and not os.path.exists(dir): 38 | os.makedirs(dir) 39 | # copy source to dest 40 | if copy: 41 | shutil.copy2(source, dest) 42 | 43 | 44 | def runcmd(syscmd): 45 | #err = os.system(syscmd) 46 | sres = os.popen(syscmd) 47 | resdata = sres.read() 48 | err = sres.close() 49 | if err: 50 | log.warning('Failed to run command:\n%s', syscmd) 51 | log.debug('Output:\n%s', resdata) 52 | return err 53 | 54 | 55 | def meps(filename): 56 | fn = splitext(filename)[0] 57 | s = "latex -halt-on-error -interaction nonstopmode %s.tex" % fn 58 | err = runcmd(s) 59 | if err: return err 60 | if sys.platform == 'win32': 61 | s = "dvips -Ppdf -G0 -D600 -E* -o%s.eps %s.dvi" % (fn, fn) 62 | err = runcmd(s) 63 | if err: return err 64 | s = "epstool --bbox --copy --output %s_tmp.eps %s.eps" % (fn, fn) 65 | err = runcmd(s) 66 | if err: return err 67 | try: 68 | os.remove("%s.eps" % fn) 69 | os.remove("%s.dvi" % fn) 70 | os.remove("%s.aux" % fn) 71 | os.remove("%s.log" % fn) 72 | #os.remove("%s.pgf" % fn) 73 | 74 | except: 75 | raise 76 | os.rename("%s_tmp.eps" % fn, "%s.eps" % fn) 77 | s = "epstopdf %s.eps" % fn 78 | err = runcmd(s) 79 | else: 80 | s = "dvips %s.dvi" % fn 81 | err = runcmd(s) 82 | s = "ps2eps -B -f %s.ps" % fn 83 | err = runcmd(s) 84 | if err: return err 85 | s = "epstopdf %s.eps" % fn 86 | err = runcmd(s) 87 | 88 | return err 89 | 90 | 91 | def create_pdf(texfile, use_pdftex=True): 92 | if not splitext(texfile)[1]: 93 | fn = basename(texfile) + '.tex' 94 | else: 95 | fn = basename(texfile) 96 | if sys.platform == 'win32': 97 | syscmd = 'texify --pdf --clean %s' % (fn) 98 | else: 99 | syscmd = 'pdflatex -halt-on-error -interaction nonstopmode %s' % (fn) 100 | err = runcmd(syscmd) 101 | return err 102 | 103 | 104 | def find_command(data): 105 | commands = re.findall(r"\$ ((?:.*?) dot2tex (?:.*?))$", data, 106 | re.MULTILINE | re.VERBOSE) 107 | if commands: 108 | return commands[0].strip() 109 | else: 110 | return None 111 | 112 | 113 | def make_img(c, filenm, name): 114 | filename = os.path.splitext(filenm)[0] 115 | err = runcmd(c) 116 | if err: 117 | return err 118 | 119 | if (c.find('--crop') > -1): 120 | #os.system('del %s.png %s.jpg' % (name,name)) 121 | err = create_pdf(filename) 122 | #print("using mppdf") 123 | else: 124 | err = meps(filename) 125 | 126 | return err 127 | 128 | 129 | def build_gallery(filelist): 130 | #os.chdir(EXAMPLES_DIR) 131 | entrylist = [] 132 | failedfiles = [] 133 | for file in filelist: 134 | f = open(file, 'r') 135 | data = f.read() 136 | f.close() 137 | entry = {} 138 | dirname, filename = os.path.split(file) 139 | os.chdir(dirname) 140 | name = os.path.splitext(filename)[0] 141 | 142 | command = find_command(data) 143 | 144 | if command: 145 | c = command.replace("dot2tex.py", "dot2tex") 146 | else: 147 | c = "dot2tex %s > %s.tex" % (file, name) 148 | print(c) 149 | 150 | err = make_img(c, filename, '') 151 | if err: 152 | log.warning('Failed to build %s', filename) 153 | failedfiles.append(filename) 154 | return failedfiles 155 | 156 | 157 | if __name__ == "__main__": 158 | filelist = [] 159 | exdir = EXAMPLES_DIR 160 | os.chdir(exdir) 161 | for f in glob.glob("*.dot"): 162 | if not f.find('dot2tex-fig') > 0: 163 | src = os.path.join(exdir, f) 164 | dst = normpath(join(DEST_DIR, basename(src))) 165 | filelist.append(dst) 166 | copyifnewer(src, dst) 167 | 168 | failedfiles = build_gallery(filelist) 169 | if failedfiles: 170 | log.warning('Failed files: %s', failedfiles); 171 | sys.exit(1) 172 | else: 173 | print("All tests passed!") 174 | sys.exit(0) 175 | 176 | #filelist=['distances.dot','tikzshapes.dot'] 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /tests/experimental/test_comparedotparsing.py: -------------------------------------------------------------------------------- 1 | """ 2 | Various test for checking that the dotparsing module is working properly. 3 | The basic test is to compare PNG renderings of the original graph and the 4 | parsed and saved version. 5 | """ 6 | 7 | import unittest 8 | 9 | #import dot2tex.dotparsing as dotp 10 | from dot2tex import dotparsing 11 | import re, os, shutil, glob, sys, time 12 | 13 | from PIL import ImageChops, Image 14 | 15 | from os.path import join, basename, splitext, normpath 16 | from dot2tex import dotparsing 17 | import logging 18 | 19 | # intitalize logging module 20 | log = logging.getLogger("test_graphparser") 21 | console = logging.StreamHandler() 22 | console.setLevel(logging.WARNING) 23 | # set a format which is simpler for console use 24 | formatter = logging.Formatter('%(levelname)-8s %(message)s') 25 | # tell the handler to use this format 26 | console.setFormatter(formatter) 27 | log.addHandler(console) 28 | 29 | 30 | # Directory with test files 31 | BASE_DIR = join(os.path.dirname(__file__), "testgraphs/") 32 | TESTFILES_DIR = "parsetests" 33 | TESTFILES_PATH = join(BASE_DIR, TESTFILES_DIR) 34 | 35 | PNG_DIR = join(TESTFILES_PATH, 'pngs') 36 | DOT_DIR = join(TESTFILES_PATH, 'dpdots') 37 | 38 | graphparser = dotparsing.DotDataParser() 39 | 40 | 41 | def equal(im1, im2): 42 | return ImageChops.difference(im1, im2).getbbox() is None 43 | 44 | 45 | def compare_dot_file(dotfile): 46 | """Check that a dot file is correctly parsed 47 | 48 | """ 49 | try: 50 | log.info('Processing %s', dotfile) 51 | basefilename = basename(dotfile) 52 | basefilenamenoext = os.path.splitext(basefilename)[0] 53 | f = open(dotfile) 54 | try: 55 | data = f.read() 56 | except: 57 | log.warning('Could not open %s', dotfile) 58 | raise 59 | f.close() 60 | try: 61 | graph = graphparser.parse_dot_data(data) 62 | # create a dotparsing version of the dot file 63 | newfilename = normpath(join(DOT_DIR, basefilename + '.new')) 64 | f = open(newfilename, 'w') 65 | f.write(str(graph)) 66 | f.close() 67 | except: 68 | log.exception('Failed to parse and save %s', basefilename) 69 | raise 70 | origpngfilename = join(PNG_DIR, basefilenamenoext + '.png') 71 | newpngfilename = join(PNG_DIR, basefilenamenoext + '.new.png') 72 | # create PNG from original dot file 73 | syscmd = 'dot -Tpng %s > %s' % (dotfile, origpngfilename) 74 | log.debug("Run %s", syscmd) 75 | err = os.system(syscmd) 76 | if err: 77 | log.warning("Failed to create original %s", origpngfilename) 78 | #failedfiles.append(basefilename) 79 | raise 80 | # create PNG from dot file generated by dotparsing 81 | syscmd = 'dot -Tpng %s > %s' % (newfilename, newpngfilename) 82 | log.debug("Run %s", syscmd) 83 | err = os.system(syscmd) 84 | if err: 85 | log.warning("Failed to create new %s", origpngfilename) 86 | return -1 87 | # load and compare images 88 | try: 89 | imorig = Image.open(origpngfilename) 90 | imnew = Image.open(newpngfilename) 91 | except: 92 | log.exception('Could not load %s images', basefilename) 93 | raise 94 | if equal(imorig, imnew): 95 | log.info('%s matches.', basefilename) 96 | # remove files 97 | os.remove(origpngfilename) 98 | os.remove(newpngfilename) 99 | os.remove(newfilename) 100 | return 1 101 | 102 | else: 103 | log.warning('%s did not match!', basefilename) 104 | return 0 105 | except: 106 | log.exception('Failed to process %s', basefilename) 107 | raise 108 | 109 | 110 | def test_dotfile(filename): 111 | return compare_dot_file(join(TESTFILES_PATH, filename)) 112 | 113 | 114 | class DotparsingTest(unittest.TestCase): 115 | def setUp(self): 116 | if not os.path.exists(PNG_DIR): 117 | os.mkdir(PNG_DIR) 118 | if not os.path.exists(DOT_DIR): 119 | os.mkdir(DOT_DIR) 120 | 121 | def test_ids(self): 122 | self.assertEqual(test_dotfile("ids.dot"), 1) 123 | 124 | def test_multilines(self): 125 | self.assertEqual(test_dotfile("multilines.dot"), 1) 126 | 127 | def test_subgraphs(self): 128 | self.assertEqual(test_dotfile("subgraphs.dot"), 1) 129 | 130 | def test_quoting(self): 131 | self.assertEqual(test_dotfile("quoting.dot"), 1) 132 | 133 | def test_unicode1(self): 134 | self.assertEqual(test_dotfile("unicode1.dot"), 1) 135 | 136 | def test_current(self): 137 | self.assertEqual(test_dotfile("current.dot"), 1) 138 | 139 | def test_ports(self): 140 | self.assertEqual(test_dotfile("ports.dot"), 1) 141 | 142 | 143 | if __name__ == "__main__": 144 | unittest.main() 145 | 146 | -------------------------------------------------------------------------------- /tests/experimental/test_graphparsing.py: -------------------------------------------------------------------------------- 1 | """Test that output from dotparsing and dot is the same""" 2 | 3 | import re, os, shutil, glob, sys, time 4 | 5 | from PIL import ImageChops, Image 6 | 7 | from os.path import join, basename, splitext, normpath 8 | from dot2tex import dotparsing 9 | 10 | # Directory with test files 11 | BASE_DIR = "d:/pycode/textools/dotconv/tests/testgraphs/" 12 | TESTFILES_DIR = "dotparsingtests" 13 | TESTFILES_PATH = join(BASE_DIR, TESTFILES_DIR) 14 | 15 | PNG_DIR = join(TESTFILES_PATH, 'pngs') 16 | DOT_DIR = join(TESTFILES_PATH, 'dpdots') 17 | 18 | import logging 19 | 20 | # intitalize logging module 21 | log = logging.getLogger("test_graphparser") 22 | console = logging.StreamHandler() 23 | console.setLevel(logging.WARNING) 24 | # set a format which is simpler for console use 25 | formatter = logging.Formatter('%(levelname)-8s %(message)s') 26 | # tell the handler to use this format 27 | console.setFormatter(formatter) 28 | log.addHandler(console) 29 | 30 | LOG_FILENAME = splitext(__file__)[0] + '.log' 31 | hdlr = logging.FileHandler(LOG_FILENAME) 32 | log.addHandler(hdlr) 33 | formatter = logging.Formatter('%(levelname)-8s %(message)s') 34 | hdlr.setFormatter(formatter) 35 | log.setLevel(logging.INFO) 36 | 37 | 38 | def equal(im1, im2): 39 | return ImageChops.difference(im1, im2).getbbox() is None 40 | 41 | 42 | def get_testfiles(): 43 | filelist = [] 44 | for f in glob.glob(join(TESTFILES_PATH, "*.dot")): 45 | filelist.append(os.path.normpath(f)) 46 | return filelist 47 | 48 | 49 | if __name__ == '__main__': 50 | graphparser = dotparsing.DotDataParser() 51 | log.info('%s Start of run', time.asctime()) 52 | dotfiles = get_testfiles() 53 | matchingfiles = [] 54 | nonmatchingfiles = [] 55 | failedfiles = [] 56 | for dotfile in dotfiles: 57 | try: 58 | log.info('Processing %s', dotfile) 59 | basefilename = basename(dotfile) 60 | basefilenamenoext = os.path.splitext(basefilename)[0] 61 | f = open(dotfile) 62 | try: 63 | data = f.read() 64 | except: 65 | log.warning('Could not open %s', dotfile) 66 | continue 67 | f.close() 68 | try: 69 | graph = graphparser.parse_dot_data(data) 70 | # create a dotparsing version of the dot file 71 | newfilename = normpath(join(DOT_DIR, basefilename + '.new')) 72 | f = open(newfilename, 'w') 73 | f.write(str(graph)) 74 | f.close() 75 | except: 76 | log.exception('Failed to parse and save %s', basefilename) 77 | continue 78 | origpngfilename = join(PNG_DIR, basefilenamenoext + '.png') 79 | newpngfilename = join(PNG_DIR, basefilenamenoext + '.new.png') 80 | # create PNG from original dot file 81 | syscmd = 'dot -Tpng %s > %s' % (dotfile, origpngfilename) 82 | log.debug("Run %s", syscmd) 83 | err = os.system(syscmd) 84 | if err: 85 | log.warning("Failed to create original %s", origpngfilename) 86 | failedfiles.append(basefilename) 87 | continue 88 | # create PNG from dot file generated by dotparsing 89 | syscmd = 'dot -Tpng %s > %s' % (newfilename, newpngfilename) 90 | log.debug("Run %s", syscmd) 91 | err = os.system(syscmd) 92 | if err: 93 | log.warning("Failed to create new %s", origpngfilename) 94 | failedfiles.append(basefilename) 95 | continue 96 | # load and compare images 97 | try: 98 | imorig = Image.open(origpngfilename) 99 | imnew = Image.open(newpngfilename) 100 | except: 101 | log.exception('Could not load %s images', basefilename) 102 | continue 103 | if equal(imorig, imnew): 104 | log.info('%s matches.', basefilename) 105 | matchingfiles.append(basefilename) 106 | # remove files 107 | os.remove(origpngfilename) 108 | os.remove(newpngfilename) 109 | os.remove(newfilename) 110 | 111 | else: 112 | log.warning('%s did not match!', basefilename) 113 | nonmatchingfiles.append(basefilename) 114 | except: 115 | log.exception('Failed to process %s', basefilename) 116 | continue 117 | 118 | log.info('Nonmatching files:\n%s', nonmatchingfiles) 119 | log.info('Matching files:\n%s', matchingfiles) 120 | log.info('Failed files:\n%s', failedfiles) 121 | log.info('%s End of run', time.asctime()) 122 | 123 | -------------------------------------------------------------------------------- /tests/experimental/test_multirender.py: -------------------------------------------------------------------------------- 1 | import os, sys 2 | 3 | from os.path import join, basename, splitext, normpath, abspath 4 | 5 | from string import Template 6 | import logging 7 | import unittest 8 | 9 | # intitalize logging module 10 | log = logging.getLogger("test_graphparser") 11 | console = logging.StreamHandler() 12 | console.setLevel(logging.WARNING) 13 | # set a format which is simpler for console use 14 | formatter = logging.Formatter('%(levelname)-8s %(message)s') 15 | # tell the handler to use this format 16 | console.setFormatter(formatter) 17 | log.addHandler(console) 18 | 19 | #LOG_FILENAME = splitext(__file__)[0]+'.log' 20 | #hdlr = logging.FileHandler(LOG_FILENAME) 21 | #log.addHandler(hdlr) 22 | #formatter = logging.Formatter('%(levelname)-8s %(message)s') 23 | #hdlr.setFormatter(formatter) 24 | #log.setLevel(logging.INFO) 25 | 26 | # Directory with test files 27 | BASE_DIR = join(abspath(os.path.dirname(__file__)), "") 28 | TESTFILES_DIR = "testgraphs/" 29 | TESTFILES_PATH = join(BASE_DIR, TESTFILES_DIR) 30 | DEST_DIR = join(BASE_DIR, 'tmp/') 31 | 32 | 33 | def runcmd(syscmd): 34 | #err = os.system(syscmd) 35 | sres = os.popen(syscmd) 36 | resdata = sres.read() 37 | err = sres.close() 38 | if err: 39 | log.warning('Failed to run command:\n%s', syscmd) 40 | log.debug('Output:\n%s', resdata) 41 | return err 42 | 43 | 44 | def meps(filename): 45 | fn = splitext(filename)[0] 46 | s = "latex -halt-on-error -interaction nonstopmode %s.tex" % fn 47 | err = runcmd(s) 48 | if err: return err 49 | if sys.platform == 'win32': 50 | s = "dvips -Ppdf -G0 -D600 -E* -o%s.eps %s.dvi" % (fn, fn) 51 | err = runcmd(s) 52 | if err: return err 53 | s = "epstool --bbox --copy --output %s_tmp.eps %s.eps" % (fn, fn) 54 | err = runcmd(s) 55 | if err: return err 56 | try: 57 | os.remove("%s.eps" % fn) 58 | os.remove("%s.dvi" % fn) 59 | os.remove("%s.aux" % fn) 60 | os.remove("%s.log" % fn) 61 | #os.remove("%s.pgf" % fn) 62 | 63 | except: 64 | raise 65 | os.rename("%s_tmp.eps" % fn, "%s.eps" % fn) 66 | s = "epstopdf %s.eps" % fn 67 | err = runcmd(s) 68 | else: 69 | s = "dvips %s.dvi" % fn 70 | err = runcmd(s) 71 | s = "ps2eps -B -f %s.ps" % fn 72 | err = runcmd(s) 73 | if err: return err 74 | s = "epstopdf %s.eps" % fn 75 | err = runcmd(s) 76 | 77 | return err 78 | 79 | 80 | testdotfile = normpath(join(BASE_DIR, 'testgraphs/', 'concentrate.dot')) 81 | 82 | textemplate = r""" 83 | \documentclass{article} 84 | \usepackage{tikz} 85 | 86 | \usepackage{verbatim} 87 | \usepackage[active,tightpage]{preview} 88 | \setlength\PreviewBorder{0pt}% 89 | \PreviewEnvironment{tikzpicture} 90 | 91 | \begin{document} 92 | \begin{tikzpicture} 93 | \matrix[every node/.style={draw=black!20}] (mtrx) { 94 | \node[label=below:original] {\includegraphics{$testfile}}; & \node[label=below:tikz] {\includegraphics{${testfile}_tikz}};\\ 95 | \node[label=below:pgf] {\includegraphics{${testfile}_pgf}}; & \node[label=below:pst] {\includegraphics{${testfile}_pst}};\\ 96 | }; 97 | \node[above] at (mtrx.north) {$testfile}; 98 | \end{tikzpicture} 99 | \end{document} 100 | """ 101 | 102 | s = Template(textemplate) 103 | 104 | 105 | def create_pdf(texfile, use_pdftex=True): 106 | if not splitext(texfile)[1]: 107 | fn = basename(texfile) + '.tex' 108 | else: 109 | fn = basename(texfile) 110 | if sys.platform == 'win32': 111 | syscmd = 'texify --pdf --clean %s' % (fn) 112 | else: 113 | syscmd = 'pdflatex -halt-on-error -interaction nonstopmode %s' % (fn) 114 | err = runcmd(syscmd) 115 | return err 116 | 117 | 118 | def create_original(dotfilename): 119 | # Process the file with dot and create a pdf 120 | # dot -Tps2 file.dot > file.ps 121 | # ps2pdf file.ps 122 | basefn = basename(dotfilename) 123 | destfile = normpath(join(DEST_DIR, splitext(basefn)[0])) 124 | cwd = os.getcwd() 125 | os.chdir(os.path.dirname(destfile)) 126 | syscmd = 'dot -Tps2 %s > %s.ps' % (dotfilename, destfile) 127 | err = runcmd(syscmd) 128 | syscmd = 'ps2pdf %s.ps' % (destfile) 129 | #os.remove("%s.ps" % destfile) 130 | err = runcmd(syscmd) 131 | os.chdir(cwd) 132 | return err 133 | 134 | 135 | def create_tikz(dotfilename): 136 | basefn = basename(dotfilename) 137 | destfile = normpath(join(DEST_DIR, splitext(basefn)[0])) + '_tikz' 138 | syscmd = 'dot2tex -ftikz --crop %s > %s.tex' % (dotfilename, destfile) 139 | err = runcmd(syscmd) 140 | cwd = os.getcwd() 141 | os.chdir(os.path.dirname(destfile)) 142 | err = create_pdf(destfile) 143 | #os.remove(destfile) 144 | os.chdir(cwd) 145 | return err 146 | 147 | 148 | def create_pgf(dotfilename): 149 | basefn = basename(dotfilename) 150 | destfile = normpath(join(DEST_DIR, splitext(basefn)[0])) + '_pgf' 151 | syscmd = 'dot2tex --crop %s > %s.tex' % (dotfilename, destfile) 152 | err = runcmd(syscmd) 153 | cwd = os.getcwd() 154 | os.chdir(os.path.dirname(destfile)) 155 | err = create_pdf(destfile) 156 | #os.remove(destfile) 157 | os.chdir(cwd) 158 | return err 159 | 160 | 161 | def create_pst(dotfilename): 162 | basefn = basename(dotfilename) 163 | destfile = normpath(join(DEST_DIR, splitext(basefn)[0])) + '_pst' 164 | syscmd = 'dot2tex -fpst %s > %s.tex' % (dotfilename, destfile) 165 | err = runcmd(syscmd) 166 | cwd = os.getcwd() 167 | os.chdir(os.path.dirname(destfile)) 168 | #syscmd = 'meps %s' % (basename(destfile)) 169 | #err = runcmd(syscmd) 170 | err = meps(basename(destfile)) 171 | os.chdir(cwd) 172 | return err 173 | 174 | 175 | def create_comparefile(dotfilename): 176 | basefn = basename(dotfilename) 177 | destfile = normpath(join(DEST_DIR, splitext(basefn)[0])) + '_cmp.tex' 178 | f = open(destfile, 'w') 179 | f.write(s.substitute(testfile=splitext(basefn)[0])) 180 | f.close() 181 | cwd = os.getcwd() 182 | os.chdir(os.path.dirname(destfile)) 183 | err = create_pdf(destfile) 184 | #if sys.platform=='win32': 185 | # syscmd = "start %s" % splitext(basename(destfile))[0]+'.pdf' 186 | # err = runcmd(syscmd) 187 | 188 | os.chdir(cwd) 189 | 190 | 191 | # Get a dot file to test 192 | 193 | # Create a tikz version 194 | # create a pgf version 195 | # create a pstricks version 196 | # Combine the images in a latex file 197 | 198 | def compare_output(testdotfile): 199 | err = create_original(testdotfile) 200 | if err: return err 201 | err = create_tikz(testdotfile) 202 | if err: return err 203 | err = create_pgf(testdotfile) 204 | if err: return err 205 | err = create_pst(testdotfile) 206 | if err: return err 207 | err = create_comparefile(testdotfile) 208 | return err 209 | 210 | 211 | # From 212 | # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/541096 213 | def confirm(prompt=None, resp=False): 214 | """prompts for yes or no response from the user. Returns True for yes and 215 | False for no. 216 | 217 | 'resp' should be set to the default value assumed by the caller when 218 | user simply types ENTER. 219 | 220 | >>> confirm(prompt='Create Directory?', resp=True) 221 | Create Directory? [y]|n: 222 | True 223 | >>> confirm(prompt='Create Directory?', resp=False) 224 | Create Directory? [n]|y: 225 | False 226 | >>> confirm(prompt='Create Directory?', resp=False) 227 | Create Directory? [n]|y: y 228 | True 229 | 230 | """ 231 | 232 | if prompt is None: 233 | prompt = 'Confirm' 234 | 235 | if resp: 236 | prompt = '%s [%s]|%s: ' % (prompt, 'y', 'n') 237 | else: 238 | prompt = '%s [%s]|%s: ' % (prompt, 'n', 'y') 239 | 240 | while True: 241 | ans = raw_input(prompt) 242 | if not ans: 243 | return resp 244 | if ans not in ['y', 'Y', 'n', 'N']: 245 | print('please enter y or n.') 246 | continue 247 | if ans == 'y' or ans == 'Y': 248 | return True 249 | if ans == 'n' or ans == 'N': 250 | return False 251 | 252 | 253 | def run_rendertest(dotfile): 254 | print("Processing %s" % dotfile) 255 | err = compare_output(normpath(join(TESTFILES_PATH, dotfile))) 256 | if err: 257 | return False 258 | else: 259 | return True 260 | s = "Is %s correct?" % (dotfile) 261 | return confirm(s, resp=True) 262 | 263 | 264 | class RenderTest(unittest.TestCase): 265 | cmplist = [] 266 | 267 | def setUp(self): 268 | if not os.path.exists(DEST_DIR): 269 | os.mkdir(DEST_DIR) 270 | 271 | def test_autosize(self): 272 | fn = 'autosize.dot' 273 | self.failUnless(run_rendertest(fn)) 274 | self.cmplist.append(fn) 275 | 276 | def test_compassports(self): 277 | fn = 'compassports.dot' 278 | self.failUnless(run_rendertest(fn)) 279 | self.cmplist.append(fn) 280 | 281 | def test_concentrate(self): 282 | fn = 'concentrate.dot' 283 | self.failUnless(run_rendertest(fn)) 284 | self.cmplist.append(fn) 285 | 286 | def test_escstr(self): 287 | fn = 'escstr.dot' 288 | self.failUnless(run_rendertest(fn)) 289 | self.cmplist.append(fn) 290 | 291 | def test_invis(self): 292 | fn = 'invis.dot' 293 | self.failUnless(run_rendertest(fn)) 294 | self.cmplist.append(fn) 295 | 296 | def test_nodenames(self): 297 | fn = 'nodenames.dot' 298 | self.failUnless(run_rendertest(fn)) 299 | self.cmplist.append(fn) 300 | 301 | def test_colors(self): 302 | fn = 'colors.dot' 303 | self.failUnless(run_rendertest(fn)) 304 | self.cmplist.append(fn) 305 | 306 | def test_zzzzzzzzzzzfinal(self): 307 | os.chdir(DEST_DIR) 308 | flist = [] 309 | for dotfile in self.cmplist: 310 | basefn = basename(dotfile) 311 | flist.append(normpath(join(splitext(basefn)[0])) + '_cmp.pdf') 312 | s = "pdftk %s cat output testrenders.pdf dont_ask" % " ".join(flist) 313 | err = runcmd(s) 314 | self.failIf(err) 315 | if sys.platform == 'win32': 316 | syscmd = "start %s" % 'testrenders.pdf' 317 | err = runcmd(syscmd) 318 | print("Check testrenders.pdf manually") 319 | 320 | 321 | testdotfile2 = normpath(join(TESTFILES_PATH, 'compassports.dot')) 322 | 323 | if __name__ == '__main__': 324 | #compare_output(testdotfile2) 325 | unittest.main() 326 | -------------------------------------------------------------------------------- /tests/test_dotparsing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import unittest 3 | 4 | import dot2tex.dotparsing as dotp 5 | 6 | 7 | class DotNodeTest(unittest.TestCase): 8 | def test_create(self): 9 | node = dotp.DotNode("a") 10 | self.assertEqual(node.name, "a") 11 | self.assertEqual(len(node.attr), 0) 12 | 13 | def test_createwithattributes(self): 14 | node = dotp.DotNode("a", label='a_1', style='filled') 15 | self.assertEqual(node.name, "a") 16 | self.assertEqual(len(node.attr), 2) 17 | self.assertEqual(node.attr['label'], 'a_1') 18 | self.assertEqual(node.attr['style'], 'filled') 19 | 20 | def test_createwithdict(self): 21 | attr = dict(label="a_1", style='filled') 22 | node = dotp.DotNode("a", **attr) 23 | self.assertEqual(len(node.attr), 2) 24 | self.assertEqual(node.attr['label'], 'a_1') 25 | self.assertEqual(node.attr['style'], 'filled') 26 | 27 | def test_createwithdictandnamed(self): 28 | attr = dict(label="a_1", style='filled') 29 | node = dotp.DotNode("a", texmode="math", **attr) 30 | self.assertEqual(len(node.attr), 3) 31 | self.assertEqual(node.attr['label'], 'a_1') 32 | self.assertEqual(node.attr['style'], 'filled') 33 | self.assertEqual(node.attr['texmode'], 'math') 34 | 35 | def test_cmp(self): 36 | node = dotp.DotNode("a") 37 | self.assertEqual(node.name, "a") 38 | self.assertEqual(node, 'a') 39 | 40 | 41 | class DotGraphTest(unittest.TestCase): 42 | def test_create(self): 43 | g = dotp.DotGraph('mygraph', strict=False, directed=True) 44 | self.assertEqual(g.name, "mygraph") 45 | self.assertEqual(g.strict, False) 46 | self.assertEqual(g.directed, True) 47 | 48 | def test_create_with_attributes(self): 49 | g = dotp.DotGraph(style='fancy', label='testgraph') 50 | self.assertEqual(len(g.attr), 2) 51 | self.assertEqual(g.attr['style'], 'fancy') 52 | self.assertEqual(g.attr['label'], 'testgraph') 53 | 54 | 55 | def test_add_node(self): 56 | g = dotp.DotGraph() 57 | na = g.add_node('a') 58 | nb = g.add_node('b') 59 | self.assertEqual(len(list(g.nodes)), 2) 60 | 61 | ## 62 | def test_addequalnodes(self): 63 | g = dotp.DotGraph() 64 | g.add_node('a', label="test1") 65 | g.add_node('a', style="filled") 66 | g.add_node('a', label="test2", texmode="math") 67 | n = g.get_node('a') 68 | self.assertEqual(len(list(g.nodes)), 1) 69 | self.assertEqual(len(n.attr), 3) 70 | self.assertEqual(n.attr['label'], 'test2') 71 | self.assertEqual(set(n.attr.keys()), set(['label', 'style', 'texmode'])) 72 | 73 | def test_add_nonstring_nodes(self): 74 | g = dotp.DotGraph() 75 | n = g.add_node(1) 76 | self.assertEqual(n.name, '1') 77 | n = g.add_node(3.14) 78 | self.assertEqual(n.name, '3.14') 79 | 80 | def test_add_edge(self): 81 | g = dotp.DotGraph() 82 | e = g.add_edge('a', 'b', label='test') 83 | e2 = g.add_edge('a', 'd', label='test2') 84 | self.assertEqual(len(g), 3) 85 | self.assertEqual(len(g.edges), 2) 86 | 87 | 88 | class DotSubgraphsTest(unittest.TestCase): 89 | def test_add_subgraph(self): 90 | g = dotp.DotGraph() 91 | s = g.add_subgraph('subG') 92 | self.assertEqual(s.name, 'subG') 93 | 94 | def test_add_edge_to_subgraph(self): 95 | g = dotp.DotGraph() 96 | s = g.add_subgraph('subG') 97 | self.assertEqual(len(g), 0) 98 | s.add_edge(1, 2) 99 | self.assertEqual(len(s), 2) 100 | self.assertEqual(len(g), 2) 101 | g.add_edge(3, 4) 102 | self.assertEqual(len(s), 2) 103 | self.assertEqual(len(g), 4) 104 | 105 | 106 | class DotDefaultAttrTest(unittest.TestCase): 107 | """Test default attributes""" 108 | 109 | def test_add_default(self): 110 | g = dotp.DotGraph() 111 | g.add_default_node_attr(color="red", label="a") 112 | self.assertEqual(len(g.default_node_attr), 2) 113 | g.add_default_edge_attr(color="red") 114 | self.assertEqual(len(g.default_edge_attr), 1) 115 | g.add_default_graph_attr(color="red") 116 | self.assertEqual(len(g.default_graph_attr), 1) 117 | 118 | def test_add_default_node(self): 119 | g = dotp.DotGraph() 120 | g.add_default_node_attr(color="red") 121 | n = g.add_node('a') 122 | self.assertTrue('color' in n.attr) 123 | self.assertEqual(n.attr['color'], "red") 124 | g.add_default_node_attr(color="blue", label="b") 125 | n = g.add_node(2) 126 | self.assertTrue('color' in n.attr) 127 | self.assertEqual(n.attr['color'], "blue") 128 | self.assertTrue('label' in n.attr) 129 | self.assertEqual(n.attr['label'], "b") 130 | 131 | def test_add_default_node_subgraph(self): 132 | g = dotp.DotGraph() 133 | g.add_default_node_attr(color="red") 134 | g.add_node('a') 135 | s = g.add_subgraph('S') 136 | s.add_default_node_attr(style='test') 137 | n = s.add_node('b') 138 | self.assertTrue('color' in n.attr) 139 | self.assertEqual(n.attr['color'], "red") 140 | self.assertTrue('style' in n.attr) 141 | nn = g.add_node(2) 142 | self.assertFalse('style' in nn.attr) 143 | 144 | 145 | ## 146 | ## 147 | ## def test_addequalnodes2(self): 148 | ## g = dotp.DotGraph() 149 | ## n = dotp.DotNode('a',label="test1") 150 | ## g.add_node(n) 151 | ## n = dotp.DotNode('a',style="filled") 152 | ## g.add_node(n) 153 | ## g.add_node('a',label="test2",texmode="math") 154 | ## n = g.get_node('a') 155 | ## self.assertEqual(len(g.nodes),1) 156 | ## self.assertEqual(len(n.attributes),3) 157 | ## self.assertEqual(n.attributes['label'],'test2') 158 | ## self.assertEqual(set(n.attributes.keys()),set(['label','style','texmode'])) 159 | ## 160 | ## def test_getnodes(self): 161 | ## g = dotp.DotGraph() 162 | ## n = g.get_node('a') 163 | ## self.assertEqual(n,None) 164 | ## g.add_node('a') 165 | ## n = g.get_node('a') 166 | ## self.assertEqual(n.name,'a') 167 | ## 168 | ## def test_addedge(self): 169 | ## g = dotp.DotGraph(graph_type='digraph') 170 | ## e1 = g.add_edge('a','b',label='a->b') 171 | ## e2 = g.add_edge('b','a',label='b->a') 172 | ## self.assertEqual(len(g.nodes),2) 173 | ## self.assertEqual(len(g.edges),2) 174 | ## self.assertEqual(e1.attributes['label'],'a->b') 175 | ## self.assertEqual(e2.attributes['label'],'b->a') 176 | ## 177 | ## 178 | ## 179 | ## 180 | ## 181 | ## 182 | ## def test_strictgraph(self): 183 | ## """A strict graph have to ignore duplicate edges""" 184 | ## g = dotp.DotGraph(strict=True) 185 | ## g.add_edge('a','b') 186 | ## g.add_edge('a','b') 187 | ## self.assertEqual(len(g.edges),1) 188 | ## 189 | ## def test_addsubgraphs(self): 190 | ## g = dotp.DotGraph() 191 | ## g.add_edge('a','b') 192 | ## n = g.get_node('a') 193 | ## self.assertEqual(n.parent,g) 194 | ## gs = g.add_subgraph('clusterG') 195 | ## gs.add_edge('a','b') 196 | ## #n = g.get_node('a') 197 | ## self.assertEqual(n.parent,gs) 198 | ## n = g.add_node('a',label="test") 199 | ## 200 | ## self.assertEqual(n.parent,gs) 201 | ## 202 | ## def test_graphlevels(self): 203 | ## g = dotp.DotGraph() 204 | ## e = g.add_edge('a','b') 205 | ## self.assertEqual(g.level,0) 206 | ## gs1 = g.add_subgraph('clusterG') 207 | ## self.assertEqual(gs1.level,1) 208 | ## gs2 = g.add_subgraph('clusterGG') 209 | ## self.assertEqual(gs2.level,1) 210 | ## gs12 = gs1.add_subgraph('ClusterG2') 211 | ## self.assertEqual(gs12.level,2) 212 | ## e = gs12.add_edge('c','d') 213 | ## self.assertEqual(e.src.parent.level,2) 214 | ## self.assertEqual(e.parent.level,2) 215 | ## 216 | ## def test_addedgesubgraphs(self): 217 | ## """ 218 | ## digraph G { 219 | ## a -> b; 220 | ## subgraph clusterG { 221 | ## a -> b; 222 | ## } 223 | ## subgraph clusterGG { 224 | ## a -> b; 225 | ## } 226 | ## 227 | ##strict digraph G { 228 | ## node [label="\N"]; 229 | ## graph [bb="0,0,86,140"]; 230 | ## subgraph clusterG { 231 | ## graph [bb="8,8,78,132"]; 232 | ## a [pos="43,106", width="0.75", height="0.50"]; 233 | ## b [pos="43,34", width="0.75", height="0.50"]; 234 | ## a -> b [pos="e,43,52 43,88 43,80 43,71 43,62"]; 235 | ## } 236 | ##} 237 | ## }""" 238 | ## g = dotp.DotGraph() 239 | ## e1 = g.add_edge('a','b') 240 | ## self.assertEqual(e1.parent.name,g.name) 241 | ## gs = g.add_subgraph('clusterG') 242 | ## e2 = gs.add_edge('a','b') 243 | ## self.assertEqual(e2.parent.name,gs.name) 244 | ## self.assertEqual(e1.parent.name,gs.name) 245 | ## gs2 = g.add_subgraph('clusterGG') 246 | ## e3 = gs2.add_edge('a','b') 247 | ## self.assertEqual(e2.parent.name,gs.name) 248 | ## self.assertEqual(e3.parent.name,gs.name) 249 | ## self.assertEqual(len(gs2.edges),3) 250 | ## 251 | ## def test_add_single_edge_to_subgraph(self): 252 | ## """Edge should belong to subgraph""" 253 | ## g = dotp.DotGraph() 254 | ## gs = g.add_subgraph('clusterG') 255 | ## na = gs.add_node('a') 256 | ## nb = gs.add_node('b') 257 | ## edge = g.add_edge('a','b') 258 | ## self.assertEqual(na.parent,gs) 259 | ## self.assertEqual(nb.parent,gs) 260 | ## self.assertEqual(edge.parent.name,gs.name) 261 | ## 262 | ## def test_add_multiple_edges_to_subgraph(self): 263 | ## """Edges should belong to subgraph""" 264 | ## g = dotp.DotGraph() 265 | ## gs = g.add_subgraph('clusterG') 266 | ## na = gs.add_node('a') 267 | ## nb = gs.add_node('b') 268 | ## edge = g.add_edge('a','b') 269 | ## self.assertEqual(edge.parent.name,gs.name) 270 | ## edge2 = g.add_edge('a','b') 271 | ## self.assertEqual(edge2.parent.name,gs.name) 272 | ## 273 | ## def test_change_edge_parent(self): 274 | ## """If edge nodes change parents, so should the edge""" 275 | ## g = dotp.DotGraph() 276 | ## edge = g.add_edge('a','b') 277 | ## gs = g.add_subgraph('clusterG') 278 | ## na = gs.add_node('a') 279 | ## nb = gs.add_node('b') 280 | ## self.assertEqual(edge.parent.name,gs.name) 281 | ## 282 | ## 283 | ## 284 | ## 285 | ## 286 | ## 287 | ## 288 | ## 289 | ## 290 | ## 291 | ## 292 | 293 | 294 | 295 | 296 | 297 | 298 | if __name__ == '__main__': 299 | unittest.main() 300 | -------------------------------------------------------------------------------- /tests/testgraphs/autosize.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | d2toptions="--autosize"; 3 | node [shape=circle]; 4 | a_1 [texlbl="$x^2+\frac{\sin y}{y^2+\cos \beta}+\gamma_3$"]; 5 | a_1 -> a_2 [label=" ", texlbl="$x_1+x_3^2+z+c+v~~$"]; 6 | a_2 -> a_1; 7 | a_2 -> a_3; 8 | a_3 [lblstyle="minimum size=4cm"]; 9 | } -------------------------------------------------------------------------------- /tests/testgraphs/clust.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | node [fontcolor=red]; 3 | subgraph cluster0 { 4 | node [style=filled,color=white, texmode=math]; 5 | style=filled; 6 | color=lightgrey; 7 | a_0 -> a_1 -> a_2 -> a_3; 8 | label="latex"; 9 | texlbl="\LaTeX"; 10 | } 11 | subgraph cluster1 { 12 | node [style=filled, texmode=math, fontcolor=red]; 13 | b_0 -> b_1 -> b_2 -> b_3; 14 | label = "process #2"; 15 | color=blue 16 | } 17 | start -> a_0; 18 | start -> b_0; 19 | a_1 -> b_3; 20 | b_2 -> a_3; 21 | a_3 -> a_0; 22 | a_3 -> end; 23 | b_3 -> end; 24 | start [shape=diamond, texlbl="${\frac{\sqrt{\gamma+\beta}}{x^2+y^2}}$"]; 25 | end [shape=Msquare]; 26 | } -------------------------------------------------------------------------------- /tests/testgraphs/colors.dot: -------------------------------------------------------------------------------- 1 | /* Test stroke and fill coloring */ 2 | digraph G { 3 | 4 | a [color=red]; 5 | b [style="filled", fillcolor=blue]; 6 | c [style="filled", color=yellow]; 7 | d [style=filled]; 8 | b [style="filled", fillcolor=pink, color=green]; 9 | f [style="filled", fillcolor="0.051 0.718 0.627",color="#40e0d0"]; 10 | g [color="#ffff00"]; 11 | a -> {b c d e f g}; 12 | i -> b [color=red]; 13 | i -> d [color="#ffff00"]; 14 | i -> d [color="0.051 0.718 0.627"]; 15 | 16 | 17 | } -------------------------------------------------------------------------------- /tests/testgraphs/compassports.dot: -------------------------------------------------------------------------------- 1 | /* Test compass points */ 2 | digraph g { 3 | graph [rankdir=LR]; 4 | node [shape=rectangle]; 5 | a [label="node A"]; 6 | b [label="node B"]; 7 | a:n -> b:n; 8 | a:ne -> b:ne; 9 | a:e -> b:e; 10 | a:se -> b:se; 11 | a:s -> b:s; 12 | a:sw -> b:sw; 13 | a:w -> b:w; 14 | a:nw -> b:nw; 15 | a:center -> b:center; 16 | a:dummy -> c:dummy; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /tests/testgraphs/concentrate.dot: -------------------------------------------------------------------------------- 1 | /* Test concentrate option */ 2 | digraph g { 3 | graph [rankdir=LR, concentrate=1]; 4 | trans1 -> trans2; 5 | trans2 -> trans3; 6 | trans1 -> state1; 7 | trans2 -> state1; 8 | trans3 -> state1; 9 | } 10 | -------------------------------------------------------------------------------- /tests/testgraphs/d2topts.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | d2toptions = "-ftikz -tmath" 3 | ; 4 | a_1-> a_2 -> a_3 -> a_1; 5 | } -------------------------------------------------------------------------------- /tests/testgraphs/dot2tikznodeshapesmapping.dot: -------------------------------------------------------------------------------- 1 | graph G { 2 | c [shape=circle]; 3 | n_1 [shape=box]; 4 | n_2 [shape=ellipse]; 5 | n_3 [shape=oval]; 6 | n_4 [shape="point"]; 7 | n_5 [shape="egg"]; 8 | n_6 [shape="triangle"]; 9 | n_7 [shape="plaintext"]; 10 | n_8 [shape="diamond"]; 11 | n_9 [shape="trapezium"]; 12 | n_10 [shape="parallelogram"]; 13 | n_11 [shape="house"]; 14 | n_12 [shape="pentagon"]; 15 | n_13 [shape="hexagon"]; 16 | n_14 [shape="septagon"]; 17 | n_15 [shape="square"]; 18 | n_16 [shape="star"]; 19 | c -- n_1 [label="box"]; 20 | c -- n_2 [label="ellipse"]; 21 | c -- n_3 [label="oval"]; 22 | c -- n_4 [label="point"]; 23 | c -- n_5 [label="egg"]; 24 | c -- n_6 [label="triangle"]; 25 | c -- n_7 [label="plaintext"]; 26 | c -- n_8 [label="diamond"]; 27 | c -- n_9 [label="trapezium"]; 28 | c -- n_10 [label="parallelogram"]; 29 | c -- n_11 [label="house"]; 30 | c -- n_12 [label="pentagon"]; 31 | c -- n_13 [label="hexagon"]; 32 | c -- n_14 [label="septagon"]; 33 | c -- n_15 [label="square"]; 34 | c -- n_16 [label="star"]; 35 | 36 | } -------------------------------------------------------------------------------- /tests/testgraphs/escstr.dot: -------------------------------------------------------------------------------- 1 | digraph testG { 2 | d2tdocpreamble="\usepackage[T1]{fontenc}\usepackage{lmodern}"; 3 | a [label="\N"]; 4 | b [label="\G"]; 5 | a -> b [label="\E"]; 6 | subgraph clusterA { 7 | c -> f [label="\T connect \H"]; 8 | } 9 | a -> c; 10 | } -------------------------------------------------------------------------------- /tests/testgraphs/invis.dot: -------------------------------------------------------------------------------- 1 | /* Test invisible edges and nodes */ 2 | digraph G { 3 | a -> { 4 | node[style="invis"] 5 | b c d; 6 | } 7 | f [style="invisible"]; 8 | a -> e [style="invisible"]; 9 | a -> g [style="invis"]; 10 | a -> f; 11 | } -------------------------------------------------------------------------------- /tests/testgraphs/latin1.dot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xyz2tex/dot2tex/5f7990022d2a5d75d80ddd686b33c6103c38c7ff/tests/testgraphs/latin1.dot -------------------------------------------------------------------------------- /tests/testgraphs/markup.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | a_1 [texlbl="$\frac{\gamma}{2x^2+y^3}$"]; 3 | a_1 -> a_2 -> a_3 -> a_1 4 | node [texmode="math"]; 5 | a_1 -> b_1 -> b_2 -> a_3; 6 | b_1 [label="\\frac{\\gamma}{x^2}"]; 7 | node [texmode="verbatim"] 8 | b_4 [label="\\feta"] 9 | b_5 [label="\\frac"] 10 | a_3 -> b_4; 11 | a_1 -> b_4; 12 | } -------------------------------------------------------------------------------- /tests/testgraphs/markup2.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | Decl [ shape=record, label = "\n\nDecl|{name|access|decl_flags|extern_c_linkage}"]; 3 | a_1 [label="$\\frac{\\gamma}{2x^2+y^3}$"]; 4 | a_1 -> a_2 -> a_3 -> a_1 5 | node [texmode="math"]; 6 | a_1 -> b_1 -> b_2 -> a_3; 7 | node [texmode="verbatim"] 8 | b_4 [label="\\feta"] 9 | b_5 [label="\frac"] 10 | a_3 -> b_4; 11 | c5 -> b_4; 12 | a_1 -> Decl; 13 | 14 | } -------------------------------------------------------------------------------- /tests/testgraphs/multilines.dot: -------------------------------------------------------------------------------- 1 | /* Test multilineattributes and concatination */ 2 | digraph G { 3 | a [label="This is\ 4 | a multiline\ 5 | text", color=red 6 | style=filled]; 7 | b [label="partA"+"partB"+"partC"]; 8 | b [label="partA" + "partB"+ 9 | "partC"]; 10 | a -> b -> c; 11 | } -------------------------------------------------------------------------------- /tests/testgraphs/nodenames.dot: -------------------------------------------------------------------------------- 1 | /* Test various tikz-unfriendly node names */ 2 | 3 | digraph G { 4 | "" -> {a b c}; 5 | {e f g} -> " "; 6 | "a,b" -> c; 7 | "a.b" -> c; 8 | "a:b" -> c; 9 | "\\a:b" -> c; 10 | a [label="\\a"]; 11 | } -------------------------------------------------------------------------------- /tests/testgraphs/parsetests/ids.dot: -------------------------------------------------------------------------------- 1 | /* Test that the various id types are parsed correctly */ 2 | digraph G { 3 | a [label=noquote]; 4 | b [label="\"quote\""]; 5 | c [label=< 6 | 7 | 8 |
leftmid dleright
>]; 9 | d [label=12.4]; 10 | e [label="node"]; 11 | a -> b -> c -> d -> e; 12 | } -------------------------------------------------------------------------------- /tests/testgraphs/parsetests/multilines.dot: -------------------------------------------------------------------------------- 1 | /* Test line joining and multiline stuff*/ 2 | digraph G { 3 | a [label="partA"+"partB"]; 4 | b [label="Line1\ 5 | line2\ 6 | line3"]; 7 | d [label="Test", 8 | color=red, 9 | style=filled]; 10 | e [shape = record,label="\n\nDecl|{name|access|decl_flags|extern_c_linkage}"]; 11 | f [label="Line1\lLine2\rLine3\nLine4",width=2]; 12 | a -> b -> c -> d -> e -> f; 13 | } -------------------------------------------------------------------------------- /tests/testgraphs/parsetests/quoting.dot: -------------------------------------------------------------------------------- 1 | /* Test that different quoting variants are parsed correctly */ 2 | digraph G { 3 | "a" -> "b"; 4 | "aa\\" -> b; 5 | "aa\\" -> c [label="test"]; 6 | "\"aa\"" -> c [label="test"]; 7 | } -------------------------------------------------------------------------------- /tests/testgraphs/parsetests/subgraphs.dot: -------------------------------------------------------------------------------- 1 | /* Test subgraphs */ 2 | digraph G { 3 | a -> { 4 | c; d; e; 5 | } 6 | subgraph clusterA { 7 | f;g;h; 8 | } -> a; 9 | {i; j; k} -> {s;t;m}; 10 | } -------------------------------------------------------------------------------- /tests/testgraphs/pststyles.dot: -------------------------------------------------------------------------------- 1 | graph G { 2 | node [shape=circle, texmode=math, fixedsize=True, width="0.4", style="filled, shadow=true", color="blue"]; 3 | edge [style="linecolor=green, showpoints=true,dotstyle=triangle"]; 4 | a_1-- a_2 -- a_3 -- a_1; 5 | node [shape=box, style="shadow=true", label=""]; 6 | edge [style="linecolor=red, shadow=true"]; 7 | b_1 -- b_2 -- a_2; 8 | } -------------------------------------------------------------------------------- /tests/testgraphs/specialchars.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | a -> b; 3 | a [label="$\\%_#{}^&"]; 4 | b [label="&^}{#_%\\$"]; 5 | } -------------------------------------------------------------------------------- /tests/testgraphs/styles.dot: -------------------------------------------------------------------------------- 1 | graph G { 2 | graph [splines=false] 3 | node [shape=circle, texmode=math, fixedsize=True, width="0.4", style="ball color = green", label=""]; 4 | edge [style="snake=zigzag, green"]; 5 | a_1-- a_2 -- a_3 -- a_1; 6 | node [style="ball color = red", label=""]; 7 | edge [style="snake=snake, blue", color=red]; 8 | b_1 -- b_2 -- a_2; 9 | } -------------------------------------------------------------------------------- /tests/testgraphs/transp.dot: -------------------------------------------------------------------------------- 1 | graph G { 2 | // graph [splines=true overlap=false] 3 | //graph [truecolor bgcolor="#ff00005f"] 4 | node [style=filled fillcolor="#00ff005f"] 5 | 1 -- 30 [f=1]; 6 | 1 -- 40 [f=14]; 7 | 8 -- 46 [f=1]; 8 | 8 -- 16 [f=18]; 9 | 10 -- 25 [f=1]; 10 | 10 -- 19 [f=5]; 11 | 10 -- 33 [f=1]; 12 | 12 -- 8 [f=1]; 13 | 12 -- 36 [f=5]; 14 | 12 -- 17 [f=16]; 15 | 13 -- 38 [f=1]; 16 | 13 -- 24 [f=19]; 17 | 24 -- 49 [f=1]; 18 | 24 -- 13 [f=1]; 19 | 24 -- 47 [f=12]; 20 | 24 -- 12 [f=19]; 21 | 25 -- 27 [f=1]; 22 | 25 -- 12 [f=1]; 23 | 27 -- 12 [f=1]; 24 | 27 -- 14 [f=8]; 25 | 29 -- 10 [f=1]; 26 | 29 -- 8 [f=17]; 27 | 30 -- 24 [f=1]; 28 | 30 -- 44 [f=15]; 29 | 38 -- 29 [f=1]; 30 | 38 -- 35 [f=15]; 31 | 2 -- 42 [f=2]; 32 | 2 -- 35 [f=3]; 33 | 2 -- 11 [f=19]; 34 | 14 -- 18 [f=2]; 35 | 14 -- 24 [f=15]; 36 | 14 -- 38 [f=18]; 37 | 18 -- 49 [f=2]; 38 | 18 -- 47 [f=20]; 39 | 26 -- 41 [f=2]; 40 | node [style=filled fillcolor="#ff00005f"] 41 | 26 -- 42 [f=15]; 42 | 31 -- 39 [f=2]; 43 | 31 -- 47 [f=17]; 44 | 31 -- 25 [f=14]; 45 | 37 -- 26 [f=2]; 46 | 37 -- 16 [f=14]; 47 | 39 -- 50 [f=2]; 48 | 39 -- 14 [f=2]; 49 | 39 -- 18 [f=17]; 50 | 39 -- 47 [f=10]; 51 | 41 -- 31 [f=2]; 52 | 41 -- 8 [f=16]; 53 | 42 -- 44 [f=2]; 54 | 42 -- 29 [f=12]; 55 | 44 -- 37 [f=2]; 56 | 44 -- 32 [f=15]; 57 | 3 -- 20 [f=2]; 58 | 3 -- 28 [f=19]; 59 | 6 -- 45 [f=2]; 60 | 6 -- 28 [f=10]; 61 | 9 -- 6 [f=2]; 62 | 9 -- 16 [f=1]; 63 | node [style=filled fillcolor="#0000ff5f"] 64 | 15 -- 16 [f=2]; 65 | 15 -- 48 [f=2]; 66 | 16 -- 50 [f=2]; 67 | 16 -- 32 [f=14]; 68 | 16 -- 39 [f=8]; 69 | 20 -- 33 [f=2]; 70 | 33 -- 9 [f=2]; 71 | 33 -- 46 [f=3]; 72 | 33 -- 48 [f=17]; 73 | 45 -- 15 [f=2]; 74 | 4 -- 17 [f=4]; 75 | 4 -- 15 [f=6]; 76 | 4 -- 12 [f=16]; 77 | 17 -- 21 [f=4]; 78 | 19 -- 35 [f=4]; 79 | 19 -- 15 [f=9]; 80 | 19 -- 43 [f=4]; 81 | 21 -- 19 [f=4]; 82 | 21 -- 50 [f=4]; 83 | 23 -- 36 [f=4]; 84 | 34 -- 23 [f=4]; 85 | 34 -- 24 [f=11]; 86 | 35 -- 34 [f=4]; 87 | 35 -- 16 [f=6]; 88 | 35 -- 18 [f=16]; 89 | 36 -- 46 [f=4]; 90 | 5 -- 7 [f=1]; 91 | 5 -- 36 [f=6]; 92 | 7 -- 32 [f=1]; 93 | 7 -- 11 [f=2]; 94 | 7 -- 14 [f=17]; 95 | 11 -- 40 [f=1]; 96 | 11 -- 50 [f=1]; 97 | 22 -- 46 [f=1]; 98 | 28 -- 43 [f=1]; 99 | 28 -- 8 [f=18]; 100 | 32 -- 28 [f=1]; 101 | 32 -- 39 [f=13]; 102 | 32 -- 42 [f=15]; 103 | 40 -- 22 [f=1]; 104 | 40 -- 47 [f=1]; 105 | 43 -- 11 [f=1]; 106 | 43 -- 17 [f=19]; 107 | } 108 | -------------------------------------------------------------------------------- /tests/testgraphs/utf8.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | a -> b -> c; 3 | a [label="æøå"]; 4 | b [label="üù"]; 5 | c [label="Éß"]; 6 | } --------------------------------------------------------------------------------