Passed
Push — develop ( 2ab520...3348f4 )
by Christophe
01:09
created

pandoc_beamer_block.block()   C

Complexity

Conditions 9

Size

Total Lines 44
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 23
dl 0
loc 44
rs 6.6666
c 0
b 0
f 0
cc 9
nop 2
1
#!/usr/bin/env python
2
3
"""
4
Pandoc filter for adding beamer block on specific div.
5
"""
6
7
from panflute import Div, RawBlock, convert_text, run_filter  # type: ignore
8
9
10
def prepare(doc):
11
    """
12
    Prepare the document.
13
14
    Arguments
15
    ---------
16
    doc
17
        The pandoc document
18
    """
19
    # Prepare the definitions
20
    doc.defined = []
21
22
    # Get the meta data
23
    meta = doc.get_metadata("pandoc-beamer-block")
24
25
    if isinstance(meta, list):
26
        # Loop on all definitions
27
        for definition in meta:
28
            # Verify the definition
29
            if (
30
                isinstance(definition, dict)
31
                and "classes" in definition
32
                and isinstance(definition["classes"], list)
33
            ):
34
                definition["classes"] = frozenset(definition["classes"])
35
                definition["type"] = definition.get("type", "info")
36
                doc.defined.append(definition)
37
38
39
def latex(elem, environment, title, optional=False):
40
    """
41
    Generate the LaTeX code.
42
43
    Arguments
44
    ---------
45
    elem
46
        The current element
47
48
    environment
49
        The environment to add
50
51
    title
52
        The environment title
53
54
    optional
55
        The title optionality
56
57
    Returns
58
    -------
59
        A list of pandoc elements.
60
    """
61
    if optional:
62
        if title:
63
            return [
64
                RawBlock(f"\\begin{{{environment}}}[{title}]", "tex"),
65
                elem,
66
                RawBlock(f"\\end{{{environment}}}", "tex"),
67
            ]
68
        return [
69
            RawBlock(f"\\begin{{{environment}}}", "tex"),
70
            elem,
71
            RawBlock(f"\\end{{{environment}}}", "tex"),
72
        ]
73
    return [
74
        RawBlock(f"\\begin{{{environment}}}{{{title}}}", "tex"),
75
        elem,
76
        RawBlock(f"\\end{{{environment}}}", "tex"),
77
    ]
78
79
80
# pylint: disable=too-many-return-statements
81
def block(elem, doc):
82
    """
83
    Transform div element.
84
85
    Arguments
86
    ---------
87
    elem
88
        current element
89
    doc
90
        pandoc document
91
92
    Returns
93
    -------
94
        A list of pandoc elements or None.
95
    """
96
    if doc.format == "beamer" and isinstance(elem, Div):
97
        classes = frozenset(elem.classes)
98
99
        # Loop on all fontsize definition
100
        for definition in doc.defined:
101
            # Are the classes correct?
102
            if classes >= definition["classes"]:
103
                if "title" in elem.attributes:
104
                    title = convert_text(
105
                        elem.attributes["title"],
106
                        output_format="latex",
107
                    )
108
                else:
109
                    title = ""
110
111
                if definition["type"] == "alert":
112
                    return latex(elem, "alertblock", title)
113
                if definition["type"] == "example":
114
                    return latex(elem, "exampleblock", title)
115
                if definition["type"] in (
116
                    "theorem",
117
                    "corollary",
118
                    "definition",
119
                    "lemma",
120
                    "fact",
121
                ):
122
                    return latex(elem, definition["type"], title, True)
123
                return latex(elem, "block", title)
124
    return None
125
126
127
def main(doc=None):
128
    """
129
    Convert the pandoc document.
130
131
    Arguments
132
    ---------
133
    doc
134
        pandoc document
135
136
    Returns
137
    -------
138
        The modified pandoc document.
139
    """
140
    return run_filter(block, doc=doc, prepare=prepare)
141
142
143
if __name__ == "__main__":
144
    main()
145