MCPcopy Create free account
hub / github.com/Python-Markdown/markdown / BlockProcessor

Class BlockProcessor

markdown/blockprocessors.py:59–150  ·  view source on GitHub ↗

Base class for block processors. Each subclass will provide the methods below to work with the source and tree. Each processor will need to define it's own `test` and `run` methods. The `test` method should return True or False, to indicate whether the current block should be proce

Source from the content-addressed store, hash-verified

57
58
59class BlockProcessor:
60 """ Base class for block processors.
61
62 Each subclass will provide the methods below to work with the source and
63 tree. Each processor will need to define it's own `test` and `run`
64 methods. The `test` method should return True or False, to indicate
65 whether the current block should be processed by this processor. If the
66 test passes, the parser will call the processors `run` method.
67
68 Attributes:
69 BlockProcessor.parser (BlockParser): The `BlockParser` instance this is attached to.
70 BlockProcessor.tab_length (int): The tab length set on the `Markdown` instance.
71
72 """
73
74 def __init__(self, parser: BlockParser):
75 self.parser = parser
76 self.tab_length = parser.md.tab_length
77
78 def lastChild(self, parent: etree.Element) -> etree.Element | None:
79 """ Return the last child of an `etree` element. """
80 if len(parent):
81 return parent[-1]
82 else:
83 return None
84
85 def detab(self, text: str, length: int | None = None) -> tuple[str, str]:
86 """ Remove a tab from the front of each line of the given text. """
87 if length is None:
88 length = self.tab_length
89 newtext = []
90 lines = text.split('\n')
91 for line in lines:
92 if line.startswith(' ' * length):
93 newtext.append(line[length:])
94 elif not line.strip():
95 newtext.append('')
96 else:
97 break
98 return '\n'.join(newtext), '\n'.join(lines[len(newtext):])
99
100 def looseDetab(self, text: str, level: int = 1) -> str:
101 """ Remove a tab from front of lines but allowing dedented lines. """
102 lines = text.split('\n')
103 for i in range(len(lines)):
104 if lines[i].startswith(' '*self.tab_length*level):
105 lines[i] = lines[i][self.tab_length*level:]
106 return '\n'.join(lines)
107
108 def test(self, parent: etree.Element, block: str) -> bool:
109 """ Test for block type. Must be overridden by subclasses.
110
111 As the parser loops through processors, it will call the `test`
112 method on each to determine if the given block of text is of that
113 type. This method must return a boolean `True` or `False`. The
114 actual method of testing is left to the needs of that particular
115 block type. It could be as simple as `block.startswith(some_string)`
116 or a complex regular expression. As the block type may be different

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected