一个面向 LINUX DO 论坛的 UserScript,用来把帖子内容导出为 Markdown 文件。
脚本会在帖子页左侧注入一个"文档下载"浮层,支持两种导出模式:
- 仅导出主楼为 Markdown
- 导出主楼 + 全部回复为 Markdown
导出时会直接调用 Discourse 的 JSON API 拉取帖子数据,再把帖子 HTML 转成适合阅读和归档的 Markdown 文本并触发浏览器下载。
- 支持在
https://linux.do/t/topic/*帖子页直接下载 Markdown - 支持导出 主楼 或 整帖(主楼 + 全部回复)
- 自动拉取完整回复流,避免只拿到当前页面已渲染的那一小截内容
- 内嵌精简版
TurndownService与 GFM 规则,无需额外依赖 - 对 Discourse 常见内容做了定制转换:
- code block
- table
- task list
details/summary折叠块- lightbox 图片
- emoji
- mention / hashtag 文本保留
- 自动清理头像、按钮、点赞区、脚本样式等无关 UI 垃圾
- 自动补充帖子标题、分类、标签、原帖链接
- 下载文件名会按标题生成,并处理 Windows 非法文件名字符
- 归档 LINUX DO 技术帖子
- 把论坛讨论整理到本地知识库
- 导入 Obsidian、Logseq、Notion 或其他 Markdown 工作流
- 离线保存长帖内容,避免以后翻帖子翻到脑壳疼
- 安装任一 UserScript 管理器:
- 新建脚本。
- 将仓库中的
linuxdo.js全量复制进去。 - 保存并启用脚本。
- 打开任意
linux.do帖子页测试。
本项目当前就是一个单文件脚本:
linuxdo.js
你只需要把这个文件加载进 UserScript 管理器即可,不需要构建步骤,也没有 npm 依赖。
- 打开任意 LINUX DO 帖子页面,例如:
https://linux.do/t/topic/12345
- 页面左侧会出现"文档下载"浮层。
- 鼠标移上去后会展开两个操作:
导出主楼为 Markdown导出全部回复为 Markdown
- 点击"下载"后,脚本会:
- 解析当前帖子 ID
- 调用 Discourse JSON API 获取主题与回帖数据
- 将 HTML 内容转换为 Markdown
- 生成
.md文件并触发浏览器下载
导出的 Markdown 结构大致如下:
# 帖子标题 > 分类: 某分类 | 标签: tag1, tag2 | 链接: https://linux.do/t/topic/12345 ## #1 作者名 (2026年04月02日) 这里是正文内容...... --- ## #2 回复作者 (2026年04月02日) 这里是回复内容...... --- 本文转自 <https://linux.do/t/topic/12345>
如果选择"仅导出主楼",则不会为每层回复生成分节标题,只保留主楼内容和元信息。
这个脚本不是去抄当前页面已经渲染好的 DOM,而是走了更稳妥的路线:
- 从当前 URL 中解析 topic ID
- 请求 Discourse 主题接口:
/t/topic/{topicId}.json
- 如果主题回复很多,继续按批次补拉缺失楼层:
/t/{topicId}/posts.json?post_ids[]=...
- 按
post_number排序,保证导出顺序正确 - 使用内嵌
TurndownService+ GFM 规则把cookedHTML 转成 Markdown - 应用 Discourse 定制规则,处理图片、折叠块、emoji 和无关节点清理
- 用
Blob生成本地.md文件并下载
这么搞的好处是:导出内容完整、结构相对稳定,而且不依赖用户是否已经把整页帖子滚到底。
.
├── linuxdo.js # UserScript 主文件,包含 UI 注入、数据拉取和 Markdown 转换逻辑
└── README.md # 项目说明文档
- 目标站点:
linux.do(Discourse 架构) - 运行环境:现代浏览器 + UserScript 管理器
- 脚本匹配规则:
*://linux.do/t/topic/* - 当前代码按 LINUX DO 页面结构与 Discourse 接口设计,换站点大概率不能直接通用
脚本当前对以下内容有明确处理:
- 标题 / 段落 / 列表
- 引用块
- 围栏代码块
- 表格
- 任务列表
- 折叠块
details/summary - 图片(含 lightbox)
- emoji
- mention / hashtag
- 项目目前是单文件脚本,没有构建、测试或发布流程
- 依赖 LINUX DO 当前的 Discourse API 结构;如果站点接口或 DOM 类名改了,脚本需要跟着调整
- 某些复杂插件内容、特殊嵌入卡片、第三方富文本块,不一定能 100% 还原成理想 Markdown
- 分类名称通过额外接口请求获取,如果该请求失败,导出不会中断,但分类信息可能缺失
- 文件下载依赖浏览器行为,不同浏览器对下载提示的展示会有细微差异
如果你想改脚本,最简单的方式就是:
- 修改
linuxdo.js - 在 UserScript 管理器中重新保存脚本
- 回到 LINUX DO 帖子页刷新验证
- 打开浏览器控制台查看报错或网络请求
重点可关注这几个函数:
getTopicIdFromUrl():从 URL 提取主题 IDfetchAllPosts(topicId):拉取主题和完整回复流postsToMarkdown(topicData, mode):把帖子数据拼成 MarkdownaddDiscourseRules(turndownService):定义 Discourse 专用转换规则injectUI():注入下载浮层和点击事件
- 增加"仅导出选中楼层 / 指定楼层范围"
- 增加 YAML frontmatter,方便接入知识库工具
- 增加文件名模板,例如标题 + 日期 / topic ID
- 增加图片本地化下载而不只是引用远程链接
- 拆分脚本结构,补基础测试与构建流程
MIT