• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

chdemko / pandoc-codeblock-include / 12371778081

17 Dec 2024 11:08AM CUT coverage: 93.548%. Remained the same
12371778081

push

github

chdemko
Merge tag '1.1.0.0' into develop

Publish 1.1.0.0

58 of 62 relevant lines covered (93.55%)

0.94 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.83
/src/pandoc_codeblock_include/_main.py
1
#!/usr/bin/env python
2

3
"""
4
Pandoc filter for including file in code block.
5
"""
6

7
from collections.abc import Iterable
1✔
8
from typing import Any
1✔
9

10
from panflute import CodeBlock, Doc, Element, debug, run_filters
1✔
11

12

13
def parse_include(parsed: dict[str, Any], name: str, value: str) -> None:
1✔
14
    """
15
    Extract include information from attributes.
16

17
    Arguments
18
    ---------
19
    parsed
20
        A dictionnary of attributes
21
    name
22
        attribute name
23
    value
24
        attribute value
25
    """
26
    if name == "include":
1✔
27
        try:
1✔
28
            with open(value, encoding="utf-8") as stream:
1✔
29
                file_content = stream.readlines()
1✔
30
            parsed["content"] = file_content
1✔
31
            parsed["include"] = value
1✔
32
        except OSError:
1✔
33
            debug("[WARNING] pandoc-codeblock-include: " + value + " not found")
1✔
34
        except UnicodeDecodeError:
1✔
35
            debug(
1✔
36
                "[WARNING] pandoc-codeblock-include: file "
37
                + value
38
                + " is not encoded in utf-8"
39
            )
40

41

42
def parse_start_from(parsed: dict[str, Any], name: str, value: str) -> None:
1✔
43
    """
44
    Extract startFrom information from attributes.
45

46
    Arguments
47
    ---------
48
    parsed
49
        A dictionnary of attributes
50
    name
51
        attribute name
52
    value
53
        attribute value
54
    """
55
    if name == "startFrom":
1✔
56
        try:
1✔
57
            parsed["start_from"] = int(value) - 1
1✔
58
        except ValueError:
1✔
59
            debug(
1✔
60
                "[WARNING] pandoc-codeblock-include: "
61
                + value
62
                + " is not a correct integer"
63
            )
64

65

66
def parse_end_at(parsed: dict[str, Any], name: str, value: str) -> None:
1✔
67
    """
68
    Extract information from attributes.
69

70
    Arguments
71
    ---------
72
    parsed
73
        A dictionnary of attributes
74
    name
75
        attribute name
76
    value
77
        attribute value
78
    """
79
    if name == "endAt":
1✔
80
        try:
1✔
81
            parsed["end_at"] = int(value)
1✔
82
        except ValueError:
1✔
83
            debug(
1✔
84
                "[WARNING] pandoc-codeblock-include: "
85
                + value
86
                + " is not a correct integer"
87
            )
88

89

90
def parse_attributes(items: Iterable[tuple[str, str]]) -> dict[str, str]:
1✔
91
    """
92
    Extract usefull information from attributes.
93

94
    Arguments
95
    ---------
96
    items
97
        element attributes
98

99
    Returns
100
    -------
101
    dict[str, str]
102
        a mapping containing possible 'content', 'start_from' and 'end_at'
103
    """
104
    parsed: dict[str, Any] = {}
1✔
105
    for name, value in items:
1✔
106
        parse_include(parsed, name, value)
1✔
107
        parse_start_from(parsed, name, value)
1✔
108
        parse_end_at(parsed, name, value)
1✔
109
    return parsed
1✔
110

111

112
def inject_content(elem: Element, parsed: dict[str, Any]) -> None:
1✔
113
    """
114
    Inject parsed attributes into element content.
115

116
    Arguments
117
    ---------
118
    elem
119
        Pandoc element
120
    parsed
121
        dictionnary of attributes
122
    """
123
    start_from = parsed.get("start_from", 0)
1✔
124
    end_at = parsed.get("end_at", len(parsed["content"]))
1✔
125
    text = parsed["content"][start_from:end_at]
1✔
126

127
    # inject file content in element text
128
    try:
1✔
129
        elem.text = "".join(line.decode("utf8") for line in text)
1✔
130
    except AttributeError:
1✔
131
        elem.text = "".join(text)
1✔
132
    except UnicodeDecodeError:
×
133
        debug(
×
134
            "[WARNING] pandoc-codeblock-include: file "
135
            + parsed["include"]
136
            + " is not encoded in utf-8"
137
        )
138

139

140
def clear_latex_attributes(elem: Element) -> None:
1✔
141
    """
142
    Clear LaTeX attributes.
143

144
    Arguments
145
    ---------
146
    elem
147
        current element
148
    """
149
    # Clear the attributes else latex will get a problem with the listings
150
    for attribute in ("include", "endAt"):
1✔
151
        if attribute in elem.attributes:
1✔
152
            del elem.attributes[attribute]
1✔
153

154

155
def include(elem: Element, doc: Doc) -> None:
1✔
156
    """
157
    Transform CodeBlock element.
158

159
    Arguments
160
    ---------
161
    elem
162
        current element
163
    doc
164
        pandoc document
165
    """
166
    # Is it a CodeBlock?
167
    if isinstance(elem, CodeBlock):
1✔
168
        parsed = parse_attributes(elem.attributes.items())
1✔
169
        if "content" in parsed:
1✔
170
            inject_content(elem, parsed)
1✔
171
        if doc.format in ("latex", "beamer"):
1✔
172
            clear_latex_attributes(elem)
1✔
173

174

175
def main(doc: Doc | None = None) -> Doc:
1✔
176
    """
177
    Convert the pandoc document.
178

179
    Arguments
180
    ---------
181
    doc
182
        pandoc document
183

184
    Returns
185
    -------
186
    Doc
187
        The modified pandoc document.
188
    """
189
    return run_filters([include], doc=doc)
1✔
190

191

192
if __name__ == "__main__":
1✔
193
    main()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc