2025-12-04 14:41:20 +08:00

71 lines
2.0 KiB
Python

from typing import TYPE_CHECKING, Any, Dict, Iterable, cast
from ..util import strip_end
if TYPE_CHECKING:
from ..core import BaseRenderer, BlockState
def render_list(renderer: "BaseRenderer", token: Dict[str, Any], state: "BlockState") -> str:
attrs = token["attrs"]
if attrs["ordered"]:
children = _render_ordered_list(renderer, token, state)
else:
children = _render_unordered_list(renderer, token, state)
text = "".join(children)
parent = token.get("parent")
if parent:
if parent["tight"]:
return text
return text + "\n"
return strip_end(text) + "\n"
def _render_list_item(
renderer: "BaseRenderer",
parent: Dict[str, Any],
item: Dict[str, Any],
state: "BlockState",
) -> str:
leading = cast(str, parent["leading"])
text = ""
for tok in item["children"]:
if tok["type"] == "list":
tok["parent"] = parent
elif tok["type"] == "blank_line":
continue
text += renderer.render_token(tok, state)
lines = text.splitlines()
text = (lines[0] if lines else "") + "\n"
prefix = " " * len(leading)
for line in lines[1:]:
if line:
text += prefix + line + "\n"
else:
text += "\n"
return leading + text
def _render_ordered_list(renderer: "BaseRenderer", token: Dict[str, Any], state: "BlockState") -> Iterable[str]:
attrs = token["attrs"]
start = attrs.get("start", 1)
for item in token["children"]:
leading = str(start) + token["bullet"] + " "
parent = {
"leading": leading,
"tight": token["tight"],
}
yield _render_list_item(renderer, parent, item, state)
start += 1
def _render_unordered_list(renderer: "BaseRenderer", token: Dict[str, Any], state: "BlockState") -> Iterable[str]:
parent = {
"leading": token["bullet"] + " ",
"tight": token["tight"],
}
for item in token["children"]:
yield _render_list_item(renderer, parent, item, state)