diff --git a/scripts/assemble_stage2.py b/scripts/assemble_stage2.py index 9da4b50..ef02dd6 100644 --- a/scripts/assemble_stage2.py +++ b/scripts/assemble_stage2.py @@ -686,10 +686,23 @@ def _assemble_type_b(run: Path, ctx: dict): if top_role: rn, info = top_role tids = info.get("topic_ids", []) - # MDX 원본 sections에서 직접 가져오기 (Kei structured_text 대신) - top_section = norm_sections[0] if norm_sections else {} - all_text = top_section.get("content", "") - topic_title_from_section = top_section.get("title", "") + # MDX 원본 sections에서 직접 가져오기 + # 상단: 첫 번째 level=2 section + 하단 대목차 전까지의 level=2 sections를 합침 + # (03번처럼 기술/사람/자연이 별도 section으로 분리된 경우 대응) + topic_title_from_section = "" + top_contents = [] + for s in norm_sections: + if s["level"] == 3: + break # level=3(소목차) 나오면 상단 끝 + if not topic_title_from_section and s.get("title"): + topic_title_from_section = s["title"] + content = s.get("content", "") + if content: + # section title도 소제목으로 포함 (첫 번째 제외) + if s["title"] and s["title"] != topic_title_from_section: + top_contents.append(f"### {s['title']}") + top_contents.append(content) + all_text = "\n".join(top_contents) # 마크다운 bold → HTML all_text_clean = re.sub(r'\*\*(.+?)\*\*', r'\1', all_text) @@ -814,13 +827,28 @@ def _assemble_type_b(run: Path, ctx: dict): # sections 구조: [level=2 상단, level=2 하단대목차, level=3 하단좌, level=3 하단우, ...] # 하단 대목차 = level=2 두 번째 # 하단 소목차들 = level=3 + # 하단: level=3이 존재하는 구역의 level=2가 대목차 bottom_title = "" sub_sections_from_norm = [] # [(제목, content)] - for s in norm_sections[1:]: # 상단 제외 - if s["level"] == 2: - bottom_title = s.get("title", "") - elif s["level"] == 3: + found_level3 = False + for s in norm_sections: + if s["level"] == 3: + found_level3 = True sub_sections_from_norm.append((s.get("title", ""), s.get("content", ""))) + elif s["level"] == 2 and not found_level3: + # level=3 전의 level=2는 상단에 속함 → 건너뜀 + continue + elif s["level"] == 2 and found_level3: + # level=3 이후의 level=2 → 하단 대목차 후보 (이미 잡혔으면 무시) + pass + # 하단 대목차: level=3 바로 앞의 level=2 + for s in norm_sections: + if s["level"] == 2: + # 이 section 다음에 level=3이 오면 이게 대목차 + idx = norm_sections.index(s) + if idx + 1 < len(norm_sections) and norm_sections[idx + 1]["level"] == 3: + bottom_title = s.get("title", "") + break bl_indent = int(font_size * 1.2) diff --git a/src/mdx_normalizer.py b/src/mdx_normalizer.py index 3236761..05d43fc 100644 --- a/src/mdx_normalizer.py +++ b/src/mdx_normalizer.py @@ -145,10 +145,10 @@ def _process_mdx_patterns(text: str) -> tuple[str, list[dict]]: # 팝업 content 정화: JSX style 제거 + 마크다운 → HTML content = re.sub(r"