원클릭으로
obsidian-wechat-publisher-dev
开发 Obsidian 微信公众号发布插件的关键技术点和踩坑记录
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
开发 Obsidian 微信公众号发布插件的关键技术点和踩坑记录
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
高德地图综合服务,支持POI搜索、路径规划、旅游规划、周边搜索和热力图数据可视化
Knowledge comic creator supporting multiple art styles and tones. Creates original educational comics with detailed panel layouts and sequential image generation. Use when user asks to create "知识漫画", "教育漫画", "biography comic", "tutorial comic", or "Logicomix-style comic".
Generate professional infographics with 21 layout types and 21 visual styles. Analyzes content, recommends layout×style combinations, and generates publication-ready infographics. Use when user asks to create "infographic", "visual summary", "信息图", "可视化", or "高密度信息大图".
Darwin Skill (达尔文.skill): autonomous skill optimizer inspired by Karpathy's autoresearch. Evaluates SKILL.md files using an 8-dimension rubric (structure + effectiveness), runs hill-climbing with git version control, validates improvements through test prompts, and generates visual result cards. Use when user mentions "优化skill", "skill评分", "自动优化", "auto optimize", "skill质量检查", "达尔文", "darwin", "帮我改改skill", "skill怎么样", "提升skill质量", "skill review", "skill打分".
从 DESIGN.md 生成预览图并截图的工作流 - 解决 Playwright 浏览器路径问题和 YAML 解析
Cron jobs auto-deliver final responses to configured targets — send_message to the same target gets deduplicated and skipped. Print report content directly as final response instead.
SOC 직업 분류 기준
| name | obsidian-wechat-publisher-dev |
| description | 开发 Obsidian 微信公众号发布插件的关键技术点和踩坑记录 |
| version | 1.0.0 |
| author | Hermes Agent |
| metadata | {"hermes":{"tags":["obsidian","plugin","wechat","typescript","esbuild"]}} |
/opt/data/workspace/Projects/obsidian-wechat-publisher/
Markdown → Obsidian MarkdownRenderer.render() → DOM
→ cleanObsidianUIElements() 清理 Obsidian UI 控件
→ formatContent() 结构化处理
├── 列表 ul/ol/li → 纯 <section> 结构(⚠️ 必须,防公众号还原默认样式)
├── 代码块 <pre> → 添加 macOS 窗口按钮(3 个彩色圆点用 <section>+inline style)
├── Callout → 内联样式的 section 结构
└── 内部嵌入图片 → 解析为 <img>
→ ThemeManager.applyTheme() 注入 <style> 标签(预览用)
→ 序列化为 HTML 字符串
→ juice 将 CSS 内联到每个元素的 style 属性
→ 输出(复制到剪贴板 / 发布)
<section> 结构公众号会自动还原 ul/ol/li 的默认样式,导致主题 CSS 失效。
转换后的 DOM:
<section class="wp-list-section" data-list-type="ordered|unordered">
<section class="wp-list-item" style="padding-left:{indent}em;line-height:1.8;">
<section class="wp-list-marker">1. </section>
<section class="wp-list-content">内容</section>
</section>
</section>
CSS 主题中禁止使用 ul/ol/li 选择器,必须用 .wp-list-section/.wp-list-item/.wp-list-marker。
#wenyan 容器MarkdownRenderer.render() 输出到普通 div,没有 id。
所有主题 CSS 选择器以 #wenyan 开头,所以预览必须手动创建 <div id="wenyan"> 包裹:
const wenyanWrapper = renderEl.createEl('div', { attr: { id: 'wenyan' } });
await MarkdownRenderer.render(app, content, wenyanWrapper, sourcePath, component);
themeManager.applyTheme(wenyanWrapper, 'wp-preview');
将 .css 文件作为 string 导入(打包进 main.js),loaders 选项在 context() API 中无效,必须用插件:
const cssRawLoader = {
name: 'css-raw-loader',
setup(build) {
build.onResolve({ filter: /\.css$/ }, args => ({
path: path.resolve(args.resolveDir, args.path),
}));
build.onLoad({ filter: /\.css$/ }, async (args) => ({
contents: fs.readFileSync(args.path, 'utf8'),
loader: 'text',
}));
},
};
var(--xxx)、::before/::after、@media、@font-face、!importantpreserveMediaQueries: false + preserveFontFaces: falsefont-family 和 font-size 被 ThemeManager 的 !important 覆盖必须用 ClipboardItem + text/html MIME,不能用 writeText():
const clipData = new ClipboardItem({
'text/html': new Blob([finalHtml], { type: 'text/html' }),
'text/plain': new Blob([plainText], { type: 'text/plain' }),
});
await navigator.clipboard.write([clipData]);
18 个元素维度,每个可独立指定主题来源。
实现方式:基础主题完整 CSS + 每个覆盖维度从指定主题提取匹配规则追加到末尾(CSS 级联覆盖)。
选择器匹配用 DIMENSION_SELECTOR_MAP 常量,按 } 分割 CSS 块后匹配选择器关键字。