补齐公文全条款视觉核验与版头定位

This commit is contained in:
mizzlelover
2026-09-10 22:07:19 +08:00
parent 3060da65ba
commit baf0407583
18 changed files with 325 additions and 23 deletions
+21
View File
@@ -0,0 +1,21 @@
各主送机关:
这是一份用于逐条实测公文版式的正文。首页必须显示正文,正文自然段左空二字,回行顶格。
一、第一层标题
第一层标题后的正文,用于观察黑体层级、正文颜色和固定网格。
(一)第二层标题
第二层标题后的正文,用于观察楷体层级。
1. 第三层标题
第三层标题后的正文,用于观察仿宋层级。
1)第四层标题
第四层标题后的正文,用于观察标题样式和目录级别。
这是第二个自然段。计量单位示例:10 kg、5 m、3.14;标点和数字仅作为版式审阅内容。
+8
View File
@@ -0,0 +1,8 @@
# 附件一:数据清单
附件正文第一段,用于观察附件首页标签、标题和连续页码。
| 项目 | 数量 |
| --- | --- |
| 摄像头 | 105 |
| 点位 | 156 |
+3
View File
@@ -0,0 +1,3 @@
# 附件二:实施计划
附件正文第二段,用于观察多个附件的分页和编号。
+6
View File
@@ -0,0 +1,6 @@
各主送机关:
| 项目 | 数量 | 备注 |
| --- | --- | --- |
| 摄像头 | 105 | 存量 |
| 点位 | 156 | 一期 |
+27
View File
@@ -0,0 +1,27 @@
各主送机关:
这是一份多页正文,用于观察首页正文、单双页页码、版记锚定和分页行为。这里重复文字以形成足够长度。
一、主体内容
这是用于形成多页输出的段落。公文排版需要在实际分页后检查正文区域、版记位置、页码连续性以及附件衔接。重复内容如下:公文格式要素包括版头、主体、版记和页码,正文一般使用三号仿宋,段落左空二字,回行顶格。公文格式要素包括版头、主体、版记和页码,正文一般使用三号仿宋,段落左空二字,回行顶格。
(二)延伸内容
这是用于形成多页输出的段落。公文排版需要在实际分页后检查正文区域、版记位置、页码连续性以及附件衔接。重复内容如下:公文格式要素包括版头、主体、版记和页码,正文一般使用三号仿宋,段落左空二字,回行顶格。公文格式要素包括版头、主体、版记和页码,正文一般使用三号仿宋,段落左空二字,回行顶格。
(三)继续内容
这是用于形成多页输出的段落。公文排版需要在实际分页后检查正文区域、版记位置、页码连续性以及附件衔接。重复内容如下:公文格式要素包括版头、主体、版记和页码,正文一般使用三号仿宋,段落左空二字,回行顶格。公文格式要素包括版头、主体、版记和页码,正文一般使用三号仿宋,段落左空二字,回行顶格。
(四)继续内容
这是用于形成多页输出的段落。公文排版需要在实际分页后检查正文区域、版记位置、页码连续性以及附件衔接。重复内容如下:公文格式要素包括版头、主体、版记和页码,正文一般使用三号仿宋,段落左空二字,回行顶格。公文格式要素包括版头、主体、版记和页码,正文一般使用三号仿宋,段落左空二字,回行顶格。
(五)继续内容
这是用于形成多页输出的段落。公文排版需要在实际分页后检查正文区域、版记位置、页码连续性以及附件衔接。重复内容如下:公文格式要素包括版头、主体、版记和页码,正文一般使用三号仿宋,段落左空二字,回行顶格。公文格式要素包括版头、主体、版记和页码,正文一般使用三号仿宋,段落左空二字,回行顶格。
(六)继续内容
这是用于形成多页输出的段落。公文排版需要在实际分页后检查正文区域、版记位置、页码连续性以及附件衔接。重复内容如下:公文格式要素包括版头、主体、版记和页码,正文一般使用三号仿宋,段落左空二字,回行顶格。公文格式要素包括版头、主体、版记和页码,正文一般使用三号仿宋,段落左空二字,回行顶格。
+19 -1
View File
@@ -31,14 +31,32 @@ unzip -p "$TMP_DIR/standard.docx" word/document.xml | grep -q 'w:snapToGrid w:va
unzip -p "$TMP_DIR/digital.docx" word/document.xml | grep -q '示例单位文件'
unzip -p "$TMP_DIR/digital.docx" word/document.xml | grep -q 'FF0000'
unzip -p "$TMP_DIR/digital.docx" word/document.xml | grep -q 'height:0.5mm'
unzip -p "$TMP_DIR/digital.docx" word/document.xml | grep -q 'w:before="1984"'
unzip -p "$TMP_DIR/digital.docx" word/document.xml | grep -q 'w:framePr.*w:xAlign="center".*w:y="2126"'
unzip -p "$TMP_DIR/digital.docx" word/document.xml | grep -q 'w:before="2015"'
unzip -p "$TMP_DIR/digital.docx" word/document.xml | grep -q 'w:snapToGrid w:val="false"'
"$NODE" "$GEN" --input "$FIXTURE" --output "$TMP_DIR/digital-fields.docx" --format formal --letterhead digital --copy-no 7 --secret "机密★3年" --urgent "特急" --org "示例单位文件" --doc-no "示例发〔20263号" --title "版头字段定位测试"
"$NODE" "$VERIFY" --input "$TMP_DIR/digital-fields.docx" --profile formal --letterhead digital
unzip -p "$TMP_DIR/digital-fields.docx" word/document.xml | grep -q 'w:framePr.*w:xAlign="left".*w:y="275"'
unzip -p "$TMP_DIR/digital-fields.docx" word/document.xml | grep -q 'w:before="2015"'
"$NODE" "$GEN" --input "$FIXTURE" --output "$TMP_DIR/preprinted-fields.docx" --format formal --letterhead preprinted --letterhead-reserve-mm 72 --copy-no 7 --secret "机密★3年" --urgent "特急" --doc-no "示例发〔20264号" --title "预印字段定位测试"
"$NODE" "$VERIFY" --input "$TMP_DIR/preprinted-fields.docx" --profile formal --letterhead preprinted
unzip -p "$TMP_DIR/preprinted-fields.docx" word/document.xml | grep -q 'w:before="1984"'
cat >"$TMP_DIR/attachment.md" <<'EOF'
# 附件一:测试附件
附件正文。
EOF
cat >"$TMP_DIR/main-send.md" <<'EOF'
各主送机关:
主送机关只应在输出中出现一次。
EOF
"$NODE" "$GEN" --input "$TMP_DIR/main-send.md" --output "$TMP_DIR/main-send.docx" --format formal --letterhead digital --org "示例单位文件" --doc-no "示例发〔20262号" --title "主送机关匹配测试" --to "各主送机关"
test "$(unzip -p "$TMP_DIR/main-send.docx" word/document.xml | grep -o '各主送机关' | wc -l | tr -d ' ')" -eq 1
"$NODE" "$GEN" --input "$FIXTURE" --output "$TMP_DIR/upward.docx" --format formal --letterhead digital --org "示例单位文件" --doc-no "示例发〔20261号" --title "上行文测试" --upward true --signer "张三"
"$NODE" "$VERIFY" --input "$TMP_DIR/upward.docx" --profile formal --letterhead digital --upward true
unzip -p "$TMP_DIR/upward.docx" word/document.xml | grep -q '签发人:'
+68
View File
@@ -0,0 +1,68 @@
#!/usr/bin/env bash
set -euo pipefail
skill_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
if [[ $# -gt 1 ]]; then
echo "Usage: $0 [output-directory]" >&2
exit 2
fi
out_dir=${1:-$(mktemp -d "${TMPDIR:-/tmp}/gongwen-visual-audit.XXXXXX")}
mkdir -p "$out_dir/docx" "$out_dir/pdf" "$out_dir/png" "$out_dir/logs"
gen="$skill_dir/scripts/generate_gongwen_docx.mjs"
verify="$skill_dir/scripts/verify_gongwen_docx.mjs"
all="$skill_dir/tests/fixtures/visual-all.md"
long="$skill_dir/tests/fixtures/visual-long.md"
attach_a="$skill_dir/tests/fixtures/visual-attachment-a.md"
attach_b="$skill_dir/tests/fixtures/visual-attachment-b.md"
horizontal="$skill_dir/tests/fixtures/visual-horizontal.md"
node "$gen" --input "$all" --output "$out_dir/docx/ordinary.docx" --format ordinary --title "普通材料全要素实测" --page-number center
node "$gen" --input "$all" --output "$out_dir/docx/formal-digital-all.docx" --format formal --letterhead digital --copy-no 7 --secret "机密★3年" --urgent "特急" --org "示例单位文件" --doc-no "示例发〔20267号" --title "正式公文全要素实测" --to "各主送机关" --sender "示例单位" --date "2026年9月10日" --note "此件公开" --attachment-note "1. 数据清单;2. 实施计划。" --cc "办公室、财务部" --print-org "示例印发机关" --print-date "2026年9月10日" --page-number standard
node "$gen" --input "$all" --output "$out_dir/docx/formal-digital-upward.docx" --format formal --letterhead digital --org "示例单位文件" --doc-no "示例发〔20268号" --title "上行文双签发人实测" --upward true --signer "张三、李四" --page-number standard
node "$gen" --input "$all" --output "$out_dir/docx/formal-preprinted.docx" --format formal --letterhead preprinted --letterhead-reserve-mm 72 --copy-no 7 --secret "机密★3年" --urgent "特急" --doc-no "示例发〔20269号" --title "预印红头套打实测" --page-number standard
node "$gen" --input "$all" --output "$out_dir/docx/formal-seal.docx" --format formal --letterhead preprinted --letterhead-reserve-mm 72 --title "盖章公文实测" --sender "示例单位" --date "2026年9月10日" --seal-mode seal --page-number standard
node "$gen" --input "$all" --output "$out_dir/docx/formal-signed.docx" --format formal --letterhead preprinted --letterhead-reserve-mm 72 --title "签名章公文实测" --sender "示例单位" --date "2026年9月10日" --seal-mode signed --signer-title "主要负责人" --signer "张三" --page-number standard
node "$gen" --input "$all" --output "$out_dir/docx/formal-attachments.docx" --format formal --letterhead preprinted --letterhead-reserve-mm 72 --doc-no "示例发〔202610号" --title "多附件实测" --attachment-note "1. 数据清单;2. 实施计划。" --attachment-file "$attach_a" --attachment-file "$attach_b" --page-number standard
node "$gen" --input "$long" --output "$out_dir/docx/formal-long.docx" --format formal --letterhead preprinted --letterhead-reserve-mm 72 --doc-no "示例发〔202611号" --title "长文版记与单双页实测" --cc "办公室、财务部、审计部、采购部、法务部、信息中心" --print-org "示例印发机关" --print-date "2026年9月10日" --page-number standard
node "$gen" --input "$all" --output "$out_dir/docx/letter.docx" --format letter --org "示例机关" --doc-no "示例〔202612号" --title "信函格式实测" --page-number none
node "$gen" --input "$all" --output "$out_dir/docx/command.docx" --format command --org "示例机关命令" --doc-no "第1号" --title "命令格式实测" --page-number standard
node "$gen" --input "$all" --output "$out_dir/docx/minutes.docx" --format minutes --org "示例机关纪要" --title "纪要格式实测" --attendees "张三(办公室)、李四(财务部)" --absent "王五(审计部)" --observers "赵六(采购部)" --page-number standard
node "$gen" --input "$horizontal" --output "$out_dir/docx/table.docx" --format formal --letterhead preprinted --letterhead-reserve-mm 72 --doc-no "示例发〔202613号" --title "表格版式实测" --page-number standard
for file in "$out_dir/docx"/*.docx; do
base=$(basename "$file" .docx)
case "$base" in
ordinary) profile=ordinary ;;
letter) profile=letter ;;
command) profile=command ;;
minutes) profile=minutes ;;
*) profile=formal ;;
esac
case "$base" in
formal-digital-*) letterhead=digital ;;
*) letterhead=preprinted ;;
esac
node "$verify" --input "$file" --profile "$profile" --letterhead "$letterhead" >"$out_dir/logs/$base.verify.log"
done
if ! command -v soffice >/dev/null 2>&1 || ! command -v pdftoppm >/dev/null 2>&1; then
echo "LibreOffice (soffice) and pdftoppm are required for screenshot audit." >&2
exit 3
fi
soffice --headless --convert-to pdf --outdir "$out_dir/pdf" "$out_dir/docx"/*.docx >"$out_dir/logs/soffice.log" 2>&1
for file in "$out_dir/pdf"/*.pdf; do
base=$(basename "$file" .pdf)
pdftoppm -png -r 150 "$file" "$out_dir/png/$base" >"$out_dir/logs/$base.pdftoppm.log" 2>&1
done
{
echo -e "profile\tdocx\tpdf\tscreenshot_prefix"
for file in "$out_dir/docx"/*.docx; do
base=$(basename "$file" .docx)
pages=$(pdfinfo "$out_dir/pdf/$base.pdf" | awk '/^Pages:/ {print $2}')
echo -e "$base\t$file\t$out_dir/pdf/$base.pdf\t$out_dir/png/$base-1.png ... $out_dir/png/$base-$pages.png"
done
} >"$out_dir/manifest.tsv"
echo "Visual audit complete: $out_dir"
cat "$out_dir/manifest.tsv"