Commits

Mark Story  committed 42f00c2 Merge

Merging with upstream

  • Participants
  • Parent commits 65b53a3, 9b9e8f5

Comments (0)

Files changed (107)

 6da7f29db01597728c377764f245ba4d895cadf3 spelling-0.2
 bb84b0519b19ee4fe3f959f602b99ae1573f109a blockdiag-0.7.0
 ff2a57ae39a45c886ebd8965e3fff96048c9ec6f doxylink-1.1
+10d03cc086cca29808e4d11a7af5c18adac5f8d6 blockdiag-0.7.1
+04a09127f2c64654e86696671f02bcf743d4d182 issuetracker-0.7.2
+63319595dba1f10ddfdef6cb2d8af56df46233d8 programoutput-0.4.1
+c89fc5f3fa40437ad3867dc72ceb5eaf56337820 plantuml-0.1
+026d48070cdb1cd6f794c073ab494523b2397136 blockdiag-0.7.2
+7289d79c921ee24dc0a9349a23601fce9db85733 sphinxcontrib-1.0
+7289d79c921ee24dc0a9349a23601fce9db85733 sphinxcontrib-1.0
+d2191ad4fce1a53509c4419b75ce427a09f6c84e sphinxcontrib-1.0
+e75d87a3282821b708ccb7adb700c8380b9cf7d4 0.8.0
+461fa170a9f410a4b161d2f58439b54d1a3a12c6 blockdiag-0.8.1
+e75d87a3282821b708ccb7adb700c8380b9cf7d4 0.8.0
+0000000000000000000000000000000000000000 0.8.0
+e75d87a3282821b708ccb7adb700c8380b9cf7d4 blockdiag-0.8.0
+3485321726923e7b8d347a57dbac587dbffee8bb actdiag-0.1.0
+06c6e6bc5b4cd2b3d0dce4018625c66b94234aad seqdiag-0.1.0
 
 spelling:
    Doug Hellmann <doug.hellmann@gmail.com>
+
+sadisplay:
+   Evgeniy Tatarkin <tatarkin.evg@gmail.com>
+
+blockdiag:
+   Takeshi KOMIYA <i.tkomiya@gmail.com>
+
+seqdiag:
+   Takeshi KOMIYA <i.tkomiya@gmail.com>
+
+actdiag:
+   Takeshi KOMIYA <i.tkomiya@gmail.com>
+
+nwdiag:
+   Takeshi KOMIYA <i.tkomiya@gmail.com>
+
+requirements:
+   Andrey Mikhaylenko <neithere@gmail.com>
 - omegat: support tools to collaborate with OmegaT_ (Sphinx 1.1 needed)
 - plantuml: embed UML diagram by using PlantUML_
 - spelling: Spelling checker using PyEnchant_
+- sadisplay: display SqlAlchemy model sadisplay_
+- blockdiag: embed block diagrams by using blockdiag_
+- seqdiag: embed sequence diagrams by using seqdiag_
+- actdiag: embed activity diagrams by using actdiag_
+- nwdiag: embed network diagrams by using nwdiag_
+- requirements: declare requirements wherever you need (e.g. in test
+  docstrings), mark statuses and collect them in a single list 
 
 .. _aafigure: http://docutils.sourceforge.net/sandbox/aafigure/
 
 
 .. _PyEnchant: http://www.rfk.id.au/software/pyenchant/
 
+.. _sadisplay: http://bitbucket.org/estin/sadisplay/wiki/Home
+
+.. _blockdiag: http://blockdiag.com/
+
+.. _seqdiag: http://blockdiag.com/
+
+.. _actdiag: http://blockdiag.com/
+
+.. _nwdiag: http://blockdiag.com/
+
+
 For contributors
 ================
 

File actdiag/AUTHORS

+Takeshi KOMIYA <i.tkomiya@gmail.com>

File actdiag/LICENSE

+If not otherwise noted, the extensions in this package are licensed
+under the following license.
+
+Copyright (c) 2009 by the contributors (see AUTHORS file).
+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.

File actdiag/MANIFEST.in

+include AUTHORS
+include LICENSE
+include README
+include CHANGES.*

File actdiag/README

+actdiag extension README
+========================
+This is a sphinx extension which render block diagrams by using
+`actdiag <http://bitbucket.org/tk0miya/actdiag/>`_ .
+
+rendered:
+
+.. actdiag::
+
+   diagram {
+     A -> B -> C -> D;
+
+     lane {
+       A; B;
+     }
+     lane {
+       C; D;
+     }
+   }
+
+source:
+
+.. code-block:: text
+
+   .. actdiag::
+
+      diagram {
+        A -> B -> C -> D;
+
+        lane {
+          A; B;
+        }
+        lane {
+          C; D;
+        }
+      }
+
+Setting
+=======
+.. You can see available package at `PyPI <http://pypi.python.org/pypi/sphinxcontrib-actdiag>`_.
+
+You can get archive file at http://bitbucket.org/birkenfeld/sphinx-contrib/
+
+Required components
+-------------------
+* `actdiag <http://bitbucket.org/tk0miya/actdiag>`_ .
+
+Install
+-------
+
+.. code-block:: bash
+
+   > easy_install sphinxcontrib-actdiag
+
+
+Configure Sphinx
+----------------
+To enable this extension, add ``sphinxcontrib.actdiag`` module to extensions 
+option at :file:`conf.py`. 
+
+.. code-block:: python
+
+   import os, sys
+
+   # Path to the folder where actdiag.py is
+   # NOTE: not needed if the package is installed in traditional way
+   # using setup.py or easy_install
+   sys.path.append(os.path.abspath('/path/to/sphinxcontrib.actdiag'))
+
+   # Enabled extensions
+   extensions = ['sphinxcontrib.actdiag']
+
+
+Directive
+=========
+
+.. describe:: .. actdiag:: [filename]
+
+   This directive insert a block diagram into the generated document.
+   If filename is specified, sphinx reads external file as source script of blockfile.
+   In another case, actdiag directive takes code block as source script.
+
+   Examples::
+
+      .. actdiag:: foobar.diag
+
+      .. actdiag::
+
+         diagram {
+            // some diagrams are here.
+         }
+
+
+Configuration File Options
+==========================
+
+.. confval:: actdiag_fontpath
+
+   This is a path for renderring fonts. You can use truetype font (.ttf) file path.
+
+.. confval:: actdiag_antialias
+
+   If :confval:`actdiag_antialias: is True, actdiag generates images
+   with anti-alias filter.
+
+
+Repository
+==========
+This code is hosted by Bitbucket.
+
+  http://bitbucket.org/birkenfeld/sphinx-contrib/

File actdiag/setup.cfg

+[egg_info]
+;tag_build = dev
+;tag_date = true
+
+[aliases]
+release = egg_info -RDb ''

File actdiag/setup.py

+# -*- coding: utf-8 -*-
+
+from setuptools import setup, find_packages
+
+long_desc = '''
+This package contains the actdiag Sphinx extension.
+
+.. _Sphinx: http://sphinx.pocoo.org/
+.. _blockdiag: http://tk0miya.bitbucket.org/blockdiag/build/html/index.html
+
+This extension enable you to insert activity diagrams in your Sphinx document.
+Following code is sample::
+
+   .. actdiag::
+
+      diagram {
+        A -> B -> C -> D;
+
+        lane {
+          A; B;
+        }
+        lane {
+          C; D;
+        }
+      }
+
+
+This module needs actdiag_.
+'''
+
+requires = ['actdiag>=0.1.5', 'Sphinx>=0.6']
+
+setup(
+    name='sphinxcontrib-actdiag',
+    version='0.1.0',
+    url='http://bitbucket.org/birkenfeld/sphinx-contrib',
+    download_url='http://pypi.python.org/pypi/sphinxcontrib-actdiag',
+    license='BSD',
+    author='Takeshi Komiya',
+    author_email='i.tkomiya@gmail.com',
+    description='Sphinx "actdiag" extension',
+    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'],
+)

File actdiag/sphinxcontrib/__init__.py

+# -*- 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__)
+

File actdiag/sphinxcontrib/actdiag.py

+# -*- coding: utf-8 -*-
+"""
+    actdiag.sphinx_ext
+    ~~~~~~~~~~~~~~~~~~~~
+
+    Allow actdiag-formatted diagrams to be included in Sphinx-generated
+    documents inline.
+
+    :copyright: Copyright 2010 by Takeshi Komiya.
+    :license: BSDL.
+"""
+
+import posixpath
+import os
+import codecs
+try:
+    from hashlib import sha1 as sha
+except ImportError:
+    from sha import sha
+
+from docutils import nodes
+from docutils.parsers.rst import directives
+
+from sphinx.errors import SphinxError
+from sphinx.util.osutil import ensuredir, ENOENT, EPIPE
+from sphinx.util.compat import Directive
+
+from actdiag_sphinxhelper import diagparser, builder, DiagramDraw
+
+
+class ActdiagError(SphinxError):
+    category = 'Actdiag error'
+
+
+class actdiag(nodes.General, nodes.Element):
+    pass
+
+
+class Actdiag(Directive):
+    """
+    Directive to insert arbitrary dot markup.
+    """
+    has_content = True
+    required_arguments = 0
+    optional_arguments = 1
+    final_argument_whitespace = False
+    option_spec = {
+        'alt': directives.unchanged,
+        'desctable': directives.flag,
+        'maxwidth': directives.nonnegative_int,
+    }
+
+    def run(self):
+        if self.arguments:
+            document = self.state.document
+            if self.content:
+                return [document.reporter.warning(
+                    'actdiag directive cannot have both content and '
+                    'a filename argument', line=self.lineno)]
+            env = self.state.document.settings.env
+            rel_filename, filename = relfn2path(env, self.arguments[0])
+            env.note_dependency(rel_filename)
+            try:
+                fp = codecs.open(filename, 'r', 'utf-8')
+                try:
+                    dotcode = fp.read()
+                finally:
+                    fp.close()
+            except (IOError, OSError):
+                return [document.reporter.warning(
+                    'External actdiag file %r not found or reading '
+                    'it failed' % filename, line=self.lineno)]
+        else:
+            dotcode = '\n'.join(self.content)
+            if not dotcode.strip():
+                return [self.state_machine.reporter.warning(
+                    'Ignoring "actdiag" directive without content.',
+                    line=self.lineno)]
+
+        node = actdiag()
+        node['code'] = dotcode
+        node['options'] = {}
+        if 'alt' in self.options:
+            node['alt'] = self.options['alt']
+        if 'maxwidth' in self.options:
+            node['options']['maxwidth'] = self.options['maxwidth']
+        if 'desctable' in self.options:
+            node['options']['desctable'] = self.options['desctable']
+        return [node]
+
+
+# compatibility to sphinx 1.0 (ported from sphinx trunk)
+def relfn2path(env, filename, docname=None):
+    if filename.startswith('/') or filename.startswith(os.sep):
+        rel_fn = filename[1:]
+    else:
+        docdir = os.path.dirname(env.doc2path(docname or env.docname,
+                                              base=None))
+        rel_fn = os.path.join(docdir, filename)
+    try:
+        return rel_fn, os.path.join(env.srcdir, rel_fn)
+    except UnicodeDecodeError:
+        # the source directory is a bytestring with non-ASCII characters;
+        # let's try to encode the rel_fn in the file system encoding
+        enc_rel_fn = rel_fn.encode(sys.getfilesystemencoding())
+        return rel_fn, os.path.join(env.srcdir, enc_rel_fn)
+
+
+def get_image_filename(self, code, format, options, prefix='actdiag'):
+    """
+    Get path of output file.
+    """
+    if format not in ('PNG', 'PDF'):
+        raise ActdiagError('actdiag error:\nunknown format: %s\n' % format)
+
+    if format == 'PDF':
+        try:
+            import reportlab
+        except ImportError:
+            msg = 'actdiag error:\n' + \
+                  'colud not output PDF format; Install reportlab\n'
+            raise ActdiagError(msg)
+
+    hashkey = code.encode('utf-8') + str(options)
+    fname = '%s-%s.%s' % (prefix, sha(hashkey).hexdigest(), format.lower())
+    if hasattr(self.builder, 'imgpath'):
+        # HTML
+        relfn = posixpath.join(self.builder.imgpath, fname)
+        outfn = os.path.join(self.builder.outdir, '_images', fname)
+    else:
+        # LaTeX
+        relfn = fname
+        outfn = os.path.join(self.builder.outdir, fname)
+
+    if os.path.isfile(outfn):
+        return relfn, outfn
+
+    ensuredir(os.path.dirname(outfn))
+
+    return relfn, outfn
+
+
+def create_actdiag(self, code, format, filename, options, prefix='actdiag'):
+    """
+    Render actdiag code into a PNG output file.
+    """
+    fontpath = self.builder.config.actdiag_fontpath
+    if fontpath and not hasattr(self.builder, '_actdiag_fontpath_warned'):
+        if not os.path.isfile(fontpath):
+            self.builder.warn('actdiag cannot load "%s" as truetype font, '
+                              'check the actdiag_path setting' % fontpath)
+            self.builder._actdiag_fontpath_warned = True
+
+    draw = None
+    try:
+        tree = diagparser.parse(diagparser.tokenize(code))
+        screen = builder.ScreenNodeBuilder.build(tree)
+
+        antialias = self.builder.config.actdiag_antialias
+        draw = DiagramDraw.DiagramDraw(format, screen, filename, font=fontpath,
+                                       antialias=antialias)
+    except Exception, e:
+        raise ActdiagError('actdiag error:\n%s\n' % e)
+
+    return draw
+
+
+def render_dot_html(self, node, code, options, prefix='actdiag',
+                    imgcls=None, alt=None):
+    has_thumbnail = False
+    try:
+        format = 'PNG'
+        relfn, outfn = get_image_filename(self, code, format, options, prefix)
+
+        image = create_actdiag(self, code, format, outfn, options, prefix)
+        if not os.path.isfile(outfn):
+            image.draw()
+            image.save()
+
+        # generate description table
+        descriptions = []
+        if 'desctable' in options:
+            for n in image.screen.nodes:
+                if n.description:
+                    descriptions.append((n.id, n.numbered, n.description))
+
+        # generate thumbnails
+        image_size = image.drawer.image.size
+        if 'maxwidth' in options and options['maxwidth'] < image_size[0]:
+            has_thumbnail = True
+            thumb_prefix = prefix + '_thumb'
+            trelfn, toutfn = get_image_filename(self, code, format,
+                                                options, thumb_prefix)
+
+            thumb_size = (options['maxwidth'], image_size[1])
+            if not os.path.isfile(toutfn):
+                image.draw()
+                image.save(toutfn, thumb_size)
+            thumb_size = image.drawer.image.size
+
+    except ActdiagError, exc:
+        self.builder.warn('dot code %r: ' % code + str(exc))
+        raise nodes.SkipNode
+
+    self.body.append(self.starttag(node, 'p', CLASS='actdiag'))
+    if relfn is None:
+        self.body.append(self.encode(code))
+    else:
+        if alt is None:
+            alt = node.get('alt', self.encode(code).strip())
+
+        imgtag_format = '<img src="%s" alt="%s" width="%s" height="%s" />\n'
+        if has_thumbnail:
+            self.body.append('<a href="%s">' % relfn)
+            self.body.append(imgtag_format %
+                             (trelfn, alt, thumb_size[0], thumb_size[1]))
+            self.body.append('</a>')
+        else:
+            self.body.append(imgtag_format %
+                             (relfn, alt, image_size[0], image_size[1]))
+
+    if descriptions:
+        numbered = [x for x in descriptions if x[1]]
+
+        self.body.append('<table border="1" class="docutils">')
+        self.body.append('<thead valign="bottom">')
+        if numbered:
+            self.body.append('<tr><th class="head">No</th><th class="head">Name</th><th class="head">Description</th></tr>')
+        else:
+            self.body.append('<tr><th class="head">Name</th><th class="head">Description</th></tr>')
+        self.body.append('</thead>')
+        self.body.append('<tbody valign="top">')
+
+        if numbered:
+            def cmp_number(a, b):
+                if a[1]:
+                    n1 = int(a[1])
+                else:
+                    n1 = 0
+
+                if b[1]:
+                    n2 = int(b[1])
+                else:
+                    n2 = 0
+
+                return cmp(n1, n2)
+
+            descriptions.sort(cmp_number)
+
+        for desc in descriptions:
+            id, number, text = desc
+            self.body.append('<tr>')
+            if numbered:
+                if number is not None:
+                    self.body.append('<td>%s</td>' % number)
+                else:
+                    self.body.append('<td></td>')
+            self.body.append('<td>%s</td>' % id)
+            self.body.append('<td>%s</td>' % text)
+            self.body.append('</tr>')
+
+        self.body.append('</tbody>')
+        self.body.append('</table>')
+
+    self.body.append('</p>\n')
+    raise nodes.SkipNode
+
+
+def html_visit_actdiag(self, node):
+    render_dot_html(self, node, node['code'], node['options'])
+
+
+def render_dot_latex(self, node, code, options, prefix='actdiag'):
+    try:
+        format = self.builder.config.actdiag_tex_image_format
+        fname, outfn = get_image_filename(self, code, format, options, prefix)
+
+        image = create_actdiag(self, code, format, outfn, options, prefix)
+        if not os.path.isfile(outfn):
+            image.draw()
+            image.save()
+
+    except ActdiagError, exc:
+        self.builder.warn('dot code %r: ' % code + str(exc))
+        raise nodes.SkipNode
+
+    if fname is not None:
+        self.body.append('\\par\\includegraphics{%s}\\par' % fname)
+    raise nodes.SkipNode
+
+
+def latex_visit_actdiag(self, node):
+    render_dot_latex(self, node, node['code'], node['options'])
+
+
+def setup(app):
+    app.add_node(actdiag,
+                 html=(html_visit_actdiag, None),
+                 latex=(latex_visit_actdiag, None))
+    app.add_directive('actdiag', Actdiag)
+    app.add_config_value('actdiag_fontpath', None, 'html')
+    app.add_config_value('actdiag_antialias', False, 'html')
+    app.add_config_value('actdiag_tex_image_format', 'PNG', 'html')

File actdiag/tox.ini

+## configuration for tox <http://codespeak.net/tox/>
+
+## tox automates running certain tasks within virtualenvs.  The following
+## tox configuration outlines a basic setup for running unit tests and
+## building sphinx docs in separate virtual environments.  Give it a try!
+
+[tox]
+envlist=python,doc
+
+# test running
+[testenv:python]
+deps=
+    ## if you use nose for test running
+    # nose
+    ## if you use py.test for test running
+    # pytest
+commands=
+    ## run tests with py.test
+    # py.test []
+    ## run tests with nose
+    # nose
+
+[testenv:doc]
+deps=
+    sphinx
+    # add all Sphinx extensions and other dependencies required to build your docs
+commands=
+    ## test links
+    # sphinx-build -W -b linkcheck -d {envtmpdir}/doctrees doc {envtmpdir}/linkcheck
+    ## test html output
+    # sphinx-build -W -b html -d {envtmpdir}/doctrees doc {envtmpdir}/html
+

File bitbucket/setup.py

     name=NAME,
     version=VERSION,
     url = 'http://www.doughellmann.com/projects/%s/' % NAME,
-    download_url = 'http://www.doughellmann.com/downloads/%s-%s.tar.gz' % \
-                    (NAME, VERSION),
+    #download_url = 'http://www.doughellmann.com/downloads/%s-%s.tar.gz' % \
+    #                (NAME, VERSION),
     license='BSD',
     author='Doug Hellmann',
     author_email='doug.hellmann@gmail.com',

File bitbucket/sphinxcontrib/bitbucket.py

         prb = inliner.problematic(rawtext, rawtext, msg)
         return [prb], [msg]
     app = inliner.document.settings.env.app
+    #app.info('issue %r' % text)
     node = make_link_node(rawtext, app, 'issue', str(issue_num), options)
     return [node], []
 
     :param content: The directive content for customization.
     """
     app = inliner.document.settings.env.app
+    #app.info('changeset %r' % text)
     node = make_link_node(rawtext, app, 'changeset', text, options)
     return [node], []
 
+def bbuser_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
+    """Link to a BitBucket user.
+
+    Returns 2 part tuple containing list of nodes to insert into the
+    document and a list of system messages.  Both are allowed to be
+    empty.
+
+    :param name: The role name used in the document.
+    :param rawtext: The entire markup snippet, with role.
+    :param text: The text marked with the role.
+    :param lineno: The line number where rawtext appears in the input.
+    :param inliner: The inliner instance that called us.
+    :param options: Directive options for customization.
+    :param content: The directive content for customization.
+    """
+    app = inliner.document.settings.env.app
+    #app.info('user link %r' % text)
+    ref = 'https://bitbucket.org/' + text
+    node = nodes.reference(rawtext, text, refuri=ref, **options)
+    return [node], []
+
 
 def setup(app):
     """Install the plugin.
     
     :param app: Sphinx application context.
     """
+    app.info('Initializing BitBucket plugin')
     app.add_role('bbissue', bbissue_role)
     app.add_role('bbchangeset', bbchangeset_role)
+    app.add_role('bbuser', bbuser_role)
     app.add_config_value('bitbucket_project_url', None, 'env')
     return
 

File blockdiag/AUTHORS

+Takeshi KOMIYA <i.tkomiya@gmail.com>

File blockdiag/LICENSE

+If not otherwise noted, the extensions in this package are licensed
+under the following license.
+
+Copyright (c) 2009 by the contributors (see AUTHORS file).
+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.

File blockdiag/MANIFEST.in

+include AUTHORS
+include LICENSE
 include README
 include CHANGES.*

File blockdiag/setup.py

 This module needs blockdiag_.
 '''
 
-requires = ['blockdiag>=0.6.7', 'Sphinx>=0.6']
+requires = ['blockdiag>=0.8.0', 'Sphinx>=0.6']
 
 setup(
     name='sphinxcontrib-blockdiag',
-    version='0.7.0',
+    version='0.8.1',
     url='http://bitbucket.org/birkenfeld/sphinx-contrib',
     download_url='http://pypi.python.org/pypi/sphinxcontrib-blockdiag',
     license='BSD',

File blockdiag/sphinxcontrib/blockdiag.py

 from sphinx.util.osutil import ensuredir, ENOENT, EPIPE
 from sphinx.util.compat import Directive
 
-from blockdiag_sphinxhelper import *
+from blockdiag_sphinxhelper import diagparser, builder, DiagramDraw
 
 
 class BlockdiagError(SphinxError):
 
     draw = None
     try:
-        DiagramNode.clear()
-        DiagramEdge.clear()
-        tree = parse(tokenize(code))
-        screen = ScreenNodeBuilder.build(tree)
+        tree = diagparser.parse(diagparser.tokenize(code))
+        screen = builder.ScreenNodeBuilder.build(tree)
 
         antialias = self.builder.config.blockdiag_antialias
         draw = DiagramDraw.DiagramDraw(format, screen, filename, font=fontpath,
         raise nodes.SkipNode
 
     if fname is not None:
-        self.body.append('\\includegraphics{%s}' % fname)
+        self.body.append('\\par\\includegraphics{%s}\\par' % fname)
     raise nodes.SkipNode
 
 

File cheeseshop/CHANGES

+tip
+===
+
+* Fix JavaScript to work with Chrome.
+
+
 Release 0.2
 ===========
 

File cheeseshop/sphinxcontrib/cheeseshop.py

     $('.release_info').each(function() {
       var self = this, anchor = $('a', this);
       $.getJSON(anchor.attr('href') + '/json?callback=?', function(data) {
-        anchor.remove();
+          anchor.remove();
         var ul = $('<ul>').appendTo(self);
-        $u.each(data.urls, function(url) {
-          $('<li>').append($('<a>').attr('href', url.url).text(url.filename))
-                   .appendTo(ul);
+        $.each(data.urls, function(url_id) {
+          var url=data.urls[url_id];
+          var li=$('<li>');
+          li.appendTo(ul);
+          var a=$('<a>').attr('href', url.url).text(url.filename);
+          a.appendTo(li);
         });
       });
     });

File email/MANIFEST.in

+include README
+include CHANGES.*

File email/README

+=========================
+ sphinxcontrib-email
+=========================
+
+This package contains sphinxcontrb.email, an email obfuscator for
+Sphinx-based documentation.
+
+
+Installation
+============
+
+1. ``pip install sphinxcontrib-email``
+
+Configuration
+=============
+
+1. Add ``'sphinxcontrib.email'`` to the ``extensions`` list in ``conf.py``.
+
+  ::
+
+    extensions = [ 'sphinxcontrib.email' ]
+
+
+Usage
+=====
+
+To obfuscate an email address use something like::
+
+    :email:`Name Surname <user@myplace.org>`
+    :email:`Name Surname (user@myplace.org)`
+
+Renders as "Name Surname" with the appropriate mailto link.
+
+    :email:`user@myplace.org`
+
+Renders as "user@myplace.org" with the appropriate mailto link
+
+History
+=======
+
+0.1
+  First public release.
+

File email/setup.cfg

+[egg_info]
+#tag_build = dev
+#tag_date = true
+
+[aliases]
+release = egg_info -RDb '' register bdist_egg sdist upload

File email/setup.py

+# -*- coding: utf-8 -*-
+
+from setuptools import setup, find_packages
+
+f = open('README', 'r')
+try:
+    long_desc = f.read()
+finally:
+    f.close()
+    
+requires = ['Sphinx>=0.6']
+
+setup(
+    name='sphinxcontrib-email',
+    version='0.1',
+    url='http://bitbucket.org/birkenfeld/sphinx-contrib',
+    download_url='http://pypi.python.org/pypi/sphinxcontrib-email',
+    license='BSD',
+    author='Kevin Teague',
+    author_email='kevin@bud.ca',
+    description='Sphinx email obfuscation extension',
+    long_description=long_desc,
+    zip_safe=False,
+    classifiers=[
+        'Development Status :: 3 - Alpha',
+        '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'],
+)

File email/sphinxcontrib/__init__.py

+# -*- 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__)
+

File email/sphinxcontrib/email.py

+# E-mail obfuscation role for Sphinx.
+
+from docutils import nodes
+
+# The obfuscation code was taken from
+#
+#   http://pypi.python.org/pypi/bud.nospam
+#
+# and was was released by Kevin Teague <kevin at bud ca> under
+# a BSD license.
+
+import re
+import string
+
+rot_13_trans = string.maketrans(
+    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
+    'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm'
+)
+
+def rot_13_encrypt(line):
+    """Rotate 13 encryption.
+
+    """
+    line = line.translate(rot_13_trans)
+    line = re.sub('(?=[\\"])', r'\\', line)
+    line = re.sub('\n', r'\n', line)
+    line = re.sub('@', r'\\100', line)
+    line = re.sub('\.', r'\\056', line)
+    line = re.sub('/', r'\\057', line)
+    return line
+
+def js_obfuscated_text(text):
+    """ROT 13 encryption with embedded in Javascript code to decrypt
+    in the browser.
+
+    """
+    return """<script type="text/javascript">document.write(
+              "%s".replace(/[a-zA-Z]/g,
+              function(c){
+                return String.fromCharCode(
+                (c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);}));
+                </script>""" % rot_13_encrypt(text)
+
+def js_obfuscated_mailto(email, displayname=None):
+    """ROT 13 encryption within an Anchor tag w/ a mailto: attribute
+
+    """
+    if not displayname:
+        displayname = email
+    return js_obfuscated_text("""<a href="mailto:%s">%s</a>""" % (
+        email, displayname
+    ))
+
+# -- end bud.nospam
+
+def email_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
+    """
+    Role to obfuscate e-mail addresses.
+    """
+    print 123456789, text, '\n\n'
+    text = text.decode('utf-8').encode('utf-8')
+    # Handle addresses of the form "Name <name@domain.org>"
+    if '<' in text and '>' in text:
+        name, email = text.split('<')
+        email = email.split('>')[0]
+    elif '(' in text and ')' in text:
+        name, email = text.split('(')
+        email = email.split(')')[0]
+    else:
+        name = text
+        email = name
+
+    obfuscated = js_obfuscated_mailto(email, displayname=name)
+    node = nodes.raw('', obfuscated, format='html')
+    return [node], []
+
+def setup(app):
+    app.add_role('email', email_role)
+
 README for sphinx-feed
 ======================
 
-This Sphinx extension generates an RSS feed your site containing all articles that occur therein indexed by document "Publish Date". Publish Date is supplied as document metadata. (see test suite for examples)
+This Sphinx extension generates an RSS feed your site containing all articles
+that occur therein, indexed by document date. Date is supplied as a standard
+document metadata field. (The `ReST cheat sheet`_ has one, for example, or see
+the test suite for other examples.)
 
-Licensing
-=========
-Incorporates feedgenerator.py from the Django project, licensed under the BSD license.
-Contributions by Dan MacKinlay are hereby also released under BSD license.
+Licence
+=======
+
+Incorporates feedgenerator.py from the Django project, licensed under the BSD
+license.
+
+The rest of the project is also released under the BSD licence.
+
+Contributors
+============
+
+Original version by `Dan MacKinlay`_ with contributions by `Keegan
+Carruthers-Smith`_. Contributors hereby release their code under the BSD
+license.
 
 TODO
 ====
-- inject rel="alternate" RSS links into document header pointing to the RSS feed. For now you roll your own in the template
+
+* inject rel="alternate" RSS links into document header pointing to
+  the RSS feed. For now you roll your own in the template
+* go from the irritating nose tests to the conventional and more debug-
+  friendly unittests
+
+.. _ReST cheat sheet: http://docutils.sourceforge.net/docs/user/rst/cheatsheet.txt
+.. _Dan MacKinlay: http://livingthing.org/
+.. _Keegan Carruthers-Smith: http://people.cs.uct.ac.za/~ksmith/

File feed/setup.py

 It creates an RSS feed of recently updated sphinx pages.
 '''
 
-requires = ['Sphinx>=0.6', 'python-dateutil', 'beautifulsoup<3.1', 'html5lib']
+requires = ['Sphinx>=0.6', 'python-dateutil<2', 'html5lib']
+tests_require = ['BeautifulSoup>=3.2.0', 'feedparser', 'nose']
 
 setup(
     name='feed',
     packages=find_packages(),
     include_package_data=True,
     install_requires=requires,
+    test_suite='nose.collector',
+    tests_require=tests_require,
     namespace_packages=['sphinxcontrib'],
 )

File feed/sphinxcontrib/feed/__init__.py

     """
     from sphinx.application import Sphinx
     if not isinstance(app, Sphinx): return
+    app.add_config_value('feed_title', '', 'html')
     app.add_config_value('feed_base_url', '', 'html')
     app.add_config_value('feed_description', '', 'html')
     app.add_config_value('feed_filename', 'rss.xml', 'html')
     global feed_entries
     import os.path
     
+    title = app.config.feed_title
+    if not title:
+        title = app.config.project
+
     feed_dict = {
-      'title': app.config.project,
+      'title': title,
       'link': app.config.feed_base_url,
       'feed_url': app.config.feed_base_url,
       'description': app.config.feed_description
     guid for uniqueness, plus will work in the FS without inconvenient
     characters. NB, at the moment, hour of publication is ignored.
     """
-    return quote_plus(MAGIC_SEPARATOR.join([date.isoformat(), docname]))
+    return quote_plus(MAGIC_SEPARATOR.join([date.isoformat(), docname]))

File feed/tests/root/conf.py

 master_doc = 'index'
 
 # General information about the project.
-project = u'Sphinx Syndicate <Test>'
-copyright = u'2009, Dan MacKinlay'
+project = u'Sphinx Syndicate Test'
+copyright = u'2011, ReST wranglers'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
 # Add any paths that contain custom static files (such as style sheets) here,
 # relative to this directory. They are copied after the builtin static files,
 # so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
+html_static_path = []
 
 # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
 # using the given strftime format.
 
 siteurl = 'file://' + os.path.abspath('./_build/html') #won't work in windows
 feed_base_url = siteurl
-feed_description = "The outpourings of one Dan MacKinlay"
+feed_description = "The outpourings of a Sphinx developer"
 feed_filename = 'rss.xml'
+feed_title = 'Sphinx Syndicate Test Title'
 

File feed/tests/test_build.py

 from util import test_root, raises, raises_msg, Struct,\
   ListOutput, TestApp, with_app, gen_with_app, path, with_tempdir,\
   write_file, sprint
-from sphinxcontrib.feed.path import path
+from path import path
 from BeautifulSoup import BeautifulSoup
 import feedparser
 from datetime import datetime
 
 FEED_WARNINGS = ENV_WARNINGS + "" # nothing here either yet
 
-TEMP_DOC = """:Date: 2002-08-11
-:Author: Santa
-
-blog post of irrelevant age
-===========================
-
-Has some cruft.
-
-"""
-
 def test_feed():
     app = TestApp(buildername='html', warning=feed_warnfile, cleanenv=True)  
     app.build(force_all=True, filenames=[]) #build_all misses the crucial finish signal
     # see http://www.feedparser.org/
     f = feedparser.parse(rss_path)
     yield assert_equals, f.bozo, 0 #feedparser well-formedness detection. We want this.
+    yield assert_equals, f.feed['title'], 'Sphinx Syndicate Test Title'
     entries = f.entries
     yield assert_equals, entries[0].updated_parsed[0:6], (2001, 8, 11, 13, 0, 0)
     yield assert_equals, entries[0].title, "The latest blog post"
     
     app.cleanup()
     app2.cleanup()
-
-# def test_feed_cleanup():
-#     """
-#     do it all again, but purge a file in between and see how we go
-#     """
-#     app0 = TestApp(buildername='html', warning=feed_warnfile, cleanenv=True)  
-#     srcdir = path(app0.srcdir)
-#     tmp_path = srcdir/'tmp.rst'
-#     rss_path = os.path.join(app0.outdir, 'rss.xml')
-#     app0.cleanup()
-#     del(app0)
-#     try:
-#         tmp_path_handle = tmp_path.open('w')
-#         tmp_path_handle.write(TEMP_DOC)
-#         tmp_path_handle.close()
-#         yield assert_true, tmp_path.exists()
-#         yield assert_equals, tmp_path.open().read(), TEMP_DOC
-#         # raise Exception
-#         app1 = TestApp(buildername='html', warning=feed_warnfile, cleanenv=True)  
-#         app1.build()
-#         f = feedparser.parse(rss_path)
-#         entries = f.entries
-#         yield assert_equals, entries[0].updated_parsed[0:6], (2002, 8, 11)
-#         yield assert_equals, entries[0].title, "blog post of irrelevant age"
-#         tmp_path.remove()
-#         yield assert_false, tmp_path.exists()
-#         app1 = TestApp(buildername='html', warning=feed_warnfile)  
-#         app1.build()
-#         f = feedparser.parse(rss_path)
-#         entries = f.entries
-#         yield assert_equals, entries[0].updated_parsed[0:6], (2001, 8, 11)
-#         yield assert_equals, entries[0].title, "The latest blog post"
-#     finally:
-#         pass #if tmp_path.exists(): tmp_path.remove()

File issuetracker/CHANGES.rst

+0.7.2 (Mar 10, 2011)
+====================
+
+- #13: Fixed source distribution to include tests again
+- Fixed extraction of issue state for open issues from bitbucket
+- Ignore references in inline literals and literal blocks
+
+
 0.7.1 (Jan 19, 2011)
 ====================
 

File issuetracker/CREDITS

+Credits
+-------
+
+sphinxcontrib-issuetracker is written and maintained by Sebastian Wiesner
+<lunaryorn@googlemail.com>
+
+The following people, listed alphabetically, contributed to this extension or
+supported its development otherwise:
+
+* Michael Fladischer – Integration of DebianBTS, Debian packaging, testing and
+  issue reporting
+* Denis Bilenko – Fixes to Google Code integration and error reporting
+
+Many thanks for all contributions!

File issuetracker/MANIFEST.in

 include README
 include LICENSE
 include CHANGES.*
-include test_issuetracker.py
+include tox.ini
 recursive-include sphinxcontrib *.css
 recursive-include doc *.rst *.py Makefile
+recursive-include tests *.py
 prune doc/_build

File issuetracker/doc/index.rst

 
 This extension for Sphinx_ 1.0 parses textual issue references like ``#10``,
 looks up the issue in the configured issue tracker, and includes a link to
-the issue.
+the issue.  References in inline literals and literal blocks (e.g. source code
+examples) are ignored.
 
-The extension is available under the terms of the BSD license, see LICENSE_
-for more information.
+The extension is available under the terms of the BSD license, see
+:doc:`license` for more information.
 
 
 Installation
 welcome!
 
 
+.. include:: ../CREDITS
+
+
 .. rubric:: Footnotes
 
 .. [#debianbts-problems] ``debianbts`` does not provide a standard
    :hidden:
 
    changes.rst
+   license.rst
 
 
 .. _Sphinx: http://sphinx.pocoo.org/
 .. _Sphinx issue tracker: https://bitbucket.org/birkenfeld/sphinx/issues/
-.. _lxml: http://codespeak.net/lxml
+.. _lxml: http://lxml.de
 .. _simplejson: http://pypi.python.org/pypi/simplejson/
 .. _launchpadlib: http://pypi.python.org/pypi/launchpadlib/
 .. _debianbts: https://github.com/venthur/python-debianbts
 .. _suds: https://fedorahosted.org/suds/
 .. _sphinx-contrib: https://bitbucket.org/birkenfeld/sphinx-contrib
 .. _issue tracker: https://bitbucket.org/birkenfeld/sphinx-contrib/issues/
-.. _LICENSE: https://bitbucket.org/birkenfeld/sphinx-contrib/src/tip/LICENSE

File issuetracker/doc/license.rst

+License
+=======
+
+.. literalinclude:: ../LICENSE

File issuetracker/setup.py

 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 # POSSIBILITY OF SUCH DAMAGE.
 
-
-import sys
-sys.path.insert(0, 'sphinxcontrib')
+import os
+import re
 
 from setuptools import setup, find_packages
 
-import issuetracker
 
 with open('README') as stream:
     long_desc = stream.read()
 
 
-requires = ['Sphinx>=1.0b2']
+VERSION_PATTERN = re.compile(r"__version__ = '([^']+)'")
+
+
+def read_version_number():
+    with open(os.path.join('sphinxcontrib', 'issuetracker.py')) as stream:
+        for line in stream:
+            match = VERSION_PATTERN.search(line)
+            if match:
+                return match.group(1)
+        else:
+            raise ValueError('Could not extract version number')
+
 
 setup(
     name='sphinxcontrib-issuetracker',
-    version=issuetracker.__version__,
+    version=read_version_number(),
     url='http://packages.python.org/sphinxcontrib-issuetracker',
     download_url='http://pypi.python.org/pypi/sphinxcontrib-issuetracker',
     license='BSD',
     platforms='any',
     packages=find_packages(),
     include_package_data=True,
-    install_requires=requires,
+    install_requires=['Sphinx>=1.0.7'],
     namespace_packages=['sphinxcontrib'],
 )

File issuetracker/sphinxcontrib/issuetracker.py

     .. moduleauthor::  Sebastian Wiesner  <lunaryorn@googlemail.com>
 """
 
-__version__ = '0.7.1'
+__version__ = '0.7.2'
 
 import re
 import urllib
         tree = parse(response)
     info = tree.getroot().cssselect('.issues-issue-infotable')[0]
     is_new = info.cssselect('.issue-status-new')
-    is_open = info.cssselect('.issue-stats-open')
+    is_open = info.cssselect('.issue-status-open')
     return {'uri': uri, 'closed': not (is_open or is_new)}
 
 
         if isinstance(issue_pattern, basestring):
             issue_pattern = re.compile(issue_pattern)
         for node in self.document.traverse(nodes.Text):
+            parent = node.parent
+            if isinstance(parent, (nodes.literal, nodes.FixedTextElement)):
+                # ignore inline and block literal text
+                continue
             text = unicode(node)
-            parent = node.parent
             new_nodes = []
             last_issue_ref_end = 0
             for match in issue_pattern.finditer(text):

File issuetracker/tests/test_transformer.py

 
 
 def assert_text(node, text):
+    __tracebackhide__ = True
     assert isinstance(node, nodes.Text)
     assert node.astext() == text
 
 
 def assert_xref(node, target):
+    __tracebackhide__ = True
     assert isinstance(node, pending_xref)
     assert_text(node[0], '#%s' % target)
     assert node['reftype'] == 'issue'
 
 def pytest_funcarg__doc(request):
     doc = nodes.paragraph()
-    doc.append(nodes.Text('foo #1 bar'))
-    em = nodes.emphasis()
-    em.append(nodes.Text('see #2 if you are #abc brave'))
-    doc.append(em)
     doc.settings = Mock(name='settings')
     doc.settings.language_code = ''
     doc.settings.env = request.getfuncargvalue('env')
     return doc
 
 
-def test_issues_references(doc):
-    transformer = issuetracker.IssuesReferences(doc)
-    transformer.apply()
-    assert isinstance(doc, nodes.paragraph)
-    assert doc.astext() == 'foo #1 barsee #2 if you are #abc brave'
-    assert_text(doc[0], 'foo ')
-    assert_xref(doc[1], '1')
-    assert_text(doc[2], ' bar')
-    em = doc[3]
-    assert isinstance(em, nodes.emphasis)
-    assert_text(em[0], 'see ')
-    assert_xref(em[1], '2')
-    assert_text(em[2], ' if you are #abc brave')
+class TestIssueReferences(object):
 
+    def transform(self, doc):
+        transformer = issuetracker.IssuesReferences(doc)
+        transformer.apply()
 
-def test_issues_references_too_many_groups(doc, config):
-    config.issuetracker_issue_pattern = r'(#)(\d+)'
-    transformer = issuetracker.IssuesReferences(doc)
-    with pytest.raises(ValueError) as exc_info:
-        transformer.apply()
-    error = exc_info.value
-    assert str(error) == ('issuetracker_issue_pattern must have '
-                          'exactly one group: %r' % ((u'#', u'1'),))
+    def test_reference_in_paragraph(self, doc):
+        doc.append(nodes.Text('Transformed #1 inside a normal paragraph'))
+        self.transform(doc)
+        assert_text(doc[0], 'Transformed ')
+        assert_xref(doc[1], '1')
+        assert_text(doc[2], ' inside a normal paragraph')
+
+    def test_reference_in_emphasis(self, doc):
+        em = nodes.emphasis()
+        em.append(nodes.Text('Transformed #2 inside emphasis'))
+        doc.append(em)
+        self.transform(doc)
+        assert_text(em[0], 'Transformed ')
+        assert_xref(em[1], '2')
+        assert_text(em[2], ' inside emphasis')
+
+    def test_reference_in_literal(self, doc):
+        lit = nodes.literal()
+        text = 'Not transformed #3 inside inline literal'
+        lit.append(nodes.Text(text))
+        doc.append(lit)
+        self.transform(doc)
+        assert_text(lit[0], text)
+
+    def test_reference_in_literal_block(self, doc):
+        block = nodes.literal_block()
+        text = 'Not transformed #4 inside literal block'
+        block.append(nodes.Text(text))
+        doc.append(block)
+        self.transform(doc)
+        assert_text(block[0], text)
+
+    def test_invalid_reference(self, doc):
+        text = 'Not transformed #abc inside a normal paragraph'
+        doc.append(nodes.Text(text))
+        self.transform(doc)
+        assert_text(doc[0], text)
+
+    def test_too_many_groups(self, doc, config):
+        doc.append(nodes.Text('example reference #1'))
+        config.issuetracker_issue_pattern = r'(#)(\d+)'
+        transformer = issuetracker.IssuesReferences(doc)
+        with pytest.raises(ValueError) as exc_info:
+            transformer.apply()
+        error = exc_info.value
+        assert str(error) == ('issuetracker_issue_pattern must have '
+                              'exactly one group: %r' % ((u'#', u'1'),))

File issuetracker/tox.ini

 [tox]
-envlist=python,doc
+envlist=py27,doc
 
-[testenv:python]
+[testenv]
 deps=
+    sphinx>=1.0.7
     lxml
     launchpadlib
-    mock
-    pytest
+    mock>=0.7
+    pytest>=2.0
 commands=
     py.test --junitxml={envlogdir}/tests.xml []
 
 [testenv:doc]
 deps=
-    sphinx
+    sphinx>=1.0.7
     lxml
-    sphinxcontrib-issuetracker
 commands=
     sphinx-build -W -b linkcheck -d {envtmpdir}/doctrees doc {envtmpdir}/linkcheck
     sphinx-build -W -b html -d {envtmpdir}/doctrees doc {envtmpdir}/html

File nwdiag/AUTHORS

+Takeshi KOMIYA <i.tkomiya@gmail.com>

File nwdiag/LICENSE

+If not otherwise noted, the extensions in this package are licensed
+under the following license.
+
+Copyright (c) 2009 by the contributors (see AUTHORS file).
+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.

File nwdiag/MANIFEST.in

+include AUTHORS
+include LICENSE
+include README
+include CHANGES.*

File nwdiag/README

+nwdiag extension README
+==========================
+This is a sphinx extension which render network diagrams by using
+`nwdiag <http://bitbucket.org/tk0miya/nwdiag/>`_ .
+
+rendered:
+
+.. nwdiag::
+
+   diagram {
+     network {
+       web01; web02;
+     }
+     network {
+       web01; web02; db01;
+     }
+   }
+
+source:
+
+.. code-block:: text
+
+   .. nwdiag::
+
+      diagram {
+        network {
+          web01; web02;
+        }
+        network {
+          web01; web02; db01;
+        }
+      }
+
+Setting
+=======
+.. You can see available package at `PyPI <http://pypi.python.org/pypi/sphinxcontrib-nwdiag>`_.
+
+You can get archive file at http://bitbucket.org/birkenfeld/sphinx-contrib/
+
+Required components
+-------------------
+* `nwdiag <http://bitbucket.org/tk0miya/nwdiag>`_ .
+
+Install
+-------
+
+.. code-block:: bash
+
+   > easy_install sphinxcontrib-nwdiag
+
+
+Configure Sphinx
+----------------
+To enable this extension, add ``sphinxcontrib.nwdiag`` module to extensions 
+option at :file:`conf.py`. 
+
+.. code-block:: python
+
+   import os, sys
+
+   # Path to the folder where nwdiag.py is
+   # NOTE: not needed if the package is installed in traditional way
+   # using setup.py or easy_install
+   sys.path.append(os.path.abspath('/path/to/sphinxcontrib.nwdiag'))
+
+   # Enabled extensions
+   extensions = ['sphinxcontrib.nwdiag']
+
+
+Directive
+=========
+
+.. describe:: .. nwdiag:: [filename]
+
+   This directive insert a network diagram into the generated document.
+   If filename is specified, sphinx reads external file as source script of blockfile.
+   In another case, nwdiag directive takes code block as source script.
+
+   Examples::
+
+      .. nwdiag:: foobar.diag
+
+      .. nwdiag::
+
+         diagram {
+            // some diagrams are here.
+         }
+
+
+Configuration File Options
+==========================
+
+.. confval:: nwdiag_fontpath
+
+   This is a path for renderring fonts. You can use truetype font (.ttf) file path.
+
+.. confval:: nwdiag_antialias
+
+   If :confval:`nwdiag_antialias: is True, nwdiag generates images
+   with anti-alias filter.
+
+
+Repository
+==========
+This code is hosted by Bitbucket.
+
+  http://bitbucket.org/birkenfeld/sphinx-contrib/

File nwdiag/setup.cfg

+[egg_info]
+;tag_build = dev
+;tag_date = true
+
+[aliases]
+release = egg_info -RDb ''

File nwdiag/setup.py

+# -*- coding: utf-8 -*-
+
+from setuptools import setup, find_packages
+
+long_desc = '''
+This package contains the nwdiag Sphinx extension.
+
+.. _Sphinx: http://sphinx.pocoo.org/
+.. _nwdiag: http://tk0miya.bitbucket.org/nwdiag/build/html/index.html
+
+This extension enable you to insert network diagrams in your Sphinx document.
+Following code is sample::
+
+   .. nwdiag::
+
+      diagram {
+        network {
+          web01; web02;
+        }
+        network {
+          web01; web02; db01;
+        }
+      }
+
+
+This module needs nwdiag_.
+'''
+
+requires = ['nwdiag>=0.2.3', 'Sphinx>=0.6']
+
+setup(
+    name='sphinxcontrib-nwdiag',
+    version='0.1.0',
+    url='http://bitbucket.org/birkenfeld/sphinx-contrib',
+    download_url='http://pypi.python.org/pypi/sphinxcontrib-nwdiag',
+    license='BSD',
+    author='Takeshi Komiya',
+    author_email='i.tkomiya@gmail.com',
+    description='Sphinx "nwdiag" extension',
+    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'],
+)

File nwdiag/sphinxcontrib/__init__.py

+# -*- 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__)
+

File nwdiag/sphinxcontrib/nwdiag.py

+# -*- coding: utf-8 -*-
+"""
+    nwdiag.sphinx_ext
+    ~~~~~~~~~~~~~~~~~~~~
+
+    Allow nwdiag-formatted diagrams to be included in Sphinx-generated
+    documents inline.
+
+    :copyright: Copyright 2010 by Takeshi Komiya.
+    :license: BSDL.
+"""
+
+import posixpath
+import os
+import codecs
+try:
+    from hashlib import sha1 as sha
+except ImportError:
+    from sha import sha
+
+from docutils import nodes
+from docutils.parsers.rst import directives
+
+from sphinx.errors import SphinxError
+from sphinx.util.osutil import ensuredir, ENOENT, EPIPE
+from sphinx.util.compat import Directive
+
+from nwdiag_sphinxhelper import diagparser, builder, DiagramDraw
+
+
+class NwdiagError(SphinxError):
+    category = 'Nwdiag error'
+
+
+class nwdiag(nodes.General, nodes.Element):
+    pass
+
+
+class Nwdiag(Directive):
+    """
+    Directive to insert arbitrary dot markup.
+    """
+    has_content = True
+    required_arguments = 0
+    optional_arguments = 1
+    final_argument_whitespace = False
+    option_spec = {
+        'alt': directives.unchanged,
+        'desctable': directives.flag,
+        'maxwidth': directives.nonnegative_int,
+    }
+
+    def run(self):
+        if self.arguments:
+            document = self.state.document
+            if self.content:
+                return [document.reporter.warning(
+                    'nwdiag directive cannot have both content and '
+                    'a filename argument', line=self.lineno)]
+            env = self.state.document.settings.env
+            rel_filename, filename = relfn2path(env, self.arguments[0])
+            env.note_dependency(rel_filename)
+            try:
+                fp = codecs.open(filename, 'r', 'utf-8')
+                try:
+                    dotcode = fp.read()
+                finally:
+                    fp.close()
+            except (IOError, OSError):
+                return [document.reporter.warning(
+                    'External nwdiag file %r not found or reading '
+                    'it failed' % filename, line=self.lineno)]
+        else:
+            dotcode = '\n'.join(self.content)
+            if not dotcode.strip():
+                return [self.state_machine.reporter.warning(
+                    'Ignoring "nwdiag" directive without content.',
+                    line=self.lineno)]
+
+        node = nwdiag()
+        node['code'] = dotcode
+        node['options'] = {}
+        if 'alt' in self.options:
+            node['alt'] = self.options['alt']
+        if 'maxwidth' in self.options:
+            node['options']['maxwidth'] = self.options['maxwidth']
+        if 'desctable' in self.options:
+            node['options']['desctable'] = self.options['desctable']
+        return [node]
+
+
+# compatibility to sphinx 1.0 (ported from sphinx trunk)
+def relfn2path(env, filename, docname=None):
+    if filename.startswith('/') or filename.startswith(os.sep):
+        rel_fn = filename[1:]
+    else:
+        docdir = os.path.dirname(env.doc2path(docname or env.docname,
+                                              base=None))
+        rel_fn = os.path.join(docdir, filename)
+    try:
+        return rel_fn, os.path.join(env.srcdir, rel_fn)
+    except UnicodeDecodeError:
+        # the source directory is a bytestring with non-ASCII characters;
+        # let's try to encode the rel_fn in the file system encoding
+        enc_rel_fn = rel_fn.encode(sys.getfilesystemencoding())
+        return rel_fn, os.path.join(env.srcdir, enc_rel_fn)
+
+
+def get_image_filename(self, code, format, options, prefix='nwdiag'):
+    """
+    Get path of output file.
+    """
+    if format not in ('PNG', 'PDF'):
+        raise NwdiagError('nwdiag error:\nunknown format: %s\n' % format)
+
+    if format == 'PDF':
+        try:
+            import reportlab
+        except ImportError:
+            msg = 'nwdiag error:\n' + \
+                  'colud not output PDF format; Install reportlab\n'
+            raise NwdiagError(msg)
+
+    hashkey = code.encode('utf-8') + str(options)
+    fname = '%s-%s.%s' % (prefix, sha(hashkey).hexdigest(), format.lower())
+    if hasattr(self.builder, 'imgpath'):