git @ Cat's Eye Technologies Cleandown / master src / cleandown / renderer.py
master

Tree @master (Download .tar.gz)

renderer.py @masterraw · history · blame

# Copyright (c) 2019 Frost Ming
#
# SPDX-License-Identifier: LicenseRef-MIT-X-Marko

# Copyright (c) 2024 Chris Pressey, Cat's Eye Technologies.
#
# SPDX-License-Identifier: LicenseRef-MIT-X-Cleandown

import logging

from marko.md_renderer import MarkdownRenderer


logger = logging.getLogger(__name__)


class CleanMarkdownRenderer(MarkdownRenderer):

    def __init__(self) -> None:
        super().__init__()
        logger.debug(f"Created new {self.__class__.__name__}")

    def render_heading(self, element) -> str:
        """Override to render h1 and h2 underlined."""
        if element.level in (1, 2):
            text = self.render_children(element)
            underline = "=" if element.level == 1 else "-"
            result = (
                self._prefix
                + text
                + "\n"
                + underline * len(text)
                + "\n"
            )
        else:
            result = (
                self._prefix
                + "#" * element.level
                + " "
                + self.render_children(element)
                + "\n"
            )
        self._prefix = self._second_prefix
        return result

    def render_list(self, element) -> str:
        """Overrise to render list items indented by 4 places, not 2."""
        result = []
        if element.ordered:
            for num, child in enumerate(element.children, element.start):
                with self.container(f"{num}. ", " " * (len(str(num)) + 2)):
                    result.append(self.render(child))
        else:
            for child in element.children:
                with self.container(f"{element.bullet}   ", "    "):
                    result.append(self.render(child))
        self._prefix = self._second_prefix
        return "".join(result)

    def render_line_break(self, element) -> str:
        """Override to render line break as double space at end of line."""
        result = "\n" + self._second_prefix if element.soft else "  \n" + self._second_prefix
        return result

    def render_link(self, element) -> str:
        """Override to render "default" reference links with trailing `[]`."""
        # There is just one line changed (the first return statement below).
        link_text = self.render_children(element)
        link_title = (
            '"{}"'.format(element.title.replace('"', '\\"')) if element.title else None
        )
        assert self.root_node
        label = self.root_node.link_ref_defs.find(element.dest, link_title)
        if label is not None:
            if self.root_node.link_ref_defs.get(label) == self.root_node.link_ref_defs.get(link_text):
                return f"[{link_text}][]"
            return f"[{link_text}][{label}]"
        title = f" {link_title}" if link_title is not None else ""
        return f"[{link_text}]({element.dest}{title})"

    def render_thematic_break(self, element) -> str:
        """Override to render thematic breaks as `- - - -`."""
        result = self._prefix + "- - - -\n"
        self._prefix = self._second_prefix
        return result

    def render_html_block(self, element) -> str:
        """Override to not add extra line breaks after HTML comments."""
        is_html_comment = element.body.rstrip().endswith("-->")

        result = self._prefix + element.body + ("\n" if not is_html_comment else "")
        self._prefix = self._second_prefix
        return result