@clawhub-nicenasa-6ded8bd922
Create, inspect, and edit Microsoft Word documents and DOCX files with reliable styles, numbering, tracked changes, tables, sections, and compatibility check...
---
name: Word / DOCX
slug: word-docx
version: 1.0.2
homepage: https://clawic.com/skills/word-docx
description: "Create, inspect, and edit Microsoft Word documents and DOCX files with reliable styles, numbering, tracked changes, tables, sections, and compatibility checks. Use when (1) the task is about Word or `.docx`; (2) the file includes tracked changes, comments, fields, tables, templates, or page layout constraints; (3) the document must survive round-trip editing without formatting drift."
changelog: Tightened the skill around fragile review workflows, reference stability, and layout drift after a stricter external audit.
metadata: {"clawdbot":{"emoji":"📘","os":["linux","darwin","win32"]}}
---
## When to Use
Use when the main artifact is a Microsoft Word document or `.docx` file, especially when tracked changes, comments, headers, numbering, fields, tables, templates, or compatibility matter.
## Core Rules
### 1. Treat DOCX as OOXML, not plain text
- A `.docx` file is a ZIP of XML parts, so structure matters as much as visible text.
- The critical parts are usually `word/document.xml`, `styles.xml`, `numbering.xml`, headers, footers, and relationship files.
- Text may be split across multiple runs; never assume one word or sentence lives in one XML node.
- Use different workflows on purpose: structured extraction for quick reading, style-driven generation for new files, and OOXML-aware editing for fragile existing documents.
- If the job is mainly reading, extracting, or reviewing, prefer a structure-preserving read path before touching OOXML.
- For deep edits, inspect the package layout instead of relying only on rendered output.
- Reading, generating, and preserving an existing reviewed document are different jobs even when the format is the same.
- Legacy `.doc` inputs usually need conversion before you can trust modern `.docx` assumptions.
### 2. Preserve styles and direct formatting deliberately
- Prefer named styles over direct formatting so the document stays editable.
- Styles layer: paragraph styles, character styles, and direct formatting do not behave the same.
- Removing direct formatting is often safer than stacking more inline formatting on top.
- When editing an existing file, extend the current style system instead of inventing a parallel one.
- Copying content between documents can silently import foreign styles, theme settings, and numbering definitions.
### 3. Lists and numbering are their own system
- Bullets and numbering belong to Word's numbering definitions, not pasted Unicode characters.
- `abstractNum`, `num`, and paragraph numbering properties all matter, so restart behavior is rarely "visual only".
- Indentation and numbering are related but not identical; a list can have broken numbering even if the indent looks right.
- A list that looks correct in one editor can restart, flatten, or renumber itself later if the underlying numbering state is wrong.
### 4. Page layout lives in sections
- Margins, orientation, headers, footers, and page numbering are section-level behavior.
- First-page and odd/even headers can differ inside the same document, so one header fix may not fix the document.
- Set page size explicitly because A4 and US Letter defaults change pagination and table widths.
- Use section breaks for layout changes; manual spacing and stray page breaks usually create drift.
- Header and footer media use part-specific relationships, so copied IDs often break images or links.
- Tables, page breaks, and headers often drift together, so treat layout fixes as document-wide, not local cosmetic edits.
- Table geometry depends on page width, margins, and fixed widths, so "close enough" table edits often break later in Google Docs or LibreOffice.
### 5. Track changes, comments, and fields need precise edits
- Visible text is not the full document when tracked changes are enabled.
- Insertions, deletions, and comments carry metadata that can survive careless edits.
- Deleted text may still exist in the XML even when it no longer appears on screen.
- Comment anchors and review ranges can break if edits move text without preserving the surrounding structure.
- Comment markers and review wrappers do not behave like inline formatting, so moving text carelessly can orphan or misplace them.
- Comments, footnotes, bookmarks, and linked media may live in separate parts, not only in the main document body.
- Tables of contents, page numbers, dates, cross-references, and mail merge placeholders are fields.
- Edit the field source carefully and expect cached display values to lag until refresh.
- Hyperlinks, bookmarks, and references can break if IDs or relationships stop matching.
- Bookmarks, footnotes, comment ranges, and cross-references depend on stable anchors even when the visible text seems untouched.
- A document can look correct while still containing stale field output that refreshes later into something different.
- For review workflows, make minimal replacements instead of rewriting whole paragraphs.
- In tracked-change workflows, only the changed span should look changed; broad rewrites create noisy reviews and can destroy the original formatting context.
- For legal, academic, or business review documents, default to review-style edits over wholesale paragraph rewrites unless the user explicitly wants a rewrite.
### 6. Verify round-trip compatibility before delivery
- Complex documents can shift between Word, LibreOffice, Google Docs, and conversion tools.
- Tables, headers, embedded fonts, and copied styles are common sources of layout drift.
- Treat `.docm` as macro-bearing and higher risk; treat `.doc` as legacy input that may need conversion first.
- When layout matters, explicit table widths are safer than auto-fit or percentage-style behavior that different editors reinterpret.
- A document that passes a text check can still fail on pagination, table widths, or reference refresh after the recipient opens it.
## Common Traps
- Copy-paste can import unwanted styles and numbering definitions.
- Header or footer images use part-specific relationships, so reusing IDs blindly breaks them.
- Empty paragraphs used as spacing make templates fragile; spacing belongs in paragraph settings.
- A clean-looking export can still hide unresolved revisions, comments, or stale field values.
- Restarting lists "by eye" usually fails because numbering state lives outside the paragraph text.
- One visible phrase can be split across several runs, bookmarks, revision tags, or field boundaries.
- Replacing a whole paragraph to change one clause often breaks review quality, bookmarks, comments, or nearby inline formatting.
- Deleting all visible text from a paragraph or list item can still leave behind an empty paragraph mark, empty bullet, or unstable numbering.
- Table auto-fit and percentage-like width behavior can look acceptable in Word and still drift in Google Docs or LibreOffice.
- LibreOffice and Google Docs can shift complex tables, section behavior, and embedded fonts even when Word looks perfect.
- Compatibility mode can silently cap newer features or change pagination behavior.
- A single change in page size or margin defaults can ripple through tables, headers, TOC, and cross-references.
- A revision workflow can look accepted on screen while leftover metadata, comments, or field caches still make the file unstable later.
- TOC entries, footnotes, and cross-references can look correct until the recipient updates fields and exposes broken anchors.
## Related Skills
Install with `clawhub install <slug>` if user confirms:
- `documents` — General document handling and format conversion.
- `brief` — Concise business writing and structured summaries.
- `article` — Long-form drafting and editorial structure.
## Feedback
- If useful: `clawhub star word-docx`
- Stay updated: `clawhub sync`
FILE:_meta.json
{
"ownerId": "kn73vp5rarc3b14rc7wjcw8f8580t5d1",
"slug": "word-docx",
"version": "1.0.2",
"publishedAt": 1773243096816
}This skill should be used when the user asks for news updates, daily briefings, or what's happening in the world. Fetches news from trusted international RSS...
---
name: news-summary
description: This skill should be used when the user asks for news updates, daily briefings, or what's happening in the world. Fetches news from trusted international RSS feeds and can create voice summaries.
---
# News Summary
## Overview
Fetch and summarize news from trusted international sources via RSS feeds.
## RSS Feeds
### BBC (Primary)
```bash
# World news
curl -s "https://feeds.bbci.co.uk/news/world/rss.xml"
# Top stories
curl -s "https://feeds.bbci.co.uk/news/rss.xml"
# Business
curl -s "https://feeds.bbci.co.uk/news/business/rss.xml"
# Technology
curl -s "https://feeds.bbci.co.uk/news/technology/rss.xml"
```
### Reuters
```bash
# World news
curl -s "https://www.reutersagency.com/feed/?best-regions=world&post_type=best"
```
### NPR (US perspective)
```bash
curl -s "https://feeds.npr.org/1001/rss.xml"
```
### Al Jazeera (Global South perspective)
```bash
curl -s "https://www.aljazeera.com/xml/rss/all.xml"
```
## Parse RSS
Extract titles and descriptions:
```bash
curl -s "https://feeds.bbci.co.uk/news/world/rss.xml" | \
grep -E "<title>|<description>" | \
sed 's/<[^>]*>//g' | \
sed 's/^[ \t]*//' | \
head -30
```
## Workflow
### Text summary
1. Fetch BBC world headlines
2. Optionally supplement with Reuters/NPR
3. Summarize key stories
4. Group by region or topic
### Voice summary
1. Create text summary
2. Generate voice with OpenAI TTS
3. Send as audio message
```bash
curl -s https://api.openai.com/v1/audio/speech \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "tts-1-hd",
"input": "<news summary text>",
"voice": "onyx",
"speed": 0.95
}' \
--output /tmp/news.mp3
```
## Example Output Format
```
📰 News Summary [date]
🌍 WORLD
- [headline 1]
- [headline 2]
💼 BUSINESS
- [headline 1]
💻 TECH
- [headline 1]
```
## Best Practices
- Keep summaries concise (5-8 top stories)
- Prioritize breaking news and major events
- For voice: ~2 minutes max
- Balance perspectives (Western + Global South)
- Cite source if asked
FILE:_meta.json
{
"ownerId": "kn72thdm1qe7rrz0vn4vqq3a297ymazh",
"slug": "news-summary",
"version": "1.0.1",
"publishedAt": 1767689990078
}Convert documents and files to Markdown using markitdown. Use when converting PDF, Word (.docx), PowerPoint (.pptx), Excel (.xlsx, .xls), HTML, CSV, JSON, XM...
---
name: markdown-converter
description: Convert documents and files to Markdown using markitdown. Use when converting PDF, Word (.docx), PowerPoint (.pptx), Excel (.xlsx, .xls), HTML, CSV, JSON, XML, images (with EXIF/OCR), audio (with transcription), ZIP archives, YouTube URLs, or EPubs to Markdown format for LLM processing or text analysis.
---
# Markdown Converter
Convert files to Markdown using `uvx markitdown` — no installation required.
## Basic Usage
```bash
# Convert to stdout
uvx markitdown input.pdf
# Save to file
uvx markitdown input.pdf -o output.md
uvx markitdown input.docx > output.md
# From stdin
cat input.pdf | uvx markitdown
```
## Supported Formats
- **Documents**: PDF, Word (.docx), PowerPoint (.pptx), Excel (.xlsx, .xls)
- **Web/Data**: HTML, CSV, JSON, XML
- **Media**: Images (EXIF + OCR), Audio (EXIF + transcription)
- **Other**: ZIP (iterates contents), YouTube URLs, EPub
## Options
```bash
-o OUTPUT # Output file
-x EXTENSION # Hint file extension (for stdin)
-m MIME_TYPE # Hint MIME type
-c CHARSET # Hint charset (e.g., UTF-8)
-d # Use Azure Document Intelligence
-e ENDPOINT # Document Intelligence endpoint
--use-plugins # Enable 3rd-party plugins
--list-plugins # Show installed plugins
```
## Examples
```bash
# Convert Word document
uvx markitdown report.docx -o report.md
# Convert Excel spreadsheet
uvx markitdown data.xlsx > data.md
# Convert PowerPoint presentation
uvx markitdown slides.pptx -o slides.md
# Convert with file type hint (for stdin)
cat document | uvx markitdown -x .pdf > output.md
# Use Azure Document Intelligence for better PDF extraction
uvx markitdown scan.pdf -d -e "https://your-resource.cognitiveservices.azure.com/"
```
## Notes
- Output preserves document structure: headings, tables, lists, links
- First run caches dependencies; subsequent runs are faster
- For complex PDFs with poor extraction, use `-d` with Azure Document Intelligence
FILE:_meta.json
{
"ownerId": "kn70pywhg0fyz996kpa8xj89s57yhv26",
"slug": "markdown-converter",
"version": "1.0.0",
"publishedAt": 1767651965151
}Provides real-time A-share stock market data from Sina Finance API for individual stocks and indices by code.
# A 股行情 Skill
实时获取 A 股股票行情数据(使用新浪财经免费 API)
## 命令
```bash
# 查询单只股票
a-stock <股票代码>
# 查询多只股票
a-stock <代码 1> <代码 2> ...
# 查询指数
a-stock sh000001 # 上证指数
a-stock sz399001 # 深证成指
a-stock sh000300 # 沪深 300
```
## 股票代码格式
- 上交所:`sh` + 6 位数字 (如 `sh600519` 贵州茅台)
- 深交所:`sz` + 6 位数字 (如 `sz000858` 五粮液)
## 示例
```bash
a-stock sh600519
a-stock sz000858 sh600519
```
FILE:README.md
# A 股行情 Skill - 实时获取 A 股股票行情
使用腾讯财经免费 API,无需 API Key。
## 安装
```bash
# 创建符号链接(需要 sudo 密码)
sudo ln -sf ~/.openclaw/workspace/skills/a-stock-market/a-stock.py /usr/local/bin/a-stock
# 或者直接在技能目录运行
python3 ~/.openclaw/workspace/skills/a-stock-market/a-stock.py sh600519
```
## 用法
```bash
# 查询单只股票
a-stock sh600519 # 贵州茅台
a-stock sz000858 # 五粮液
# 查询多只股票
a-stock sh600519 sz000858 sh000300
# 查询指数
a-stock sh000001 # 上证指数
a-stock sz399001 # 深证成指
a-stock sh000300 # 沪深 300
```
## 股票代码格式
- **上交所**: `sh` + 6 位数字
- `sh600519` 贵州茅台
- `sh601318` 中国平安
- `sh000001` 上证指数
- **深交所**: `sz` + 6 位数字
- `sz000858` 五粮液
- `sz300750` 宁德时代
- `sz399001` 深证成指
## 输出示例
```
📈 贵州茅台 (sh600519)
现价:1680.00 +1.23%
开盘:1665.00 最高:1685.00 最低:1660.00
昨收:1659.50
成交量:12345 手 成交额:20678 万
```
## 数据来源
腾讯财经免费 API: `https://qt.gtimg.cn/q={股票代码}`
- 实时更新(交易时间内)
- 无需 API Key
- 支持 A 股所有股票和指数
FILE:_meta.json
{
"ownerId": "kn728eqpsd3ztk33hxgcv6csp180sxta",
"slug": "a-stock-market",
"version": "1.0.0",
"publishedAt": 1772910851760
}
FILE:a-stock.py
#!/usr/bin/env python3
"""
A 股行情查询 - 使用腾讯财经免费 API
"""
import sys
import urllib.request
def get_stock_info(symbol):
"""获取股票信息 - 腾讯财经 API"""
url = f"https://qt.gtimg.cn/q={symbol}"
try:
req = urllib.request.Request(url, headers={
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
'Referer': 'https://stock.tencent.com/'
})
with urllib.request.urlopen(req, timeout=5) as response:
data = response.read().decode('gbk')
# 解析:v_sh600519="1~ 贵州茅台~600519~1426.19~1440.11~..."
if '~' in data:
# 去掉开头的 v_xxxxxx="
data = data.split('="')[1].strip('";')
parts = data.split('~')
if len(parts) >= 35:
name = parts[1] if len(parts) > 1 else symbol
current = float(parts[3]) if parts[3] else 0
last_close = float(parts[4]) if parts[4] else 0
open_price = float(parts[5]) if parts[5] else 0
high = float(parts[33]) if len(parts) > 33 and parts[33] else 0
low = float(parts[34]) if len(parts) > 34 and parts[34] else 0
volume = float(parts[6]) if len(parts) > 6 and parts[6] else 0
amount = float(parts[7]) if len(parts) > 7 and parts[7] else 0 # 成交额 (万)
return {
'name': name,
'symbol': symbol,
'current': current,
'open': open_price,
'high': high,
'low': low,
'volume': volume,
'amount': amount, # 万
'last_close': last_close,
}
except Exception as e:
return {'error': str(e)}
return None
def format_change(current, last_close):
"""计算涨跌幅"""
if last_close == 0:
return 0
return ((current - last_close) / last_close) * 100
def main():
if len(sys.argv) < 2:
print("用法:a-stock <股票代码> [代码 2] ...\n示例:a-stock sh600519 sz000858")
sys.exit(1)
symbols = sys.argv[1:]
for symbol in symbols:
info = get_stock_info(symbol)
if info and 'error' not in info:
change = format_change(info['current'], info['last_close'])
change_str = f"{'+' if change >= 0 else ''}{change:.2f}%"
arrow = "📈" if change >= 0 else "📉"
print(f"{arrow} {info['name']} ({info['symbol']})")
print(f" 现价:{info['current']:.2f} {change_str}")
print(f" 开盘:{info['open']:.2f} 最高:{info['high']:.2f} 最低:{info['low']:.2f}")
print(f" 昨收:{info['last_close']:.2f}")
print(f" 成交量:{info['volume']:.0f}手 成交额:{info['amount']:.0f}万")
print()
elif info and 'error' in info:
print(f"❌ {symbol}: {info['error']}")
else:
print(f"❌ {symbol}: 无法获取数据")
if __name__ == '__main__':
main()