File: bt2sphinxurl.py

package info (click to toggle)
babeltrace2 2.1.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 42,660 kB
  • sloc: cpp: 106,162; ansic: 78,276; python: 27,115; sh: 9,053; makefile: 1,807; xml: 46
file content (110 lines) | stat: -rw-r--r-- 3,487 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2020 Philippe Proulx <pproulx@efficios.com>
#
# This file is a Sphinx extension which adds the following roles:
#
# `bt2man`:
#     A typical manual page reference, like `grep(1)`.
#
#     Example:
#
#         :bt2man:`grep(1)`
#
#     This role creates a simple inline literal node with the role's
#     text if it's not a Babeltrace 2 manual page reference, or an
#     external link to the corresponding online manual page (on
#     `babeltrace.org`) with the appropriate project's version
#     (`version` configuration entry) otherwise.
#
# `bt2link`:
#     An external link with an URL in which a specific placeholder is
#     replaced with the project's version.
#
#     The role's text follows the typical external link format, for
#     example:
#
#         Link text <https://example.com/>
#
#     Any `@ver@` in the URL is replaced with the project's version
#     (`version` configuration entry).
#
#     Example:
#
#         :bt2link:`libbabeltrace2 <https://babeltrace.org/docs/v@ver@/libbabeltrace2/>`

import re
import functools

import docutils
import docutils.nodes
import docutils.utils


def _bt2man_role(
    bt2_version, name, rawtext, text, lineno, inliner, options=None, content=None
):
    # match a manual page reference
    m = re.match(r"^([a-zA-Z0-9_.:-]+)\(([a-zA-Z0-9]+)\)$", text)

    if not m:
        msg = "Cannot parse manual page reference `{}`".format(text)
        inliner.reporter.severe(msg, line=lineno)
        return [inliner.problematic(rawtext, rawtext, msg)], [msg]

    # matched manual page and volume
    page = m.group(1)
    vol = m.group(2)

    # create nodes: `ret_node` is the node to return
    page_node = docutils.nodes.strong(rawtext, page)
    vol_node = docutils.nodes.inline(rawtext, "({})".format(vol))
    man_node = docutils.nodes.inline(rawtext, "", page_node, vol_node)
    ret_node = docutils.nodes.literal(rawtext, "", man_node)

    if page.startswith("babeltrace2"):
        # Babeltrace 2 manual page: wrap `ret_node` with an external
        # link node
        url_tmpl = "https://babeltrace.org/docs/v{ver}/man{vol}/{page}.{vol}/"
        url = url_tmpl.format(ver=bt2_version, vol=vol, page=page)
        ret_node = docutils.nodes.reference(
            rawtext, "", ret_node, internal=False, refuri=url
        )

    return [ret_node], []


def _bt2link_role(
    bt2_version, name, rawtext, text, lineno, inliner, options=None, content=None
):
    # match link text and URL
    m = re.match(r"^([^<]+) <([^>]+)>$", text)

    if not m:
        msg = "Cannot parse link template `{}`".format(text)
        inliner.reporter.severe(msg, line=lineno)
        return [inliner.problematic(rawtext, rawtext, msg)], [msg]

    link_text = m.group(1)

    # replace `@ver@` with the project's version
    url = m.group(2).replace("@ver@", bt2_version)

    # create and return an external link node
    node = docutils.nodes.reference(rawtext, link_text, internal=False, refuri=url)
    return [node], []


def _add_roles(app):
    # add the extension's roles; the role functions above expect the
    # project's version as their first parameter
    app.add_role("bt2man", functools.partial(_bt2man_role, app.config.version))
    app.add_role("bt2link", functools.partial(_bt2link_role, app.config.version))


def setup(app):
    app.connect("builder-inited", _add_roles)
    return {
        "version": app.config.version,
        "parallel_read_safe": True,
    }