【免费下载链接】clearly
Markdown editor for Mac, iOS and iPadOS
Clearly 是一款原生 Markdown 编辑器,面向 Mac、iOS 与 iPadOS。很多人好奇:同一个 Markdown 文件,为什么它在 Mac 的预览窗、Finder 的 QuickLook、甚至 iPhone 的预览里长得一模一样?秘密就在一个名为 ClearlyCore 的本地 Swift 包中——它把 Markdown 渲染、语法高亮、主题配色与文档状态等所有平台无关逻辑收进同一个包,让 Mac 与 iOS 两份 App 共用同一套"大脑"。
这篇文章带你拆解这个包的结构:从跨平台抽象层、cmark-gfm 渲染管线,到"一个包驱动五个构建目标"的工程配置,看完你会收获一套可直接套用的跨平台 Swift 架构思路 📦
一、认识 ClearlyCore:五大模块各司其职
ClearlyCore 是一个本地 Swift Package,位于 Packages/ClearlyCore/,在 Package.swift 中声明支持macOS 15与iOS 17双平台。包内目录即职责划分:
| 目录 | 职责 | 代表文件 |
|---|---|---|
| Rendering/ | Markdown → HTML 渲染管线与主题 | MarkdownRenderer.swift、PreviewCSS.swift |
| State/ | 大纲、查找替换、状态栏等文档级状态 | OutlineState.swift、FindState.swift |
| Platform/ | 抹平 AppKit 与 UIKit 差异的抽象层 | Platform.swift |
| Diagnostics/ | 日志与 Bug 上报 URL 生成 | DiagnosticLog.swift |
| Stats/ | 字数统计 | MarkdownStats.swift |
包外还有一个"隐藏功臣":Shared/Resources/ 目录里的 KaTeX、Mermaid、highlight.js 等前端资源,由 project.yml 统一打包进各个构建目标,保证渲染依赖"同源同版本"。
二、跨平台第一招:一套类型别名抹平 AppKit 与 UIKit
macOS 用 AppKit 的NSFont、NSColor,iOS 用 UIKit 的UIFont、UIColor——核心代码若直接引用这些类型,就得写两遍。Platform.swift 用编译期#if给每对类型起了统一别名:
#if os(macOS) public typealias PlatformFont = NSFont public typealias PlatformColor = NSColor #else public typealias PlatformFont = UIFont public typealias PlatformColor = UIColor #endif于是 Theme.swift 之类的文件只面向PlatformFont/PlatformColor编程,颜色统一从 Colors.xcassets 读取(自动适配明暗模式),字体默认值再按平台微调——Mac 用 12pt 适合桌面密排,iOS 用 17pt 贴合系统正文习惯。同一份代码,两种"手感",这是跨平台渲染一致性的低成本起点。
三、渲染管线:cmark-gfm 打底 + 多步后置加工
把 Markdown 变成 HTML 的核心在 MarkdownRenderer.swift 的renderHTML():
- 先抽离 frontmatter,避免 YAML 头干扰解析;
- 调用 cmark-gfm 库(GFM:表格、任务列表、删除线、自动链接)把正文转成 HTML;
- 依次执行后置加工:数学公式(
$...$→ KaTeX span)、==高亮==、上下标、:emoji:短码、Callout 提示块、[[toc]]目录、表格标题、代码块文件名标签; - 全程用
protectCodeRegions()保护<pre>/<code>区域,防止代码块内容被误改写。
这条管线还有个巧思:每个 HTML 节点都带data-sourcepos(源码行号),渲染结果与源文件行号精确对齐——"双击预览跳回源码"这类交互就靠它。完整管线细节可参考官方文档 docs/markdown-rendering-architecture.md。
四、一个包驱动五个构建目标:XcodeGen + SwiftPM
project.yml 用 XcodeGen 声明了五个 target,全部依赖同一个 ClearlyCore 包:
| 构建目标 | 平台 | 形态 |
|---|---|---|
Clearly | macOS | 主 App(AppKit 编辑器 + WKWebView 预览) |
Clearly-iOS | iOS 17 | iPhone/iPad 主 App(UIKit 编辑器 + WKWebView 预览) |
ClearlyQuickLook | macOS | Finder QuickLook 预览扩展 |
ClearlyPreview-iOS | iOS | 文件 App 预览扩展 |
ClearlyThumbnail-iOS | iOS | 文件列表缩略图扩展 |
SwiftPM 会为每个目标平台自动编译对应版本,五个 target 共享同一份源码与同一套资源,天然保证"Mac 上看到的预览,和 iPhone 上看到的预览像素级一致"。
iOS 端的差异其实很小:把 Mac 的NSViewRepresentable换成UIViewRepresentable(如 EditorView_iOS.swift、PreviewView_iOS.swift),渲染器、CSS、语法高亮、大纲、查找则全部直接复用 ClearlyCore。
五、架构小结:一份核心,多端薄壳
这套架构最值得借鉴的三点:
- 逻辑归包、UI 归壳:平台无关逻辑全部进 ClearlyCore,
Clearly/与Clearly/iOS/只保留视图桥接; - 类型别名抽象:用
Platform*别名替代满屏#if,跨平台代码可读性拉满; - 声明式多目标:XcodeGen + SwiftPM 让五个构建目标共用一份依赖声明,升级 cmark-gfm 或前端资源只需改一处。
对于需要同时支持多平台、且要求渲染/行为严格一致的 Swift 项目,"单一核心包 + 多端薄壳"是绕不开的参考范式 🚀
【免费下载链接】clearly
Markdown editor for Mac, iOS and iPadOS
相关推荐
libwebsockets lws-md 流式 Markdown 渲染器:结构化事件驱动的安全渲染架构解析
libwebsockets lws md 流式 Markdown 渲染器:结构化事件驱动的安全渲染架构解析 lws md 是 libwebsockets 库中一
后端网络通信OpenChamber 1.2.2 解析:Agent Task 实时进度渲染与统一 Markdown 渲染
OpenChamber 1.2.2 解析:Agent Task 实时进度渲染与统一 Markdown 渲染 本篇围绕 OpenChamber 1.2.2(202
技术博客如何使用Swift Markdown UI在iOS应用中优雅渲染Markdown内容
如何使用Swift Markdown UI在iOS应用中优雅渲染Markdown内容 Swift Markdown UI是一款专为SwiftUI打造的原生Mar
UI组件富文本
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考