@topmindspace/tms-skills 0.3.5 → 0.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +88 -1
- package/README.en.md +4 -4
- package/README.md +4 -4
- package/bin/tms-skills.js +9 -1
- package/package.json +1 -1
- package/top-ppt-html/README.en.md +2 -2
- package/top-ppt-html/README.md +1 -1
- package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.html +43 -14
- package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.html +43 -14
- package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.html +43 -14
- package/top-ppt-html/assets/examples/2026-09-26-topmind-tms-skills-showcase.html +43 -14
- package/top-ppt-html/assets/pptx-export.js +42 -13
- package/top-ppt-html/assets/style-gallery.html +1 -1
- package/top-ppt-html/assets/templates/architecture.html +45 -15
- package/top-ppt-html/assets/templates/presentation.html +45 -15
- package/top-ppt-html/assets/templates/research.html +45 -15
- package/top-ppt-html/scripts/audit_css.py +1 -1
- package/top-ppt-html/scripts/build_pptx.js +136 -25
- package/top-ppt-html/scripts/layout-constants.json +1 -1
- package/top-ppt-html/scripts/regression.py +3 -3
- package/top-ppt-html/scripts/render_compare.py +1 -1
- package/top-ppt-html/scripts/scaffold_report.py +1 -1
- package/top-ppt-html/scripts/sync_runtime.py +14 -14
- package/top-ppt-html/scripts/validate_report.py +4 -0
- package/topmind-cover/README.en.md +8 -9
- package/topmind-cover/README.md +8 -9
- package/topmind-cover/SKILL.md +28 -8
- package/topmind-cover/assets/examples/README.md +2 -2
- package/topmind-cover/assets/examples/big-type-wechat.png +0 -0
- package/topmind-cover/assets/examples/big-type.png +0 -0
- package/topmind-cover/assets/examples/brand-launch-wechat.png +0 -0
- package/topmind-cover/assets/examples/brand-launch.png +0 -0
- package/topmind-cover/assets/examples/gan-huo-wechat.png +0 -0
- package/topmind-cover/assets/examples/gan-huo.png +0 -0
- package/topmind-cover/assets/examples/ip-fun-wechat.png +0 -0
- package/topmind-cover/assets/examples/ip-fun.png +0 -0
- package/topmind-cover/assets/examples/magazine-wechat.png +0 -0
- package/topmind-cover/assets/examples/magazine.png +0 -0
- package/topmind-cover/assets/examples/minimal-wechat.png +0 -0
- package/topmind-cover/assets/examples/minimal.png +0 -0
- package/topmind-cover/assets/examples/news-flash-wechat.png +0 -0
- package/topmind-cover/assets/examples/news-flash.png +0 -0
- package/topmind-cover/assets/examples/overview.png +0 -0
- package/topmind-cover/assets/examples/tutorial-steps-wechat.png +0 -0
- package/topmind-cover/assets/examples/tutorial-steps.png +0 -0
- package/topmind-cover/references/cover-styles.md +160 -172
- package/topmind-cover/references/impact-language.md +91 -0
- package/topmind-cover/scripts/crop-cover.py +19 -13
- package/topmind-wechat-post/README.en.md +2 -2
- package/topmind-wechat-post/README.md +2 -2
- package/topmind-wechat-post/SKILL.md +1 -1
- package/topmind-wechat-post/scripts/md2wechat.py +12 -3
- package/topmind-x-article/README.en.md +1 -1
- package/topmind-x-article/README.md +1 -1
- package/topmind-x-article/scripts/md2x.py +7 -2
|
@@ -31,7 +31,10 @@ def main() -> None:
|
|
|
31
31
|
|
|
32
32
|
src = Path(args.src)
|
|
33
33
|
out_dir = Path(args.out_dir)
|
|
34
|
-
|
|
34
|
+
try:
|
|
35
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
36
|
+
except OSError as e:
|
|
37
|
+
sys.exit(f"错误:无法创建输出目录 {out_dir}({e})")
|
|
35
38
|
|
|
36
39
|
if not src.is_file():
|
|
37
40
|
sys.exit(f"错误:找不到输入图片 {src}")
|
|
@@ -50,18 +53,21 @@ def main() -> None:
|
|
|
50
53
|
x0, y0 = (w - cw) // 2, (h - ch) // 2
|
|
51
54
|
base = img.crop((x0, y0, x0 + cw, y0 + ch))
|
|
52
55
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
56
|
+
try:
|
|
57
|
+
for name, (tw, th) in TARGETS.items():
|
|
58
|
+
ratio = tw / th
|
|
59
|
+
bw, bh = base.size
|
|
60
|
+
if bw / bh > ratio:
|
|
61
|
+
cw2, ch2 = int(bh * ratio), bh
|
|
62
|
+
else:
|
|
63
|
+
cw2, ch2 = bw, int(bw / ratio)
|
|
64
|
+
x1, y1 = (bw - cw2) // 2, (bh - ch2) // 2
|
|
65
|
+
out = base.crop((x1, y1, x1 + cw2, y1 + ch2)).resize((tw, th), Image.LANCZOS)
|
|
66
|
+
dest = out_dir / name
|
|
67
|
+
out.save(dest)
|
|
68
|
+
print(f"OK {dest} ({tw}x{th})")
|
|
69
|
+
except OSError as e:
|
|
70
|
+
sys.exit(f"错误:写入封面图失败({e})")
|
|
65
71
|
|
|
66
72
|
|
|
67
73
|
if __name__ == "__main__":
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Full lifecycle for WeChat articles: delivery package, review & rewrite, three quality gates, status sync, WeChat inline typography, and publish checklist.
|
|
6
6
|
|
|
7
|
-
- Version: **v0.1.0** (same tag as `@topmindspace/tms-skills@0.3.
|
|
7
|
+
- Version: **v0.1.0** (same tag as `@topmindspace/tms-skills@0.3.9`)
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
@@ -60,7 +60,7 @@ Output `demo/demo-公众号版.html` (open in a browser → click "复制正文"
|
|
|
60
60
|
|
|
61
61
|
```html
|
|
62
62
|
<!-- h2 auto-numbered; closing chapters like "总结" get ∞ -->
|
|
63
|
-
<h2 ...><span ...>
|
|
63
|
+
<h2 ...><span ...>1</span>Chapter One</h2>
|
|
64
64
|
<!-- images inlined as base64, pasted along with the text -->
|
|
65
65
|
<img src="data:image/png;base64,iVBORw0KGgo..." ...>
|
|
66
66
|
```
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
公众号文章全生命周期:交付包、审校改写、质量三关、状态同步、微信内联排版与发布清单。
|
|
6
6
|
|
|
7
|
-
- 版本:**v0.1.0**(与 `@topmindspace/tms-skills@0.3.
|
|
7
|
+
- 版本:**v0.1.0**(与 `@topmindspace/tms-skills@0.3.9` 同 tag)
|
|
8
8
|
|
|
9
9
|
## 安装
|
|
10
10
|
|
|
@@ -59,7 +59,7 @@ python3 scripts/md2wechat.py --input demo.md --out-dir demo --slug demo --embed-
|
|
|
59
59
|
|
|
60
60
|
```html
|
|
61
61
|
<!-- 二级标题自动编号;"总结"类末章编号为 ∞ -->
|
|
62
|
-
<h2 ...><span ...>
|
|
62
|
+
<h2 ...><span ...>1</span>第一章</h2>
|
|
63
63
|
<!-- 图片 base64 内嵌,粘贴即带图 -->
|
|
64
64
|
<img src="data:image/png;base64,iVBORw0KGgo..." ...>
|
|
65
65
|
```
|
|
@@ -50,7 +50,7 @@ updated: 2026-09-29
|
|
|
50
50
|
| `scripts/scan_ai_flavor.py` | 中文去 AI 味扫描(与 `qu-aiwei-zh` 同源) |
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
|
-
# 路径解析:CLI --base
|
|
53
|
+
# 路径解析:CLI --base → env TOPMIND_WECHAT_BASE / TOPMIND_WORKSPACE / TOPSTREAM_ROOT → 惯例
|
|
54
54
|
export TOPMIND_WORKSPACE=/path/to/workspace # 推荐
|
|
55
55
|
python3 scripts/new-article.py --slug demo --title "标题" --direction reverse
|
|
56
56
|
python3 scripts/lint-wechat.py --input <包>/公众号稿.md --fix
|
|
@@ -920,7 +920,10 @@ def resolve_image(src, md_path, out_dir, assets, asset_root):
|
|
|
920
920
|
"missing": True})
|
|
921
921
|
return src
|
|
922
922
|
img_dir = os.path.join(out_dir, "images")
|
|
923
|
-
|
|
923
|
+
try:
|
|
924
|
+
os.makedirs(img_dir, exist_ok=True)
|
|
925
|
+
except OSError as e:
|
|
926
|
+
sys.exit("错误:无法创建图片目录 %s(%s)" % (img_dir, e))
|
|
924
927
|
base = os.path.basename(abs_path)
|
|
925
928
|
target = os.path.join(img_dir, base)
|
|
926
929
|
n = 1
|
|
@@ -929,7 +932,10 @@ def resolve_image(src, md_path, out_dir, assets, asset_root):
|
|
|
929
932
|
target = os.path.join(img_dir, "%s-%d%s" % (stem, n, ext))
|
|
930
933
|
n += 1
|
|
931
934
|
if not os.path.exists(target):
|
|
932
|
-
|
|
935
|
+
try:
|
|
936
|
+
shutil.copy2(abs_path, target)
|
|
937
|
+
except OSError as e:
|
|
938
|
+
sys.exit("错误:复制图片失败 %s → %s(%s)" % (abs_path, target, e))
|
|
933
939
|
rel = os.path.relpath(target, out_dir)
|
|
934
940
|
assets.append({"src": src, "local": rel, "remote": False,
|
|
935
941
|
"basename": os.path.basename(target),
|
|
@@ -1609,7 +1615,10 @@ def main():
|
|
|
1609
1615
|
except OSError as e:
|
|
1610
1616
|
sys.exit("错误:无法读取输入文件 %s(%s)" % (args.input, e))
|
|
1611
1617
|
|
|
1612
|
-
|
|
1618
|
+
try:
|
|
1619
|
+
os.makedirs(args.out_dir, exist_ok=True)
|
|
1620
|
+
except OSError as e:
|
|
1621
|
+
sys.exit("错误:无法创建输出目录 %s(%s)" % (args.out_dir, e))
|
|
1613
1622
|
body, assets, diagrams, footnotes = convert(
|
|
1614
1623
|
md_text, os.path.abspath(args.input), args.out_dir, theme,
|
|
1615
1624
|
args.link_mode, args.render_mermaid, args.asset_root or None,
|
|
@@ -281,6 +281,8 @@ def main() -> None:
|
|
|
281
281
|
|
|
282
282
|
inp = Path(args.input)
|
|
283
283
|
if not inp.is_file():
|
|
284
|
+
if inp.is_dir():
|
|
285
|
+
sys.exit(f"错误:输入是目录不是文件 {inp}")
|
|
284
286
|
sys.exit(f"错误:找不到输入文件 {inp}")
|
|
285
287
|
try:
|
|
286
288
|
md = inp.read_text(encoding="utf-8-sig")
|
|
@@ -291,8 +293,11 @@ def main() -> None:
|
|
|
291
293
|
text, images = convert(md)
|
|
292
294
|
|
|
293
295
|
out = Path(args.out)
|
|
294
|
-
|
|
295
|
-
|
|
296
|
+
try:
|
|
297
|
+
out.parent.mkdir(parents=True, exist_ok=True)
|
|
298
|
+
out.write_text(text, encoding="utf-8")
|
|
299
|
+
except OSError as e:
|
|
300
|
+
sys.exit(f"错误:无法写入输出文件 {out}({e})")
|
|
296
301
|
|
|
297
302
|
chars = len(text.replace("\n", ""))
|
|
298
303
|
print(f"OK {out}")
|