|
1 | 1 | import re |
2 | | -from typing import TYPE_CHECKING, Match |
| 2 | +from typing import TYPE_CHECKING, Match, Optional |
3 | 3 |
|
4 | 4 | if TYPE_CHECKING: |
5 | 5 | from ..block_parser import BlockParser |
|
12 | 12 | _BLOCK_SPOILER_START = re.compile(r"^ {0,3}! ?", re.M) |
13 | 13 | _BLOCK_SPOILER_MATCH = re.compile(r"^( {0,3}![^\n]*\n)+$") |
14 | 14 |
|
15 | | -INLINE_SPOILER_PATTERN = r">!\s*(?P<spoiler_text>.+?)\s*!<" |
| 15 | +INLINE_SPOILER_PATTERN = r">!" |
| 16 | +_INLINE_SPOILER_END = re.compile(r"\s*(?P<spoiler_text>.+?)\s*!<") |
16 | 17 |
|
17 | 18 |
|
18 | 19 | def parse_block_spoiler(block: "BlockParser", m: Match[str], state: "BlockState") -> int: |
@@ -46,13 +47,28 @@ def parse_block_spoiler(block: "BlockParser", m: Match[str], state: "BlockState" |
46 | 47 | return state.cursor |
47 | 48 |
|
48 | 49 |
|
49 | | -def parse_inline_spoiler(inline: "InlineParser", m: Match[str], state: "InlineState") -> int: |
50 | | - text = m.group("spoiler_text") |
| 50 | +def parse_inline_spoiler(inline: "InlineParser", m: Match[str], state: "InlineState") -> Optional[int]: |
| 51 | + pos = m.end() |
| 52 | + cache_key = (id(state.src), "inline_spoiler") |
| 53 | + cache = state.formatting_no_end.get(cache_key) |
| 54 | + if cache is not None and cache[0] is state.src and pos <= cache[1]: |
| 55 | + return None |
| 56 | + |
| 57 | + line_end = state.src.find("\n", pos) |
| 58 | + if line_end == -1: |
| 59 | + line_end = len(state.src) |
| 60 | + |
| 61 | + m2 = _INLINE_SPOILER_END.match(state.src, pos, line_end) |
| 62 | + if not m2: |
| 63 | + state.formatting_no_end[cache_key] = (state.src, line_end) |
| 64 | + return None |
| 65 | + |
| 66 | + text = m2.group("spoiler_text") |
51 | 67 | new_state = state.copy() |
52 | 68 | new_state.src = text |
53 | 69 | children = inline.render(new_state) |
54 | 70 | state.append_token({"type": "inline_spoiler", "children": children}) |
55 | | - return m.end() |
| 71 | + return m2.end() |
56 | 72 |
|
57 | 73 |
|
58 | 74 | def render_block_spoiler(renderer: "BaseRenderer", text: str) -> str: |
|
0 commit comments