Community程式設計與開發github.com

GreenWich-art/agent-skills

按學術論文規範(小三黑體一級標題/四號黑體二級/小四正文宋體1.5倍行距/三線表/中西文混排Times New Roman/統計量斜體),批量重整Markdown或已有docx的格式。

agent-skills 是什麼?

此技能專為需要將Markdown分析報告或表格轉換成符合學術論文投稿規範的docx檔案所設計。它基於python-docx直接生成文檔,避免了逐段插入API無法精確控制三線表邊框、run級rFonts和斜體拆分等問題。支援平台包括Claude Code、Cursor、Codex等可執行Python腳本的AI代理環境。技能核心在於處理複雜的格式細節:自動設定多級標題的字號與行距(如小三黑體、四號黑體)、應用三線表規範(僅頂、底及表頭下三條線)、處理中西文混排(中文宋體、西文Times New Roman)、以及精確拆分流式統計量(如P值、χ²)為斜體。同時嚴格遵守工作流程鐵律,如僅用段落間距而非空段落實現留白、絕不擅自加粗或使用用戶未要求的格式,並提供完整的自檢腳本確保格式正確性。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/GreenWich-art/agent-skills/tree/HEAD/skills/docx-academic-format

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

學術論文 docx 格式重整

何時用

  • 需要把 Markdown 分析報告/表格轉成符合投稿規範的 docx
  • 需要批量設定中西文混排、三線表、多級標題字號間距
  • 逐段插入類 API 無法控制三線表邊框、run 級 rFonts、斜體拆分時,用本 skill

中文字號 → 磅值

字號磅
三號16
小三15
四號14
小四12
五號10.5

默認規範(可按目標期刊/學校要求覆蓋):一級標題小三黑體、二級四號黑體、 正文小四宋體 1.5 倍行距、西文一律 Times New Roman、表格五號宋體。

關鍵實現要點(踩過的坑)

1. 三線表邊框

w:tblBorders 的 w:sz 單位是 1/8 磅:

  • 頂/底 1.5 磅 → sz=12
  • 中間線(表頭下方)1.0 磅 → sz=8
  • 豎線必須顯式 val="none",否則 Word 會畫默認豎線

表頭下方那條線要靠 row.cells[i] 逐格設 w:tcBorders/w:bottom,只設 tblBorders 的 insideH 在某些渲染器下不可靠。

2. cell.text = '' 會留下無格式空 run

清空單元格要用:

p = cell.paragraphs[0]
for r in list(p.runs):
    r._element.getparent().remove(r._element)

否則 runs[0] 是一個無 rPr 的空 run,後續校驗字體時會誤判。

3. 中西文混排必須同時設 4 個字體槽位

rFonts.set(qn('w:ascii'), 'Times New Roman')
rFonts.set(qn('w:hAnsi'), 'Times New Roman')
rFonts.set(qn('w:eastAsia'), '宋體')   # 中文字體
rFonts.set(qn('w:cs'), 'Times New Roman')

漏設 eastAsia → 中文回落到默認字體。

4. 斜體要拆 run

統計量(P<0.001、OR=2.17、CI、β、P 值)必須拆成獨立 run 才能單獨設 italic。 正則順序有講究:P值 要用 \bP(\s*值)\b 整體匹配; 先匹配 P\s*[<>=]\s*[\d.]+ 再匹配孤立的 P,否則 P=0.06 會被拆成 P + =0.06。

5. 「空一行」= 段落間距,不是空段落

絕對不要用回車(空段落)實現"空一行"。 空段落會在 Word 裡造成:

  • 後續編輯時多出空行、無法乾淨刪除
  • 列印/轉 PDF 時出現不確定的空白
  • 與段前段後間距疊加後間距失控

正確做法——用 space_before / space_after(單位磅):

場景實現
一級標題「上下各空一行」space_before = Pt(小四字號×1.5)、space_after = 同值
二級標題「上面空一行」space_before = Pt(小四字號×1.5)、space_after = Pt(0)
三級及以下標題不設間距
正文space_before = Pt(0)、space_after = Pt(0)
圖/表與正文之間空一行在圖/表所在段落上設 space_before/after,不另插空段

參考值:小四(12pt) 空一行 ≈ 18 磅;五號(10.5pt) 空一行 ≈ 15.75 磅。

校驗方式:sum(1 for p in doc.paragraphs if not p.text.strip()) == 0 ——正常文檔不應存在任何空段落。

6. 禁止自動加粗

任何時候都不要給文字加粗,除非用戶明確要求。

這條極易踩坑:Markdown 裡的 **文字** 是源文件的強調標記,不是排版指令。 把它渲染成 Word 加粗,等於擅自給原文加重點。

正確做法:

  • **文字** → 只取文字內容,不加粗
  • 需要分小標題時,用獨立段落 + 目標字體/字號,不要靠加粗實現層級
  • 層級感只能來自:字體(黑體/楷體)、字號、段前段後間距、編號

同樣禁止的還有:斜體除指定的統計量/符號外不要用;底線、著重號、 彩色字、字元縮放/字間距——用戶沒要求的一律不動。

轉換完成後應自檢:

# 不應出現任何非用戶要求的 bold
bold = [r.text for p in doc.paragraphs for r in p.runs if r.font.bold]

表頭是否加粗看用戶要求;本 skill 默認表頭不加粗(靠字號+三線表區分)。

7. 三級及以下標題不空行

只有 1、2 級標題設段前段後間距;3 級及以下不加間距、不加粗。

腳本

腳本用途
scripts/tri_line_table.py三線表邊框(含 verify_table_borders() 自檢)
scripts/fmt_lib.py字體/間距/加粗段解析/單元格樣式 工具函式庫
scripts/fix_italic.py統計量斜體拆分(原地改,不重建 run)
scripts/fix_spacing2.py中英文混排與符號間距修正(原地改,不重建 run)

依賴:pip install python-docx

fmt_lib.parse_bold_segments(text, allow_bold=False) 默認丟棄但不渲染 ** 標記; 只有用戶明確要求加粗時才傳 allow_bold=True。

對已有 docx 做格式修正時的執行順序(不可反序):

python3 scripts/fix_italic.py  目標.docx   # 先拆斜體
python3 scripts/fix_spacing2.py 目標.docx  # 後修間距

反序會被間距規則把已拆開的符號重新拼錯。

校驗清單(生成後必查)

  1. 空段落數 == 0 —— 最高優先級,sum(1 for p in doc.paragraphs if not p.text.strip())
  2. 加粗 run == 0(除非用戶要求)——[r.text for p in doc.paragraphs for r in p.runs if r.font.bold] 必須為空;表格內同樣檢查
  3. 一級標題 sz==15 且 eastAsia==黑體,space_before==space_after==18pt
  4. 二級標題 sz==14,space_before==18pt
  5. 正文 sz==12、eastAsia==宋體、line_spacing==1.5
  6. 所有 run 的 ascii/hAnsi==Times New Roman
  7. 斜體 run 數量 >0 且內容是統計量(這是唯一允許的特殊格式)
  8. 三線表:用 verify_table_borders(table) 逐表校驗,應全部返回 (True, [])
  9. 表題:五號黑體置中、句末無標點
  10. 表格內所有 run: 宋體 + 10.5pt
  11. 正文段落 alignment == JUSTIFY,標題與表題保持原樣
  12. 百分號前有空格:33 % 而非 33%
  13. 符號與漢字間無空格:30餘次;符號與數字間有空格:≥ 10 小時、P < 0.05

一次性自檢腳本:

import sys; sys.path.insert(0, '<skill>/scripts')
from tri_line_table import verify_table_borders
from docx import Document
d = Document('out.docx'); ps = d.paragraphs
assert sum(1 for x in ps if not x.text.strip()) == 0, '存在空段落'
assert not [r for x in ps for r in x.runs if r.font.bold], '存在加粗'
assert not [r for t in d.tables for row in t.rows for c in row.cells
            for r in c.paragraphs[0].runs if r.font.bold], '表格存在加粗'
for i, t in enumerate(d.tables, 1):
    good, prob = verify_table_borders(t)
    assert good, f'表{i} 三線表不合規: {prob}'
print('全部通過')

無可視化驗證環境時

沒有 LibreOffice / Word 可轉 PDF 目視驗證三線表時, 改用 XML 層校驗(清單第 1–9 項),能可靠覆蓋字號、字體、邊框、間距。

補充:三線表的精確規範

只有 3 條線:

位置磅值w:sz
表頭行(上框線)1.512
表頭行(下框線)1.08
末行(下框線)1.512
其餘所有框線(含所有中間行、豎線)空val="none"

關鍵:不能只在 tblBorders 設 insideH。表級邊框會被單元格級 tcBorders 覆蓋, 一旦某儲存格寫了 bottom,就以儲存格級為準。必須逐儲存格顯式設定:

  1. 表級 tblBorders 六項全設 none
  2. 所有行 tcBorders 四邊先全設 none
  3. 表頭行儲存格:top=('single',12) + bottom=('single',8)
  4. 末行儲存格:bottom=('single',12)

clear_row_borders() 要對每一行呼叫,不能只清表頭和末行——否則中間行殘留線條。

補充:中文引號替換

Markdown 裡的 " 是直引號,轉 docx 後必須成對替換為 「 / 」:

dq_index = 0   # 必須跨 run 連續計數,不能每個 run 從 0 開始
for r in p.runs:
    for ch in r.text:
        if ch == '"':
            out.append('「' if dq_index % 2 == 0 else '」')
            dq_index += 1

只改 r.text,不動 rPr → 字體/字號/斜體全部保留。 替換後必須驗證:全文 " 計數 == 0、「 計數 == 」 計數、逐段左右配對 (整篇平衡不代表逐段平衡)。

補充:Word 編輯會產生碎片 run

用戶在 Word 裡手工編輯後,段落會被拆成多個 run,其中部分(被拆出的 -、單字) 不帶 rFonts,會回落到默認字體。修完引號/邊框後應掃一遍:

rf = r._element.rPr.rFonts if r._element.rPr is not None else None
if rf is None or rf.get(qn('w:eastAsia')) is None:  # → 需補齊

補齊方式:取段內第一個已設定字體的 run 作參照,繼承其 rFonts/sz/b。

重要工作流程提醒

用戶在 Word 中手工修改過文件後,絕不能重新生成整份文件——會覆蓋用戶改動。 正確做法:讀取現有 docx → 原地定點修 XML → 儲存。 修前先備份:cp xxx.docx /tmp/backup.docx。

斜體規範

唯一判定標準:該字元在數學/統計學中是否是變數或符號

類別是否斜體示例
統計學顯著性 P斜體P = 0.04、P < 0.001
檢驗水準 α斜體α = 0.05
檢驗統計量 F、Z、H、χ²、t、r斜體F = 4.52、χ² = 8.31
特殊字母(基因符號、甲基化 β 值等)斜體β
OR、CI、RR、HR、SD、SE、AUC不斜體OR = 3.14、95% CI
多字母縮寫(BMI、OGTT、FPG…)不斜體BMI、OGTT
中文文字不斜體值、為

⚠️ 最易錯:「P值」只有 P 斜體

✗ 斜體 'P值'         ← "值" 跟著斜了
✓ 斜體 'P' + 正體 '值'
✓ 斜體 'P' + 正體 '值為' + ...

P 值、P值、P 值為 0.07 ——一律只有 P 斜體,緊跟的漢字全部正體。

斜體拆分的三條鐵律(踩過血)

  1. 絕不重建 run。用"字元流重組 run"修格式會導致 rFonts/sz/b 全丟、 三線表邊框被清空、斜體標記錯位成碎片。只能改 run.text,絕不刪/建 run 元素。
  2. 拆分必須用 copy.deepcopy(run._element) 保留全部格式屬性; 插入位置 parent.insert(index+1, el)(緊鄰原 run)。用 append 會跑到段末、 順序錯亂出現 PP。 副本文本 = lead + rest + trail(不含 stat),原 run 文本 = lead + stat。
  3. run.text = x 不會清空已有 <w:t> 節點,在 deepcopy 副本上會追加。 必須先 el.remove(child) 刪掉所有 w:t/w:br/w:tab/w:cr; 且要先移除 w:i/w:iCs 再設文本,順序反了也會錯。

參考實現見 scripts/fix_italic.py。

中英文混排與符號間距

基本規則

場景規則示例
中文 ↔ 數字/字母/標點不加空格在30餘次未校正檢驗的背景下、但Table 1顯示
漢字 ↔ 漢字不加空格研究目的
英文單詞之間加空格Table 1
數學運算式內部字母/數字 與 運算子 之間加空格P = 0.04、BMI < 18.5
數學運算式 ↔ 中文加空格P < 0.05 為閾值

符號與數字/字母/漢字的間距(易錯)

組合規則示例
符號 ↔ 數字加空格33 %、87.3 %、P = 0.04
符號 ↔ 英文單詞/字母加空格Table 1;α = 0.05
符號 ↔ 漢字不加空格30餘次、≥10小時(符號緊貼漢字)

易錯點:30 餘次(錯,符號與漢字間多空格) vs 30餘次(對)。 運算子類符號(≥ ≤ = < >)與數字之間要空格,但符號與緊隨的漢字之間不補空格。

百分號

33 % 數字與 % 之間加空格。這是科技論文規範的要求,不要寫成 33%。

參考實現見 scripts/fix_spacing2.py(含 fix_spacing_in_run)。

正文段落對齊

正文段落用兩端對齊——即 Word 的 JUSTIFY(Cmd+J / Ctrl+J), 注意不是 DISTRIBUTE。

from docx.enum.text import WD_ALIGN_PARAGRAPH
p.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY

只應用到正文段落,以下保持各自原有對齊,不要改動:

  • 各級標題——通常左對齊
  • 表題——置中
  • 表格內儲存格——按需(左對齊或置中)

⚠️ 三條鐵律(執行順序與校驗)

執行順序

python3 scripts/fix_italic.py  目標.docx   # 先拆斜體
python3 scripts/fix_spacing2.py 目標.docx  # 後修間距

校驗(必做,缺一不可)

import re
norm = lambda s: re.sub(r'\s', '', s)
# ① 文字零遺失——防吞字/重複字
assert all(norm(a.text) == norm(b.text)
           for a, b in zip(原文件.paragraphs, 新文件.paragraphs))
# ② 斜體 run 只能是統計符號本身(P/α/β/F/Z/H/χ/t/r),不得含:
#    - 運算子或數字:[=<>≤≥0-9]
#    - 漢字('P值' 的 '值' 必須是正體)
#    - OR/CI/RR 等縮寫
for p in 新文件.paragraphs:
    for r in p.runs:
        if r.font.italic and r.text.strip():
            t = r.text.strip()
            assert not re.search(r'[=<>≤≥0-9\u4e00-\u9fff]', t), f'斜體含運算子/數字/漢字: {t!r}'
            assert t.split(' ')[0] not in ('OR','CI','RR','HR','SD','SE','AUC'), f'縮寫不應斜體: {t!r}'
# ③ 正文段落必須兩端對齊
from docx.enum.text import WD_ALIGN_PARAGRAPH
assert any(p.alignment == WD_ALIGN_PARAGRAPH.JUSTIFY for p in 新文件.paragraphs)
# ④ 中文引號成對
assert sum(p.text.count('「') for p in 新文件.paragraphs) == \
       sum(p.text.count('」') for p in 新文件.paragraphs)

⚠️ 最高優先級鐵律(違反即返工)

  1. 「空一行」只能用段落間距(space_before/space_after),絕不能用回車/空段落。
  2. 任何時候都不要給文字加粗,除非用戶在需求裡明確說了要加粗。 Markdown 的 **文字** 是源文件的強調記號,不是排版指令——只去標記、不加粗。
  3. 用戶沒要求的格式(底線、著重號、彩色字、字間距、字元縮放)一律不動。
  4. 用戶手工改過文件後,禁止重新生成整份文件,只能讀現有檔案原地改 XML。

層級感只能來自字體(黑體/楷體)、字號、段前段後間距、編號——不是加粗。

精簡正文/表格文字時的注意事項

在用戶已修改的 docx 上精簡文字內容時:

鐵律:合併寫入第一個 run,其餘置空

def set_paragraph_text(p, text):
    runs = p.runs
    if not runs: return False
    runs[0].text = text          # 格式保留在第一個 run
    for r in runs[1:]:
        r.text = ''              # ⚠️ 必須置空,否則殘留舊文字造成重複
    return True

同樣遵守「不重建 run」原則——只改 run.text,絕不刪/建 <w:r>。

定位表格:依文件流順序,不能用 doc.paragraphs 索引

段落裡嵌著表格時,doc.paragraphs[i] 的序號與表格不對應。必須走 body 流:

from docx.table import Table
from docx.text.paragraph import Paragraph
W = '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}'
seq = []
for c in doc.element.body.iterchildren():
    if c.tag == W+'p':   seq.append(('p', Paragraph(c, doc)))
    elif c.tag == W+'tbl': seq.append(('t', Table(c, doc)))

增刪行的兩個坑

  1. table.rows 每次存取都重新解析 XML —— 刪行後再用 rows[ri] 會越界。 先 rows = list(table.rows) 快照,從後往前刪。
  2. 克隆出來的行會丟末行下框線 —— 克隆末行補齊後,三線表的底線會變成 nil。 收尾必須重新補末行 bottom 邊框(sz=12)。

⚠️ 偵測邊框時不要只認 none

Word 自己的三線表,中間行寫的是 w:val="nil" 而非 "none"。 判定"無線"要同時接受兩者:

assert tv in ('nil','none') and bv in ('nil','none')

只認 none 會誤報"邊框損壞",實際是偵測邏輯錯。

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

GreenWich-art/agent-skills

桌面 GUI 操作的统一编排入口。当用户要求操作一个只有图形界面的应用(改设置、点按钮、填表单、操作无 CLI/连接器的软件)时使用此 skill。提供四级能力:①路由决策——判断任务该走连接器、浏览器控制、Office 技能、命令行还是 computer use 桌面接管;②授权引导——检测并引导用户完成 macOS 辅助功能/屏幕录制权限授权,处理授权不生效等常见坑;③任务派发与验证——按目标/边界/失败处理三段式描述派发 GUI 任务,并以最终截图为准确认结果;④AX 兜底层——内置 axctl 工具做元素级无障碍读写(AXPress 语义点击,不碰鼠标不抢焦点),适用于 computer use 不可用或轻量场景。台前调度全场景实测(macOS 15 + 27.0.1 复检)。触发词:操控电脑、操作某个软件、点某个按钮、GUI 操作、电脑设置。

GreenWich-art/agent-skills

参考文献的 GB/T 7714-2015 著录规范化,以及 URL / DOI / PMID / PMC 链接的 可访问性批量核验与"假失效"识别。 触发场景: - 论文 / 综述 / 作业要交,需要核对参考文献格式 - "帮我按国标改一下参考文献" - 要交付一份文献清单,需要确认链接没死 - 已经有一堆 links,要批量验证哪些还能打开 含一个可复用脚本 `scripts/check_refs.py`,能自动判别 URL / DOI / PMID / PMC 并并发核验,且能区分「真死」与「被反爬」——后者不该判为失效。 不适用:从零生成一份带引文的正文(那是写作任务); Zotero 样式定制(见正文第六节,按需手工改 CSL)。

GreenWich-art/agent-skills

Local OCR using the macOS Vision framework. Triggers: OCR, 识别图片文字, 提取截图内容, 扫描件转文字, 图片转文字, 扫描版PDF转文字, read text from image/screenshot/photo/scanned PDF. Local-first and offline; prefer it over cloud OCR whenever data is sensitive or the machine is offline.

GreenWich-art/agent-skills

Download open-access biomedical article PDFs from PMC with offline Proof-of-Work solving. Triggers: 下载文献PDF, PMC PDF, 403/404 on PDF link, Preparing to download, reCAPTCHA page, OA full text, supplementary files, download paper PDF.

相關技能