Swift Markdown Kit · DOCS
主题与语法
主题与语法
配色模式与主题
刻意分成两件事:colorScheme 决定这套设计渲染成浅色还是深色,theme 决定这套
设计本身是什么。
var options = MarkdownRenderOptions()
options.colorScheme = .auto // .auto 跟随系统;.light / .dark 强制
options.theme = .github // .system(默认)或 .github
两者都在运行时生效 —— 不需要重新出包,也没有额外的样式表。
Token 覆盖
一个主题 = 命名预设 + 逐 token 覆盖,每个覆盖都同时给浅色和深色值:
let theme = MarkdownTheme.github
.textColor(light: .label, dark: .label)
.linkColor(light: .systemIndigo, dark: .systemTeal)
.codeBlockSurface(light: .secondarySystemBackground, dark: .tertiarySystemBackground)
.blockquoteBorder(light: .systemGreen, dark: .systemGreen)
.bodyLineHeight(1.55)
.codeCornerRadius(8)
.headingSize(level: 1, em: 1.4)
.headingSize(level: 2, em: 1.25)
var options = MarkdownRenderOptions()
options.theme = theme
命名方法没覆盖到的部分,直接设底层的 CSS 自定义属性:
let theme = MarkdownTheme.system
.token("--md-reasoning-color", light: .secondaryLabel, dark: .secondaryLabel)
.token("--chat-table-border", light: "#d0d7de", dark: "#30363d")
.metric("--md-paragraph-margin", "0.9em")
.codeToken("--hljs-keyword", light: .systemPink, dark: .systemPink)
三类 token:token 是深浅色不同的颜色,metric 是与配色无关的尺寸,
codeToken 是语法高亮。
字体与布局
var options = MarkdownRenderOptions()
options.baseFontSize = 16
options.respectsDynamicType = true // 跟随系统字号
options.minFontScale = 0.85 // 夹住倍率,避免无障碍字号撑破布局
options.maxFontScale = 1.6
options.contentPadding = UIEdgeInsets(top: 20, left: 16, bottom: 20, right: 16)
options.bottomGap = 24 // 给覆盖在底部的输入框留出空间
options.backgroundColor = .systemBackground
会话还多两个,因为消息气泡和它所在的栏是两个宽度:
var chat = MarkdownChatRenderOptions()
chat.maxMessageWidth = .points(780) // 阅读栏宽度
chat.userMessageMaxWidth = .fraction(0.82, upTo: 620) // 用户自己的气泡
chat.messageSpacing = 14
自定义行内语法
声明式注册行内扩展。没有任何代码跨越 bridge:每条规则只是一个识别模式,每个
匹配渲染成完全转义的 .md-ext-{name} span,点击后回传给你。
var options = MarkdownRenderOptions()
options.extensions = [
.mention(), // @handle
.hashtag(), // #tag
.ticker(), // $AAPL —— 仅大写,所以 "$5" 不受影响
.wikilink(), // [[Page]]
.prefix(name: "issue", trigger: "ISSUE-", body: .upperDigit, action: "issue"),
.delimiter(name: "spoiler", open: "||", close: "||", action: "spoiler")
]
两种识别模式:
- prefix —— 触发串加一段受字符类约束的正文(
.word、.alnum、.letter、.upper、.upperDigit,或.chars("…"))。热路径上没有正则,因此不存在 灾难性回溯。 - delimiter —— 一对开闭定界符,捕获中间的文本。
点击以 action 形式抵达:
var options = MarkdownRenderOptions()
options.extensions = [.mention(), .wikilink()]
MarkdownRenderView(markdown: article, options: options) { event in
guard case .action(let action) = event else { return }
if case .extensionTapped(let name, let tapped, let value) = action {
route(name: name, action: tapped, value: value)
}
}
每个扩展都暴露自己的主题 token —— --md-ext-{name}-color、-bg、-radius、
-padding、-weight、-decoration —— 所以样式走的是和其他一切相同的机制:
let theme = MarkdownTheme.system
.token("--md-ext-mention-color", light: .systemBlue, dark: .systemTeal)
.metric("--md-ext-mention-radius", "4px")
运行时改不了的部分
基线样式表 —— 默认间距、代码块外框、表格分隔线 —— 编译在渲染核心里。预设和 token 覆盖能改到视觉表层;要改基线本身需要重新构建 framework。如果你需要的 token 缺失,告诉我们,通常是一个很小的改动。