source: rtems-docs/common/sphinxcontrib/bibtex/transforms.py @ aa4f8e2

5
Last change on this file since aa4f8e2 was aa4f8e2, checked in by Chris Johns <chrisj@…>, on 08/07/17 at 11:58:52

Add the sphinxcontrib.bibtex extension to the repo.

  • Property mode set to 100644
File size: 4.7 KB
Line 
1"""
2    New Doctree Transforms
3    ~~~~~~~~~~~~~~~~~~~~~~
4
5    .. autoclass:: BibliographyTransform
6        :show-inheritance:
7
8        .. autoattribute:: default_priority
9        .. automethod:: apply
10
11    .. autofunction:: node_text_transform
12
13    .. autofunction:: transform_curly_bracket_strip
14
15    .. autofunction:: transform_url_command
16"""
17
18import docutils.nodes
19import docutils.transforms
20
21from pybtex.plugin import find_plugin
22
23from sphinxcontrib.bibtex.nodes import bibliography
24
25
26def node_text_transform(node, transform):
27    """Apply transformation to all Text nodes within node."""
28    for child in node.children:
29        if isinstance(child, docutils.nodes.Text):
30            node.replace(child, transform(child))
31        else:
32            node_text_transform(child, transform)
33
34
35def transform_curly_bracket_strip(textnode):
36    """Strip curly brackets from text."""
37    text = textnode.astext()
38    if '{' in text or '}' in text:
39        text = text.replace('{', '').replace('}', '')
40        return docutils.nodes.Text(text)
41    else:
42        return textnode
43
44
45def transform_url_command(textnode):
46    """Convert '\\\\url{...}' into a proper docutils hyperlink."""
47    text = textnode.astext()
48    if '\\url' in text:
49        text1, _, text = text.partition('\\url')
50        text2, _, text3 = text.partition('}')
51        text2 = text2.lstrip(' {')
52        ref = docutils.nodes.reference(refuri=text2)
53        ref += docutils.nodes.Text(text2)
54        node = docutils.nodes.inline()
55        node += transform_url_command(docutils.nodes.Text(text1))
56        node += ref
57        node += transform_url_command(docutils.nodes.Text(text3))
58        return node
59    else:
60        return textnode
61
62
63class BibliographyTransform(docutils.transforms.Transform):
64
65    """A docutils transform to generate citation entries for
66    bibliography nodes.
67    """
68
69    # transform must be applied before references are resolved
70    default_priority = 10
71    """Priority of the transform. See
72    http://docutils.sourceforge.net/docs/ref/transforms.html
73    """
74
75    def apply(self):
76        """Transform each
77        :class:`~sphinxcontrib.bibtex.nodes.bibliography` node into a
78        list of citations.
79        """
80        env = self.document.settings.env
81        docname = env.docname
82        for bibnode in self.document.traverse(bibliography):
83            id_ = bibnode['ids'][0]
84            bibcache = env.bibtex_cache.get_bibliography_cache(
85                docname=docname, id_=id_)
86            entries = env.bibtex_cache.get_bibliography_entries(
87                docname=docname, id_=id_, warn=env.app.warn)
88            # locate and instantiate style and backend plugins
89            style = find_plugin('pybtex.style.formatting', bibcache.style)()
90            backend = find_plugin('pybtex.backends', 'docutils')()
91            # create citation nodes for all references
92            if bibcache.list_ == "enumerated":
93                nodes = docutils.nodes.enumerated_list()
94                nodes['enumtype'] = bibcache.enumtype
95                if bibcache.start >= 1:
96                    nodes['start'] = bibcache.start
97                    env.bibtex_cache.set_enum_count(
98                        env.docname, bibcache.start)
99                else:
100                    nodes['start'] = env.bibtex_cache.get_enum_count(
101                        env.docname)
102            elif bibcache.list_ == "bullet":
103                nodes = docutils.nodes.bullet_list()
104            else:  # "citation"
105                nodes = docutils.nodes.paragraph()
106            # remind: style.format_entries modifies entries in unpickable way
107            for entry in style.format_entries(entries):
108                if bibcache.list_ in ["enumerated", "bullet"]:
109                    citation = docutils.nodes.list_item()
110                    citation += backend.paragraph(entry)
111                else:  # "citation"
112                    citation = backend.citation(entry, self.document)
113                    # backend.citation(...) uses entry.key as citation label
114                    # we change it to entry.label later onwards
115                    # but we must note the entry.label now;
116                    # at this point, we also already prefix the label
117                    key = citation[0].astext()
118                    bibcache.labels[key] = bibcache.labelprefix + entry.label
119                node_text_transform(citation, transform_url_command)
120                if bibcache.curly_bracket_strip:
121                    node_text_transform(
122                        citation,
123                        transform_curly_bracket_strip)
124                nodes += citation
125                if bibcache.list_ == "enumerated":
126                    env.bibtex_cache.inc_enum_count(env.docname)
127            bibnode.replace_self(nodes)
Note: See TracBrowser for help on using the repository browser.