Commits

Georg Brandl committed 4a9c6fc

Added the ``extlinks`` extension.

  • Participants
  • Parent commits 84d9f9e

Comments (0)

Files changed (5)

 Release 1.0 (in development)
 ============================
 
+* Added the ``extlinks`` extension.
+
 * Allow searching for object names including the module name, like
   ``sys.argv``.
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.addons.*') or your custom ones.
 extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo',
-              'sphinx.ext.autosummary']
+              'sphinx.ext.autosummary', 'sphinx.ext.extlinks']
+
+extlinks = {'issue': ('http://bugs.python.org/issue', 'issue ')}
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']

File doc/ext/extlinks.rst

+:mod:`sphinx.ext.extlinks` -- Markup to shorten external links
+==============================================================
+
+.. module:: sphinx.ext.extlinks
+   :synopsis: Allow inserting external links with common base URLs easily.
+.. moduleauthor:: Georg Brandl
+
+.. versionadded:: 1.0
+
+
+This extension is meant to help with the common pattern of having many external
+links that point to URLs on one and the same site, e.g. links to bug trackers,
+version control web interfaces, or simply subpages in other websites.  It does
+so by providing aliases to base URLs, so that you only need to give the subpage
+name when creating a link.
+
+Let's assume that you want to include many links to issues at the Sphinx
+tracker, at :samp:`http://bitbucket.org/birkenfeld/sphinx/issue/{num}`.  Typing
+this URL again and again is tedious, so you can use :mod:`~sphinx.ext.extlinks`
+to avoid repeating yourself.
+
+The extension adds one new config value:
+
+.. confval:: extlinks
+
+   This config value must be a dictionary of external sites, mapping unique
+   short alias names to a base URL and a *prefix*.  For example, to create an
+   alias for the above mentioned issues, you would add ::
+
+      extlinks = {'issue': ('http://bitbucket.org/birkenfeld/sphinx/issue/',
+                            'issue ')}
+
+   Now, you can use the alias name as a new role, e.g. ``:issue:`123```.  This
+   then inserts a link to http://bitbucket.org/birkenfeld/sphinx/issue/123.
+
+   The link *caption* depends on the second item in the tuple, the *prefix*:
+
+   - If the prefix is ``None``, the link caption is the full URL.
+   - If the prefix is the empty string, the link caption is the partial URL
+     given in the role content (``123`` in this case.)
+   - If the prefix is a non-empty string, the link caption is the partial URL,
+     prepended by the prefix -- in the above example, the link caption would be
+     ``issue 123``.
+
+   You can also use the usual "explicit title" syntax supported by other roles
+   that generate links, i.e. ``:issue:`this issue <123>`.  In this case, the
+   *prefix* is not relevant.

File doc/extensions.rst

    ext/ifconfig
    ext/coverage
    ext/todo
+   ext/extlinks
 
 
 Third-party extensions

File sphinx/ext/extlinks.py

+# -*- coding: utf-8 -*-
+"""
+    sphinx.ext.extlinks
+    ~~~~~~~~~~~~~~~~~~~
+
+    Extension to save typing and prevent hard-coding of base URLs in the reST
+    files.
+
+    This adds a new config value called ``extlinks`` that is created like this::
+
+       extlinks = {'exmpl': ('http://example.com/', prefix), ...}
+
+    Now you can use e.g. :exmpl:`foo` in your documents.  This will create a
+    link to ``http://example.com/foo``.  The link caption depends on the
+    *prefix* value given:
+
+    - If it is ``None``, the caption will be the full URL.
+    - If it is a string (empty or not), the caption will be the prefix prepended
+      to the role content.
+
+    You can also give an explicit caption, e.g. :exmpl:`Foo <foo>`.
+
+    :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from docutils import nodes, utils
+
+from sphinx.util import split_explicit_title
+
+
+def make_link_role(base_url, prefix):
+    def role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
+        text = utils.unescape(text)
+        has_explicit_title, title, url = split_explicit_title(text)
+        # NOTE: not using urlparse.urljoin() here, to allow something like
+        # base_url = 'bugs.python.org/issue'  and  url = '1024'
+        full_url = base_url + url
+        if not has_explicit_title:
+            if prefix is None:
+                title = full_url
+            else:
+                title = prefix + url
+        pnode = nodes.reference(title, title, refuri=full_url)
+        return [pnode], []
+    return role
+
+def setup_link_roles(app):
+    for name, (base_url, prefix) in app.config.extlinks.iteritems():
+        app.add_role(name, make_link_role(base_url, prefix))
+
+def setup(app):
+    app.add_config_value('extlinks', {}, 'env')
+    app.connect('builder-inited', setup_link_roles)