/* 스프레드시트 D 순수 규칙 시험 도우미 — 고름 · 입력 글 규칙 · 가리키기 자리 · 채우기 끌기 목표. * pytest(test_spreadsheet_d_input.py)가 부르고 결과 JSON 을 판정. */ const path = require("path"); const { load, SS } = require("./helper_spreadsheet_d_bundle.cjs"); const sel = load(path.join(SS, "spreadsheet_selection.ts")); const ed = load(path.join(SS, "spreadsheet_editor.ts")); const mouse = load(path.join(SS, "spreadsheet_mouse.ts")); const addr = load(path.join(SS, "spreadsheet_address.ts")); const sample = require(path.join(SS, "spreadsheet_sample.json")); const s1 = sample.시트[0]; const a1 = (s) => `${addr.toA1(s.활성.r, s.활성.c)}|${addr.rangeToA1(s.범위[0])}`; const cell = (r, c) => sel.selectCell(s1, r, c); const keys = (start, list) => { let s = start; return list.map(([dr, dc, o]) => a1((s = sel.move(s1, s, dr, dc, o || {})))); }; const out = { // 병합 C4:F4 안을 누르면 병합 전체 · 활성은 왼위 mergeClick: a1(cell(3, 4)), // 병합에서 오른쪽 → G4 · 왼쪽 → B4 mergeMove: keys(cell(3, 2), [ [0, 1], [0, -1], [0, -1], ]), // Shift+→ 두 번(병합 걸침) · Shift+← 줄임 · Shift+↓ shiftExtend: keys(cell(3, 0), [ [0, 1, { extend: true }], [0, 1, { extend: true }], [0, -1, { extend: true }], [1, 0, { extend: true }], ]), // Ctrl+↓ 값 뭉치 끝 → 시트 끝 · Ctrl+↑ 되돌아 값 ctrlJump: keys(cell(2, 0), [ [1, 0, { jump: true }], [1, 0, { jump: true }], [-1, 0, { jump: true }], ]), // 숨긴 열 J 건너뜀(I → K) hiddenSkip: keys(cell(0, 8), [[0, 1]]).map((x) => x.split("|")[0]), // 열 머리 C — 병합 C3:F3 걸쳐 C:F colHead: addr.rangeToA1(sel.selectCols(s1, 2, 2).범위[0]), // 고름 안 Enter 돌기(열 먼저) · Tab(행 먼저) cycleEnter: (() => { let s = { 시트: "s1", 범위: [{ r0: 10, c0: 10, r1: 11, c1: 11 }], 활성: { r: 10, c: 10 }, 기준: { r: 10, c: 10 }, }; return [1, 1, 1, 1].map(() => addr.toA1((s = sel.cycle(s1, s, 1, 0)).활성.r, s.활성.c)); })(), cycleTab: (() => { let s = { 시트: "s1", 범위: [{ r0: 10, c0: 10, r1: 11, c1: 11 }], 활성: { r: 10, c: 10 }, 기준: { r: 10, c: 10 }, }; return [1, 1, 1].map(() => addr.toA1((s = sel.cycle(s1, s, 0, 1)).활성.r, s.활성.c)); })(), cycleSingle: sel.cycle(s1, cell(3, 2), 1, 0), usedEnd: addr.toA1(sel.usedEnd(s1).r, sel.usedEnd(s1).c), // 입력 글 → 칸 textToCell: ["12", "1,234.5", "50%", "-1e3", "true", "'=12", "=", "=A1+1", "", "1,23", "abc"].map( (t) => ed.textToCell(t, { 서식: 4 }), ), textToCellNoStyle: ed.textToCell("", {}), cellToText: [ { 값: "=12" }, { 값: "12" }, { 값: "abc" }, { 값: 1.5 }, { 값: false }, { 식: "A1*2" }, undefined, ].map((c) => ed.cellToText(c)), // 참조 넣을 자리 insertable: [ ["=", 1], ["=A1+", 4], ["=A1", 3], ["=SUM(", 5], ["=SUM(A1,", 8], ["=1 + ", 5], ["abc", 3], ["=A1+B", 4], ].map(([t, p]) => ed.insertableAt(t, p)), // 참조 색 — 같은 글은 같은 색 · 다른 시트 highlights: ed .refHighlights("=A1+B2:C3*A1+치수!B1", "s1", (n) => (n === "치수" ? "s2" : null)) .map((h) => `${h.시트}:${addr.rangeToA1(h.범위)}:${h.색번호}`), // 함수 자동 완성 · 인자 도움말 자리 hint: ["=su", "=A1+ro", "=A1", "=ROUND(B5,", "=SUM(A1,MAX(1,2),", '=IF(A1=",",', "abc"].map((t) => ed.formulaHint(t), ), // 채우기 끌기 목표 fill: [[{ r: 9, c: 1 }], [{ r: 2, c: 6 }], [{ r: 3, c: 1 }], [{ r: 2, c: 1 }]].map(([p]) => { const t = mouse.fillTarget({ r0: 1, c0: 1, r1: 3, c1: 2 }, p); return [addr.rangeToA1(t.target), t.clear && addr.rangeToA1(t.clear)]; }), }; console.log(JSON.stringify(out));