publish-substack-article
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePublish Substack Article
发布Substack文章
Publish Markdown content to Substack post editor, converting Markdown to HTML and pasting as rich text. Saves as draft for user review before publishing.
将Markdown内容发布到Substack文章编辑器,将Markdown转换为HTML并粘贴为富文本。保存为草稿供用户审核后再发布。
Prerequisites
前提条件
- Browser automation MCP (either one):
- Chrome DevTools MCP ()
mcp__chrome-devtools__* - Playwright MCP ()
mcp__playwright__*
- Chrome DevTools MCP (
- User logged into Substack
- Python 3 with package (
markdown)pip install markdown - script (shared from publish-zsxq-article skill)
copy_to_clipboard.py
- 浏览器自动化MCP(任选其一):
- Chrome DevTools MCP ()
mcp__chrome-devtools__* - Playwright MCP ()
mcp__playwright__*
- Chrome DevTools MCP (
- 用户已登录Substack
- 安装了包的Python 3环境(执行
markdown安装)pip install markdown - 脚本(来自publish-zsxq-article技能)
copy_to_clipboard.py
Browser MCP Tool Mapping
浏览器MCP工具映射
This skill works with both Chrome DevTools MCP and Playwright MCP. Use whichever is available:
| Action | Chrome DevTools MCP | Playwright MCP |
|---|---|---|
| Navigate | | |
| Take snapshot | | |
| Take screenshot | | |
| Click element | | |
| Fill text | | |
| Press key | | |
| Evaluate JS | | |
Detection: Check available tools at runtime. If exists, use Chrome DevTools MCP. If exists, use Playwright MCP.
mcp__chrome-devtools__navigate_pagemcp__playwright__browser_navigate本技能兼容Chrome DevTools MCP和Playwright MCP,使用可用的任意一种即可:
| 操作 | Chrome DevTools MCP | Playwright MCP |
|---|---|---|
| 导航页面 | | |
| 生成快照 | | |
| 截取屏幕截图 | | |
| 点击元素 | | |
| 填充文本 | | |
| 按键操作 | | |
| 执行JS | | |
检测方式:运行时检查可用工具。若存在,则使用Chrome DevTools MCP;若存在,则使用Playwright MCP。
mcp__chrome-devtools__navigate_pagemcp__playwright__browser_navigateKey URLs
关键URL
- Substack dashboard:
https://{publication}.substack.com/publish - Post editor:
https://{publication}.substack.com/publish/post/{postId} - Default publication:
verysmallwoods
- Substack控制台:
https://{publication}.substack.com/publish - 文章编辑器:
https://{publication}.substack.com/publish/post/{postId} - 默认发布账号:
verysmallwoods
Editor Interface
编辑器界面
The Substack post editor uses Tiptap (ProseMirror-based WYSIWYG editor).
Substack文章编辑器使用Tiptap(基于ProseMirror的WYSIWYG编辑器)。
Key Elements
关键元素
- Title input: (placeholder: "Title")
textbox "title" - Subtitle input:
textbox "Add a subtitle…" - Content area: (Tiptap editor, "Start writing...")
.ProseMirror - Save status: (auto-saves)
button "Saved" - Preview button:
button "Preview" - Continue button: (publish flow - DO NOT USE)
button "Continue" - Settings sidebar: (title, description, thumbnail)
button "Settings"
- 标题输入框:(占位符:"Title")
textbox "title" - 副标题输入框:
textbox "Add a subtitle…" - 内容区域:(Tiptap编辑器,提示文字:"Start writing...")
.ProseMirror - 保存状态:(自动保存)
button "Saved" - 预览按钮:
button "Preview" - 继续按钮:(发布流程按钮 - 禁止使用)
button "Continue" - 设置侧边栏:(可设置标题、描述、缩略图)
button "Settings"
Settings Sidebar (left panel)
设置侧边栏(左侧面板)
When "Settings" or "File Settings" is open:
- Title:
textbox "Add a title..." - Description:
textbox "Add a description..." - Thumbnail: Upload button (3:2 aspect ratio)
当“Settings”或“File Settings”打开时:
- 标题:
textbox "Add a title..." - 描述:
textbox "Add a description..." - 缩略图:上传按钮(比例3:2)
Toolbar
工具栏
Bold, Italic, Strikethrough, Code, Link, Image, Audio, Video, Quote, Lists (bullet/ordered), Button, More (Code block, Divider, Footnote, LaTeX, etc.)
加粗、斜体、删除线、行内代码、链接、图片、音频、视频、引用、列表(无序列表/有序列表)、按钮、更多选项(代码块、分隔线、脚注、LaTeX等)
Content Insertion Method
内容插入方式
CRITICAL: Use clipboard paste with HTML content, NOT direct fill or plain Markdown paste.
The Tiptap editor handles HTML paste natively and renders it as rich content. The workflow is:
- Convert Markdown to HTML using Python's library
markdown - Copy HTML to system clipboard using
copy_to_clipboard.py html - Focus the editor content area
- Press Cmd+V (macOS) or Ctrl+V (Windows/Linux) to paste
Why HTML paste?
- tool → Content treated as plain text, no formatting
fill - Plain Markdown paste → Tiptap does NOT parse Markdown on paste
- HTML paste → Tiptap renders HTML as rich content (headings, code blocks, links, bold, etc.)
Known limitation: Substack's editor does NOT support HTML tables. Tables will be collapsed into plain text. See Step 0: Pre-Processing for converting tables to images.
重要提示:使用剪贴板粘贴HTML内容,禁止直接填充或粘贴纯文本Markdown
Tiptap编辑器原生支持HTML粘贴,并会将其渲染为富文本内容。工作流如下:
- 使用Python的库将Markdown转换为HTML
markdown - 使用将HTML复制到系统剪贴板
copy_to_clipboard.py html - 聚焦编辑器内容区域
- 按下Cmd+V(macOS)或Ctrl+V(Windows/Linux)进行粘贴
为何选择HTML粘贴?
- 工具 → 内容会被视为纯文本,丢失所有格式
fill - 纯Markdown粘贴 → Tiptap不会解析Markdown格式
- HTML粘贴 → Tiptap会将HTML渲染为富文本内容(包括标题、代码块、链接、加粗等)
已知限制:Substack编辑器不支持HTML表格。表格会被折叠为纯文本。请查看步骤0:预处理部分了解如何将表格转换为图片。
Main Workflow
主工作流
Step 0: Pre-Processing — Convert Tables to Images
步骤0:预处理 — 将表格转换为图片
Substack does NOT render HTML tables. They collapse into plain text. Any Markdown table must be converted to a PNG image and uploaded separately.
Workflow:
-
Detect tables in the Markdown file (lines withforming table structure)
| -
Create styled HTML for each table:
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 0; padding: 20px; background: white; }
table { border-collapse: collapse; width: 100%; font-size: 15px; line-height: 1.6; }
th { background: #f8f8f8; font-weight: 600; text-align: left; padding: 10px 16px; border-bottom: 2px solid #e0e0e0; }
td { padding: 8px 16px; border-bottom: 1px solid #eee; }
tr:hover { background: #fafafa; }
code { background: #f0f0f0; padding: 2px 6px; border-radius: 3px; font-size: 13px; font-family: 'SF Mono', Menlo, monospace; }
</style>
</head>
<body>
<table>
<!-- table content here -->
</table>
</body>
</html>- Render to screenshot: Open the HTML file in a browser tab, take a screenshot, close the tab:
undefinedSubstack不渲染HTML表格,表格会被折叠为纯文本。所有Markdown表格都必须转换为PNG图片并单独上传。
工作流:
-
检测表格:在Markdown文件中检测表格(包含的行组成的表格结构)
| -
为每个表格创建带样式的HTML:
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 0; padding: 20px; background: white; }
table { border-collapse: collapse; width: 100%; font-size: 15px; line-height: 1.6; }
th { background: #f8f8f8; font-weight: 600; text-align: left; padding: 10px 16px; border-bottom: 2px solid #e0e0e0; }
td { padding: 8px 16px; border-bottom: 1px solid #eee; }
tr:hover { background: #fafafa; }
code { background: #f0f0f0; padding: 2px 6px; border-radius: 3px; font-size: 13px; font-family: 'SF Mono', Menlo, monospace; }
</style>
</head>
<body>
<table>
<!-- table content here -->
</table>
</body>
</html>- 渲染为截图:在浏览器标签页中打开HTML文件,截取屏幕截图,关闭标签页:
undefinedOpen HTML in new tab
在新标签页中打开HTML
browser_navigate or new_page: file:///tmp/table1.html
browser_navigate or new_page: file:///tmp/table1.html
Take screenshot
截取屏幕截图
browser_take_screenshot: filename=/tmp/table1.png, fullPage=true
browser_take_screenshot: filename=/tmp/table1.png, fullPage=true
Close tab and return to editor
关闭标签页并返回编辑器
browser_tabs: action=close
4. **Note the position** of each table in the article for later insertion (after which heading/paragraph)
5. **Remove table Markdown** from the content before HTML conversion (so it won't appear as plain text in the pasted content)
**Image upload** happens after pasting the main content — see Step 7.browser_tabs: action=close
4. **记录每个表格在文章中的位置**:以便后续插入(在哪个标题/段落之后)
5. **在HTML转换前移除表格的Markdown内容**:避免粘贴时出现纯文本表格
**图片上传**:在粘贴主内容后进行 — 请查看步骤7。Step 1: Prepare Content
步骤1:准备内容
Read the Markdown file and extract:
- Title: from YAML frontmatter field, or H1 header
title, or filename# Title - Subtitle: from YAML frontmatter or
excerptfielddescription - Content: full Markdown body (strip YAML frontmatter and any cross-reference links)
读取Markdown文件并提取:
- 标题:来自YAML前置元数据的字段,或H1标题
title,或文件名# Title - 副标题:来自YAML前置元数据的或
excerpt字段description - 内容:完整的Markdown正文(移除YAML前置元数据和任何交叉引用链接)
Step 2: Convert Markdown to HTML
步骤2:将Markdown转换为HTML
Use Python's library with and extensions:
markdowntablesfenced_codepython
import markdown
import re
with open('/path/to/article.md', 'r') as f:
content = f.read()使用Python的库,并启用和扩展:
markdowntablesfenced_codepython
import markdown
import re
with open('/path/to/article.md', 'r') as f:
content = f.read()Strip YAML frontmatter
移除YAML前置元数据
content = re.sub(r'^---\n.*?\n---\n', '', content, flags=re.DOTALL)
content = re.sub(r'^---\n.*?\n---\n', '', content, flags=re.DOTALL)
Strip cross-reference links (e.g., English version link)
移除交叉引用链接(例如,英文版本链接)
Adjust pattern as needed for your articles
根据你的文章调整匹配模式
content = re.sub(r'^> .* available at.*\n\n?', '', content, flags=re.MULTILINE)
content = re.sub(r'^> .* available at.*\n\n?', '', content, flags=re.MULTILINE)
Convert to HTML
转换为HTML
html = markdown.markdown(content, extensions=['tables', 'fenced_code'])
html = markdown.markdown(content, extensions=['tables', 'fenced_code'])
Write to temp file
写入临时文件
with open('/tmp/substack_article.html', 'w') as f:
f.write(html)
**IMPORTANT**: Do NOT use `nl2br` extension - it converts single newlines to `<br>` tags, causing extra line breaks in the editor.with open('/tmp/substack_article.html', 'w') as f:
f.write(html)
**重要提示**:不要使用`nl2br`扩展 — 它会将单个换行符转换为`<br>`标签,导致编辑器中出现多余的换行。Step 3: Navigate to Substack
步骤3:导航到Substack
Navigate to the Substack dashboard and create a new post:
undefined导航到Substack控制台并创建新文章:
undefinedNavigate to Substack dashboard
导航到Substack控制台
navigate to: https://verysmallwoods.substack.com/publish
If not logged in, prompt user to log in:请先登录 Substack,登录完成后告诉我。
Please log in to Substack first, then let me know.
undefinednavigate to: https://verysmallwoods.substack.com/publish
若未登录,提示用户登录:请先登录Substack,登录完成后告诉我。
Please log in to Substack first, then let me know.
undefinedStep 4: Create New Post
步骤4:创建新文章
From the dashboard, create a new text post:
- Click "Create new" in the sidebar
- Select "Text post" (or navigate directly to a new post URL)
Alternatively, if the editor is already open with an empty post, proceed directly.
从控制台创建新的文字文章:
- 点击侧边栏中的“Create new”
- 选择“Text post”(或直接导航到新文章URL)
或者,如果编辑器已打开且为空,可直接继续。
Step 5: Fill Title and Subtitle
步骤5:填写标题和副标题
- Click the title textbox ()
textbox "title" - Type the article title
- Click the subtitle textbox ()
textbox "Add a subtitle…" - Type the subtitle/excerpt
click: title textbox
fill/type: article title
click: subtitle textbox
fill/type: article subtitle- 点击标题输入框()
textbox "title" - 输入文章标题
- 点击副标题输入框()
textbox "Add a subtitle…" - 输入副标题/摘要
click: title textbox
fill/type: article title
click: subtitle textbox
fill/type: article subtitleStep 6: Insert HTML Content (via Clipboard Paste)
步骤6:插入HTML内容(通过剪贴板粘贴)
CRITICAL: Do NOT use tool - it inserts plain text without formatting.
fill- Copy HTML to system clipboard:
bash
python3 /path/to/copy_to_clipboard.py html --file /tmp/substack_article.html-
Click the editor content area (or paragraph element inside it)
.ProseMirror -
Press Cmd+V to paste:
press_key: Meta+v (macOS)
press_key: Control+v (Windows/Linux)This triggers Tiptap's HTML paste handler, which renders the content as rich text with proper formatting.
重要提示:禁止使用工具 — 它会插入无格式的纯文本。
fill- 将HTML复制到系统剪贴板:
bash
python3 /path/to/copy_to_clipboard.py html --file /tmp/substack_article.html-
点击编辑器内容区域(或其中的段落元素)
.ProseMirror -
按下Cmd+V进行粘贴:
press_key: Meta+v (macOS)
press_key: Control+v (Windows/Linux)这会触发Tiptap的HTML粘贴处理程序,将内容渲染为带格式的富文本。
Step 7: Insert Table Images
步骤7:插入表格图片
If the article had tables converted to images in Step 0, insert them now:
-
Navigate to the correct position in the editor — click on the paragraph or empty line where the table should appear (after the relevant heading/text)
-
Click the Image toolbar button () — a dropdown menu appears with options: Image, Gallery, Stock photos, Generate image
button "Image" -
Click "Image" menuitem from the dropdown — a file chooser dialog opens
-
Upload the image via file chooser:
- Playwright MCP: with the image path
browser_file_upload - Chrome DevTools MCP: with the image path
upload_file
- Playwright MCP:
Important notes:
- File path restriction: Playwright MCP only allows file uploads from within allowed roots (project directories). If your image is in , copy it to the project directory first
/tmp/ - Repeat for each table: Position cursor at the correct location, then upload each table image
- Delete residual text: If table content was pasted as plain text (because it wasn't removed in pre-processing), select it (triple-click to select paragraph) and delete before inserting the image
如果文章在步骤0中转换了表格为图片,现在进行插入:
-
导航到正确位置:在编辑器中点击表格应出现的段落或空行(相关标题/文本之后)
-
点击工具栏中的Image按钮()— 会出现下拉菜单,包含选项:Image, Gallery, Stock photos, Generate image
button "Image" -
点击下拉菜单中的“Image”选项 — 会打开文件选择对话框
-
上传图片:
- Playwright MCP:使用并指定图片路径
browser_file_upload - Chrome DevTools MCP:使用并指定图片路径
upload_file
- Playwright MCP:使用
注意事项:
- 文件路径限制:Playwright MCP仅允许从允许的根目录(项目目录)上传文件。若图片在目录下,请先将其复制到项目目录
/tmp/ - 重复操作每个表格:将光标定位到正确位置,然后上传每个表格图片
- 删除残留文本:如果表格内容因未在预处理中移除而被粘贴为纯文本,请选中它(三击选中段落)并删除,然后插入图片
Step 8: Verify Draft
步骤8:验证草稿
After pasting:
- Check the "Saved" status indicator (green dot + "Saved" text)
- Take a snapshot to verify content structure
- Optionally take a screenshot for visual verification
The editor auto-saves, so no explicit save action is needed.
粘贴完成后:
- 检查“Saved”状态指示器(绿色圆点 + “Saved”文字)
- 生成快照以验证内容结构
- 可选:截取屏幕截图进行视觉验证
编辑器会自动保存,无需手动执行保存操作。
Step 9: Report Completion
步骤9:报告完成
草稿已保存到 Substack。请在 Substack 中预览并手动发布。
Draft saved to Substack. Please preview and publish manually.
Post URL: https://verysmallwoods.substack.com/publish/post/{postId}草稿已保存到Substack。请在Substack中预览并手动发布。
Draft saved to Substack. Please preview and publish manually.
Post URL: https://verysmallwoods.substack.com/publish/post/{postId}Complete Example Flow
完整示例流程
User: "把 /path/to/my-article.md 发布到 Substack"
0. Pre-process tables (if any)
- Detect Markdown tables
- Create styled HTML for each table
- Render to screenshots (open in browser, screenshot, close tab)
- Remove table Markdown from content
- Note insertion positions
1. Read /path/to/my-article.md
- Extract title from frontmatter or H1
- Extract subtitle from frontmatter excerpt
- Get full Markdown content (with tables removed)
2. Convert Markdown to HTML
- Strip frontmatter
- Use markdown.markdown() with ['tables', 'fenced_code']
- Write to /tmp/substack_article.html
3. Navigate to Substack dashboard or new post
4. Check if logged in
- If not, prompt user to login
5. Fill title and subtitle
6. Copy HTML to clipboard + Paste
- python3 copy_to_clipboard.py html --file /tmp/substack_article.html
- Click editor content area
- Press Cmd+V
7. Insert table images at correct positions
- For each table: click position → Image button → Image menuitem → file upload
8. Verify draft saved
- Check "Saved" status
9. Report success
- "草稿已保存,请手动预览并发布"用户:"把 /path/to/my-article.md 发布到 Substack"
0. 预处理表格(如果有)
- 检测Markdown表格
- 为每个表格创建带样式的HTML
- 渲染为截图(在浏览器中打开、截图、关闭标签页)
- 从内容中移除表格的Markdown
- 记录插入位置
1. 读取 /path/to/my-article.md
- 从前置元数据或H1提取标题
- 从前置元数据的excerpt字段提取副标题
- 获取完整的Markdown内容(已移除表格)
2. 将Markdown转换为HTML
- 移除前置元数据
- 使用markdown.markdown()并启用['tables', 'fenced_code']扩展
- 写入 /tmp/substack_article.html
3. 导航到Substack控制台或新文章页面
4. 检查登录状态
- 若未登录,提示用户登录
5. 填写标题和副标题
6. 复制HTML到剪贴板并粘贴
- python3 copy_to_clipboard.py html --file /tmp/substack_article.html
- 点击编辑器内容区域
- 按下Cmd+V
7. 在正确位置插入表格图片
- 每个表格:定位光标 → 点击Image按钮 → 选择Image选项 → 上传文件
8. 验证草稿已保存
- 检查“Saved”状态
9. 报告成功
- "草稿已保存,请手动预览并发布"Critical Rules
关键规则
- NEVER click "Continue" - This starts the publish flow. Only save as draft (auto-save handles this)
- Always convert to HTML first - Plain Markdown will not be parsed by the Tiptap editor
- Use clipboard paste - The only reliable way to insert formatted content
- Check login status - Prompt user to login if needed
- Preserve original file - Never modify the source Markdown file
- Report completion - Tell user the draft is saved and needs manual review
- No extension - Causes double line breaks
nl2br - Tables → images - Pre-process tables before pasting content; upload images after paste
- Playwright file paths - Playwright MCP restricts file uploads to allowed roots; copy temp files to project directory before uploading
- 禁止点击“Continue”按钮 — 这会启动发布流程。仅保存为草稿(自动保存会处理)
- 必须先转换为HTML — 纯Markdown不会被Tiptap编辑器解析
- 使用剪贴板粘贴 — 这是插入格式化内容的唯一可靠方式
- 检查登录状态 — 必要时提示用户登录
- 保留原始文件 — 绝不修改源Markdown文件
- 报告完成状态 — 告知用户草稿已保存,需要手动审核
- 禁止使用扩展 — 会导致双倍换行
nl2br - 表格转图片 — 在粘贴内容前预处理表格;粘贴后上传图片
- Playwright文件路径 — Playwright MCP限制文件上传到允许的根目录;上传前将临时文件复制到项目目录
Troubleshooting
故障排除
Content Shows as Plain Text (No Formatting)
内容显示为纯文本(无格式)
If you see raw HTML tags or unformatted text:
- Cause: Content was inserted using tool instead of clipboard paste
fill - Solution: Use the + Cmd+V method (see Step 6)
copy_to_clipboard.py
如果看到原始HTML标签或无格式文本:
- 原因:使用了工具而非剪贴板粘贴
fill - 解决方案:使用+ Cmd+V的方式(参见步骤6)
copy_to_clipboard.py
Tables Not Rendering (Shows Plain Text)
表格未渲染(显示纯文本)
Substack's Tiptap editor does not support HTML tables. They collapse into inline plain text.
- Solution: Convert tables to styled HTML → render as screenshots → upload as images (see Step 0 and Step 7)
- Alternative: Restructure simple tables as formatted lists
- If plain text already pasted: Triple-click the plain text paragraph to select it, press Backspace to delete, then insert the table image at that position
Substack的Tiptap编辑器不支持HTML表格,表格会被折叠为行内纯文本。
- 解决方案:将表格转换为带样式的HTML → 渲染为截图 → 作为图片上传(参见步骤0和步骤7)
- 替代方案:将简单表格重构为格式化列表
- 如果已粘贴纯文本:三击选中纯文本段落,按Backspace删除,然后在该位置插入表格图片
Login Required
需要登录
If page shows login prompt:
请先登录 Substack: https://verysmallwoods.substack.com
登录完成后告诉我。如果页面显示登录提示:
请先登录Substack: https://verysmallwoods.substack.com
登录完成后告诉我。Editor Not Loading
编辑器未加载
If editor elements are not visible:
- Wait for page to fully load
- Take a new snapshot
- If still not loading, refresh the page
如果编辑器元素不可见:
- 等待页面完全加载
- 生成新快照
- 若仍未加载,刷新页面
Clipboard Copy Fails
剪贴板复制失败
If fails:
copy_to_clipboard.py- Ensure dependencies: (macOS)
pip install pyobjc-framework-Cocoa - Check the HTML file exists and is readable
- Try copying a smaller test string first
如果执行失败:
copy_to_clipboard.py- 确保依赖已安装:(macOS)
pip install pyobjc-framework-Cocoa - 检查HTML文件是否存在且可读
- 尝试先复制一个较小的测试字符串
Element Reference
元素参考
| Element | Selector/Identifier | Description |
|---|---|---|
| Title input | | Post title |
| Subtitle input | | Post subtitle |
| Content area | | Post content |
| Save status | | Auto-save indicator |
| Preview button | | Preview post |
| Continue button | | DO NOT USE - starts publish flow |
| Settings button | | Open settings sidebar |
| Exit button | | Exit editor |
| Image button | | Opens image upload dropdown |
| Image menuitem | | Opens file chooser for image upload |
| Author button | | Author/publication selector |
| 元素 | 选择器/标识符 | 描述 |
|---|---|---|
| 标题输入框 | | 文章标题 |
| 副标题输入框 | | 文章副标题 |
| 内容区域 | | 文章内容 |
| 保存状态 | | 自动保存指示器 |
| 预览按钮 | | 预览文章 |
| 继续按钮 | | 禁止使用 - 启动发布流程 |
| 设置按钮 | | 打开设置侧边栏 |
| 退出按钮 | | 退出编辑器 |
| 图片按钮 | | 打开图片上传下拉菜单 |
| 图片选项 | | 打开文件选择对话框以上传图片 |
| 作者按钮 | | 作者/发布账号选择器 |
Technical Details
技术细节
Editor Stack
编辑器栈
- Tiptap: A headless, framework-agnostic rich-text editor built on ProseMirror
- ProseMirror: The underlying rich-text editing framework
- Paste handling: Tiptap natively parses HTML from clipboard and converts to its internal document model
- Tiptap:一个基于ProseMirror的无头、与框架无关的富文本编辑器
- ProseMirror:底层的富文本编辑框架
- 粘贴处理:Tiptap原生解析剪贴板中的HTML,并将其转换为内部文档模型
Content Conversion Pipeline
内容转换流程
Markdown file
↓ (Python markdown library)
HTML string
↓ (copy_to_clipboard.py)
System clipboard (text/html + text/plain)
↓ (Cmd+V keyboard shortcut)
Tiptap ProseMirror editor
↓ (auto-save)
Substack draftMarkdown文件
↓ (Python markdown库)
HTML字符串
↓ (copy_to_clipboard.py)
系统剪贴板(text/html + text/plain)
↓ (Cmd+V快捷键)
Tiptap ProseMirror编辑器
↓ (自动保存)
Substack草稿Supported Formatting
支持的格式
The following Markdown elements are correctly rendered after HTML conversion and paste:
| Markdown Element | Substack Support | Notes |
|---|---|---|
| Headings (H2-H6) | Yes | H1 not recommended (title is separate) |
| Bold / Italic | Yes | |
| Inline code | Yes | |
| Code blocks | Yes | Syntax highlighting may vary |
| Links | Yes | |
| Blockquotes | Yes | |
| Bullet lists | Yes | |
| Ordered lists | Yes | |
| Horizontal rules | Yes | |
| Tables | No → Image | Convert to styled HTML, screenshot, upload as image |
| Images | Manual | Upload via Image toolbar button → file chooser |
以下Markdown元素在转换为HTML并粘贴后可正确渲染:
| Markdown元素 | Substack支持情况 | 说明 |
|---|---|---|
| 标题(H2-H6) | 是 | 不推荐使用H1(标题单独设置) |
| 加粗 / 斜体 | 是 | |
| 行内代码 | 是 | |
| 代码块 | 是 | 语法高亮可能有所不同 |
| 链接 | 是 | |
| 引用 | 是 | |
| 无序列表 | 是 | |
| 有序列表 | 是 | |
| 水平线 | 是 | |
| 表格 | 否 → 图片 | 转换为带样式的HTML,截图后作为图片上传 |
| 图片 | 手动上传 | 通过工具栏的Image按钮 → 文件选择对话框上传 |