Files
Aislo/A00_Common/formula_doc_render.ts
eomsangdonandClaude Opus 5.5 7480aebc96 feat(804-6): 옛 수식 탭 걷음 · 줄 쌓기 = 첫 「수식」 탭(요구 686-1)
- M01 단가산출 기초 · M02 단가산출 상세 보기 = 수식(줄 쌓기 · 기본) · 단가산출 상세 둘
- 줄 쌓기에 M02 사본 [단가 갱신] · [재생성](미리 셈 → 알림 → 저장 · 고침 있으면 막음) · 판 바뀜(409) 문서 그대로면 새 판으로 다시 저장 옮김
- 옛 수식 문서 화면 걷음(formula_doc_screen · defs · edit · lines · math · math_model · rows · sub · formula_doc.css) · 이미 안 부르던 796-2 수식 나무 화면(LogicLab_Equation · Defs · Var · css · M01_Logic_Equation_Model · sheet_formula_cell · ui_template_equation_defs · edit) 걷음 — 18 파일 4,860 줄
- formula_doc_render = 줄 쌓기가 쓰는 reach 만 · 옵션 가로 CSS 는 line_stack.css 로
- 남김 = 계산기 common_util_formula_doc* · 서버 길 · 옵션 · 사본 표지 · 합계 상자 · KaTeX · 시험 페이지 tools/line-stack-test
- 시험: test_796_2 지움(걷은 화면 원본 검사뿐) · 799_1 · 800_2 걷은 화면 줄만 뺌 · 799_2 · 802_4b2 · 804_2 보기 · 화면 파일 대상 바꿈 · test_804_6 새로(걷은 파일 · 부르는 곳 없음 · 첫 탭 · 사본 할일)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 11:09:44 +09:00

83 lines
2.8 KiB
TypeScript

/* =============================================================================
* formula_doc_render.ts
* 수식 문서 닿는 기호(PLAN 802-3 · 804-6) — 줄 쌓기 산출근거(`line_stack_out.ts`)가 씀
* reach = 지금 탄 갈래로 닿는 기호(만약 안 탄 갈래 · 숨김 자리 인자 빼고)
* 옛 수식 문서 탭의 조판 그림(renderNode · 값 식 · 수 바꿈)은 804-6 에 걷음
* ========================================================================== */
import {
linkNames,
varId,
type FormulaDoc,
type Node,
} from "../common_util/common_util_formula_doc";
import {
offLine,
takenOf,
tryParse,
type Values,
} from "../common_util/common_util_formula_doc_view";
/** 탄 갈래로 부르는 이름(만약 안 탄 갈래 · 숨김 자리 인자 빼고) */
function namesTaken(n: Node, vals: Values, out: string[] = []): string[] {
const add = (x: string): void => {
if (!out.includes(x)) out.push(x);
};
switch (n[0]) {
case "var":
add(n[1]);
break;
case "bin":
namesTaken(n[2], vals, out);
namesTaken(n[3], vals, out);
break;
case "neg":
case "pct":
case "field":
namesTaken(n[1], vals, out);
break;
case "call": {
const pick = takenOf(n, vals);
const items = pick ? [n[2][0], n[2][pick]] : n[2];
items.forEach((x) => namesTaken(x, vals, out));
break;
}
}
return out;
}
const RESERVED_MONEY = new Set(["노무비", "재료비", "경비", "번지", "단계"]);
/** 정의 영역에 보일 기호 — 식 줄 · 금액 줄 · 결과에서 지금 탄 갈래로 닿는 것(보이는 차례) */
export function reach(doc: FormulaDoc, vals: Values, showOff = false): string[] {
const vars = new Map((doc.변수 ?? []).map((v) => [varId(v), v]));
const lines = new Map((doc.식 ?? []).map((l) => [String(l.기호 ?? ""), l.식]));
const money = new Set((doc.금액 ?? []).map((l) => String(l.기호 ?? "")).filter(Boolean));
const out: string[] = [];
const visit = (name: string): void => {
if (!name || out.includes(name) || RESERVED_MONEY.has(name) || money.has(name)) return;
out.push(name);
if (lines.has(name)) {
const n = tryParse(lines.get(name));
if (n) namesTaken(n, vals).forEach(visit);
}
const v = vars.get(name);
if (v?.연결 && v.연결.갈래 !== "식") linkNames(v.연결).forEach(visit);
};
const from = (text: unknown): void => {
const n = tryParse(text);
if (n) namesTaken(n, vals).forEach(visit);
};
for (const l of doc.식 ?? []) {
visit(String(l.기호 ?? ""));
from(l.식);
}
for (const l of doc.금액 ?? []) {
if (!showOff && offLine(l, vals, lines)) continue;
from(l.수량);
from(l.단가);
}
if (doc.결과) visit(String(doc.결과));
return out;
}