| 56 | |
| 57 | |
| 58 | class AdmonitionProcessor(BlockProcessor): |
| 59 | |
| 60 | CLASSNAME = 'admonition' |
| 61 | CLASSNAME_TITLE = 'admonition-title' |
| 62 | RE = re.compile(r'(?:^|\n)!!! ?([\w\-]+(?: +[\w\-]+)*)(?: +"(.*?)")? *(?:\n|$)') |
| 63 | RE_SPACES = re.compile(' +') |
| 64 | |
| 65 | def __init__(self, parser: blockparser.BlockParser): |
| 66 | """Initialization.""" |
| 67 | |
| 68 | super().__init__(parser) |
| 69 | |
| 70 | self.current_sibling: etree.Element | None = None |
| 71 | self.content_indent = 0 |
| 72 | |
| 73 | def parse_content(self, parent: etree.Element, block: str) -> tuple[etree.Element | None, str, str]: |
| 74 | """Get sibling admonition. |
| 75 | |
| 76 | Retrieve the appropriate sibling element. This can get tricky when |
| 77 | dealing with lists. |
| 78 | |
| 79 | """ |
| 80 | |
| 81 | old_block = block |
| 82 | the_rest = '' |
| 83 | |
| 84 | # We already acquired the block via test |
| 85 | if self.current_sibling is not None: |
| 86 | sibling = self.current_sibling |
| 87 | block, the_rest = self.detab(block, self.content_indent) |
| 88 | self.current_sibling = None |
| 89 | self.content_indent = 0 |
| 90 | return sibling, block, the_rest |
| 91 | |
| 92 | sibling = self.lastChild(parent) |
| 93 | |
| 94 | if sibling is None or sibling.tag != 'div' or sibling.get('class', '').find(self.CLASSNAME) == -1: |
| 95 | sibling = None |
| 96 | else: |
| 97 | # If the last child is a list and the content is sufficiently indented |
| 98 | # to be under it, then the content's sibling is in the list. |
| 99 | last_child = self.lastChild(sibling) |
| 100 | indent = 0 |
| 101 | while last_child is not None: |
| 102 | if ( |
| 103 | sibling is not None and block.startswith(' ' * self.tab_length * 2) and |
| 104 | last_child is not None and last_child.tag in ('ul', 'ol', 'dl') |
| 105 | ): |
| 106 | |
| 107 | # The expectation is that we'll find an `<li>` or `<dt>`. |
| 108 | # We should get its last child as well. |
| 109 | sibling = self.lastChild(last_child) |
| 110 | last_child = self.lastChild(sibling) if sibling is not None else None |
| 111 | |
| 112 | # Context has been lost at this point, so we must adjust the |
| 113 | # text's indentation level so it will be evaluated correctly |
| 114 | # under the list. |
| 115 | block = block[self.tab_length:] |