Georg Brandl, el 24 de mayo a las 22:02 me escribiste:
> 
> Leandro Lucarella schrieb:
> > Leandro Lucarella, el 15 de mayo a las 17:45 me escribiste:
> >> Hello. I've created a tasty sphinx extension to include embeded Message
> >> Sequence Charts (MSC) using mscgen[1]. I based the plugin in the grpahviz
> >> extension (as mscgen was inspired in graphviz too =) and I hope mscgen
> >> extension can make it into sphinx, because it's a great tool and it
> >> spreading quickly (for example Doxygen alredy support msggen embeded
> >> charts, as well as graphviz graphs).
> >> 
> >> Attached is the simple module. It requires epstopdf tool for now because
> >> mscgen can't create PDFs directly yet (this is needed only if you want
> >> latex/PDF output).
> > 
> > I finished the module to support image maps for HTML output.
> > 
> > I'd like to know if there is any interest in adding this extension to
> > Sphinx, because if there is no interest I would set up a project to it (of
> > course I will love that the module would be part of Sphinx).
> 
> I'd suggest putting it into the new contrib repository.  You can have access;
> you just need to sign up at bitbucket and give me your user name.

Sounds fair. But I must warn you that I don't know anything about egs,
PYPI and easy_install, so I might need help with that.

I completed the templates generated by make-ext.py where I thought it made
sense. Are you going to generate the extensions documentation in some way?
If so, will be the README used or should I put the documentation in the
module itself?

Well, here are the results of my first try. Review is greatly appreciated
=)

BTW, my bitbucket user is 'luca'.

-- 
Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/
----------------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------------
I would drape myself in velvet if it were socially acceptable.
        -- George Constanza

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sphinx-dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/sphinx-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

# HG changeset patch
# User Leandro Lucarella <[email protected]>
# Date 1243262717 10800
# Node ID 8938137f623a1d6f687b44e03fd95d46f2d84ac3
# Parent  e4c220f6037ae10e1aedb7adfd5cf515aab6fc31
Add mscgen extension

diff -r e4c220f6037a -r 8938137f623a AUTHORS
--- a/AUTHORS	Sun May 24 19:49:32 2009 +0200
+++ b/AUTHORS	Mon May 25 11:45:17 2009 -0300
@@ -1,1 +1,5 @@
 This file lists all extensions in this package and their authors.
+
+mscgen:
+   Leandro Lucarella <[email protected]>
+
diff -r e4c220f6037a -r 8938137f623a README
--- a/README	Sun May 24 19:49:32 2009 +0200
+++ b/README	Mon May 25 11:45:17 2009 -0300
@@ -35,6 +35,7 @@
 List of extensions
 ==================
 
+* mscgen
 
 For contributors
 ================
diff -r e4c220f6037a -r 8938137f623a mscgen/CHANGES
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mscgen/CHANGES	Mon May 25 11:45:17 2009 -0300
@@ -0,0 +1,14 @@
+.. -*- restructuredtext -*-
+
+This file describes user-visible changes between the extension versions.
+
+Version 0.2
+-----------
+
+* Add image maps support for HTML output.
+
+Version 0.1
+-----------
+
+* Initial version.
+
diff -r e4c220f6037a -r 8938137f623a mscgen/LICENSE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mscgen/LICENSE	Mon May 25 11:45:17 2009 -0300
@@ -0,0 +1,25 @@
+Copyright (c) 2009 by Leandro Lucarella.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in the
+  documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff -r e4c220f6037a -r 8938137f623a mscgen/MANIFEST.in
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mscgen/MANIFEST.in	Mon May 25 11:45:17 2009 -0300
@@ -0,0 +1,3 @@
+include README
+include LICENSE
+include CHANGES
diff -r e4c220f6037a -r 8938137f623a mscgen/README
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mscgen/README	Mon May 25 11:45:17 2009 -0300
@@ -0,0 +1,94 @@
+.. -*- restructuredtext -*-
+
+=========================================================
+:abbr:`MSC (Message Sequence Chart)` extension for Sphinx
+=========================================================
+
+:copyright: Copyright 2009 by Leandro Lucarella.
+:license: BSD, see LICENSE for details.
+
+
+About
+=====
+
+This extension  allow mscgen-formatted :abbr:`MSC` diagrams to be included in
+Sphinx-generated documents inline.
+
+
+Usage
+=====
+
+The _mscgen program is used to render the :abbr:`MSC`, so you should refer
+to its documentation for details on how to specify the diagram. You should
+have the program installed for this extension to work. If you need LaTeX
+output, you'll need the _epstopdf program too.
+
+.. _mscgen: http://www.mcternan.me.uk/mscgen/
+.. _epstopdf: http://www.ctan.org/tex-archive/support/epstopdf/
+
+This extension adds the ``mscgen`` and ``msc`` directives. The former let
+you specify a full diagram, the later let you omit the ``msc { ... }``
+bits so you can jump right to the important stuff.
+
+Example
+-------
+
+The most common way to inline a :abbr:`MSC` diagram is to use the ``msc``
+directive::
+
+   .. msc::
+
+      hscale = "2";
+
+      a,b,c;
+      
+      a->b [ label = "ab()" ] ;
+      b->c [ label = "bc(TRUE)"];
+      c=>c [ label = "process()" ];
+
+If you need full control over the :abbr:`MSC` diagram you can use the
+``mscgen`` directive::
+
+   .. mscgen::
+
+      msc {
+         hscale = "2";
+
+         a,b,c;
+         
+         a->b [ label = "ab()" ] ;
+         b->c [ label = "bc(TRUE)"];
+         c=>c [ label = "process()" ];
+      }
+
+
+Configuration
+=============
+
+A few configuration options are added (all optional):
+
+``mscgen``:
+   location of the *mscgen* program. It's expected to be in the PATH by
+   default. The full path, including the binary, should be given if that's
+   not the case.
+
+``mscgen_args``:
+   extra command line arguments for *mscgen* (should be a list of
+   strings).
+
+``mscgen_epstopdf``:
+   location of the *epstopdf* program. It's expected to be in the PATH by
+   default. The full path, including the binary, should be given if that's
+   not the case.
+
+``mscgen_epstopdf_args``:
+   extra command line arguments for *epstopdf* (should be a list of
+   strings).
+
+
+Requirements
+=============
+
+* mscgen_ (tested with 0.14).
+* epstopdf_ for LaTeX/PDF output.
+
diff -r e4c220f6037a -r 8938137f623a mscgen/setup.cfg
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mscgen/setup.cfg	Mon May 25 11:45:17 2009 -0300
@@ -0,0 +1,6 @@
+[egg_info]
+tag_build = dev
+tag_date = true
+
+[aliases]
+release = egg_info -RDb ''
diff -r e4c220f6037a -r 8938137f623a mscgen/setup.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mscgen/setup.py	Mon May 25 11:45:17 2009 -0300
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+
+from setuptools import setup, find_packages
+
+long_desc = '''
+This package contains the mscgen Sphinx extension.
+
+Allow mscgen-formatted Message Sequence Chart graphs to be included in
+Sphinx-generated documents inline.
+'''
+
+requires = ['Sphinx>=0.6']
+
+setup(
+    name='mscgen',
+    version='0.2',
+    url='http://bitbucket.org/birkenfeld/sphinx-contrib',
+    download_url='http://pypi.python.org/pypi/mscgen',
+    license='BSD',
+    author='Leandro Lucarella',
+    author_email='[email protected]',
+    description='Sphinx extension mscgen',
+    long_description=long_desc,
+    zip_safe=False,
+    classifiers=[
+        'Development Status :: 4 - Beta',
+        'Environment :: Console',
+        'Environment :: Web Environment',
+        'Intended Audience :: Developers',
+        'License :: OSI Approved :: BSD License',
+        'Operating System :: OS Independent',
+        'Programming Language :: Python',
+        'Topic :: Documentation',
+        'Topic :: Utilities',
+    ],
+    platforms='any',
+    packages=find_packages(),
+    include_package_data=True,
+    install_requires=requires,
+    namespace_packages=['sphinxcontrib'],
+)
diff -r e4c220f6037a -r 8938137f623a mscgen/sphinxcontrib/__init__.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mscgen/sphinxcontrib/__init__.py	Mon May 25 11:45:17 2009 -0300
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinxcontrib
+    ~~~~~~~~~~~~~
+
+    This package is a namespace package that contains all extensions
+    distributed in the ``sphinx-contrib`` distribution.
+
+    :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+__import__('pkg_resources').declare_namespace(__name__)
+
diff -r e4c220f6037a -r 8938137f623a mscgen/sphinxcontrib/mscgen.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mscgen/sphinxcontrib/mscgen.py	Mon May 25 11:45:17 2009 -0300
@@ -0,0 +1,221 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinxcontrib.mscgen
+    ~~~~~~~~~~~~~~~~~~~~
+
+    Allow mscgen-formatted :abbr:`MSC (Message Sequence Chart)` graphs to be
+    included in Sphinx-generated documents inline.
+
+    See the README file for details.
+
+    :copyright: Copyright 2009 by Leandro Lucarella (based on \
+        sphinx.ext.graphviz).
+    :license: BSD, see LICENSE for details.
+"""
+
+import sys
+import posixpath
+from os import path
+from subprocess import Popen, PIPE
+try:
+    from hashlib import sha1 as sha
+except ImportError:
+    from sha import sha
+
+from docutils import nodes
+
+from sphinx.errors import SphinxError
+from sphinx.util import ensuredir
+from sphinx.util.compat import Directive
+
+
+class MscgenError(SphinxError):
+    category = 'mscgen error'
+
+
+class mscgen(nodes.General, nodes.Element):
+    pass
+
+
+class Mscgen(Directive):
+    """
+    Directive to insert arbitrary mscgen markup.
+    """
+    has_content = True
+    required_arguments = 0
+    optional_arguments = 0
+    final_argument_whitespace = False
+    option_spec = {}
+
+    def run(self):
+        node = mscgen()
+        node['code'] = '\n'.join(self.content)
+        node['options'] = []
+        return [node]
+
+
+class MscgenSimple(Directive):
+    """
+    Directive to insert mscgen markup that goes inside ``msc { ... }``.
+    """
+    has_content = True
+    required_arguments = 0
+    optional_arguments = 0
+    final_argument_whitespace = False
+    option_spec = {}
+
+    def run(self):
+        node = mscgen()
+        node['code'] = 'msc {\n%s\n}\n' % ('\n'.join(self.content))
+        node['options'] = []
+        return [node]
+
+
+def run_cmd(builder, cmd, cmd_name, cfg_name, stdin=''):
+    try:
+        p = Popen(cmd, stdout=PIPE, stdin=PIPE, stderr=PIPE)
+    except OSError, err:
+        if err.errno != 2:   # No such file or directory
+            raise
+        builder.warn('%s command %r cannot be run (needed for mscgen '
+                          'output), check the %s setting' %
+                          (cmd_name, builder.config.mscgen, cfg_name))
+        builder._mscgen_warned = True
+        return False
+    stdout, stderr = p.communicate(stdin)
+    if p.returncode != 0:
+        raise MscgenError('%s exited with error:\n[stderr]\n%s\n'
+                            '[stdout]\n%s' % (cmd_name, stderr, stdout))
+    return True
+
+
+def eps_to_pdf(builder, epsfn, pdffn):
+    epstopdf_args = [builder.config.mscgen_epstopdf]
+    epstopdf_args.extend(builder.config.mscgen_epstopdf_args)
+    epstopdf_args.extend(['--outfile=' + pdffn, epsfn])
+    return run_cmd(builder, epstopdf_args, 'epstopdf', 'mscgen_epstopdf')
+
+
+def get_map_code(mapfn, id):
+    mapfile = open(mapfn)
+    try:
+        lines = mapfile.readlines()
+    finally:
+        mapfile.close()
+    mapcode = '<map id="%s" name="%s">' % (id, id)
+    for line in lines:
+        (type, name, coords) = line.split(' ', 2)
+        mapcode += '<area shape="%s" href="%s" alt="" coords="%s" />' % (
+                    type, name, coords)
+    mapcode += '</map>'
+    return mapcode
+
+
+def render_msc(self, code, options, format, prefix='mscgen'):
+    """
+    Render mscgen code into a PNG or PDF output file.
+    """
+    hashkey = code.encode('utf-8') + str(options) + \
+              str(self.builder.config.mscgen_args)
+    id = sha(hashkey).hexdigest()
+    fname = '%s-%s.%s' % (prefix, id, format)
+    if hasattr(self.builder, 'imgpath'):
+        # HTML
+        relfn = posixpath.join(self.builder.imgpath, fname)
+        outfn = path.join(self.builder.outdir, '_images', fname)
+        tmpfn = outfn
+        mapfn = outfn + '.map'
+    else:
+        # LaTeX
+        relfn = fname
+        outfn = path.join(self.builder.outdir, fname)
+        format = 'eps'
+        tmpfn = outfn[:-3] + format
+
+    if path.isfile(outfn):
+        return relfn, outfn, id
+
+    if hasattr(self.builder, '_mscgen_warned'):
+        return None, None, None
+
+    ensuredir(path.dirname(outfn))
+
+    # mscgen don't support encodings very well. ISO-8859-1 seems to work best,
+    # at least for PNG.
+    if isinstance(code, unicode):
+        code = code.encode('iso-8859-1')
+
+    mscgen_args = [self.builder.config.mscgen]
+    mscgen_args.extend(self.builder.config.mscgen_args)
+    mscgen_args.extend(options)
+    mscgen_args.extend(['-T', format, '-o', tmpfn])
+    if not run_cmd(self.builder, mscgen_args, 'mscgen', 'mscgen', code):
+        return None, None, None
+
+    if format == 'png':
+        mscgen_args = mscgen_args[:-4] + ['-T', 'ismap', '-o', mapfn]
+        if not run_cmd(self.builder, mscgen_args, 'mscgen', 'mscgen', code):
+            return None, None, None
+    else: # PDF/EPS
+        if not eps_to_pdf(self.builder, tmpfn, outfn):
+            return None
+
+    return relfn, outfn, id
+
+
+def render_msc_html(self, node, code, options, prefix='mscgen', imgcls=None):
+    try:
+        fname, outfn, id = render_msc(self, code, options, 'png', prefix)
+    except MscgenError, exc:
+        self.builder.warn('mscgen code %r: ' % code + str(exc))
+        raise nodes.SkipNode
+
+    self.body.append(self.starttag(node, 'p', CLASS='mscgen'))
+    if fname is None:
+        self.body.append(self.encode(code))
+    else:
+        imgmap = get_map_code(outfn + '.map', id)
+        imgcss = imgcls and 'class="%s"' % imgcls or ''
+        if not imgmap:
+            # nothing in image map
+            self.body.append('<img src="%s" alt="%s" %s/>\n' %
+                             (fname, self.encode(code).strip(), imgcss))
+        else:
+            # has a map
+            self.body.append('<img src="%s" alt="%s" usemap="#%s" %s/>\n' %
+                             (fname, self.encode(code).strip(), id, imgcss))
+            self.body.extend(imgmap)
+    self.body.append('</p>\n')
+    raise nodes.SkipNode
+
+
+def html_visit_mscgen(self, node):
+    render_msc_html(self, node, node['code'], node['options'])
+
+
+def render_msc_latex(self, node, code, options, prefix='mscgen'):
+    try:
+        fname, outfn, id = render_msc(self, code, options, 'pdf', prefix)
+    except MscgenError, exc:
+        self.builder.warn('mscgen code %r: ' % code + str(exc))
+        raise nodes.SkipNode
+
+    if fname is not None:
+        self.body.append('\\includegraphics{%s}' % fname)
+    raise nodes.SkipNode
+
+
+def latex_visit_mscgen(self, node):
+    render_msc_latex(self, node, node['code'], node['options'])
+
+def setup(app):
+    app.add_node(mscgen,
+                 html=(html_visit_mscgen, None),
+                 latex=(latex_visit_mscgen, None))
+    app.add_directive('mscgen', Mscgen)
+    app.add_directive('msc', MscgenSimple)
+    app.add_config_value('mscgen', 'mscgen', 'html')
+    app.add_config_value('mscgen_args', [], 'html')
+    app.add_config_value('mscgen_epstopdf', 'epstopdf', 'html')
+    app.add_config_value('mscgen_epstopdf_args', [], 'html')
+

Reply via email to