Source code for markdown_environments.div

import re
import xml.etree.ElementTree as etree

from markdown.blockprocessors import BlockProcessor
from markdown.extensions import Extension

from . import utils


class DivProcessor(BlockProcessor):

    def __init__(self, *args, types: dict, html_class: str, is_thm: bool, **kwargs):
        super().__init__(*args, **kwargs)
        self.html_class = html_class
        self.is_thm = is_thm
        self.types, self.start_pattern_choices, self.end_pattern_choices = utils.init_env_types(types, self.is_thm)
        self.start_pattern = None
        self.end_pattern = None

    def test(self, parent, block):
        typ = utils.test_for_env_types(self.start_pattern_choices, parent, block)
        if typ == "":
            return False
        self.type_opts = self.types[typ]
        self.start_pattern = self.start_pattern_choices[typ]
        self.end_pattern = self.end_pattern_choices[typ]
        return True

    def run(self, parent, blocks):
        org_block_start = blocks[0]
        # generate default thm heading if applicable
        thm_heading_md = ""
        if self.is_thm:
            thm_heading_md = utils.gen_thm_heading_md(self.type_opts, self.start_pattern, blocks[0])
        # remove starting delim (after generating thm heading from it, if applicable)
        blocks[0] = self.start_pattern.sub("", blocks[0])

        # find and remove ending delim, and extract element
        delim_found = False
        for i, block in enumerate(blocks):
            if self.end_pattern.search(block):
                delim_found = True
                # remove ending delim
                blocks[i] = self.end_pattern.sub("", block)
                # build HTML
                elem = etree.SubElement(parent, "div")
                if self.html_class != "" or self.type_opts.get("html_class") != "":
                    elem.set("class", f"{self.html_class} {self.type_opts.get('html_class')}")
                blocks[i] = blocks[i].rstrip() # remove trailing whitespace from the newline into `\end{}`
                self.parser.parseBlocks(elem, blocks[0:i + 1])
                # remove used blocks
                for _ in range(0, i + 1):
                    blocks.pop(0)
                # add thm heading if applicable
                utils.prepend_thm_heading_md(self.type_opts, elem, thm_heading_md)
                break
        # if no ending delim, restore and do nothing
        if not delim_found:
            blocks[0] = org_block_start
            return False
        return True


[docs] class DivExtension(Extension): r""" A general-purpose `<div>` that you can tack on HTML `class` es to. Usage: .. code-block:: py import markdown from markdown_environments import DivExtension input_text = ... output_text = markdown.markdown(input_text, extensions=[ DivExtension(html_class="up", types={ type1: {}, type2: {"html_class": "never"} }) ]) Markdown usage: .. code-block:: md \begin{<type>} <content> \end{<type>} becomes… .. code-block:: html <div class="[html_class] [type's html_class]"> [content] </div> """
[docs] def __init__(self, **kwargs): r""" Initialize div extension, with configuration options passed as the following keyword arguments: - **types** (*dict*) -- Types of div environments to define. Defaults to `{}`. - **html_class** (*str*) -- HTML `class` attribute to add to divs. Defaults to `""`. The key for each type defined in `types` is inserted directly into the regex patterns that search for `\\begin{<type>}` and `\\end{<type>}`, so anything you specify will be interpreted as regex. However, if the key is an empty string, its regex will never be matched against, so it is effectively useless. In addition, each type's value is itself a dictionary with the following possible options: - **html_class** (*str*) -- HTML `class` attribute to add to divs of that type. Defaults to `""`. """ self.config = { "types": [ {}, "Types of div environments to define. Defaults to `{}`." ], "html_class": [ "", "HTML `class` attribute to add to div. Defaults to `\"\"`." ], "is_thm": [ False, ( "Whether to use theorem logic (e.g. heading); you shouldn't have to set this value." "Defaults to `False`." ) ] } utils.init_extension_with_configs(self, **kwargs) # set default options for individual types for type, opts in self.getConfig("types").items(): opts.setdefault("html_class", "")
def extendMarkdown(self, md): md.parser.blockprocessors.register(DivProcessor(md.parser, **self.getConfigs()), "div", 105)
def makeExtension(**kwargs): return DivExtension(**kwargs)