fix(b08): 헛단위 뺌 — [주] 인용 「‘13-3. 기초다짐 및 뒤채움’ 항을 적용한다」를 제목으로 읽던 것(표 F0405·F0406 → 13-4-1 · F0418 → 13-5-2) · 부록 사례 표 일곱이 본문 절 번호와 겹쳐 붙던 것(이름 닮음 0.3 아래면 못 붙인 표 목록 · 진짜 제목은 0.34 이상) · 산림 목록 627 → 620 · 단가표 전후 대조: 헛단위 B-FP-13-03 셋 빠짐 · B-FP-13-05-02 가 메붙임+찰붙임 합으로 약 두 배(쓰는 곳 0 · KnownGaps 「쓰면 안 됨」 · 갈래 가르기 대기) · 나머지 단가 불변 · 시험 셋(브레인 · 서브 훑기)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BW6Jdsh18WPtYUR6THZJqn
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import difflib
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
@@ -146,10 +147,16 @@ def renumber_from_body(
|
||||
return fixed
|
||||
|
||||
|
||||
#: ⚠ [주] 속 **인용** — 「‘13-3. 기초다짐 및 뒤채움’ 항을 적용한다」(13-4-1 [주]④ · 13-5-2 [주]⑤).
|
||||
#: 「번호. 이름」 꼴이라 제목으로 읽혀 표 셋(F0405·F0406·F0418)이 13-3 에 붙고 없는 갈래 3줄이 섰음
|
||||
#: (2026-09-17 서브 훑기 · 브레인). 닫는 따옴표 뒤에 「항·을·를」이 오면 인용.
|
||||
_CITATION_RE = re.compile(r"[’”]\s*(?:항|을|를)")
|
||||
|
||||
|
||||
def _is_section_title(section: str, by_number: dict[str, dict[str, Any]]) -> bool:
|
||||
"""진짜 절 제목인가 — 「번호. 이름」, 또는 마침표 없이 번호 뒤 글이 목차 절 이름과 같음."""
|
||||
"""진짜 절 제목인가 — 「번호. 이름」(인용 아님), 또는 마침표 없이 번호 뒤 글이 목차 절 이름과 같음."""
|
||||
if re.match(r"^\s*\d+(?:-\d+){0,3}\.\s", section):
|
||||
return True
|
||||
return not _CITATION_RE.search(section)
|
||||
number = section_number(section)
|
||||
node = by_number.get(number) if number else None
|
||||
if node is None:
|
||||
@@ -158,6 +165,35 @@ def _is_section_title(section: str, by_number: dict[str, dict[str, Any]]) -> boo
|
||||
return "".join(tail.split()) == "".join(str(node.get("name") or "").split())
|
||||
|
||||
|
||||
#: 목차 이름과 본문 제목이 **글자만** 다른 자리(「깍기」·「깎기」 · 「㎝」·「cm」)를 같게 봄 — 이름 닮음 잴 때만.
|
||||
_NAME_GLYPHS = (("㎝", "cm"), ("․", "·"), ("ㆍ", "·"), ("~", "~"), ("∼", "~"), ("깎", "깍"))
|
||||
#: 이름 닮음 아래턱 — 부록 사례(「4-1. 소나무재선충병방제」 ↔ 목차 4-1 수확베기)는 0.09 이하 ·
|
||||
#: 진짜 제목의 글자 차이(「비탈면 고르기」 ↔ 「비탈면 면고르기」 0.96 · 「면벽」 ↔ 「면벅」 0.5)는 0.34 이상(2026-09-17 전수).
|
||||
NAME_LIKENESS_FLOOR = 0.3
|
||||
|
||||
|
||||
def _plain(name: str) -> str:
|
||||
text = "".join(str(name or "").split())
|
||||
for glyph, same in _NAME_GLYPHS:
|
||||
text = text.replace(glyph, same)
|
||||
return text
|
||||
|
||||
|
||||
def title_names_node(section: str, node: dict[str, Any]) -> bool:
|
||||
"""「번호. 이름」 제목의 이름이 그 번호 목차 줄 이름을 가리키는가 — 번호만 겹친 **딴 문서 표**를 거름.
|
||||
|
||||
⚠ 부록 사례 표 일곱(F0455·F0456·F0472~F0476)이 본문 절 번호와 겹쳐 그 절에 붙어
|
||||
없는 공종 줄(4-1 수확베기 ← 소나무재선충병방제)이 섰음(2026-09-17 브레인 헛단위). 못 붙인 표로 목록에 남김.
|
||||
"""
|
||||
found = re.match(r"^\s*\d+(?:-\d+){0,3}\.\s+(.+)$", section)
|
||||
if found is None:
|
||||
return True # 마침표 없는 제목은 `_is_section_title` 이 이미 목차 이름과 같은지 봤음
|
||||
title, name = _plain(found.group(1)), _plain(node.get("name"))
|
||||
if title.startswith(name) or name.startswith(title):
|
||||
return True
|
||||
return difflib.SequenceMatcher(None, title, name).ratio() >= NAME_LIKENESS_FLOOR
|
||||
|
||||
|
||||
def section_number(section: str) -> str | None:
|
||||
"""`"9-3-1. 인력"` → `"9-3-1"`. 번호가 없으면 `None`."""
|
||||
m = re.match(r"^\s*(\d+(?:-\d+){0,3})[.\s]", section + " ")
|
||||
@@ -208,6 +244,8 @@ def build() -> tuple[
|
||||
number = section_number(section)
|
||||
chapter = number.split("-")[0] if number else None
|
||||
node = by_number.get(number) if number else None
|
||||
if node is not None and not title_names_node(section, node):
|
||||
node = None # 번호만 겹친 딴 문서 표(부록 사례) — 못 붙인 표 목록으로
|
||||
entry = table_entry(
|
||||
table, section, number, chapter, source_lines, node and node["name"], report
|
||||
)
|
||||
|
||||
@@ -123,7 +123,7 @@ FORM_JUDGMENTS: dict[str, tuple[str, str, str]] = {
|
||||
# ── 제13장 구조물 ───────────────────────────────────────────────
|
||||
"F0400": ("13-2-3", "reference", "큰돌 직경별 뒷길이 기준(㎝)"),
|
||||
"F0406": (
|
||||
"13-3",
|
||||
"13-4-1", # 2026-09-17 절 바로잡음 — [주]④ 인용을 13-3 제목으로 읽었던 것(표는 13-4-1 메쌓기 아래)
|
||||
"reference",
|
||||
"〈돌쌓기의 개수 및 중량의 표준〉 — [주] 인력 돌쌓기·돌붙임 기준",
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user