Files
Aislo/resources/master_data/scripts/_설비_읽기.py
T

132 lines
5.3 KiB
Python

# -*- coding: utf-8 -*-
"""건설품셈 기계설비 제7~13장 md 읽기 (build_소요량_건설품셈_기계설비.py 가 씀).
항(###) · 목(####) · 표 · 표 머리 깊이(주석) · 표 앞 글 · [주] [비고] [계산예] 글을 읽음.
"""
import re
from _md표_읽기 import unesc
from _토목_읽기 import ROOT
BASE = ROOT / "resources/knowledge/original/원가계산/건설공사_표준품셈/본문/04_기계설비부문"
DIV = "건설품셈 기계설비 "
NOTE0 = re.compile(r"^[①-⑳]")
BLOCK = re.compile(r"^\[(주|비고|계산예|참고|참고자료|별표)\]\s*(.*)$")
class Tab:
def __init__(self, ident, title, mok, base, rows, k, hdr, pre):
self.ident, self.title, self.mok, self.base = ident, title, mok, base
self.rows, self.k, self.hdr, self.pre = rows, k, hdr, pre
self.notes: list[str] = []
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 clean(ln):
ln = re.sub(r"<!--.*?-->", "", ln).rstrip()
return re.sub(r"^>\s?", "", ln)
def read_chapter(chdir):
"""장 폴더 → 표 목록 (표마다 항 · 목 · 기준 · 머리 깊이 · 앞 글 · 주)."""
tabs = []
for p in sorted(next(BASE.glob(chdir + "*")).glob("*.md")):
L = p.read_text(encoding="utf-8").split("\n")
L = L[[i for i, x in enumerate(L) if x.strip() == "---"][1] + 1 :]
ident = title = mok = base = ""
pre: list[str] = []
k, mode, i = 0, "", 0
while i < len(L):
raw = L[i]
ln = clean(raw)
m = re.match(r"^(#{2,4})\s+(.*)$", ln)
if m:
mode, base, pre = "", "", []
d = len(m.group(1))
if d == 2:
mm = re.match(r"^(\d+-\d+)\s+(.*)$", m.group(2))
ident, title, mok, k = mm.group(1), title_of(mm.group(2)), "", 0
elif 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
elif d == 4:
mk = re.match(r"^(?:\d+|[가-힣])\.\s*(.*)$", m.group(2))
mok = title_of(mk.group(1) if mk else m.group(2))
i += 1
continue
if not ident:
i += 1
continue
if ln.startswith("|"):
j, rows = i, []
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
hint = ""
while j < len(L) and (L[j].startswith("<!--") or not L[j].strip()):
hint += L[j] if L[j].startswith("<!--") else ""
if not L[j].strip() and not (j + 1 < len(L) and L[j + 1].startswith("<!--")):
break
j += 1
mh = re.search(r"몸 (\d+)행까지 머리", hint)
b = base[1:-1] if base else ""
tabs.append(
Tab(ident, title, mok, b, rows, k, 1 + int(mh.group(1)) if mh else 1, pre)
)
k += 1
base, pre, mode = "", [], ""
i = j
continue
s = ln.strip()
i += 1
if not s or s.startswith("!["):
continue
mb = BLOCK.match(s)
if mb:
kind, rest = mb.groups()
mode_before = mode
mode = "note" if kind in ("주", "계산예", "비고") else ""
if kind in ("참고", "참고자료", "별표"):
if "참조" in rest and tabs and tabs[-1].ident == ident:
mode = mode_before # 딴 곳을 가리키는 글 = 앞 주 이어짐
tabs[-1].notes.append(unesc(f"{kind} {rest}"))
continue
pre = [s] if not rest else [f"[{kind}] {rest}"]
mode = ""
continue
first = rest if kind == "주" else f"{kind} {rest}".strip()
if first and tabs and tabs[-1].ident == ident:
tabs[-1].notes.append(unesc(first))
mode = "note" if kind in ("주", "계산예") else ""
if kind == "계산예":
mode = "calc"
continue
if re.fullmatch(r"\(.*\)", s) and not s.startswith("(주"):
base, mode = s, ""
continue
if mode in ("note", "calc") and tabs and tabs[-1].ident == ident:
t = tabs[-1]
if mode == "calc":
t.notes.append("계산예 " + unesc(s)) if not t.notes or not t.notes[
-1
].startswith("계산예") else t.notes.__setitem__(
-1, t.notes[-1] + " " + unesc(s)
)
elif NOTE0.match(s) or not t.notes:
t.notes.append(unesc(s))
else:
t.notes[-1] += " " + unesc(s)
else:
pre.append(s)
return tabs