40 lines
1.4 KiB
Python
40 lines
1.4 KiB
Python
|
|
"""
|
|||
|
|
按 chapter_story_links 顺序将各 story 正文物化为单一 markdown(无 LLM)。
|
|||
|
|
保留 story 内 asset:// 引用不变。
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
from typing import Any
|
|||
|
|
|
|||
|
|
|
|||
|
|
def compose_ordered_stories_to_markdown(
|
|||
|
|
ordered: list[tuple[str, str]],
|
|||
|
|
) -> str:
|
|||
|
|
"""
|
|||
|
|
:param ordered: (story_title, canonical_markdown) 已按阅读顺序排好
|
|||
|
|
:return: 章节级 markdown;每个故事为 ## 标题 + 正文,故事之间用 markdown 水平线 --- 分隔
|
|||
|
|
(配图在 story 正文中,自然落在该故事块内、--- 之前)
|
|||
|
|
"""
|
|||
|
|
parts: list[str] = []
|
|||
|
|
for title, md in ordered:
|
|||
|
|
title = (title or "").strip() or "故事"
|
|||
|
|
body = (md or "").strip()
|
|||
|
|
parts.append(f"## {title}\n\n{body}" if body else f"## {title}")
|
|||
|
|
return "\n\n---\n\n".join(parts)
|
|||
|
|
|
|||
|
|
|
|||
|
|
def materialize_chapter_markdown_from_loaded_chapter(chapter: Any) -> str:
|
|||
|
|
"""要求 chapter.story_links 已 eager-load,且各 link.story 可用。"""
|
|||
|
|
links = sorted(
|
|||
|
|
list(getattr(chapter, "story_links", None) or []),
|
|||
|
|
key=lambda x: getattr(x, "order_index", 0),
|
|||
|
|
)
|
|||
|
|
pairs: list[tuple[str, str]] = []
|
|||
|
|
for link in links:
|
|||
|
|
st = getattr(link, "story", None)
|
|||
|
|
if st is None:
|
|||
|
|
continue
|
|||
|
|
title = (getattr(st, "title", None) or "").strip()
|
|||
|
|
body = (getattr(st, "canonical_markdown", None) or "").strip()
|
|||
|
|
pairs.append((title, body))
|
|||
|
|
return compose_ordered_stories_to_markdown(pairs)
|