"""M02 일위대가 실무자료 단가산출 블록 글 → 절 나무 · 선택값 · 상수 · 대입식 · 몫(PLAN 785-1 · 요구 642 · 설계 642-A 2-2 ⓑ · 2-5 ④-2 · ④-3 B2~B4). 글 먼저 · 찾기 없음 — 글에 적힌 것만 꼴로 옮김(값을 짓지 않음 · 못 읽은 것은 안 냄) · M01 · 엔진 안 부름. 절 나무 `tree(글, 글행, 항목)` → [절] — 절 = {번, 층, 제목, 갈래, 행 [시작, 끝], 글 [첫, 끝], 상수, 식, 선택값, 몫, 소계, 항목, 아래}: 층 1 「1.」 · 2 「가.」 · 3 「1)」 · 빠진 번호 그대로(단산6 1 → 3) · 갈래 = 합계(합계 · 소계 · 총계) · 비목(재료비 · 인건비 · 노무비 · 경비 …) · 일(그 밖) · 상수 = 「q = 0.6㎥ K = 0.55」 · 「L = 6m {경사도 = 35°(α=8)}」 · 「운반회수 : n = 42회/일」 → {기호, 값, 단위, 덧?, 이름?, 행} · 식 = 「기호 = 식 = … = 값」 → {기호, 글, 값, 단위, 꼴 곱|합|분수, 분자, 분모, 대입, 행} — 곱 = 「×」 「÷」 「/」 만 · 괄호 뒤 「÷」 는 괄호 안 모두 분모 · 대입 = 기호 식과 수 식의 인자 자리가 같을 때 {기호: 수} · 합(「+」) · 분수(「──」 그림 줄)는 값만 · 선택값 = 「※ …」 · 작업조건 줄 {글, 행} · 몫 = 그 절 비목 줄(노무비 · 재료비 · 경비) 「단가 ÷ Q」 · 「단가 × Q」 뒤 곱수(모두 같을 때) · 없으면 직종 줄 「단가 × 품」 뒤 % 곱수 → {글, 값, 행} · 소계 = 합계 갈래 아래 절(없으면 그 절 「소계」 줄) 비목 값 {노무비, 재료비, 경비, 계} · 항목 = 행이 그 절(아래 절 뺌) 안인 단위 줄 차례. 머리 `head(글, 글행)` = 첫 절 앞 줄 {행, 상수, 식, 선택값}. 일 절 `works(나무)` = 일 갈래 중 아래에 일 절이 없는 절 · 하나도 없으면 [](블록 통째 한 일). """ from __future__ import annotations import re from typing import Any NUM = r"[\d,]+(?:\.\d+)?" _LEVELS = ( (1, re.compile(r"^\s*(\d+)\s*\.\s*(.*)$")), (2, re.compile(r"^\s*([가-하])\s*\.\s*(.*)$")), (3, re.compile(r"^\s*(\d+)\)\s*(.*)$")), ) _DECIMAL = re.compile(r"^\s*\d+\.\d") _TOTAL = re.compile(r"(합\s*계|소\s*계|총\s*계)") _COSTS = ("재료비", "인건비", "노무비", "경비", "기계경비", "자재비", "재료", "인건", "노무") _SEG = re.compile( r"(?:^\s*|(?<=\s\s)|(?<=[{(]))(?:(?P