feat(est): save multiple quantity text edits

This commit is contained in:
2026-11-06 22:51:01 +09:00
parent 0880665f28
commit ed2d95745e
3 changed files with 62 additions and 23 deletions
+44 -21
View File
@@ -15,6 +15,33 @@ function escapeText(text) {
.join("");
}
function editRun(div, before, after, parse) {
for (const match of div.matchAll(/>([^<>]+)(?=<)/g)) {
const raw = match[1],
decoded = quantity.entities(raw.replace(/\r?\n/g, ""));
if (!decoded) continue;
let position = -1;
while ((position = before.LineData.indexOf(decoded, position + 1)) >= 0) {
const prefix = before.LineData.slice(0, position),
suffix = before.LineData.slice(position + decoded.length);
if (
!after.LineData.startsWith(prefix) ||
!after.LineData.endsWith(suffix) ||
after.LineData.length < prefix.length + suffix.length
)
continue;
const replacement = after.LineData.slice(
prefix.length,
after.LineData.length - suffix.length,
);
const at = match.index + 1;
const candidate = div.slice(0, at) + escapeText(replacement) + div.slice(at + raw.length);
if (same(parse(candidate)[0], after)) return candidate;
}
}
return null;
}
// Change text inside an existing styled run, never WPTools tags or bookmarks.
function editDocument(text, oldSheet, sheet) {
if (
@@ -34,28 +61,24 @@ function editDocument(text, oldSheet, sheet) {
if (same(before, after)) return div;
if (!same(before.markers, after.markers))
throw Error("수량산출서 표지 변경은 저장할 수 없습니다.");
for (const match of div.matchAll(/>([^<>]+)(?=<)/g)) {
const raw = match[1],
decoded = quantity.entities(raw.replace(/\r?\n/g, ""));
if (!decoded) continue;
let position = -1;
while ((position = before.LineData.indexOf(decoded, position + 1)) >= 0) {
const prefix = before.LineData.slice(0, position),
suffix = before.LineData.slice(position + decoded.length);
if (
!after.LineData.startsWith(prefix) ||
!after.LineData.endsWith(suffix) ||
after.LineData.length < prefix.length + suffix.length
)
continue;
const replacement = after.LineData.slice(
prefix.length,
after.LineData.length - suffix.length,
);
const at = match.index + 1;
const candidate = div.slice(0, at) + escapeText(replacement) + div.slice(at + raw.length);
if (same(parse(candidate)[0], after)) return candidate;
const direct = editRun(div, before, after, parse);
if (direct) return direct;
const split = /([\x03\x0c\x0e\x11\x12\x13\x15\x1a])/g,
previous = before.LineData.split(split),
next = after.LineData.split(split);
if (previous.length === next.length && previous.every((v, i) => i % 2 === 0 || v === next[i])) {
let candidate = div,
current = before;
for (let i = 0; i < previous.length; i += 2) {
if (previous[i] === next[i]) continue;
previous[i] = next[i];
const updated = { ...current, LineData: previous.join("") };
const patched = editRun(candidate, current, updated, parse);
if (!patched) break;
candidate = patched;
current = updated;
}
if (same(current, after)) return candidate;
}
throw Error(
`수량산출서 ${rowIndex}행: 기존 서식 구간을 넘는 편집은 ESTX에 저장할 수 없습니다.`,