Georges Discry avatar Georges Discry committed b1d7dac

create a new Scala domain with basic package handling

The domain currently only supports marking packages. Basic documentation is
included as well as basic acceptance testing.

A Tox configuration is included for Python 2.7 and 3.2.

Comments (0)

Files changed (14)

 
 sqltable:
    Doug Hellmann <doug.hellmann@gmail.com>
+
+scaladomain:
+   Georges Discry <georges@discry.be>
   docstrings), mark statuses and collect them in a single list
 - rubydomain: an extension for Ruby support (Sphinx 1.0 needed)
 - sadisplay: display SqlAlchemy model sadisplay_
+- scaladomain: an extension for Scala_ support (Sphinx 1.0 needed)
 - sdedit: an extension inserting sequence diagram by using Quick Sequence.
   Diagram Editor (sdedit_)
 - seqdiag: embed sequence diagrams by using seqdiag_
 
 .. _ClearQuest: http://www-01.ibm.com/software/awdtools/clearquest/
 
+.. _Scala: http://www.scala-lang.org/
+
 For contributors
 ================
 

scaladomain/CHANGES.rst

+0.1 (2012-03-03)
+================
+
+- Initial release
+- Basic support for packages

scaladomain/LICENSE

+Copyright (c) 2012 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.

scaladomain/MANIFEST.in

+include README
+include LICENSE
+include CHANGES.*
+
+recursive-include tests *
+prune tests/acceptance/_build
+
+recursive-include doc *
+prune doc/_build

scaladomain/README

+============
+Scala Domain
+============
+
+:author: Georges Discry <georges@discry.be>
+
+A Sphinx_ extension that provides a Scala_ domain.
+
+.. _Scala: http://www.scala-lang.org/
+.. _Sphinx: http://sphinx.pocoo.org/latest
+
+Installation
+============
+
+This extension can be installed from the Python Package Index::
+
+   pip install sphinxcontrib-scaladomain
+
+Alternatively, you can clone the sphinx-contrib_ repository from BitBucket and
+install the extension directly from the repository::
+
+   hg clone http://bitbucket.org/birkenfeld/sphinx-contrib
+   cd sphinx-contrib/scaladomain
+   python setup.py install
+
+.. _sphinx-contrib: http://bitbucket.org/birkenfeld/sphinx-contrib
+
+Usage
+=====
+
+Please refer to the documentation_ for further information.
+
+.. _documentation: http://packages.python.org/sphinxcontrib-scaladomain

scaladomain/doc/conf.py

+# -*- coding: utf-8 -*-
+#
+# sphinxcontrib-scaladomain documentation build configuration file, created by
+# sphinx-quickstart on Sat Mar  3 17:36:17 2012.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+from sphinxcontrib import scaladomain
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.intersphinx']
+
+# Add any paths that contain templates here, relative to this directory.
+#templates_path = []
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'sphinxcontrib-scaladomain'
+copyright = u'2012, Georges Discry'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = scaladomain.__version__
+# The full version, including alpha/beta/rc tags.
+release = scaladomain.__release__
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+modindex_common_prefix = ['sphinxcontrib.']
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = 'nature'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# 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 = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'sphinxcontrib-scaladomaindoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'sphinxcontrib-scaladomain.tex', u'sphinxcontrib-scaladomain Documentation',
+   u'Georges Discry', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+intersphinx_mapping = {
+    'sphinx': ('http://sphinx.pocoo.org', None)
+}
+
+def setup(app):
+    app.add_object_type('confval', 'confval',
+                        objname='configuration value',
+                        indextemplate='pair: %s; configuration value')

scaladomain/doc/index.rst

+.. py:module:: sphinxcontrib.scaladomain
+
+==============================================================
+:py:mod:`sphinxcontrib.scaladomain` --- Documenting Scala APIs
+==============================================================
+
+This Sphinx_ extension provides a domain for documenting Scala_ APIs.
+
+.. _Scala: http://www.scala-lang.org/
+.. _Sphinx: http://sphinx.pocoo.org/latest
+
+Getting Started
+===============
+
+Installation
+------------
+
+This extension can be installed from the Python Package Index::
+
+   pip install sphinxcontrib-scaladomain
+
+Alternatively, you can clone the sphinx-contrib_ repository from BitBucket and
+install the extension directly from the repository::
+
+   hg clone http://bitbucket.org/birkenfeld/sphinx-contrib
+   cd sphinx-contrib/scaladomain
+   python setup.py install
+
+.. _sphinx-contrib: http://bitbucket.org/birkenfeld/sphinx-contrib
+
+Configuration
+-------------
+
+Add ``sphinxcontrib.scaladomain`` to the configuration value
+:confval:`sphinx:extensions` in your :file:`conf.py` configuration file.
+
+.. confval:: scaladomain_pkgindex_common_prefix
+
+   A list of prefixes that are ignored for sorting the Scala Package Index
+   (e.g., if this is set to ``['foo.']``, then ``foo.bar`` is shown under
+   ``B``, not ``F``). This can be handy if you document a project that consists
+   of a single parent package. Works only for the HTML builder currently.
+   Default is ``[]``.
+
+Domain Markup
+=============
+
+As most Sphinx domains, the Scala domain (name **scl**) provides a number of
+*object description directives*, used to describe specific objects provided by
+packages. Each directive requires one or more signatures to provide basic
+information about what is being described, and the content should be in the
+description. The basic version makes entries in the general index; if no index
+entry is desired, you can give the directive option flag ``:noindex:``.
+
+The Scala domain also provides roles that link back to these object
+descriptions. Both directive and role names contain the domain name and the
+directive name.
+
+Describing Scala objects
+------------------------
+
+The Scala domain provides the following directives for package
+declarations:
+
+.. rst:directive:: .. scl:package:: name
+
+   This directive marks the beginning of the description of a package. It does
+   not create content.
+
+   This directive will also cause an entry in the Global Package Index.
+
+   The ``platform`` option, if present, is a comma-separated list of the
+   platforms on which the module is available. (if it is available on all
+   platforms, the option should be omitted). The keys are short identifiers;
+   examples that are in use include "IRIX", "Mac", "Windows", and "Unix". It is
+   important to use a key which has already been used when applicable.
+
+   The ``synopsis`` option should consist of one sentence describing the
+   package's purpose -- it is currently only used in the Global Package Index.
+
+   The ``deprecated`` option can be given (with no value) to mark a package as
+   deprecated; it will be designated as such in various locations then.
+
+.. rst:directive:: .. scl:currentpackage:: name
+
+   This directive tells Sphinx that the classes, objects etc. documented from
+   here are in the given package (like :rst:dir:`scl:package`),  but it will
+   not create index entries, an index in the Global Package Index, or a link
+   target for :rst:role:`scl:pkg`. This is helpful in situations where
+   documentation for things in a package is spread over multiple files or
+   sections -- one location has the :rst:dir:`scl:package` directive, the
+   others only :rst:dir:`scl:currentpackage`.
+
+Scala Signatures
+----------------
+
+Cross-referencing Scala objects
+-------------------------------
+
+The following roles refer to objects in packages and are possibly hyperlinked
+if a matching identifier is found:
+
+.. rst:role:: scl:pkg
+
+   Reference a package.
+
+Contribution
+============
+
+Please contact the author or create an issue in the `issue tracker`_ of the
+`sphinx-contrib`_ repository, if you have found any bugs or miss some
+functionality. Patches are welcome!
+
+.. _issue tracker: https://bitbucket.org/birkenfeld/sphinx-contrib/issues
+
+==================
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+

scaladomain/setup.py

+# -*- coding: utf-8 -*-
+
+from setuptools import setup, find_packages
+from sphinxcontrib import scaladomain
+import sys
+
+long_desc = '''
+This package contains the scaladomain Sphinx extension.
+
+This extension adds a Scala domain to Sphinx.
+'''
+
+requires = ['Sphinx>=1.0']
+
+extra = {}
+if sys.version_info >= (3,):
+    extra['use_2to3'] = True
+
+setup(
+    name='sphinxcontrib-scaladomain',
+    version=scaladomain.__release__,
+    url='http://bitbucket.org/birkenfeld/sphinx-contrib',
+    download_url='http://pypi.python.org/pypi/sphinxcontrib-scaladomain',
+    license='BSD',
+    author='Georges Discry',
+    author_email='georges@discry.be',
+    description='Sphinx domain for Scala APIs',
+    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',
+        'Programming Language :: Python :: 2',
+        'Programming Language :: Python :: 3',
+        'Topic :: Documentation',
+        'Topic :: Utilities',
+    ],
+    platforms='any',
+    packages=find_packages(),
+    include_package_data=True,
+    install_requires=requires,
+    namespace_packages=['sphinxcontrib'],
+    **extra
+)

scaladomain/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__)
+

scaladomain/sphinxcontrib/scaladomain.py

+# -*- coding: utf-8 -*-
+"""
+    sphinxcontrib.scaladomain
+    ~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    The Sphinx domain for documenting Scala APIs.
+
+    :copyright: (c) 2012 by Georges Discry.
+    :license: BSD, see LICENSE for more details.
+"""
+
+__version__ = '0.1'
+__release__ = '0.1a1'
+
+from docutils import nodes
+from docutils.parsers.rst import directives
+
+from sphinx import addnodes
+from sphinx.directives import ObjectDescription
+from sphinx.domains import Domain, ObjType, Index
+from sphinx.roles import XRefRole
+from sphinx.util.docfields import Field, GroupedField, TypedField
+from sphinx.util.compat import Directive
+from sphinx.util.nodes import make_refnode
+
+class ScalaPackage(Directive):
+    """Directive to mark description of a new package."""
+
+    has_content = False
+    required_arguments = 1
+    optional_arguments = 0
+    final_argument_whitespace = False
+    option_spec = {
+        'platform': lambda x: x,
+        'synopsis': lambda x: x,
+        'noindex': directives.flag,
+        'deprecated': directives.flag,
+    }
+
+    def run(self):
+        env = self.state.document.settings.env
+        pkgname = self.arguments[0].strip()
+        noindex = 'noindex' in self.options
+        env.temp_data['scl:package'] = pkgname
+        if noindex:
+            return []
+        env.domaindata['scl']['packages'][pkgname] = \
+            (env.docname, self.options.get('synopsis', ''),
+             self.options.get('platform', ''), 'deprecated' in
+             self.options)
+        # Make a duplicate entry in 'objects' to facilitate searching for the
+        # package in ScalaDomain.find_obj()
+        env.domaindata['scl']['objects'][pkgname] = \
+            (env.docname, 'package')
+        targetnode = nodes.target(ids=['package-' + pkgname])
+        self.state.document.note_explicit_target(targetnode)
+        indextext = '%s (package)' % pkgname
+        inode = addnodes.index(entries=[('single', indextext,
+                                         'package-' + pkgname, '')])
+        return [targetnode, inode]
+
+
+class ScalaCurrentPackage(Directive):
+    """Directive to mark the description of the content of a package, but
+    the links to the package won't lead here.
+    """
+
+    has_content = False
+    required_arguments = 1
+    optional_arguments = 0
+    final_argument_whitespace = False
+    option_spec = {}
+
+    def run(self):
+        env = self.state.document.settings.env
+        pkgname = self.arguments[0].strip()
+        if pkgname == 'None':
+            env.temp_data['scl:package'] = None
+        else:
+            env.temp_data['scl:package'] = pkgname
+        return []
+
+
+class ScalaXRefRole(XRefRole):
+    """Scala cross-referencing role."""
+
+    def process_link(self, env, refnode, has_explicit_title, title, target):
+        refnode['scl:package'] = env.temp_data.get('scl:package')
+        if not has_explicit_title:
+            title = title.lstrip('.') # Only has a meaning for the target
+            target = target.lstrip('~') # Only has a meaning for the title
+            # If the first character is a tilde, don't display the package part
+            # of the contents
+            if title[0:1] == '~':
+                title = title[1:]
+                dot = title.rfind('.')
+                if dot != -1:
+                    title = title[dot+1:]
+        # If the first character is a dot, search more specific namespaces
+        # first, else search builtins first
+        if target[0:1] == '.':
+            target = target[1:]
+            refnode['refspecific'] = True
+        return title, target
+
+
+class ScalaPackageIndex(Index):
+    """Index subclass to provide the Scala package index."""
+
+    name = 'pkgindex'
+    localname = 'Scala Package Index'
+    shortname = 'packages'
+
+    def generate(self, docnames=None):
+        content = {}
+        # List of prefixes to ignore
+        ignores = self.domain.env.config['scaladomain_pkgindex_common_prefix']
+        ignores = sorted(ignores, key=len, reverse=True)
+        # List of all packages, sorted by name
+        packages = sorted(self.domain.data['packages'].iteritems(),
+                          key=lambda x: x[0].lower())
+        # Sort out collapsable packages
+        prev_pkgname = ''
+        num_toplevels = 0
+        for pkgname, (docname, synopsis, platforms, deprecated) in packages:
+            if docnames and docname not in docnames:
+                continue
+
+            for ignore in ignores:
+                if pkgname.startswith(ignore):
+                    pkgname = pkgname[len(ignore):]
+                    stripped = ignore
+                    break
+            else:
+                stripped = ''
+            # The whole package name was stripped
+            if not pkgname:
+                pkgname, stripped = stripped, ''
+
+            entries = content.setdefault(pkgname[0].lower(), [])
+
+            parent = pkgname.split('.')[0]
+            if parent != pkgname:
+                # It's a child package
+                if prev_pkgname == parent:
+                    # First children package -- make parent a group head
+                    if entries:
+                        entries[-1][1] = 1
+                elif not prev_pkgname.startswith(parent):
+                    # Orphan package, add dummy entry
+                    entries.append([stripped + parent, 1, '', '', '', '', ''])
+                subtype = 2
+            else:
+                num_toplevels += 1
+                subtype = 0
+
+            qualifier = 'Deprecated' if deprecated else ''
+            entries.append([stripped + pkgname, subtype, docname,
+                        'package-' + stripped + pkgname, platforms, qualifier,
+                        synopsis])
+            prev_pkgname = pkgname
+        # Collapse only if the number of top-level packages is larger than the
+        # number of sub-packages
+        collapse = len(packages) - num_toplevels < num_toplevels
+        # Sort by first letter
+        content = sorted(content.iteritems())
+
+        return content, collapse
+
+
+class ScalaDomain(Domain):
+    """Scala language domain."""
+
+    name = 'scl'
+    label = 'Scala'
+    object_types = {
+        'package': ObjType('package', 'pkg'),
+    }
+    directives = {
+        'package': ScalaPackage,
+        'currentpackage': ScalaCurrentPackage,
+    }
+    roles = {
+        'pkg': ScalaXRefRole(),
+    }
+    initial_data = {
+        'objects': {},
+        'packages': {},
+    }
+    indices = [
+        ScalaPackageIndex,
+    ]
+
+    def clear_doc(self, docname):
+        for fullname, (fn, _) in self.data['objects'].items():
+            if fn == docname:
+                del self.data['objects'][fullname]
+        for pkgname, (fn, _, _, _) in self.data['packages'].items():
+            if fn == docname:
+                del self.data['packages'][pkgname]
+
+    def find_obj(self, env, pkgname, name, type, searchmode=0):
+        """Find a Scala object for "name", perhaps using the given package.
+        Returns a list of (name, object entry) tuples.
+        """
+
+        if not name:
+            return []
+
+        objects = self.data['objects']
+        matches = []
+
+        newname = None
+        if searchmode == 1:
+            objtypes = self.objtypes_for_role(type)
+            if objtypes is not None:
+                if pkgname and pkgname + '.' + name in objects and \
+                   objects[pkgname + '.' + name][1] in objtypes:
+                    newname = pkgname + '.' + name
+                elif name in objects and objects[name][1] in objtypes:
+                    newname = name
+                else:
+                    searchname = '.' + name
+                    matches = [(oname, objects[oname]) for oname in objects
+                               if oname.endswith(searchname)
+                               and objects[oname][1] in objtypes]
+        else:
+            # NOTE: Searching for exact match, object type not considered
+            if name in objects:
+                newname = name
+            elif type == 'pkg':
+                return []
+            elif pkgname and pkgname + '.' + name in objects:
+                newname = pkgname + '.' + name
+        if newname is not None:
+            matches.append((newname, objects[newname]))
+        return matches
+
+    def resolve_xref(self, env, fromdocname, builder, type, target, node,
+                     contnode):
+        pkgname = node.get('scl:package')
+        searchmode = 1 if node.hasattr('refspecific') else 0
+        matches = self.find_obj(env, pkgname, target, type, searchmode)
+        if not matches:
+            return None
+        elif len(matches) > 1:
+            env.warn_node(
+                'more than one target found for cross-reference '
+                '%r: %s' % (target, ', '.join(match[0] for match in matches)),
+                node)
+        name, obj = matches[0]
+
+        if obj[1] == 'package':
+            docname, synopsis, platform, deprecated = self.data['packages'][name]
+            assert docname == obj[0]
+            title = name
+            if synopsis:
+                title += ': ' + synopsis
+            if deprecated:
+                title += ' (deprecated)'
+            if platform:
+                title += ' (' + platform + ')'
+            return make_refnode(builder, fromdocname, docname,
+                                'package-' + name, contnode, title)
+        else:
+            return make_refnode(builder, fromdocname, obj[0], name,
+                                contnode, name)
+
+    def get_objects(self):
+        for pkgname, info in self.data['packages'].iteritems():
+            yield (pkgname, pkgname, 'package', info[0], 'package-' + pkgname, 0)
+        for refname, (docname, type) in self.data['objects'].iteritems():
+            yield (refname, refname, type, docname, refname, 1)
+
+
+
+def setup(app):
+    app.add_config_value('scaladomain_pkgindex_common_prefix', [], 'html')
+    app.add_domain(ScalaDomain)

scaladomain/tests/acceptance/conf.py

+# -*- coding: utf-8 -*-
+#
+# shinxcontrib-scaladomain-acceptancetest documentation build configuration file, created by
+# sphinx-quickstart on Mon Mar  5 13:50:55 2012.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+from sphinxcontrib import scaladomain
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinxcontrib.scaladomain']
+
+# Add any paths that contain templates here, relative to this directory.
+#templates_path = []
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'shinxcontrib-scaladomain-acceptancetest'
+copyright = u'2012, Georges Discry'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = scaladomain.__version__
+# The full version, including alpha/beta/rc tags.
+release = scaladomain.__release__
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = 'nature'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# 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 = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'shinxcontrib-scaladomain-acceptancetestdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'shinxcontrib-scaladomain-acceptancetest.tex', u'shinxcontrib-scaladomain-acceptancetest Documentation',
+   u'Georges Discry', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+scaladomain_pkgindex_common_prefix = ['scala.']

scaladomain/tests/acceptance/index.rst

+.. shinxcontrib-scaladomain-acceptancetest documentation master file, created by
+   sphinx-quickstart on Mon Mar  5 13:50:55 2012.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to shinxcontrib-scaladomain-acceptancetest's documentation!
+===================================================================
+
+.. scl:package:: scala
+
+Scala Package
+-------------
+
+.. scl:package:: scala.actors
+   :deprecated:
+
+Scala Actors Packages
+---------------------
+
+.. scl:package:: scala.collection
+   :synopsis: Collections
+
+Scala Collections Packages
+--------------------------
+
+.. scl:package:: scala.collection.generic
+
+Scala Generic Collections Package
+---------------------------------
+
+.. scl:package:: scala.collection.immutable
+
+Scala Immutable Collections Package
+-----------------------------------
+
+.. scl:package:: scala.collection.interfaces
+
+Scala Collection Interfaces Package
+-----------------------------------
+
+.. scl:package:: scala.collection.mutable
+
+Scala Mutable Collections Package
+---------------------------------
+
+.. scl:package:: scala.collection.parallel
+
+Scala Parallel Collections Package
+----------------------------------
+
+.. scl:package:: scala.collection.parallel.immutable
+
+Scala Parallel Immutable Collections Package
+--------------------------------------------
+
+.. scl:package:: scala.collection.parallel.mutable
+
+Scala Parallel Mutable Collections Package
+------------------------------------------
+
+.. scl:package:: scala.collection.script
+
+Scala Collection Scripts Package
+--------------------------------
+
+References
+==========
+
+- :scl:pkg:`scala`
+- :scl:pkg:`scala.actors`
+- :scl:pkg:`scala.collection`
+- :scl:pkg:`scala.collection.generic`
+- :scl:pkg:`scala.collection.immutable`
+- :scl:pkg:`scala.collection.interfaces`
+- :scl:pkg:`scala.collection.mutable`
+- :scl:pkg:`scala.collection.parallel`
+- :scl:pkg:`scala.collection.parallel.immutable`
+- :scl:pkg:`scala.collection.parallel.mutable`
+- :scl:pkg:`scala.collection.script`
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`search`
+

scaladomain/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=py27,py32
+
+[testenv]
+deps=
+    Sphinx
+commands=
+    sphinx-build -n -W -b html -d {envtmpdir}/tests/doctrees tests/acceptance {envtmpdir}/tests/html
+    sphinx-build -n -W -b linkcheck -d {envtmpdir}/doc/doctrees doc {envtmpdir}/doc/linkcheck
+    sphinx-build -n -W -b html -d {envtmpdir}/doc/doctrees doc {envtmpdir}/doc/html
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.