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

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

 



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!

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
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
--
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