File: details.py

package info (click to toggle)
drgn 0.0.32-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,096 kB
  • sloc: ansic: 50,186; python: 46,462; awk: 423; makefile: 339; sh: 114
file content (85 lines) | stat: -rw-r--r-- 2,577 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
# Copyright 2017-2019 by Takeshi KOMIYA
# SPDX-License-Identifier: Apache-2.0
# From https://pypi.org/project/sphinxcontrib-details-directive/, patched to
# use the proper name for the :class: option.

from docutils import nodes
from docutils.parsers.rst import Directive, directives
from sphinx.transforms.post_transforms import SphinxPostTransform
from sphinx.util.nodes import NodeMatcher


class details(nodes.Element, nodes.General):
    pass


class summary(nodes.TextElement, nodes.General):
    pass


def visit_details(self, node):
    if node.get('opened'):
        self.body.append(self.starttag(node, 'details', open="open"))
    else:
        self.body.append(self.starttag(node, 'details'))


def depart_details(self, node):
    self.body.append('</details>')


def visit_summary(self, node):
    self.body.append(self.starttag(node, 'summary'))


def depart_summary(self, node):
    self.body.append('</summary>')


class DetailsDirective(Directive):
    required_arguments = 1
    final_argument_whitespace = True
    has_content = True
    option_spec = {
        'class': directives.class_option,
        'name': directives.unchanged,
        'open': directives.flag,
    }

    def run(self):
        admonition = nodes.container('',
                                     classes=self.options.get('class', []),
                                     opened='open' in self.options,
                                     type='details')
        textnodes, messages = self.state.inline_text(self.arguments[0],
                                                     self.lineno)
        admonition += nodes.paragraph(self.arguments[0], '', *textnodes)
        admonition += messages
        self.state.nested_parse(self.content, self.content_offset, admonition)
        self.add_name(admonition)
        return [admonition]


class DetailsTransform(SphinxPostTransform):
    default_priority = 200
    builders = ('html',)

    def run(self):
        matcher = NodeMatcher(nodes.container, type='details')
        for node in self.document.traverse(matcher):
            newnode = details(**node.attributes)
            newnode += summary('', '', *node[0])
            newnode.extend(node[1:])
            node.replace_self(newnode)


def setup(app):
    app.add_node(details, html=(visit_details, depart_details))
    app.add_node(summary, html=(visit_summary, depart_summary))
    app.add_directive('details', DetailsDirective)
    app.add_post_transform(DetailsTransform)

    return {
        'parallel_read_safe': True,
        'parallel_write_safe': True,
    }