# -*- coding: utf-8 -*- """건설품셈 토목 제1 · 2 · 6장 md 읽기 · 표 만들기 · 쓰기 도구 (build_소요량_건설품셈_토목.py 가 씀). 값은 md 에서 읽음(손으로 적지 않음). 표 모양 다섯 갈래: 인력·장비 편성표(crew) · 줄이 관경인 납작표(flat) · 요율 · 글 표 · 손 지정. """ import json import re from pathlib import Path from _md표_읽기 import N, R, Raw, join, js, unesc ROOT = Path(__file__).resolve().parents[3] BASE = ROOT / "resources/knowledge/original/원가계산/건설공사_표준품셈/본문/02_토목부문" DIV = "건설품셈 토목 " NUM = r"\d[\d,]*(?:\.\d+)?" UNITS = "인 hr 시간 ㎜ ㎡ ㎥ m % 대 회 식 일 본 개소 개 ㎏ kg ton 톤 m/일".split() ROLE = re.compile(r"^(수량|시공량|소요일수)") class Tab: def __init__(self, ident, title, mok, base, rows, k): self.ident, self.title, self.mok, self.base, self.rows, self.k = ( ident, title, mok, base, rows, k, ) self.notes: list[str] = [] self.pre = "" # 표 앞 글줄(별표 제목 등) def cells(line): return [c.strip() for c in line.strip().strip("|").split("|")] def title_of(s): return re.sub(r"\s*\((?:['‘’]\d\d[^)]*)\)\s*$", "", s).strip() def read_chapter(chdir): """장 폴더의 항 · 표 · 주 를 차례로 읽음 → (표 목록, 항 본문 줄 사전).""" tabs, text, order = [], {}, [] for p in sorted((next(BASE.glob(chdir + "*"))).glob("*.md")): L = p.read_text(encoding="utf-8").split("\n") at = [i for i, x in enumerate(L) if x.strip() == "---"] L = L[at[1] + 1 :] ident = title = mok = base = pre = "" k = 0 in_note = False i = 0 while i < len(L): ln = L[i].rstrip() m = re.match(r"^(#{2,4})\s+(.*)$", ln) if m: in_note = False d = len(m.group(1)) if d == 3: mm = re.match(r"^(\d+-\d+-\d+)\s+(.*)$", m.group(2)) ident, title, mok, k = mm.group(1), title_of(mm.group(2)), "", 0 order.append(ident) text[ident] = [] elif d == 4: mk = re.match(r"^(\d+)\.\s*(.*)$", m.group(2)) mok = title_of(mk.group(2)) if mk else title_of(m.group(2)) i += 1 continue if not ident: i += 1 continue text[ident].append(ln) if ln.startswith("|"): j = i rows = [] while j < len(L) and L[j].startswith("|"): c = cells(L[j]) if not all(re.fullmatch(r":?-+:?", x) for x in c): rows.append(c) j += 1 b = base if re.fullmatch(r"\(.*당\)|\(m/일\)|\(.*\)", base) else "" tabs.append(Tab(ident, title, mok, base[1:-1] if b else "", rows, k)) tabs[-1].pre = pre k += 1 base = pre = "" in_note = False i = j continue s = ln.strip() if s == "[주]": in_note = True elif in_note and s and not s.startswith(("