fix(pipeline): 법령 md 부칙 절단·목 미출력 결함 수정 + 보정 도구 신설

- collect_law.py: 부칙단위[:20] 상한 제거(법제처 XML은 오래된 순 → 최신 부칙
  절단됨), 목이 항의 직속 자식으로 오는 구조 처리(문서 순서 순회), _meta에
  수집일 필드 추가
- split_cost_docs.py: 노임 표 신뢰도 플래그(*/**) 캡처 → 별도 열로 복원
- patch_law_md.py 신설: 보관 XML 기준 누락분만 보충(전량 재생성은 후처리
  파괴하므로 금지). README에 사유·절차 명문화
This commit is contained in:
2026-08-14 20:37:39 +09:00
parent cc51b60c13
commit 06640d04ea
4 changed files with 196 additions and 12 deletions
@@ -27,7 +27,7 @@ CAK_DIR = "노임단가_건설업_대한건설협회"
CAK_STEM = "2026상반기_건설업_임금실태조사_대한건설협회"
PAGE_TABLE = (9, 13) # 0-based: 원문 p.10~13 = 개별직종 노임단가 표
CAK_CH = [("1. 조사개요", 1), ("2. 임금적용요령", 5), ("3. 개별직종 노임단가", 9), ("4. 직종해설", 13)]
CAK_COLS = "| 직종코드 | 직종명 | 2026.1.1 | 2025.9.1 | 2025.1.1 | 2024.9.1 |"
CAK_COLS = "| 직종코드 | 직종명 | 신뢰도 | 2026.1.1 | 2025.9.1 | 2025.1.1 | 2024.9.1 |"
def parse_cak_table():
@@ -41,13 +41,18 @@ def parse_cak_table():
code, seg = parts[i], parts[i + 1]
if not (1 <= int(code[1:]) <= 99):
continue
# 원문은 직종번호 앞에 신뢰도 기호를 붙인다: `*`=조사현장 5개 미만,
# `**`=미조사. 값 채택 시 경고로 남겨야 하므로 반드시 보존한다.
flag_m = re.search(r"(\*{1,2})\s*$", parts[i - 1])
flag = flag_m.group(1) if flag_m else ""
slots = re.findall(r"\d{1,3}(?:,\d{3})+|(?<![\d,])-(?![\d,])", seg)[:4]
first = re.search(r"\d{1,3}(?:,\d{3})+|(?<![\d,])-(?![\d,])", seg)
name = "".join(re.findall(r"[가-힣A-Za-z/]", seg[: first.start()] if first else seg))
if code not in result and len(slots) == 4 and name:
result[code] = (name, slots)
rows = [CAK_COLS, "|---|---|---|---|---|---|"]
rows += [f"| {c} | {result[c][0]} | {' | '.join(result[c][1])} |" for c in sorted(result)]
result[code] = (name, slots, flag)
rows = [CAK_COLS, "|---|---|---|---|---|---|---|"]
rows += [f"| {c} | {result[c][0]} | {result[c][2]} | {' | '.join(result[c][1])} |"
for c in sorted(result)]
return len(result), "\n".join(rows) + "\n"
@@ -75,7 +80,9 @@ def split_cak():
if "개별직종" in fname:
body = ("## Ⅲ. 개별직종 노임단가 (1일 8시간 기준, 원)\n\n"
f"> PDF 좌표·스트림 정밀 파싱으로 재구성 — {cnt}개 직종 전수, 최근 4개 공표일 병기.\n"
"> `-` = 해당 공표일 미공표(표본 부족·신설 등). 원문 각주는 PDF 참조.\n\n" + table)
"> `-` = 해당 공표일 미공표(표본 부족·신설 등). 원문 각주는 PDF 참조.\n"
"> **신뢰도** 열 = 원문이 직종번호 앞에 붙이는 기호 — `*` 조사현장 5개 미만(적용 시 유의), "
"`**` 미조사(임금적용요령 Ⅱ 참조). 빈칸 = 정상 공표.\n\n" + table)
(BASE / CAK_DIR / f"{fname}.md").write_text(
f"# {fname.split('. ', 1)[1]}\n\n{hdr}{body}\n", encoding="utf-8")
print("wrote", fname)