feat(est): save multiple quantity text edits
This commit is contained in:
@@ -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에 저장할 수 없습니다.`,
|
||||
|
||||
Reference in New Issue
Block a user