Process ordered list blocks.
| 325 | |
| 326 | |
| 327 | class OListProcessor(BlockProcessor): |
| 328 | """ Process ordered list blocks. """ |
| 329 | |
| 330 | TAG: str = 'ol' |
| 331 | """ The tag used for the the wrapping element. """ |
| 332 | STARTSWITH: str = '1' |
| 333 | """ |
| 334 | The integer (as a string ) with which the list starts. For example, if a list is initialized as |
| 335 | `3. Item`, then the `ol` tag will be assigned an HTML attribute of `starts="3"`. Default: `"1"`. |
| 336 | """ |
| 337 | LAZY_OL: bool = True |
| 338 | """ Ignore `STARTSWITH` if `True`. """ |
| 339 | SIBLING_TAGS: list[str] = ['ol', 'ul'] |
| 340 | """ |
| 341 | Markdown does not require the type of a new list item match the previous list item type. |
| 342 | This is the list of types which can be mixed. |
| 343 | """ |
| 344 | |
| 345 | def __init__(self, parser: BlockParser): |
| 346 | super().__init__(parser) |
| 347 | # Detect an item (`1. item`). `group(1)` contains contents of item. |
| 348 | self.RE = re.compile(r'^[ ]{0,%d}\d+\.[ ]+(.*)' % (self.tab_length - 1)) |
| 349 | # Detect items on secondary lines. they can be of either list type. |
| 350 | self.CHILD_RE = re.compile(r'^[ ]{0,%d}((\d+\.)|[*+-])[ ]+(.*)' % |
| 351 | (self.tab_length - 1)) |
| 352 | # Detect indented (nested) items of either type |
| 353 | self.INDENT_RE = re.compile(r'^[ ]{%d,%d}((\d+\.)|[*+-])[ ]+.*' % |
| 354 | (self.tab_length, self.tab_length * 2 - 1)) |
| 355 | |
| 356 | def test(self, parent: etree.Element, block: str) -> bool: |
| 357 | return bool(self.RE.match(block)) |
| 358 | |
| 359 | def run(self, parent: etree.Element, blocks: list[str]) -> None: |
| 360 | # Check for multiple items in one block. |
| 361 | items = self.get_items(blocks.pop(0)) |
| 362 | sibling = self.lastChild(parent) |
| 363 | |
| 364 | if sibling is not None and sibling.tag in self.SIBLING_TAGS: |
| 365 | # Previous block was a list item, so set that as parent |
| 366 | lst = sibling |
| 367 | # make sure previous item is in a `p` - if the item has text, |
| 368 | # then it isn't in a `p` |
| 369 | if lst[-1].text: |
| 370 | # since it's possible there are other children for this |
| 371 | # sibling, we can't just `SubElement` the `p`, we need to |
| 372 | # insert it as the first item. |
| 373 | p = etree.Element('p') |
| 374 | p.text = lst[-1].text |
| 375 | lst[-1].text = '' |
| 376 | lst[-1].insert(0, p) |
| 377 | # if the last item has a tail, then the tail needs to be put in a `p` |
| 378 | # likely only when a header is not followed by a blank line |
| 379 | lch = self.lastChild(lst[-1]) |
| 380 | if lch is not None and lch.tail: |
| 381 | p = etree.SubElement(lst[-1], 'p') |
| 382 | p.text = lch.tail.lstrip() |
| 383 | lch.tail = '' |
| 384 |
no outgoing calls
no test coverage detected
searching dependent graphs…