Coverage for portality/cms/implied_attr_list.py: 100%

34 statements  

« prev     ^ index     » next       coverage.py v6.4.2, created at 2022-07-22 15:59 +0100

1import markdown 

2import re 

3from markdown.extensions import attr_list 

4 

5 

6def makeExtension(**kwargs): # pragma: no cover 

7 return ImpliedAttrListExtension(**kwargs) 

8 

9 

10class ImpliedAttrListExtension(markdown.Extension): 

11 """Extension for attatching `attr_list` entries to implied elements. Specifically: lists and tables""" 

12 

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) 

17 

18 

19class ImpliedAttrListPreprocessor(markdown.preprocessors.Preprocessor): 

20 

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 """ 

27 

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 

34 

35 

36class ImpliedAttrListTreeprocessor(attr_list.AttrListTreeprocessor): 

37 

38 def run(self, doc): 

39 """ 

40 Iterate through the doc, locating <p> tags that contain ONLY the syntax for attr_lists. 

41 

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 

44 

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 

54 

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) 

60 

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)