Re: [RFC PATCH] doc-rst: automatically convert Graphviz and SVG images

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Em Mon, 28 Nov 2016 09:47:56 +0100
Daniel Vetter <daniel@xxxxxxxx> escreveu:

> On Sun, Nov 27, 2016 at 04:02:05PM +0100, Markus Heiser wrote:
> > Replacement for the sphinx ``figure`` and ``images`` directive.
> > 
> > A image (or figure) directive which make use of the *glob* notation::
> > 
> >   .. figure::  hello.*  
> 
> For namespacing, I think we should call this kernel-figure or something
> like that. Just to make it clear that this is our thing (like kernel-doc
> and kernel-include).
> 
> > will be converted automatically with the tool chains listed below.:
> > 
> > * DOT to SVG: ``DOT(1)`` (http://www.graphviz.org) If graphviz is not
> >   available, the DOT language is inserted as literal-include.
> > 
> > * SVG to PDF:
> > 
> >   * CairoSVG (http://cairosvg.org) if installed or alternatively
> >   * ``convert(1)``: ImageMagick (https://www.imagemagick.org)
> > 
> > Signed-off-by: Markus Heiser <markus.heiser@xxxxxxxxxxx>  
> 
> Otherwise exactly what I think we should have to make .dot/.svg images as
> easy to use as possible from a doc-writer pov. Together with Mauro's patch
> to auto-detect .dot/.svg files of course. Also comes with good docs
> itself, which is always great!

Actually, after taking Markus patch, and converting the existing
files to use the new image directives, we can get rid of my
Makefile-based approach.

> 
> Acked-by: Daniel Vetter <daniel.vetter@xxxxxxxx>
> > ---
> >  Documentation/conf.py              |   2 +-
> >  Documentation/doc-guide/hello.dot  |   3 +
> >  Documentation/doc-guide/sphinx.rst |  18 ++++++
> >  Documentation/sphinx/figure.py     | 123 +++++++++++++++++++++++++++++++++++++
> >  4 files changed, 145 insertions(+), 1 deletion(-)
> >  create mode 100644 Documentation/doc-guide/hello.dot
> >  create mode 100644 Documentation/sphinx/figure.py
> > 
> > diff --git a/Documentation/conf.py b/Documentation/conf.py
> > index 1ac958c..386d792 100644
> > --- a/Documentation/conf.py
> > +++ b/Documentation/conf.py
> > @@ -34,7 +34,7 @@ from load_config import loadConfig
> >  # Add any Sphinx extension module names here, as strings. They can be
> >  # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
> >  # ones.
> > -extensions = ['kerneldoc', 'rstFlatTable', 'kernel_include', 'cdomain']
> > +extensions = ['kerneldoc', 'rstFlatTable', 'kernel_include', 'cdomain', 'figure']
> >  
> >  # The name of the math extension changed on Sphinx 1.4
> >  if major == 1 and minor > 3:
> > diff --git a/Documentation/doc-guide/hello.dot b/Documentation/doc-guide/hello.dot
> > new file mode 100644
> > index 0000000..504621d
> > --- /dev/null
> > +++ b/Documentation/doc-guide/hello.dot
> > @@ -0,0 +1,3 @@
> > +graph G {
> > +      Hello -- World
> > +}
> > diff --git a/Documentation/doc-guide/sphinx.rst b/Documentation/doc-guide/sphinx.rst
> > index 96fe7ccb..6f8fdd1 100644
> > --- a/Documentation/doc-guide/sphinx.rst
> > +++ b/Documentation/doc-guide/sphinx.rst
> > @@ -217,3 +217,21 @@ Rendered as:
> >        * .. _`last row`:
> >  
> >          - column 3
> > +
> > +Figures
> > +=======
> > +
> > +If you want to add an image on either Graphviz or SVG format, you should
> > +use Sphinx ``figure``, where the name of the image file should end with
> > +``.*``, like::
> > +
> > +  .. figure::  hello.*
> > +     :alt:    hello world
> > +
> > +     DOT's hello world example
> > +
> > +
> > +.. figure::  hello.*
> > +   :alt:    hello world
> > +
> > +   DOT's hello world example
> > diff --git a/Documentation/sphinx/figure.py b/Documentation/sphinx/figure.py
> > new file mode 100644
> > index 0000000..1aeeefa
> > --- /dev/null
> > +++ b/Documentation/sphinx/figure.py
> > @@ -0,0 +1,123 @@
> > +# -*- coding: utf-8; mode: python -*-
> > +# pylint: disable=W0141,C0113,C0103,C0325
> > +u"""
> > +    images
> > +    ~~~~~~
> > +
> > +    Replacement for the sphinx ``figure`` and ``images`` directive.
> > +
> > +    :copyright:  Copyright (C) 2016  Markus Heiser
> > +    :license:    GPL Version 2, June 1991 see Linux/COPYING for details.
> > +
> > +    List of customizations:
> > +
> > +    * generate PDF from SVG
> > +
> > +    * generate SVG / PDF from DOT files, see
> > +      http://www.graphviz.org/content/dot-language
> > +
> > +    A image (or figure) directive which make use of the *glob* notation will be
> > +    converted automatically with the tool chains listed below.:
> > +
> > +    * DOT to SVG: ``DOT(1)`` (http://www.graphviz.org) If graphviz is not
> > +      available, the DOT language is inserted as literal-include.
> > +
> > +    * SVG to PDF:
> > +
> > +      * CairoSVG (http://cairosvg.org) if installed or alternatively
> > +      * ``convert(1)``: ImageMagick (https://www.imagemagick.org)
> > +"""
> > +
> > +import os
> > +from glob import glob
> > +import subprocess
> > +
> > +from docutils import nodes
> > +from docutils.parsers.rst import directives
> > +from docutils.parsers.rst.directives import images
> > +
> > +from sphinx.directives import patches
> > +
> > +try:
> > +    import cairosvg
> > +except ImportError:
> > +    cairosvg = None
> > +
> > +def cmd_exists(cmd):
> > +    exit_code = subprocess.call(
> > +        "type " + cmd, shell = True,
> > +        stdout = subprocess.PIPE, stderr = subprocess.PIPE )
> > +    return bool(exit_code == 0)
> > +
> > +convert_exists = cmd_exists('convert')
> > +dot_exists = cmd_exists('dot')
> > +
> > +def setup(app):  # pylint: disable=W0613
> > +    directives.register_directive('figure', Figure)
> > +    directives.register_directive('image', Image)
> > +
> > +def asterix_conversions(folder, node):
> > +    if not node['uri'].endswith('.*'):
> > +        return True
> > +    name = folder + os.path.sep + os.path.splitext(node['uri'])[0]
> > +
> > +    fnames = glob(name + '.*')
> > +    if (name + '.dot' in fnames):
> > +        if not dot_exists:
> > +            with open(name + '.dot', "r") as dot:
> > +                data = dot.read()
> > +                node = nodes.literal_block(data, data)
> > +        else:
> > +            dot2svg(name)
> > +
> > +    fnames = glob(name + '.*')
> > +    if (name + '.svg' in fnames):
> > +        svg2pdf(name)
> > +    return node
> > +
> > +
> > +def dot2svg(fname):
> > +    cmd = "dot -Tsvg %s.dot" % fname
> > +    with open(fname + '.svg', "w") as svg:
> > +        exit_code = subprocess.call(
> > +            cmd, shell = True,
> > +            stdout = svg,
> > +            stderr = subprocess.PIPE )
> > +        svg.flush()
> > +    return bool(exit_code == 0)
> > +
> > +def svg2pdf(fname):
> > +
> > +    if cairosvg:
> > +        cairosvg.svg2pdf(url = fname + '.svg', write_to = fname + '.pdf')
> > +        return True
> > +
> > +    if convert_exists:
> > +        cmd = "convert %s.svg %s.pdf" % (fname, fname)
> > +        exit_code = subprocess.call(
> > +            cmd, shell = True,
> > +            stdout = subprocess.PIPE, stderr = subprocess.PIPE )
> > +        return bool(exit_code == 0)
> > +
> > +    return False
> > +
> > +class Image(images.Image):
> > +
> > +    def run(self):
> > +        result = images.Image.run(self)
> > +        if len(result) == 2 or isinstance(result[0], nodes.system_message):
> > +            return result
> > +        folder = os.path.dirname(self.state.document.current_source)
> > +        result[0] = asterix_conversions(folder, result[0])
> > +        return result
> > +
> > +class Figure(patches.Figure):
> > +
> > +    def run(self):
> > +        result = patches.Figure.run(self)
> > +        if len(result) == 2 or isinstance(result[0], nodes.system_message):
> > +            return result
> > +        folder = os.path.dirname(self.state.document.current_source)
> > +        result[0][0] = asterix_conversions(folder, result[0][0])
> > +        return result
> > +
> > -- 
> > 2.7.4
> >   
> 



Thanks,
Mauro
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux