File: admonition.py

package info (click to toggle)
pymdown-extensions 10.13-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 7,104 kB
  • sloc: python: 60,117; javascript: 846; sh: 8; makefile: 5
file content (125 lines) | stat: -rw-r--r-- 3,616 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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
"""Admonitions."""
import xml.etree.ElementTree as etree
from .block import Block, type_html_identifier
from .. blocks import BlocksExtension
import re

RE_SEP = re.compile(r'[_-]+')


class Admonition(Block):
    """
    Admonition.

    Arguments (1 optional):
    - A title.

    Options:
    - `type` (string): Attach a single special class for styling purposes. If more are needed,
      use the built-in `attributes` options to apply as many classes as desired.

    Content:
    Detail body.
    """

    NAME = 'admonition'
    ARGUMENT = None
    OPTIONS = {
        'type': ['', type_html_identifier],
    }
    DEF_TITLE = None
    DEF_CLASS = None

    def on_validate(self, parent):
        """Handle on validate event."""

        if self.NAME != 'admonition':
            self.options['type'] = {'name': self.NAME}
            if self.DEF_TITLE:
                self.options['type']['title'] = self.DEF_TITLE
            if self.DEF_TITLE:
                self.options['type']['class'] = self.DEF_CLASS
        return True

    def on_create(self, parent):
        """Create the element."""

        # Set classes
        classes = ['admonition']
        obj = self.options['type']
        atype = def_title = class_name = ''
        if isinstance(obj, dict):
            atype = obj['name']
            class_name = obj.get('class', atype)
            def_title = obj.get('title', RE_SEP.sub(' ', class_name).title())
        elif isinstance(obj, str):
            atype = obj
            class_name = atype
            def_title = RE_SEP.sub(' ', atype).title()

        if atype and atype != 'admonition':
            classes.append(class_name)

        # Create the admonition
        el = etree.SubElement(parent, 'div', {'class': ' '.join(classes)})

        # Create the title
        title = None
        if self.argument is None:
            if atype:
                title = def_title
        elif self.argument:
            title = self.argument

        if title is not None:
            ad_title = etree.SubElement(el, 'p', {'class': 'admonition-title'})
            ad_title.text = title

        return el


class AdmonitionExtension(BlocksExtension):
    """Admonition Blocks Extension."""

    def __init__(self, *args, **kwargs):
        """Initialize."""

        self.config = {
            "types": [
                ['note', 'attention', 'caution', 'danger', 'error', 'tip', 'hint', 'warning'],
                "Generate Admonition block extensions for the given types."
            ]
        }

        super().__init__(*args, **kwargs)

    def extendMarkdownBlocks(self, md, block_mgr):
        """Extend Markdown blocks."""

        block_mgr.register(Admonition, self.getConfigs())

        # Generate an admonition subclass based on the given names.
        for obj in self.getConfig('types', []):
            if isinstance(obj, dict):
                name = obj['name']
                class_name = obj.get('class', name)
                title = obj.get('title', RE_SEP.sub(' ', class_name).title())
            else:
                name = obj
                class_name = name
                title = RE_SEP.sub(' ', class_name).title()
            subclass = RE_SEP.sub('', name).title()
            block_mgr.register(
                type(
                    subclass,
                    (Admonition,),
                    {'OPTIONS': {}, 'NAME': name, 'DEF_TITLE': title, 'DEF_CLASS': class_name}
                ),
                {}
            )


def makeExtension(*args, **kwargs):
    """Return extension."""

    return AdmonitionExtension(*args, **kwargs)