关于 docx-processing-lawvable
供 VS Code 中处理 DOCX 的技能,通过 SuperDoc 扩展读取和编辑文档,并在预览中查看修订。适合需要跟踪文字修改、插入内容及审阅评论的文档工作流。
主要功能
- 01读取文本、HTML 和文档结构
- 02查找替换并跟踪修订
- 03插入文本、表格和评论
- 04设置文本及段落格式
- 05创建带导航链接的目录
适用场景
- 01在合同中替换占位内容并保留修订记录
- 02为文档增加段落、表格或审阅评论
- 03检查 DOCX 的段落和表格结构
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ lawve-ai/ awesome-legal-skills --skill docx-processing-lawvable安装后在 Claude Code 中输入/docx-processing-lawvable确认已加载。
附带文件LICENSE.txt
详细介绍
DOCX 实时编辑器
通过 SuperDoc 扩展,在 VS Code 中编辑 Word 文档、实时预览并跟踪更改。
工作原理
- 将自定义命令写入
path/to/.superdoc/{docname}.json - 扩展执行命令,并用响应覆盖该文件
- 更改会实时显示在 SuperDoc Webview 中。
状态: "command" 字段表示待处理;"success" 字段表示响应已就绪
前提条件
-
已安装 SuperDoc 扩展。 验证方式:
code --profile "Lawvable" --list-extensions | grep -i superdoc -
编辑前必须在 VS Code 中打开文档:
code --profile "Lawvable" path/to/doc.docx -
创建新的空白文档:
code --open-url "vscode://superdoc.superdoc-vscode-extension/create?path=./new-document.docx"路径可以是相对路径或绝对路径。如果缺少
.docx扩展名,系统会自动添加。
如果找不到 code 命令: 请改用完整路径 /Applications/Visual Studio Code.app/Contents/Resources/app/bin/code。
文件结构
.superdoc/ 文件夹必须与 DOCX 文件位于同一目录。JSON 文件使用与 DOCX 相同的基本文件名:
project/
├── contract.docx ← document at root
├── .superdoc/
│ └── contract.json ← commands for contract.docx
└── subfolder/
├── report.docx ← document in subfolder
└── .superdoc/
└── report.json ← commands for subfolder/report.docx
工作流
重要规则:
- 收到上一个命令返回的
{"success": ...}之前,绝不要发送下一个命令 - 如果响应显示的是原始命令 JSON,而不是结果,则说明文档未处于活动状态——请先重新打开文档
命令模式
写入命令,轮询直到响应中包含 "success",然后读取:
echo '{"command":"...","args":{...}}' > path/to/.superdoc/doc.json && until grep -q '"success"' path/to/.superdoc/doc.json; do sleep 0.1; done && cat path/to/.superdoc/doc.json
步骤 1:确认作者(每个会话一次)
进行任何编辑前,务必使用 AskUserQuestion 询问更改应归属于用户(询问用户姓名)还是 Agent。如果用户选择署名,请在每个 replaceText、insertContent、insertTable 和 addComment 命令中传入 "author":{"name":"Their Name"}。
步骤 2:先读取(并确认文档处于活动状态)
mkdir -p path/to/.superdoc && echo '{"command":"getText","args":{"format":"text"}}' > path/to/.superdoc/doc.json && until grep -q '"success"' path/to/.superdoc/doc.json; do sleep 0.1; done && cat path/to/.superdoc/doc.json
确认文档处于活动状态: 响应必须包含 {"success": true, "result": ...}。如果看到:
- 返回原始命令 JSON → 文档未打开,请用
code --profile "Lawvable" path/to/doc.docx重新打开 {"success": false, "error": "No active editor"}→ 文档未获得焦点,请重新打开
在收到包含文档内容的成功响应之前,不要继续步骤 3。
步骤 3:进行编辑
echo '{"command":"replaceText","args":{"search":"2024","replacement":"2025"}}' > path/to/.superdoc/doc.json && until grep -q '"success"' path/to/.superdoc/doc.json; do sleep 0.1; done && cat path/to/.superdoc/doc.json
步骤 4:相信响应结果
不要使用 getText 重新验证编辑。 命令响应 {"success": true, "replacedCount": N} 是判断结果的依据。
原因: 启用修订跟踪后,getText 会将已删除和已插入的文本拼接返回(例如 "LawvableJamie" 而不是 "Jamie")。这是预期行为——删除的文本在视觉上会显示为删除线,但仍会保留在纯文本提取结果中。
多次编辑模式
对每次编辑,重复步骤 2-4。每次编辑都单独调用一次 bash。
何时使用哪条命令(修订跟踪指南)
核心原则: 仅在更改现有文本时使用 replaceText。在添加新文本时使用 insertContent。
| 任务 | 命令 | 修订跟踪显示 |
|---|---|---|
| 更改一个值 | replaceText | |
| 填写占位符 | replaceText | |
| 修正拼写错误 | replaceText | |
| 更改单词 | replaceText | |
| 向句子中添加单词 | insertContent | existing text added word |
| 添加新段落 | insertContent | entire new paragraph |
| 添加新章节 | insertContent | entire new section |
| 添加免责声明 | insertContent | disclaimer text |
| 添加审阅评论 | addComment | (评论气泡,不跟踪更改) |
搜索与最佳实践
搜索仅提取纯文本,忽略所有格式:
- ✅ 可匹配粗体/普通文本、修订内容和段落中的文本
- ✅ 空白字符灵活(多余空格/制表符/换行符均可)
- 返回第一个匹配项。使用
occurrence参数查找第 N 个匹配项,或添加更多上下文使模式唯一。
使用独特短语(5 个以上单词):
- ❌
"the"或"Agreement"(过于常见) - ✅
"agrees to pay the sum of"或"Section 3.2 Confidentiality"
搜索时无需考虑格式——可以匹配粗体、修订内容等。
使用 occurrence 查找有歧义的匹配项(从 1 开始计数):
{"command":"replaceText","args":{"search":"the","replacement":"that","occurrence":3}}
插入内容时,请查找附近独特的锚定文本。
命令
getText - 读取文档内容
// Get both text and HTML (default)
{"command":"getText","args":{}}
// Get only plain text (fewer tokens)
{"command":"getText","args":{"format":"text"}}
// Get only HTML (preserves structure)
{"command":"getText","args":{"format":"html"}}
格式: text(带段落分隔的纯文本)、html(完整 HTML)、both(默认)
getNodes - 获取文档结构
获取特定类型的所有节点及其位置。可在编辑前用于了解文档结构。
// Get all paragraphs (use to identify section titles for TOC)
{"command":"getNodes","args":{"type":"paragraph"}}
// Get all tables
{"command":"getNodes","args":{"type":"table"}}
有效类型: paragraph、table、tableRow、tableCell、bulletList、orderedList、listItem、image、blockquote
返回:
{
"nodes": [
{"index": 0, "type": "paragraph", "from": 0, "to": 31, "text": "Non-Disclosure Agreement", "textLength": 24},
{"index": 1, "type": "paragraph", "from": 227, "to": 241, "text": "Background", "textLength": 10},
{"index": 2, "type": "paragraph", "from": 586, "to": 601, "text": "Definitions", "textLength": 11, "marker": "1."}
],
"count": 3
}
replaceText - 查找并替换(删除 + 插入)
适用场景: 将现有文本改为其他内容。找到的文本会被删除并替换。
修订效果: 显示为 删除的文本 + 新文本(删除线 + 下划线)。
范围: 默认替换所有匹配项。使用 occurrence 参数仅替换第 N 个匹配项。
// Change a value: "2024" → "2025"
{"command":"replaceText","args":{"search":"2024","replacement":"2025"}}
// Change a placeholder: "[ORG_NAME]" → "Lawvable"
{"command":"replaceText","args":{"search":"[ORG_NAME]","replacement":"Lawvable"}}
// Change a word: "shall" → "must"
{"command":"replaceText","args":{"search":"shall","replacement":"must","occurrence":1}}
// Add formatting to existing text (text is replaced with formatted version)
{"command":"replaceText","args":{"search":"Important Notice","replacement":"<strong>Important Notice</strong>"}}
insertContent - 插入新内容(仅插入)
适用场景: 添加新文本/元素,同时保留锚定文本。锚定文本保持不变,新内容会插入其前后。 修订效果: 仅显示为 新文本(下划线,无删除线)。
重要: 如果需要在句子中添加词语,但不修改现有词语,必须使用 insertContent,而不是 replaceText。使用 replaceText 会导致整个句子显示为已删除并重写,使修订视图显得杂乱。
// CORRECT: Add a word after existing text - shows only the addition as tracked
// Original: "The party agrees to pay" → Result: "The party agrees to pay promptly"
{"command":"insertContent","args":{"content":" promptly","position":{"after":"agrees to pay"}}}
// WRONG: Using replaceText to add a word - shows entire phrase as deleted + rewritten
// This would show: "~~agrees to pay~~" + "agrees to pay promptly" (ugly track changes!)
// {"command":"replaceText","args":{"search":"agrees to pay","replacement":"agrees to pay promptly"}}
// Add a new section after a heading
{"command":"insertContent","args":{"content":"<h2>New Section</h2><p>Content here.</p>","position":{"after":"Introduction"}}}
// Add a disclaimer before signatures
{"command":"insertContent","args":{"content":"<p>By signing below, parties confirm agreement.</p>","position":{"before":"Signatures"}}}
// Add a clause after a section
{"command":"insertContent","args":{"content":"<p>Additional clause text.</p>","position":{"after":"Section 2."},"author":{"name":"Jane Smith"}}}
insertTable - 创建表格
// Insert 3x4 table after specific text
{"command":"insertTable","args":{"rows":3,"cols":4,"position":{"after":"Introduction"}}}
// Insert 2x2 table (default) before specific text
{"command":"insertTable","args":{"position":{"before":"Signatures"}}}
// Pre-populated table with headers and data (dimensions inferred)
{"command":"insertTable","args":{"data":[["Name","Role"],["Alice","Engineer"]],"position":{"after":"Team:"}}}
// Cells support HTML formatting
{"command":"insertTable","args":{"data":[["<strong>Header</strong>"],["Value"]]}}
// With custom author for track changes
{"command":"insertTable","args":{"rows":2,"cols":3,"author":{"name":"John"}}}
参数:
rows、cols- 表格尺寸(默认值:2;也可根据data推断)data- 单元格内容的二维数组(按行排列)。支持纯文本或 HTML。空单元格使用空字符串。position- 使用{"after": "text"}或{"before": "text"}根据锚定文本定位author- 可选的作者,用于修订归属
addComment - 为文本添加评论
// Add a comment on specific text
{"command":"addComment","args":{"search":"confidential information","comment":"This clause needs legal review"}}
// Comment on nth occurrence
{"command":"addComment","args":{"search":"Party","comment":"Verify party name","occurrence":2}}
参数:
search(必需)- 要查找并附加评论的文本comment(必需)- 评论内容occurrence- 指定匹配项(从 1 开始计数),默认为第一个author- 可选的{name, email},用于标注作者
formatText - 应用格式
应用文本样式、段落属性和标题转换。不记录修订(为提升性能而直接应用)。
// Multiple text formats on entire document
{"command":"formatText","args":{"fontFamily":"Arial","fontSize":"12pt","color":"#333333","scope":"document"}}
// Bold + highlight on specific range (use getNodes to find positions)
{"command":"formatText","args":{"bold":true,"highlight":"#FFEB3B","scope":{"from":100,"to":200}}}
// Remove formatting (false removes, omit leaves unchanged)
{"command":"formatText","args":{"bold":false,"highlight":false,"scope":{"from":100,"to":200}}}
// Add hyperlink to text range
{"command":"formatText","args":{"link":"https://example.com","scope":{"from":100,"to":120}}}
// Remove hyperlink
{"command":"formatText","args":{"link":false,"scope":{"from":100,"to":120}}}
// Set line height on entire document
{"command":"formatText","args":{"lineHeight":"1.5","scope":"document"}}
// Set spacing + indent
{"command":"formatText","args":{"spacingBefore":"12pt","spacingAfter":"6pt","indent":36,"scope":"document"}}
// Align text right (use with scope from getNodes)
{"command":"formatText","args":{"textAlign":"right","scope":{"from":0,"to":25}}}
文本级参数:
fontFamily- 字体名称(例如:"Arial"、"Times New Roman")fontSize- 带单位的字号(例如:"12pt"、"14px")color- CSS 文本颜色(例如:"#ff0000"、"red")highlight- 背景颜色,或使用false移除bold、italic、underline、strikethrough- 使用true应用,使用false移除,省略则保持不变link- 用于创建超链接的 URL 字符串,或使用false移除
块级参数:
textAlign- 段落对齐方式:left、center、right、justifylineHeight- 行间距(例如:"1.0"、"1.5"、"2.0")indent- 左缩进,单位为点(例如:36 表示 0.5",72 表示 1")。使用 0 移除缩进。spacingBefore- 段前间距(例如:"12pt"、"6pt")spacingAfter- 段后间距(例如:"12pt"、"6pt")
范围: "document" 表示整个文档,或使用 {"from": N, "to": M} 指定范围。使用 getNodes 查找位置。
insertTableOfContents - 使用书签创建目录
插入带有内部导航链接的规范目录。由你识别标题条目(位置 + 级别),命令负责处理书签和目录节点的创建。
工作流:
- 使用
getNodes并指定类型paragraph,获取所有段落位置 - 根据文本内容、粗体样式、编号等,识别哪些段落是章节标题。带编号的段落包含
marker字段(例如"marker": "1.")——目录会自动将其添加到条目文本前。 - 将它们的位置和标题级别传递给
insertTableOfContents
// TOC matching document font (always pass style with fontFamily + fontSize)
{"command":"insertTableOfContents","args":{"entries":[{"level":1,"from":227,"to":241},{"level":2,"from":586,"to":601}],"position":{"after":"Non-Disclosure Agreement"},"style":{"fontFamily":"Arial","fontSize":"10pt"}}}
// Custom title
{"command":"insertTableOfContents","args":{"entries":[{"level":2,"from":229,"to":243}],"style":{"fontFamily":"Arial","fontSize":"10pt"},"title":"Contents"}}
// No title
{"command":"insertTableOfContents","args":{"entries":[{"level":2,"from":229,"to":243}],"style":{"fontFamily":"Arial","fontSize":"10pt"},"title":""}}
参数:
entries(必填)-{level: 1-6, from: N, to: M}数组。位置取自getNodes的输出。命令会自动读取文本。position-{"after": "text"}或{"before": "text"}(默认:文档开头)title- 目录标题(默认:"Table of Contents";设为""表示不显示标题)style(必填)-{fontFamily, fontSize},用于匹配文档的字体规范。务必使用html格式的getText检测文档的字体系列和字号,并在此传入。默认应用粗体和黑色(#000000)。标题字号自动比条目大 2pt。可选:使用color覆盖默认黑色。author- 可选,用于修订跟踪归属的作者
命令会在每个标题处插入不可见书签,并创建指向这些书签的目录条目内链。所有条目都会根据其 level 自动设置左缩进(每级 0.5")。现有文本和样式不会被修改。
deleteTableOfContents - 删除目录
从文档中删除目录。
// Remove TOC only
{"command":"deleteTableOfContents","args":{}}
// Remove TOC and its bookmarks
{"command":"deleteTableOfContents","args":{"removeBookmarks":true}}
undo / redo - 历史记录导航
// Undo the last action
{"command":"undo","args":{}}
// Redo the last undone action
{"command":"redo","args":{}}
返回值: 如果操作已撤销/重做,则返回 {"success": true};如果没有可撤销/重做的操作,则返回 {"success": false}。
acceptAllChanges / rejectAllChanges - 完成修订跟踪
接受或拒绝文档中的所有修订。请在编辑完成并审核后使用。
// Accept all tracked changes (removes strikethroughs, keeps insertions)
{"command":"acceptAllChanges","args":{}}
// Reject all tracked changes (removes insertions, restores deleted text)
{"command":"rejectAllChanges","args":{}}
注意: 接受所有修订后,getText 将返回不含已删除内容拼接结果的纯净文本。
页眉/页脚编辑
通过切换编辑模式来编辑文档页眉和页脚。在页眉/页脚模式下,所有命令(getText、replaceText、insertContent 等)都会操作页眉/页脚内容,而不是正文。
focusHeader / focusFooter - 进入页眉/页脚模式
{"command":"focusHeader","args":{}}
{"command":"focusFooter","args":{}}
exitHeaderFooter - 返回正文模式
{"command":"exitHeaderFooter","args":{}}
页眉/页脚工作流
# 1. Focus header
echo '{"command":"focusHeader","args":{}}' > .superdoc/doc.json && until grep -q '"success"' .superdoc/doc.json; do sleep 0.1; done && cat .superdoc/doc.json
# 2. Read current header content
echo '{"command":"getText","args":{"format":"text"}}' > .superdoc/doc.json && until grep -q '"success"' .superdoc/doc.json; do sleep 0.1; done && cat .superdoc/doc.json
# 3. Insert content (no position needed for empty header/footer)
echo '{"command":"insertContent","args":{"content":"<p>CONFIDENTIAL</p>"}}' > .superdoc/doc.json && until grep -q '"success"' .superdoc/doc.json; do sleep 0.1; done && cat .superdoc/doc.json
# 4. Exit back to body
echo '{"command":"exitHeaderFooter","args":{}}' > .superdoc/doc.json && until grep -q '"success"' .superdoc/doc.json; do sleep 0.1; done && cat .superdoc/doc.json
注意:
- DOCX 结构中必须已定义页眉/页脚(无法新建,但可以编辑空白页眉/页脚)
- 对于空白页眉/页脚,不带
position参数的insertContent会在开头插入内容 - 完成后务必执行
exitHeaderFooter,返回正文编辑模式
HTML 格式
| 格式 | HTML |
|---|---|
| 标题 | <h1>、<h2>、<h3> |
| 段落 | <p>Text</p> |
| 粗体/斜体/下划线 | <strong>、<em>、<u> |
| 颜色 | <span style="color: red">text</span> |
| 列表 | <ul><li>...</li></ul>、<ol><li>...</li></ol> |
| 链接 | <a href="url">text</a> |
为现有文本添加链接:
使用带有 link 参数和位置范围的 formatText:
// Step 1: Get paragraph positions
{"command":"getNodes","args":{"type":"paragraph"}}
// Step 2: Apply link to the target range
{"command":"formatText","args":{"link":"https://example.com","scope":{"from":218,"to":230}}}
重要: 只有当替换字符串以 <tag> 开头并以 </tag> 结尾时,才会将其解析为 HTML。若前后包含文本(例如 (<a>text</a>)),则整个字符串会被视为纯文本。
使用 insertContent 创建列表:
// Bullet list
{"command":"insertContent","args":{"content":"<ul><li>First</li><li>Second</li></ul>","position":{"after":"Key points:"}}}
// Numbered list with nested items and formatting
{"command":"insertContent","args":{"content":"<ol><li><strong>Step one</strong><ul><li>Sub-item</li></ul></li><li>Step two</li></ol>","position":{"after":"Instructions:"}}}
批量编辑(多个文档)
当编辑涉及多个文档时,请按顺序逐一处理——打开每个文档、进行编辑、检查,然后再处理下一个。不要使用子 Agent;顺序迭代更简单,也能避免竞争条件。
模式:
for each document:
1. Open: code --profile "Lawvable" path/to/doc.docx
2. Read: getText
3. Edit: replaceText / insertContent
4. Verify response shows success
将文档保留在标签页中打开——编辑期间无需关闭。
故障排查
- 命令未执行/返回原始 JSON:文档未打开。使用
code --profile "Lawvable" path/to/doc.docx重新打开,然后重试。 - 找不到
code命令:改用完整路径/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code。 - “未找到文本”错误:先使用
getText查看实际内容,然后在搜索字符串中加入更多上下文。 - 替换内容损坏:发送命令时未等待响应。发送下一条命令前,务必等待
{"success": ...}。