From 2fba32dd916c20d5684d3aed8e3c5622c0a1cef4 Mon Sep 17 00:00:00 2001 From: Sébastien Dailly Date: Mon, 5 May 2014 21:36:19 +0200 Subject: Update post about graphviz --- content/Informatique/rst_graphviz.rst | 74 ++++++++++--- content/images/graphe.png | Bin 4110 -> 0 bytes content/images/graphviz/graphe.png | Bin 0 -> 11631 bytes content/images/graphviz/no.png | Bin 0 -> 11046 bytes content/images/graphviz/options.png | Bin 0 -> 10627 bytes content/resources/rst_graphviz/rst2html.py | 30 ++++-- content/resources/rst_graphviz/rst2latex.py | 155 +++++++++++++++++++++++++--- 7 files changed, 224 insertions(+), 35 deletions(-) delete mode 100644 content/images/graphe.png create mode 100644 content/images/graphviz/graphe.png create mode 100644 content/images/graphviz/no.png create mode 100644 content/images/graphviz/options.png diff --git a/content/Informatique/rst_graphviz.rst b/content/Informatique/rst_graphviz.rst index b2dc477..0682514 100644 --- a/content/Informatique/rst_graphviz.rst +++ b/content/Informatique/rst_graphviz.rst @@ -11,7 +11,10 @@ Ajouter graphviz dans les documents restructuredText .. default-role:: literal -.. image:: |filename|/images/graphe.png +:2014-05-05: Je met l'article à jour avec la dernière version du script que + j'utilise. J'en profite pour donner un peu plus d'exemples. + +.. image:: |filename|/images/graphviz/graphe.png :class: floatleft :scale: 50 :alt: Graphe @@ -31,7 +34,7 @@ la description du graphe, l'application nous génère une image (avec différent formats possibles) du graphe. Par exemple, l'image ci contre peut-être représentée avec le code suivant : -.. code-block:: C +.. code-block:: dot digraph G { @@ -53,26 +56,64 @@ de la génération du document. Pour ça, j'ai créé une nouvelle directive_, .. _directive: http://docutils.sourceforge.net/docs/ref/rst/directives.html -.. code-block:: rst +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + :widths: 10 45 45 + + * - Exemple + - Code + - Résultat + * - Insérer un graphe orienté + - + .. code-block:: rst + + .. graphviz:: digraph + + a -> a + a -> b + d -> b + b -> c + c -> b + + .. + ceci est une légende + - - Voici une image : + .. figure:: |filename|/images/graphviz/graphe.png - .. graphviz:: + ceci est une légende - digraph G { + * - Insérer un graphe non-orienté + - + .. code-block:: rst - a -> a - a -> b - d -> b - b -> c - c -> b - } + .. graphviz:: graph -deviendra : + a -- a + a -- b + d -- b + b -- c + c -- b + - - Voici une image : + .. figure:: |filename|/images/graphviz/no.png + * - Utiliser des options + - + .. code-block:: rst - .. image:: |filename|/images/graphe.png + .. graphviz:: digraph + + rankdir = LR; + + a -> a + a -> b + d -> b + b -> c + c -> b + - + + .. figure:: |filename|/images/graphviz/options.png Pour ceux que ça intéresse, voici le script pour rst2html_ et rst2latex_. Le code est similaire, cela ajoute une nouvelle directive qui génère le document à @@ -80,6 +121,9 @@ l'aide de graphviz, et stocke l'image dans un fichier temporaire, créé dans un répertoire *tmp* (qui doit exister avant de lancer la commande). On pourrait très facilement l'ajouter à rst2odt en suivant le même principe. +Le script rst2latex génère les images en pdf, il est prévu pour être utilisé +avec `pdflatex`. + C'est tout, le langage est tellement simple que ça serait dommage de ne pas en profiter ! diff --git a/content/images/graphe.png b/content/images/graphe.png deleted file mode 100644 index 9c20f10..0000000 Binary files a/content/images/graphe.png and /dev/null differ diff --git a/content/images/graphviz/graphe.png b/content/images/graphviz/graphe.png new file mode 100644 index 0000000..cf50a38 Binary files /dev/null and b/content/images/graphviz/graphe.png differ diff --git a/content/images/graphviz/no.png b/content/images/graphviz/no.png new file mode 100644 index 0000000..da3c726 Binary files /dev/null and b/content/images/graphviz/no.png differ diff --git a/content/images/graphviz/options.png b/content/images/graphviz/options.png new file mode 100644 index 0000000..4a6805e Binary files /dev/null and b/content/images/graphviz/options.png differ diff --git a/content/resources/rst_graphviz/rst2html.py b/content/resources/rst_graphviz/rst2html.py index ab09012..953ee97 100755 --- a/content/resources/rst_graphviz/rst2html.py +++ b/content/resources/rst_graphviz/rst2html.py @@ -8,6 +8,10 @@ A minimal front end to the Docutils Publisher, producing HTML. """ +import sys +reload(sys) +sys.setdefaultencoding('utf-8') + try: import locale locale.setlocale(locale.LC_ALL, '') @@ -28,8 +32,8 @@ description = ('Generates (X)HTML documents from standalone reStructuredText ' class Graphviz(Figure): """ Generate a graphviz image """ - required_arguments = 0 - optional_arguments = 1 + required_arguments = 1 + optional_arguments = 0 final_argument_whitespace = True has_content = True @@ -38,22 +42,36 @@ class Graphviz(Figure): def run(self): - text = '\n'.join(self.content) + if self.content.count("..") == 0: + sep = -1 + text = '\n'.join(self.content) + else: + sep = self.content.index("..") + text = '\n'.join(self.content[:sep]) extension = 'png' imageFile = "tmp/%s.%s" % (hash(text), extension) if not os.path.exists(imageFile): - conversion = subprocess.Popen(['/usr/bin/dot', + conversion = subprocess.Popen(['dot', '-T', 'png', + "-Gcharset=utf8", '-o', imageFile, ], stdin=subprocess.PIPE ) - conversion.communicate(text) + try: + conversion.stdin.write("%s G { \n %s \n}" % (self.arguments[0], + text.encode("utf-8"))) + except: + pass + conversion.stdin.close() conversion.wait() self.arguments = [imageFile] self.options['scale'] = 50 - self.content = None + if sep == -1: + self.content = None + else: + self.content = self.content[sep+1:] return Figure.run(self) directives.register_directive('graphviz', Graphviz) diff --git a/content/resources/rst_graphviz/rst2latex.py b/content/resources/rst_graphviz/rst2latex.py index 9185405..615d2e5 100755 --- a/content/resources/rst_graphviz/rst2latex.py +++ b/content/resources/rst_graphviz/rst2latex.py @@ -8,6 +8,10 @@ A minimal front end to the Docutils Publisher, producing LaTeX. """ +import sys +reload(sys) +sys.setdefaultencoding('utf-8') + try: import locale locale.setlocale(locale.LC_ALL, '') @@ -19,7 +23,7 @@ import os.path from docutils.core import publish_cmdline from docutils.parsers.rst import directives -from docutils.parsers.rst.directives.images import Figure +from docutils.parsers.rst.directives.images import Figure, Image description = ('Generates LaTeX documents from standalone reStructuredText ' 'sources. ' @@ -28,11 +32,103 @@ description = ('Generates LaTeX documents from standalone reStructuredText ' ' for ' 'the full reference.') +DOT2TEX = "dot2tex" + +def processContent(node): + + if node.content.count("..") == 0: + sep = -1 + text = '\n'.join(node.content) + else: + sep = node.content.index("..") + text = '\n'.join(node.content[:sep]) + extension = 'pdf' + pdfFile = "tmp/%s.pdf" % (hash(text)) + + + if not os.path.exists(pdfFile): + conversion = subprocess.Popen(['dot', + '-T', extension, + "-Gcharset=utf8", + ], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + ) + + ps2pdf = subprocess.Popen(['ps2pdf', + "-", + pdfFile + ], + stdin = conversion.stdout + ) + conversion.stdin.write("%s G {\n" % + node.arguments[0].encode("utf-8")) + conversion.stdin.write(text.encode("utf-8")) + conversion.stdin.write("\n}") + conversion.stdin.close() + conversion.stdout.close() + + ps2pdf.wait() + conversion.wait() + if conversion.returncode != 0: + raise node.error( + 'Error in "%s" directive:\n' % node.name) + + return (sep, pdfFile) + +class GraphvizImage(Image): + """ Generate a graphviz image + """ + required_arguments = 1 + optional_arguments = 0 + final_argument_whitespace = True + + has_content = True + + option_spec = Image.option_spec.copy() + + def run(self): + + + sep, arguments = processContent(self) + self.arguments = [arguments] + self.options['scale'] = 66 + if sep == -1: + self.content = None + else: + self.content = self.content[sep+1:] + + return Image.run(self) + class Graphviz(Figure): """ Generate a graphviz image """ - required_arguments = 0 - optional_arguments = 1 + required_arguments = 1 + optional_arguments = 0 + final_argument_whitespace = True + + has_content = True + + option_spec = Figure.option_spec.copy() + + def run(self): + + sep, arguments = processContent(self) + self.arguments = [arguments] + self.options['scale'] = 66 + if sep == -1: + self.content = None + else: + self.content = self.content[sep+1:] + + return Figure.run(self) + + +class Dot2Tex(Figure): + """ Generate a graphviz image using dot2tex + """ + required_arguments = 1 + optional_arguments = 0 final_argument_whitespace = True has_content = True @@ -41,24 +137,55 @@ class Graphviz(Figure): def run(self): - text = '\n'.join(self.content) - extension = 'png' - imageFile = "tmp/%s.%s" % (hash(text), extension) - if not os.path.exists(imageFile): - conversion = subprocess.Popen(['/usr/bin/dot', - '-T', 'png', - '-o', imageFile, + if self.content.count("..") == 0: + sep = -1 + text = '\n'.join(self.content) + else: + sep = self.content.index("..") + text = '\n'.join(self.content[:sep]) + pdfFile = "tmp/%s.pdf" % (hash(text)) + texFile = "tmp/%s.tex" % (hash(text)) + + + if not os.path.exists(pdfFile): + conversion = subprocess.Popen([DOT2TEX, + '-c', + '-o', texFile, ], stdin=subprocess.PIPE ) - conversion.communicate(text) + conversion.communicate("%s G { \n %s \n}" + % (self.arguments[0], text)) conversion.wait() - self.arguments = [imageFile] - self.options['scale'] = 50 - self.content = None + ps2pdf = subprocess.Popen(['pdflatex', + '-output-directory', 'tmp', + texFile, + ], + ) + ps2pdf.wait() + if conversion.returncode != 0: + raise self.error( + 'Error in "%s" directive:\n' % self.name) + + self.arguments = [pdfFile] + self.options['scale'] = 66 + if sep == -1: + self.content = None + else: + self.content = self.content[sep+1:] + return Figure.run(self) +#try: +# # Check if dot2tex exists and register the conversion with dot2tex and +# # pdftex +# subprocess.check_call([DOT2TEX, "-V"]) +# directives.register_directive('graphviz', Dot2Tex) +# directives.register_directive('graphimg', GraphvizImage) +#except: +# # Otherwise use the old graphviz program directives.register_directive('graphviz', Graphviz) +directives.register_directive('graphimg', GraphvizImage) publish_cmdline(writer_name='latex', description=description) -- cgit v1.2.3