Skip to content

blag.markdown

Markdown Processing.

This module contains the methods responsible for blag's markdown processing.

MarkdownLinkExtension

Bases: Extension

markdown.extension that converts relative .md- to .html-links.

Source code in blag/markdown.py
124
125
126
127
128
129
130
131
132
133
class MarkdownLinkExtension(Extension):
    """markdown.extension that converts relative .md- to .html-links."""

    def extendMarkdown(self, md: Markdown) -> None:
        """Register the MarkdownLinkTreeprocessor."""
        md.treeprocessors.register(
            MarkdownLinkTreeprocessor(md),
            "mdlink",
            0,
        )

extendMarkdown(md)

Register the MarkdownLinkTreeprocessor.

Source code in blag/markdown.py
127
128
129
130
131
132
133
def extendMarkdown(self, md: Markdown) -> None:
    """Register the MarkdownLinkTreeprocessor."""
    md.treeprocessors.register(
        MarkdownLinkTreeprocessor(md),
        "mdlink",
        0,
    )

MarkdownLinkTreeprocessor

Bases: Treeprocessor

Converts relative links to .md files to .html.

Source code in blag/markdown.py
 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
class MarkdownLinkTreeprocessor(Treeprocessor):
    """Converts relative links to .md files to .html."""

    def run(self, root: Element) -> Element:
        """Process the ElementTree."""
        for element in root.iter():
            if element.tag == "a":
                url = element.get("href")
                # element.get could also return None, we haven't seen this so
                # far, so lets wait if we raise this
                assert url is not None
                url = str(url)
                converted = self.convert(url)
                element.set("href", converted)
        return root

    def convert(self, url: str) -> str:
        """Convert relative .md-links to .html-links."""
        scheme, netloc, path, query, fragment = urlsplit(url)
        logger.debug(
            f"{url}: {scheme=} {netloc=} {path=} {query=} {fragment=}"
        )
        if scheme or netloc or not path:
            return url
        if path.endswith(".md"):
            path = path[:-3] + ".html"

        url = urlunsplit((scheme, netloc, path, query, fragment))
        return url

convert(url)

Convert relative .md-links to .html-links.

Source code in blag/markdown.py
109
110
111
112
113
114
115
116
117
118
119
120
121
def convert(self, url: str) -> str:
    """Convert relative .md-links to .html-links."""
    scheme, netloc, path, query, fragment = urlsplit(url)
    logger.debug(
        f"{url}: {scheme=} {netloc=} {path=} {query=} {fragment=}"
    )
    if scheme or netloc or not path:
        return url
    if path.endswith(".md"):
        path = path[:-3] + ".html"

    url = urlunsplit((scheme, netloc, path, query, fragment))
    return url

run(root)

Process the ElementTree.

Source code in blag/markdown.py
 96
 97
 98
 99
100
101
102
103
104
105
106
107
def run(self, root: Element) -> Element:
    """Process the ElementTree."""
    for element in root.iter():
        if element.tag == "a":
            url = element.get("href")
            # element.get could also return None, we haven't seen this so
            # far, so lets wait if we raise this
            assert url is not None
            url = str(url)
            converted = self.convert(url)
            element.set("href", converted)
    return root

convert_markdown(md, markdown)

Convert markdown into html and extract meta data.

Some meta data is treated special: * date is converted into datetime with local timezone * tags is interpreted as a comma-separeted list of strings. All strings are stripped and converted to lower case.

Parameters:

Name Type Description Default
md Markdown

the Markdown instance

required
markdown str

the markdown text that should be converted

required

Returns:

Type Description
(str, dict[str, str])

html and metadata

Source code in blag/markdown.py
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
def convert_markdown(
    md: Markdown,
    markdown: str,
) -> tuple[str, dict[str, str]]:
    """Convert markdown into html and extract meta data.

    Some meta data is treated special:
        * `date` is converted into datetime with local timezone
        * `tags` is interpreted as a comma-separeted list of strings.
          All strings are stripped and converted to lower case.

    Parameters
    ----------
    md
        the Markdown instance
    markdown
        the markdown text that should be converted

    Returns
    -------
    str, dict[str, str]
        html and metadata

    """
    md.reset()
    content = md.convert(markdown)
    meta = md.Meta  # type: ignore

    # markdowns metadata consists as list of strings -- one item per
    # line. let's convert into single strings.
    for key, value in meta.items():
        value = "\n".join(value)
        meta[key] = value

    # convert known metadata
    # date: datetime
    if "date" in meta:
        meta["date"] = datetime.fromisoformat(meta["date"])
        meta["date"] = meta["date"].astimezone()
    # tags: list[str] and lower case
    if "tags" in meta:
        tags = meta["tags"].split(",")
        tags = [t.lower() for t in tags]
        tags = [t.strip() for t in tags]
        meta["tags"] = tags

    return content, meta

markdown_factory()

Create a Markdown instance.

This method exists only to ensure we use the same Markdown instance for tests as for the actual thing.

Returns:

Type Description
Markdown
Source code in blag/markdown.py
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
def markdown_factory() -> Markdown:
    """Create a Markdown instance.

    This method exists only to ensure we use the same Markdown instance
    for tests as for the actual thing.

    Returns
    -------
    markdown.Markdown

    """
    md = Markdown(
        extensions=[
            "meta",
            "fenced_code",
            "codehilite",
            "smarty",
            MarkdownLinkExtension(),
        ],
        output_format="html",
    )
    return md