Coverage for portality/cms/implied_attr_list.py: 100%
34 statements
« prev ^ index » next coverage.py v6.4.2, created at 2022-07-19 17:05 +0100
« prev ^ index » next coverage.py v6.4.2, created at 2022-07-19 17:05 +0100
1import markdown
2import re
3from markdown.extensions import attr_list
6def makeExtension(**kwargs): # pragma: no cover
7 return ImpliedAttrListExtension(**kwargs)
10class ImpliedAttrListExtension(markdown.Extension):
11 """Extension for attatching `attr_list` entries to implied elements. Specifically: lists and tables"""
13 def extendMarkdown(self, md: markdown.Markdown, *args, **kwargs):
14 md.preprocessors.register(ImpliedAttrListPreprocessor(md), "implied_attr_list", 100)
15 md.treeprocessors.register(ImpliedAttrListTreeprocessor(md), 'implied_attr_list', 100)
16 md.registerExtension(self)
19class ImpliedAttrListPreprocessor(markdown.preprocessors.Preprocessor):
21 def run(self, lines):
22 """
23 Insert a blank line in between the declaration of the attr_list and the thing that it applies to
24 This will allow it to render the list normally. The attr_list will get rendered into the text of a paragraph
25 tag which the Treeprocessor below will handle
26 """
28 new_lines = []
29 for line in lines:
30 new_lines.append(line)
31 if re.fullmatch(ImpliedAttrListTreeprocessor.BASE_RE, line):
32 new_lines.append("")
33 return new_lines
36class ImpliedAttrListTreeprocessor(attr_list.AttrListTreeprocessor):
38 def run(self, doc):
39 """
40 Iterate through the doc, locating <p> tags that contain ONLY the syntax for attr_lists.
42 Once one is found, the value is applied to the next element in the iteration of the doc, and the
43 <p> tag is removed
45 :param doc:
46 :return:
47 """
48 holdover = None
49 removes = []
50 for elem in doc.iter():
51 if holdover is not None:
52 self.assign_attrs(elem, holdover)
53 holdover = None
55 if elem.tag in ["p"] and elem.text is not None:
56 m = re.fullmatch(self.BASE_RE, elem.text)
57 if m:
58 holdover = m.group(1)
59 removes.append(elem)
61 if len(removes) > 0:
62 parent_map = {c: p for p in doc.iter() for c in p}
63 for r in removes:
64 parent = parent_map[r]
65 parent.remove(r)