blob: 35c3b123a4c8afee7b15ac0c09d14797edbf02ca [file] [log] [blame]
Spyridon Mastorakis5897c962015-08-31 15:37:18 -07001# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
2# Based on http://doughellmann.com/2010/05/09/defining-custom-roles-in-sphinx.html
3
4"""Integration of Sphinx with Redmine.
5"""
6
7from docutils import nodes, utils
8from docutils.parsers.rst.roles import set_classes
9
10def redmine_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
11 """Link to a Redmine issue.
12
13 Returns 2 part tuple containing list of nodes to insert into the
14 document and a list of system messages. Both are allowed to be
15 empty.
16
17 :param name: The role name used in the document.
18 :param rawtext: The entire markup snippet, with role.
19 :param text: The text marked with the role.
20 :param lineno: The line number where rawtext appears in the input.
21 :param inliner: The inliner instance that called us.
22 :param options: Directive options for customization.
23 :param content: The directive content for customization.
24 """
25 try:
26 issue_num = int(text)
27 if issue_num <= 0:
28 raise ValueError
29 except ValueError:
30 msg = inliner.reporter.error(
31 'Redmine issue number must be a number greater than or equal to 1; '
32 '"%s" is invalid.' % text, line=lineno)
33 prb = inliner.problematic(rawtext, rawtext, msg)
34 return [prb], [msg]
35 app = inliner.document.settings.env.app
36 node = make_link_node(rawtext, app, 'issues', str(issue_num), options)
37 return [node], []
38
39def make_link_node(rawtext, app, type, slug, options):
40 """Create a link to a Redmine resource.
41
42 :param rawtext: Text being replaced with link node.
43 :param app: Sphinx application context
44 :param type: Link type (issue, changeset, etc.)
45 :param slug: ID of the thing to link to
46 :param options: Options dictionary passed to role func.
47 """
48 #
49 try:
50 base = app.config.redmine_project_url
51 if not base:
52 raise AttributeError
53 except AttributeError, err:
54 raise ValueError('redmine_project_url configuration value is not set (%s)' % str(err))
55 #
56 slash = '/' if base[-1] != '/' else ''
57 ref = base + slash + type + '/' + slug + '/'
58 set_classes(options)
59 node = nodes.reference(rawtext, 'Issue #' + utils.unescape(slug), refuri=ref,
60 **options)
61 return node
62
63def setup(app):
64 """Install the plugin.
65
66 :param app: Sphinx application context.
67 """
68 app.add_role('issue', redmine_role)
69 app.add_config_value('redmine_project_url', None, 'env')
70 return