☰
Clearly架构解析:一个ClearlyCore包如何同时驱动Mac与iOS的Markdown渲染
2026/10/14 19:54:28 网站建设 项目流程

【免费下载链接】clearly

Markdown editor for Mac, iOS and iPadOS

项目地址:https://gitcode.com/gh_mirrors/cle/clearly
点击查看免费下载

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():

  1. 先抽离 frontmatter,避免 YAML 头干扰解析;
  2. 调用 cmark-gfm 库(GFM:表格、任务列表、删除线、自动链接)把正文转成 HTML;
  3. 依次执行后置加工:数学公式($...$→ KaTeX span)、==高亮==、上下标、:emoji:短码、Callout 提示块、[[toc]]目录、表格标题、代码块文件名标签;
  4. 全程用protectCodeRegions()保护<pre>/<code>区域,防止代码块内容被误改写。

这条管线还有个巧思:每个 HTML 节点都带data-sourcepos(源码行号),渲染结果与源文件行号精确对齐——"双击预览跳回源码"这类交互就靠它。完整管线细节可参考官方文档 docs/markdown-rendering-architecture.md。

四、一个包驱动五个构建目标:XcodeGen + SwiftPM

project.yml 用 XcodeGen 声明了五个 target,全部依赖同一个 ClearlyCore 包:

构建目标平台形态
ClearlymacOS主 App(AppKit 编辑器 + WKWebView 预览)
Clearly-iOSiOS 17iPhone/iPad 主 App(UIKit 编辑器 + WKWebView 预览)
ClearlyQuickLookmacOSFinder QuickLook 预览扩展
ClearlyPreview-iOSiOS文件 App 预览扩展
ClearlyThumbnail-iOSiOS文件列表缩略图扩展

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

项目地址:https://gitcode.com/gh_mirrors/cle/clearly
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询