From 9f41d72aab98d5ba4d4dd3dd773c083b255a97c5 Mon Sep 17 00:00:00 2001 From: mizzlelover Date: Fri, 11 Sep 2026 08:56:39 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=A5=E6=A0=BC=E6=A0=A1=E9=AA=8C=E9=A2=84?= =?UTF-8?q?=E5=8D=B0=E7=BA=A2=E5=A4=B4=E7=95=99=E7=99=BD=E8=BE=B9=E7=95=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/traework-gongwen-skill.zip | Bin 4570115 -> 4570600 bytes scripts/verify_gongwen_docx.mjs | 18 ++++++++++++++++-- tests/run_tests.sh | 19 +++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/dist/traework-gongwen-skill.zip b/dist/traework-gongwen-skill.zip index 1a4249bc07a854bf90faf1be8bdddd33f86d627c..902f2673f2e3e151e09c11277343329608bdacbc 100644 GIT binary patch delta 13223 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%0A5uE_;4Qh@WUhh0fxhS~T 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 diff --git a/scripts/verify_gongwen_docx.mjs b/scripts/verify_gongwen_docx.mjs index e9e01a5..748bf18 100755 --- a/scripts/verify_gongwen_docx.mjs +++ b/scripts/verify_gongwen_docx.mjs @@ -165,9 +165,23 @@ if (profile === "formal") { check("Upward document number and signer share one row", paragraphs(doc).some((p) => /签发人:/.test(textOf(p)) && /〔|\[|文号|发/.test(textOf(p))), "signer is in the same paragraph row as the document number"); } } else { - const preprintedReserveParagraph = /w:line="1" w:lineRule="exact"[\s\S]*?w:snapToGrid w:val="false"[\s\S]*?w:sz w:val="2"/.test(doc); - check("Preprinted letterhead reserve", preprintedReserveParagraph, "first-page top reserve is present"); const preprintedParagraphs = paragraphs(doc); + const reserveCandidate = (p) => /w:jc w:val="left"/.test(p) + && /w:line="1"/.test(p) + && /w:lineRule="exact"/.test(p) + && /w:snapToGrid w:val="false"/.test(p) + && /w:sz w:val="2"/.test(p) + && /]*> <\/w:t>/.test(p); + const reserveIndex = preprintedParagraphs.findIndex(reserveCandidate); + const reserveParagraph = reserveIndex >= 0 ? preprintedParagraphs[reserveIndex] : ""; + const reserveSpacing = reserveParagraph.match(/]*>/)?.[0] ?? ""; + const reserveBefore = Number((reserveSpacing.match(/w:before="(\d+)"/) ?? [])[1]); + const reserveBeforeInRange = Number.isFinite(reserveBefore) && reserveBefore >= 0 && reserveBefore <= Math.round((130 - 37) * 56.692913); + const priorParagraphsAreFloating = reserveIndex >= 0 && preprintedParagraphs.slice(0, reserveIndex).every((p) => /w:framePr\b/.test(p)); + const preprintedReserveParagraph = reserveIndex >= 0 + && priorParagraphsAreFloating + && reserveBeforeInRange; + check("Preprinted letterhead reserve", preprintedReserveParagraph, "first non-floating body paragraph reserves 37-130 mm paper-top agency-mark space"); const titleXmlStart = firstTitleIndex < 0 ? doc.length : doc.indexOf(preprintedParagraphs[firstTitleIndex]); const preprintedHeaderXml = titleXmlStart < 0 ? doc : doc.slice(0, titleXmlStart); check("No red drawing for preprinted letterhead", !/w:color w:val="FF0000"/.test(preprintedHeaderXml), "preprinted mode does not redraw red letterhead or rule"); diff --git a/tests/run_tests.sh b/tests/run_tests.sh index f813d08..cbeb5da 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -42,6 +42,25 @@ PY "$NODE" "$GEN" --input "$FIXTURE" --output "$TMP_DIR/preprinted-minimum.docx" --format formal --letterhead preprinted --letterhead-reserve-mm 37 --doc-no "示例发〔2026〕7号" --title "最小预印留白测试" "$NODE" "$VERIFY" --input "$TMP_DIR/preprinted-minimum.docx" --profile formal --letterhead preprinted +python3 - "$TMP_DIR/preprinted-minimum.docx" "$TMP_DIR/preprinted-malformed.docx" <<'PY' +import sys, zipfile +source, target = sys.argv[1:] +with zipfile.ZipFile(source) as src, zipfile.ZipFile(target, 'w', zipfile.ZIP_DEFLATED) as dst: + for item in src.infolist(): + data = src.read(item.filename) + if item.filename == 'word/document.xml': + text = data.decode() + old = '' + assert text.count(old) == 1 + text = text.replace(old, '', 1) + data = text.encode() + dst.writestr(item, data) +PY +if "$NODE" "$VERIFY" --input "$TMP_DIR/preprinted-malformed.docx" --profile formal >"$TMP_DIR/preprinted-malformed.out" 2>&1; then + echo "malformed preprinted reserve unexpectedly passed" >&2 + exit 1 +fi +grep -q 'Preprinted letterhead reserve' "$TMP_DIR/preprinted-malformed.out" "$NODE" "$GEN" --input "$FIXTURE" --output "$TMP_DIR/digital.docx" --format formal --letterhead digital --org "示例单位文件" --doc-no "示例发〔2026〕1号" --title "电子红头测试" --page-number standard "$NODE" "$VERIFY" --input "$TMP_DIR/digital.docx" --profile formal --letterhead digital