从 Substack 文章提取数据 → 转换为多种格式 → 下载到本地
- 第一阶段(核心体验增强):✅ 100% 完成 (6/6)
- 第二阶段(高级功能):✅ 100% 完成 (4/4) ← v1.1.6 完成
- 第三阶段(架构升级):⬜ 0% 完成 (0/3)
- 第四阶段(合规性检查):⬜ 0% 完成 (0/5)
- ✅ 支持所有 Substack 自定义域名
- ✅ 友好的文件名生成(3种格式可选)
- ✅ 不破坏原始 DOM
- ✅ 健壮的错误处理
- ✅ UI 重设计 (Substack 原生风)
- ✅ 设置面板视觉增强(v1.0.4)
- ✅ 设置按钮交互优化(v1.0.4)
- ✅ YAML Frontmatter 支持 (Obsidian 兼容)
- ✅ 剪贴板一键复制
- ✅ PDF 打印优化(v1.0.3 修复标题空白)
- ✅ 客户端 PDF 直接导出(v1.1.6 新增)
- ✅ 图片本地化 ZIP 导出
- ✅ Obsidian 一键保存(URI Scheme)
- ✅ Markdown 预览界面
- ✅ 脚注支持(标准 Markdown 格式)
- ✅ UI/UX 全面升级(v1.1.5 Phase 1-3)
- ✅ 个人资料页面支持(v1.1.6 新增)
- ✅ 支持 /@username/p-xxx URL 格式
- ✅ JSON-LD Person 类型检测
- ✅ 多作者显示
- ✅ 品牌标识和预览图(v1.1.6 新增)
- ✅ 沉浸式卡片布局
- ✅ 骨架屏加载动画
- ✅ 空状态设计
- ✅ 状态管理重构(data-state)
- ✅ 操作视觉反馈优化
chrome-plugin-substack/
├── manifest.json # Manifest V3 配置
├── popup.js # 核心逻辑 (注入提取与转换)
├── popup.html # 用户界面
└── icons/ # 图标资源
目标:打造与 Substack 平台视觉一致的沉浸式体验。
- 视觉风格:
- 极简主义 (Clean & Minimalist):去除厚重渐变背景,采用极简白底 + 柔和阴影。
- 品牌色:使用 Substack Orange (#FF6719) 作为主操作按钮颜色,建立"原生感"。
- 字体:标题使用衬线体 (Georgia / Merriweather) 呼应文学质感,正文使用系统无衬线体。
- 排版:增加留白 (Whitespace),提升阅读呼吸感。
- 交互体验:
- 渐进式披露:初始仅显示文章卡片(封面+标题),点击"预览"或"设置"后展开更多面板。
- 微交互:按钮加载状态、成功/失败的轻微震动反馈。
- Tab 布局:重构为底部导航栏 (主页 / 历史 / 设置)。
- 布局重构:
- Header: Logo + 设置入口。
- Main: 带有封面图背景的文章状态卡片 + 大尺寸 CTA 按钮。
- Footer: 导航切换。
方案:一键复制生成的 Markdown
- 在 Popup 界面添加 "Copy to Clipboard" 按钮
- 方便直接粘贴到 Notion, Obsidian 或其他笔记软件
- 显示 "Copied!" Toast 提示
方案:下载前确认内容
- 在下载前展示 Markdown 预览窗口
- 允许用户简单编辑或勾选需要保留的段落
- 使用 Monaco Editor 或 Highlight.js 渲染预览
- 右键菜单集成:网页右键菜单添加 "Save as Markdown"
- 快捷键:支持
Alt+Shift+M快速触发
方案A:原生打印优化 (Native Print) - 🌟 推荐方案 利用 Chrome 原生渲染引擎,注入打印样式表
- 实现:点击 "Export PDF" 时注入
@media print样式 - 样式优化:移除侧边栏/导航/广告,强制白底黑字,优化图片分页逻辑
- 优势:渲染最完美(文字矢量可复制),代码极轻量
- 劣势:需用户在打印预览框手动保存
方案B:Markdown 转 PDF (Markdown-based) - 🟡 远期规划 在前端将生成的 Markdown 重渲染为 PDF
- 实现:
Markdown->pagedjs->PDF - 优势:格式最纯净,完全重排版
- 状态:列为低优先级,视未来需求决定是否实现
方案:满足笔记软件(Obsidian/Notion)的元数据需求
- YAML 头:标准化的元数据块,支持 tags, date, author, url
- 模板配置:
--- title: "{{title}}" author: "{{author}}" date: {{date}} url: "{{url}}" tags: [substack, {{tags}}] --- # {{title}}
- 文件名模板:允许用户定义
{{date}}-{{title}}或{{author}}/{{title}}
- 支持 HTML (纯净版)
方案:解决远程图片失效及防盗链问题
- 引入
JSZip库 - 自动下载文章内图片到
assets/目录 - Markdown 引用相对路径
- 打包下载
article.zip(包含.md和图片文件夹)
方案:移除干扰信息
- 移除营销内容(Subscribe 按钮、"Gift a subscription"、推荐阅读)
- 增加黑名单选择器配置
- 提取核心正文,过滤 Sidebar 和 Footer
方案:完善学术/深度文章体验
- 识别
<sup>标签和脚注链接 - 转换为标准 Markdown 脚注格式 (
[^1]: ...) - 确保引用跳转正常
- 调用 OpenAI/Claude API 生成文章摘要
- 在 Markdown 顶部添加 "TL;DR"
方案:添加"订阅源批量下载"功能
- 从作者归档页面 (
/archive) 提取所有文章链接 - 队列化下载,避免请求过载
- 显示进度条和下载状态
- 支持暂停/恢复
方案:定期自动检查并下载新文章
- 后台定时任务(每小时/每天)
- 只下载新文章,去重机制
方案:优化 Obsidian 工作流
- URI Scheme 唤起:增加 "Save to Obsidian" 按钮
- 使用
obsidian://new?name=...&content=...直接创建笔记
- 一键推送到 Notion 数据库(需集成 Notion API)
- WebDAV 网盘同步支持
方案:增强容错性
- 当 Substack 特定选择器失效时,自动回退到 Mozilla 的
Readability.js算法 - 确保非标准页面也能提取出正文
方案:更稳健的 Markdown 生成
- 引入
turndown库替代手写正则替换 - 更好地处理复杂嵌套(表格、引用代码块)
- 将
popup.js拆分为:extractor.js: 负责 DOM 解析converter.js: 负责 HTML -> MD 转换ui.js: 负责 Popup 交互
基于 "Quick Wins" -> "Core Value" -> "Scale" 的策略:
目标:不改变架构,大幅提升生成的 Markdown 质量和易用性,并完成 UI 改版。 预计耗时:3-4 天
- ✅ UI/UX 重构: 实现 "Substack 原生风" 界面(白底、橙色按钮、衬线体)。
- ✅ YAML Frontmatter: 添加标准元数据头,方便 Obsidian/Notion 索引。
- ✅ PDF 导出 (Lite): 实现基于 CSS 的原生打印优化方案。
- ✅ v1.0.3 修复: 使用 Chrome DevTools MCP 工具分析并修复打印时标题上方 ~100px 空白问题(modalViewer 和 article 的 padding/margin 重置)
- ✅ 剪贴板支持: 添加 "Copy Markdown" 按钮,解决高频粘贴需求。
- ✅ 脚注支持: 解析
<sup>和锚点,生成标准脚注。 - ✅ 自定义文件名: 允许用户配置命名规则(如
yyyy-MM-dd-Title.md)。
目标:解决"永久存档"和"无缝集成"的痛点。 预计耗时:1 周 | 实际进度:4/4 完成 (100%)
- ✅ 图片本地化 (ZIP): 使用 JSZip 打包图片和 Markdown,实现真正离线阅读。
- ✅ Obsidian 一键保存: 利用 URI Scheme 直接写入 Obsidian Vault。
- ✅ 智能内容清理: 增加"纯净模式"选项,移除推广干扰。
- ✅ 预览界面: 下载前预览并确认内容(v1.0.3 已实现基础预览功能)。
- ✅ 客户端 PDF 导出: 使用 pdfmake 直接生成 PDF,无需打印对话框(v1.1.6 新增)。
目标:提升代码稳健性,支持更多场景。 预计耗时:2 周
- 引入 Readability.js & Turndown: 重构核心提取与转换层。
- 批量下载: 队列化处理订阅源归档。
- 多平台适配: 扩展支持 Medium 等平台。
目标:确保插件符合 Store 发布标准(优先级最低,功能完备后再做)。 预计耗时:1 天
- 依赖本地化: 检查所有第三方库(如 JSZip, Turndown)是否已下载到本地,移除所有 CDN 链接。
- CSP 检查: 确保无内联脚本违反 Content Security Policy。
- 权限最小化: 移除未使用的
host_permissions或permissions。 - 图标规范: 补充 32x32px 图标,检查各尺寸图标显示效果。
- Service Worker 持久化: 检查后台任务是否依赖全局变量(针对 V3 瞬时特性)。
分支: feat/settings-and-image-optimization
提交: c949be0, 83add44
本版本新增 个人资料页面文章支持 和 品牌标识。
问题:某些 Substack 文章链接使用个人资料路径格式(如 /@username/p-xxx),之前的版本无法正确识别和提取。
解决方案:
-
JSON-LD 类型检测
- 识别
Person类型 JSON-LD(个人资料页面) - 回退到 meta 标签提取策略
- 识别
-
元数据优先级调整
- 优先使用
og:title和og:image - 提升个人资料页面的提取准确性
- 优先使用
-
日期解析增强
- 正则表达式改为不区分大小写
- 支持 "Feb"、"FEB"、"feb" 等各种格式
-
作者提取优化
- 从日期元素的父容器提取作者信息
- 支持多作者显示
技术细节:
// 日期正则(不区分大小写)
const dateRegex = /^[A-Z][a-z]{2}\s+\d{1,2},\s+\d{4}$/i;
// ↑ 添加 i 标志
// JSON-LD 类型检测
if (jsonLdData['@type'] === 'Person') {
// 使用 meta 标签回退策略
}
// 多作者支持
const authors = Array.from(authorContainer.querySelectorAll('a'))
.map(a => a.textContent.trim());目标:增强品牌识别度和专业形象。
变更内容:
-
README 优化
- 添加预览图片展示插件界面
- 提升用户第一印象
-
Popup 页脚更新
- 添加 "Powered By Activer" 署名
- 替换原有版本号显示
-
PDF 品牌页脚
- 生成的 PDF 底部添加品牌标识
- 使用
markdown-pdf.js的 footer 功能
技术细节:
// PDF 页脚配置
const docDefinition = {
footer: function(currentPage, pageCount) {
return {
text: 'Powered By Activer',
alignment: 'center',
fontSize: 8,
color: '#999'
};
}
};分支: feat/settings-and-image-optimization
PRs: #9, #10, #12, #13
版本说明:本次更新包含重大功能改进,因此次版本号从 1.0.x 升级至 1.1.x。
分支: feat/settings-and-image-optimization
PRs: #9, #10, #12, #13
本版本完成了 UI/UX 全面升级(Phase 1-3) 和 客户端 PDF 直接导出 功能。
目标:打造现代、沉浸式的用户体验。
核心变更:
-
设计系统
- 引入 CSS 变量(颜色、字体、间距、阴影)
- 统一主题系统,便于后续维护
-
沉浸式卡片布局
- 使用封面图作为背景,添加渐变遮罩
- 创造视觉冲击力,增强文章识别度
-
布局重构
- 紧凑头部:品牌与标题无缝集成
- 并排主按钮:"Markdown" 和 "ZIP" 并列显示
- 4 列工具网格:Copy、PDF、Obsidian、Preview 整齐排列
-
提取修复
- 修复 og:image 提取(DOM 回退模式)
技术细节:
/* 沉浸式卡片 */
.article-card {
background: linear-gradient(to bottom, rgba(0,0,0,0.1), rgba(0,0,0,0.6)),
url('var(--cover-image)') center/cover;
}目标:提升感知性能和用户引导。
核心变更:
-
骨架屏加载动画
- Shimmer 效果模拟真实卡片布局
- 减少布局偏移(CLS),提升感知速度
-
空状态设计
- 专属 "No Article Detected" 视图
- 清晰插图 + "Retry" 按钮
-
设置面板动画
- 从顶部滑下(
transform: translateY) - 不推动内容,保持上下文
- 从顶部滑下(
-
状态管理重构
- 从手动
style.display切换到data-state属性 - CSS 强制互斥,防止 Loading/Empty/Success 状态重叠
- 从手动
技术细节:
/* 状态管理 */
body[data-state="loading"] .skeleton { display: block; }
body[data-state="success"] .article-card { display: block; }
/* 防止重叠 */
body[data-state="loading"] .article-card { display: none; }目标:无需打印对话框,直接生成高质量 PDF。
核心功能:
-
客户端生成
- 使用
pdfmake在浏览器中生成 PDF - 无需服务器,保护隐私
- 使用
-
自定义字体支持
- 集成
Noto Serif SC - 完美支持中英文混排
- 集成
-
智能排版
- 自动检测文章语言(基于标题)
- 英文文章:智能引号 → 直引号(修复 CJK 字体间距问题)
- 自定义 Markdown 解析器(加粗、斜体、代码块)
-
图片嵌入
- 自动下载并嵌入文章图片到 PDF
技术细节:
// 语言检测
const isChinese = /[\u4e00-\u9fa5]/.test(title);
// 智能引号处理
const cleanText = isChinese ? text : text.replace(/'/g, "'");
// 字体配置
pdfMake.vfs = {
'NotoSerifSC.subset.ttf': base64Font
};新增文件:
libs/pdfmake.min.jslibs/vfs_fonts.js(自定义构建)utils/markdown-pdf.js
目标:突出 PDF 导出功能,优化操作反馈。
核心变更:
-
按钮布局调整
- "PDF (Direct)" 提升至主操作按钮(与 Markdown 并排)
- "ZIP" 移至次要工具栏
- "PDF (Print)" 重命名为 "Print"
-
视觉反馈
- PDF 按钮:Processing → Exported
- ZIP 按钮:Packing → Saved
- Obsidian 按钮:Opening → 确认提示
-
Bug 修复
- 修复字体路径
NotoSerifSC.subset.ttf,解决 "File not found" 错误 - 修复 PDF 按钮点击闪烁问题(正确管理按钮状态)
- 修复字体路径
提交记录:
- 53d57bd: Refactor: remove base64 image support and increase popup height
- 0905001: Feat: overhaul settings UI and add new config options
- 0ed7077: Fix: swap pdf/zip buttons and improve feedback logic
- 9d7dcc4: Chore: optimize font size and finalize pdf export features
- 78c7c42: Feat: optimize pdf typography with smart quote handling
- ca4b2fc: Feat: add direct PDF export functionality
分支: fix/settings-button
PR: #11
用户报告设置按钮点击无响应。经分析发现:
- JS 使用
display属性控制显示/隐藏 - CSS 使用
transform/opacity/visibility控制显示/隐藏 - 两者机制不一致导致修改
display后 CSS 动画不生效
1. 修复设置按钮切换逻辑
- 将
toggleSettings()从修改display改为切换.openCSS 类 - 与 CSS 中的
.settings-drawer.open动画配合
2. 增强设置面板视觉设计
- 渐变背景:
rgba(255,255,255,0.98)→rgba(249,250,251,0.98) - 顶部 3px 橙色强调线(品牌色
#FF6719) - 左右各 8px 空隙,创造悬浮效果
- 双层阴影增强深度感
- 底部 12px 圆角
3. 改进图标一致性
- 替换为更简洁的 Material Design 风格设置图标
- 与底部操作按钮图标风格保持一致
4. 增强交互体验
- 点击设置面板外部区域自动关闭
- Escape 键关闭设置面板和预览模态框
// 修改前
function toggleSettings() {
const isVisible = settingsPanel.style.display !== 'none';
settingsPanel.style.display = isVisible ? 'none' : 'block';
settingsBtn.style.color = isVisible ? '#888' : '#FF6719';
}
// 修改后
function toggleSettings() {
settingsPanel.classList.toggle('open');
const isOpen = settingsPanel.classList.contains('open');
settingsBtn.style.color = isOpen ? '#FF6719' : '#888';
}
// 新增:点击外部关闭
document.addEventListener('click', (e) => {
if (!settingsPanel.contains(e.target) && !settingsBtn.contains(e.target)) {
if (settingsPanel.classList.contains('open')) {
settingsPanel.classList.remove('open');
settingsBtn.style.color = '#888';
}
}
});/* 设置面板新样式 */
.settings-drawer {
background: linear-gradient(to bottom, rgba(255,255,255,0.98), rgba(249,250,251,0.98));
border: 1px solid rgba(0,0,0,0.08);
border-top: 3px solid var(--primary);
box-shadow:
0 8px 24px rgba(0,0,0,0.12),
0 2px 6px rgba(0,0,0,0.08);
border-radius: 0 0 var(--radius-lg) var(--radius-lg);
margin: 0 8px;
width: calc(100% - 16px);
}- f958d78: Fix settings button toggle logic
- 3c2f4f3: Enhance settings drawer visual distinction
- 6190e82: Improve icon consistency and add click-outside-to-close
分支: fix/pdf-print-top-spacing
使用 Chrome DevTools MCP 工具分析打印页面布局,发现:
modalViewerInner:padding: 12pxmodalViewer内部子元素:paddingTop: 88px⚠️ 主要问题源article:paddingTop: 16px- 累计空白: ~101px
- 重置
[class*="modalViewer"]及其所有子元素的 padding/margin - 重置
article元素的 padding/margin - 重置
article > *:first-child的顶部间距 - 重置
h1的 margin-top 和 padding-top
/* 关键修复规则 */
[class*="modalViewer"] {
padding: 0 !important;
margin: 0 !important;
}
[class*="modalViewer"] [class*="pc-padding"] {
padding-top: 0 !important;
padding-bottom: 0 !important;
/* ... */
}
article {
padding: 0 !important;
margin: 0 !important;
}
article > *:first-child {
margin-top: 0 !important;
padding-top: 0 !important;
}
h1 {
margin-top: 0 !important;
padding-top: 0 !important;
}状态:✅ v1.1.6 已完成
已完成任务:
- ✅ 在 popup.html 添加"纯净模式"checkbox
- ✅ 实现内容过滤逻辑(黑名单选择器)
- ✅ 过滤 Subscribe/Upgrade/Gift 等推广内容
- ✅ 测试不同页面的过滤效果
预计耗时:1-2 天 价值:🌟🌟🌟⭐⭐ (为后续功能打好基础)
任务清单:
- 拆分 popup.js → extractor.js, converter.js, ui.js
- 更新 manifest.json 引用
- 测试重构后的功能完整性
预计耗时:1 天 价值:🌟🌟🌟🌟🌟 (发布前必须完成)
任务清单:
- 依赖本地化检查(确认无 CDN 链接)
- CSP 检查(无内联脚本)
- 权限最小化审查
- 补充 32x32 图标
- Service Worker 持久化测试
预计耗时:3-5 天 价值:🌟🌟🌟🌟⭐ (核心功能,用户期待)
预计耗时:2-3 天 价值:🌟🌟🌟⭐⭐ (提升代码质量)
预计耗时:1-2 周 价值:🌟🌟⭐⭐⭐ (扩展生态)
- 右键菜单集成
- 快捷键支持
- Notion API 集成
- AI 摘要生成
- WebDAV 同步
- 本地数据库(IndexedDB)
v1.1.6 (当前) → v1.2.0 (Chrome Store 发布)
- Chrome Store 发布准备(1 天)
- 提交 Chrome Web Store 审核
v1.1.6 (当前) → v1.2.0 (代码模块化) → v1.3.0 (批量下载) → v1.4.0 (Chrome Store 发布)
- 代码模块化重构(1-2 天)
- 批量下载功能(3-5 天)
- Chrome Store 发布准备(1 天)
文档更新时间:2026-02-05 当前版本:v1.1.6 状态:第一阶段 ✅ 100% | 第二阶段 ✅ 100% | 第三阶段 ⬜ 0% | 第四阶段 ⬜ 0%