feat(m01): /text 줄마다 요소조각 — 로직 부르기 이름 + 인자 글 (PLAN 5장)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V1MKKZKpUHTPKb513FneU8
This commit is contained in:
2026-09-24 11:13:20 +09:00
co-authored by Claude Sonnet 5
parent cebd49980a
commit 53c23d2739
2 changed files with 60 additions and 0 deletions
@@ -468,6 +468,7 @@ def lines(files: dict, key: str, given: dict) -> dict:
env["줄"] = {r["이름"]: r["금액"] for r in shown if r["이름"]}
for item, line in zip(items, shown):
조각 = _formula_pieces(item["수량"], env, master, name_of, alias_by_name)
요소 = _item_pieces(item, env, master)
for part, money in _shares(line):
split = part if len(line["비목"]) > 1 else None
one = {
@@ -476,6 +477,7 @@ def lines(files: dict, key: str, given: dict) -> dict:
"이름글": _line_names(item, line, env, master, split, name_of),
"금액": money,
"조각": 조각,
"요소조각": 요소,
}
why = _why(item, line)
made[part].append({**one, "까닭": why} if why else one)
@@ -491,6 +493,7 @@ def lines(files: dict, key: str, given: dict) -> dict:
else [item.get("비목")]
)
조각 = _formula_pieces(item["수량"], env, master, name_of, alias_by_name)
요소 = _item_pieces(item, env, master)
for part in parts:
if part not in mf.COST_ITEMS:
continue
@@ -502,6 +505,7 @@ def lines(files: dict, key: str, given: dict) -> dict:
"이름글": _line_names(item, {}, env, master, split, name_of),
"금액": None,
"조각": 조각,
"요소조각": 요소,
}
)
for extra in row.get("덧줄") or []:
@@ -529,6 +533,42 @@ def lines(files: dict, key: str, given: dict) -> dict:
return _paired({"ok": True, "groups": groups, "계": 계, "별칭": marks})
def _arg_text(node, env: dict, master) -> str:
"""로직 부르기 인자 값을 사람이 읽는 글로 — 요소 키는 이름 · 입력 자리는 지금 값."""
try:
value = mf.evaluate(node, env, master, 0)
except _CALC_ERRORS: # 값 없는 입력 자리 — 이름만
return str(node[1]) if node[0] in ("name", "str") else ""
if isinstance(value, str):
for ref in (value, f"EQ:{value}"): # 기계 입력은 원문번호(0602-0025)
try:
return mc.plain(master.get(ref).get("이름")) or value
except mf.FormulaError:
pass
return value
return fmt(value)
def _item_pieces(item: dict, env: dict, master) -> list[dict]:
"""줄의 단가 자리(요소 · 로직 부르기) 조각 — PLAN 3-1 요소조각."""
ref = item.get("요소")
if item.get("종류") != "로직":
name = str(item.get("이름") or "")
if isinstance(ref, dict): # 재료 고르기 조건 — 품명만
return [{"kind": "요소", "글": name}]
piece = _elem_piece(master, ref)
return [{**piece, "글": name or piece["글"]}]
try:
node = mf.parse(ref)
key = mf.fill(node[1], env)
name = str(master.logic(key).get("이름") or key)
except _CALC_ERRORS:
return [{"kind": "로직", "글": str(item.get("이름") or "")}]
args = " · ".join(f"{k} {_arg_text(v, env, master)}" for k, v in node[2])
out = [{"kind": "로직", "글": name, "참조": {"테이블": key[:2], "키": key}}]
return out + ([{"kind": "글", "글": args}] if args else [])
def _paired(answer: dict) -> dict:
"""줄마다 짝 번호 — 두 칸(이름 꼴 · 값 꼴)이 같은 차례로 놓이게 1 부터."""
at = 0
@@ -536,6 +576,7 @@ def _paired(answer: dict) -> dict:
for one in group["줄"]:
at += 1
one["짝"] = at
one.setdefault("요소조각", [])
return answer