@cellgit/markdown-render 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/QUICK_START_iOS.md +219 -0
- package/README.md +343 -0
- package/dist/fonts/KaTeX_AMS-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_AMS-Regular.woff +0 -0
- package/dist/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
- package/dist/fonts/KaTeX_Fraktur-Bold.woff +0 -0
- package/dist/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Fraktur-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-Bold.ttf +0 -0
- package/dist/fonts/KaTeX_Main-Bold.woff +0 -0
- package/dist/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
- package/dist/fonts/KaTeX_Main-BoldItalic.woff +0 -0
- package/dist/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-Italic.ttf +0 -0
- package/dist/fonts/KaTeX_Main-Italic.woff +0 -0
- package/dist/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Main-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
- package/dist/fonts/KaTeX_Math-BoldItalic.woff +0 -0
- package/dist/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/dist/fonts/KaTeX_Math-Italic.ttf +0 -0
- package/dist/fonts/KaTeX_Math-Italic.woff +0 -0
- package/dist/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/dist/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
- package/dist/fonts/KaTeX_SansSerif-Bold.woff +0 -0
- package/dist/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
- package/dist/fonts/KaTeX_SansSerif-Italic.woff +0 -0
- package/dist/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/dist/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_SansSerif-Regular.woff +0 -0
- package/dist/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Script-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Script-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size1-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Size1-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size2-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Size2-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size3-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Size3-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size4-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Size4-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
- package/dist/fonts/KaTeX_Typewriter-Regular.woff +0 -0
- package/dist/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/dist/markdown-render.css +3 -0
- package/dist/markdown-render.esm.css +3 -0
- package/dist/markdown-render.esm.js +91452 -0
- package/dist/markdown-render.html +80 -0
- package/dist/markdown-render.js +91457 -0
- package/iOS_COLORS.md +146 -0
- package/ios-example/MarkdownViewController.swift +147 -0
- package/ios-example/README.md +185 -0
- package/package.json +73 -0
package/iOS_COLORS.md
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# iOS 系统颜色适配说明
|
|
2
|
+
|
|
3
|
+
本项目已完全适配 iOS 系统颜色规范,使用系统第一主色(System Colors),确保与原生 iOS 应用视觉一致。
|
|
4
|
+
|
|
5
|
+
## 颜色映射表
|
|
6
|
+
|
|
7
|
+
### 亮色模式(Light Mode)
|
|
8
|
+
|
|
9
|
+
| 元素 | CSS 变量 | 颜色值 | iOS 系统颜色 |
|
|
10
|
+
|------|---------|--------|-------------|
|
|
11
|
+
| 主要文字 | `--chat-text-color` | `#000000` | label |
|
|
12
|
+
| 次要文字 | `--chat-secondary-text-color` | `rgba(60, 60, 67, 0.6)` | secondaryLabel |
|
|
13
|
+
| 链接 | `--chat-link-color` | `#007AFF` | systemBlue |
|
|
14
|
+
| 主背景 | `--chat-background` | `#FFFFFF` | systemBackground |
|
|
15
|
+
| 次级背景 | `--chat-secondary-background` | `#F2F2F7` | secondarySystemBackground |
|
|
16
|
+
| 三级背景 | `--chat-tertiary-background` | `#FFFFFF` | tertiarySystemBackground |
|
|
17
|
+
| 代码块背景 | `--chat-code-bg` | `#F2F2F7` | secondarySystemBackground |
|
|
18
|
+
| 代码块文字 | `--chat-code-color` | `#000000` | label |
|
|
19
|
+
| 内联代码背景 | `--chat-inline-code-bg` | `rgba(0, 0, 0, 0.06)` | - |
|
|
20
|
+
| 表格边框 | `--chat-table-border` | `rgba(60, 60, 67, 0.29)` | separator |
|
|
21
|
+
| 表格背景 | `--chat-table-bg` | `#FFFFFF` | systemBackground |
|
|
22
|
+
| 表格交替行 | `--chat-table-alt-bg` | `#F2F2F7` | secondarySystemBackground |
|
|
23
|
+
|
|
24
|
+
### 暗色模式(Dark Mode)
|
|
25
|
+
|
|
26
|
+
| 元素 | CSS 变量 | 颜色值 | iOS 系统颜色 |
|
|
27
|
+
|------|---------|--------|-------------|
|
|
28
|
+
| 主要文字 | `--chat-text-color` | `#FFFFFF` | label |
|
|
29
|
+
| 次要文字 | `--chat-secondary-text-color` | `rgba(235, 235, 245, 0.6)` | secondaryLabel |
|
|
30
|
+
| 链接 | `--chat-link-color` | `#0A84FF` | systemBlue |
|
|
31
|
+
| 主背景 | `--chat-background` | `#000000` | systemBackground |
|
|
32
|
+
| 次级背景 | `--chat-secondary-background` | `#1C1C1E` | secondarySystemBackground |
|
|
33
|
+
| 三级背景 | `--chat-tertiary-background` | `#2C2C2E` | tertiarySystemBackground |
|
|
34
|
+
| 代码块背景 | `--chat-code-bg` | `#1C1C1E` | secondarySystemBackground |
|
|
35
|
+
| 代码块文字 | `--chat-code-color` | `#FFFFFF` | label |
|
|
36
|
+
| 内联代码背景 | `--chat-inline-code-bg` | `rgba(255, 255, 255, 0.1)` | - |
|
|
37
|
+
| 表格边框 | `--chat-table-border` | `rgba(84, 84, 88, 0.65)` | separator |
|
|
38
|
+
| 表格背景 | `--chat-table-bg` | `#000000` | systemBackground |
|
|
39
|
+
| 表格交替行 | `--chat-table-alt-bg` | `#1C1C1E` | secondarySystemBackground |
|
|
40
|
+
|
|
41
|
+
## 关键特性
|
|
42
|
+
|
|
43
|
+
### 1. 纯黑/纯白背景
|
|
44
|
+
- **亮色模式**:使用纯白 `#FFFFFF` 作为主背景(systemBackground)
|
|
45
|
+
- **暗色模式**:使用纯黑 `#000000` 作为主背景(systemBackground)
|
|
46
|
+
|
|
47
|
+
### 2. 系统蓝色链接
|
|
48
|
+
- **亮色模式**:`#007AFF` (iOS 标准蓝)
|
|
49
|
+
- **暗色模式**:`#0A84FF` (iOS 暗色模式蓝)
|
|
50
|
+
|
|
51
|
+
### 3. 层次分明的背景
|
|
52
|
+
- 主背景:systemBackground
|
|
53
|
+
- 代码块/表格:secondarySystemBackground (比主背景稍深/浅)
|
|
54
|
+
- 为内容提供清晰的视觉层次
|
|
55
|
+
|
|
56
|
+
### 4. 自动主题切换
|
|
57
|
+
使用 `color-scheme: light dark` 和 `@media (prefers-color-scheme: dark)` 实现自动切换,无需 JavaScript。
|
|
58
|
+
|
|
59
|
+
## 代码高亮配色
|
|
60
|
+
|
|
61
|
+
### 亮色模式
|
|
62
|
+
- 基于 **GitHub Light** 主题
|
|
63
|
+
- 背景:`#F2F2F7` (iOS secondarySystemBackground)
|
|
64
|
+
- 文字:`#000000` (iOS label)
|
|
65
|
+
|
|
66
|
+
### 暗色模式
|
|
67
|
+
- 基于 **GitHub Dark** 主题
|
|
68
|
+
- 背景:`#1C1C1E` (iOS secondarySystemBackground)
|
|
69
|
+
- 文字:`#FFFFFF` (iOS label)
|
|
70
|
+
|
|
71
|
+
## 使用方法
|
|
72
|
+
|
|
73
|
+
### 在 iOS 项目中
|
|
74
|
+
颜色会自动跟随系统主题:
|
|
75
|
+
1. 在 **设置 > 显示与亮度** 中切换"浅色/深色"
|
|
76
|
+
2. 应用会立即响应系统主题变化
|
|
77
|
+
3. 所有文字、背景、链接颜色自动适配
|
|
78
|
+
|
|
79
|
+
### 在浏览器中
|
|
80
|
+
1. 打开 Safari 或 Chrome
|
|
81
|
+
2. 在系统设置中切换"浅色/深色"外观
|
|
82
|
+
3. 网页会自动切换颜色方案
|
|
83
|
+
|
|
84
|
+
## 文件位置
|
|
85
|
+
|
|
86
|
+
主要颜色定义位于:
|
|
87
|
+
- `src/styles.css` - 主样式和颜色变量
|
|
88
|
+
- `src/highlight-theme.css` - 代码高亮颜色
|
|
89
|
+
- `templates/markdown-render.html` - HTML 模板样式
|
|
90
|
+
|
|
91
|
+
## iOS 系统颜色参考
|
|
92
|
+
|
|
93
|
+
官方文档:[Human Interface Guidelines - Color](https://developer.apple.com/design/human-interface-guidelines/color)
|
|
94
|
+
|
|
95
|
+
主要系统颜色:
|
|
96
|
+
- **systemBackground**: 主要背景色
|
|
97
|
+
- **secondarySystemBackground**: 次级背景色(比主背景稍微深/浅)
|
|
98
|
+
- **tertiarySystemBackground**: 三级背景色
|
|
99
|
+
- **label**: 主要文字颜色
|
|
100
|
+
- **secondaryLabel**: 次要文字颜色(带透明度)
|
|
101
|
+
- **systemBlue**: 系统蓝色(用于链接、按钮等交互元素)
|
|
102
|
+
- **separator**: 分隔线颜色
|
|
103
|
+
|
|
104
|
+
## 更新日志
|
|
105
|
+
|
|
106
|
+
### v1.1.0 - iOS 系统颜色适配
|
|
107
|
+
- ✅ 使用 iOS systemBackground (白/黑) 替代自定义背景色
|
|
108
|
+
- ✅ 使用 iOS label (黑/白) 作为主要文字颜色
|
|
109
|
+
- ✅ 使用 iOS systemBlue (#007AFF/#0A84FF) 作为链接颜色
|
|
110
|
+
- ✅ 代码块使用 secondarySystemBackground 作为背景
|
|
111
|
+
- ✅ 表格、引用块等元素完全适配 iOS 系统颜色
|
|
112
|
+
- ✅ 完美支持系统暗黑/亮色模式自动切换
|
|
113
|
+
|
|
114
|
+
## 验证方法
|
|
115
|
+
|
|
116
|
+
1. **iOS 设备测试**:
|
|
117
|
+
```
|
|
118
|
+
- 在 Xcode 中运行应用
|
|
119
|
+
- 切换系统外观:设置 > 显示与亮度
|
|
120
|
+
- 观察颜色变化是否与原生 iOS 应用一致
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
2. **浏览器测试**:
|
|
124
|
+
```
|
|
125
|
+
- 打开 test-dark-mode.html
|
|
126
|
+
- 切换系统外观设置
|
|
127
|
+
- 验证背景、文字、链接颜色
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## 技术细节
|
|
131
|
+
|
|
132
|
+
### CSS 变量优势
|
|
133
|
+
使用 CSS 自定义属性(变量)实现:
|
|
134
|
+
- 统一管理颜色
|
|
135
|
+
- 自动响应媒体查询
|
|
136
|
+
- 易于维护和修改
|
|
137
|
+
- 性能优异,无需 JavaScript
|
|
138
|
+
|
|
139
|
+
### WebView 配置
|
|
140
|
+
在 `MarkdownViewController.swift` 中:
|
|
141
|
+
```swift
|
|
142
|
+
webView.isOpaque = false
|
|
143
|
+
webView.backgroundColor = .clear // 透明,让 CSS 控制颜色
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
这确保 WebView 不会覆盖 CSS 定义的背景色。
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import UIKit
|
|
2
|
+
import WebKit
|
|
3
|
+
|
|
4
|
+
/// A view controller that renders Markdown content using WKWebView
|
|
5
|
+
class MarkdownViewController: UIViewController {
|
|
6
|
+
|
|
7
|
+
// MARK: - Properties
|
|
8
|
+
|
|
9
|
+
private var webView: WKWebView!
|
|
10
|
+
private var isHTMLLoaded = false
|
|
11
|
+
|
|
12
|
+
// MARK: - Lifecycle
|
|
13
|
+
|
|
14
|
+
override func loadView() {
|
|
15
|
+
let config = WKWebViewConfiguration()
|
|
16
|
+
|
|
17
|
+
// Configure message handlers for iOS communication
|
|
18
|
+
let contentController = WKUserContentController()
|
|
19
|
+
contentController.add(self, name: "renderComplete")
|
|
20
|
+
contentController.add(self, name: "pageReady")
|
|
21
|
+
config.userContentController = contentController
|
|
22
|
+
|
|
23
|
+
// Create and configure webView
|
|
24
|
+
webView = WKWebView(frame: .zero, configuration: config)
|
|
25
|
+
webView.scrollView.isScrollEnabled = true
|
|
26
|
+
webView.scrollView.bounces = true
|
|
27
|
+
|
|
28
|
+
// Use transparent background to let CSS control colors for dark mode support
|
|
29
|
+
webView.isOpaque = false
|
|
30
|
+
webView.backgroundColor = .clear
|
|
31
|
+
webView.scrollView.backgroundColor = .clear
|
|
32
|
+
|
|
33
|
+
view = webView
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
override func viewDidLoad() {
|
|
37
|
+
super.viewDidLoad()
|
|
38
|
+
loadHTMLFile()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// MARK: - Public Methods
|
|
42
|
+
|
|
43
|
+
/// Render markdown content
|
|
44
|
+
/// - Parameter markdown: The markdown string to render
|
|
45
|
+
func renderMarkdown(_ markdown: String) {
|
|
46
|
+
guard isHTMLLoaded else {
|
|
47
|
+
// Queue the render request until HTML is loaded
|
|
48
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
|
|
49
|
+
self?.renderMarkdown(markdown)
|
|
50
|
+
}
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Escape the markdown string for JavaScript
|
|
55
|
+
let escapedMarkdown = markdown
|
|
56
|
+
.replacingOccurrences(of: "\\", with: "\\\\")
|
|
57
|
+
.replacingOccurrences(of: "`", with: "\\`")
|
|
58
|
+
.replacingOccurrences(of: "$", with: "\\$")
|
|
59
|
+
.replacingOccurrences(of: "\n", with: "\\n")
|
|
60
|
+
.replacingOccurrences(of: "\r", with: "\\r")
|
|
61
|
+
.replacingOccurrences(of: "\"", with: "\\\"")
|
|
62
|
+
|
|
63
|
+
let javascript = "window.renderMarkdown(`\(escapedMarkdown)`)"
|
|
64
|
+
|
|
65
|
+
webView.evaluateJavaScript(javascript) { result, error in
|
|
66
|
+
if let error = error {
|
|
67
|
+
print("❌ Error rendering markdown: \(error.localizedDescription)")
|
|
68
|
+
} else {
|
|
69
|
+
print("✅ Markdown rendered successfully")
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/// Get the height of the rendered content
|
|
75
|
+
/// - Parameter completion: Callback with the content height in points
|
|
76
|
+
func getContentHeight(completion: @escaping (CGFloat) -> Void) {
|
|
77
|
+
webView.evaluateJavaScript("window.getContentHeight()") { result, error in
|
|
78
|
+
if let height = result as? CGFloat {
|
|
79
|
+
completion(height)
|
|
80
|
+
} else if let height = result as? Int {
|
|
81
|
+
completion(CGFloat(height))
|
|
82
|
+
} else {
|
|
83
|
+
completion(0)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/// Clear the rendered content
|
|
89
|
+
func clearContent() {
|
|
90
|
+
webView.evaluateJavaScript("window.clearContent()")
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// MARK: - Private Methods
|
|
94
|
+
|
|
95
|
+
private func loadHTMLFile() {
|
|
96
|
+
// Try to find the HTML file in the markdown-render-bundle directory
|
|
97
|
+
guard let htmlPath = Bundle.main.path(
|
|
98
|
+
forResource: "markdown-render",
|
|
99
|
+
ofType: "html",
|
|
100
|
+
inDirectory: "markdown-render-bundle"
|
|
101
|
+
) else {
|
|
102
|
+
print("❌ HTML file not found!")
|
|
103
|
+
print("📍 Bundle path: \(Bundle.main.bundlePath)")
|
|
104
|
+
print("⚠️ Make sure you added markdown-render-bundle using 'Create folder references'")
|
|
105
|
+
return
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
print("✅ HTML path: \(htmlPath)")
|
|
109
|
+
|
|
110
|
+
let htmlURL = URL(fileURLWithPath: htmlPath)
|
|
111
|
+
let bundleURL = htmlURL.deletingLastPathComponent()
|
|
112
|
+
|
|
113
|
+
do {
|
|
114
|
+
let htmlContent = try String(contentsOf: htmlURL, encoding: .utf8)
|
|
115
|
+
webView.loadHTMLString(htmlContent, baseURL: bundleURL)
|
|
116
|
+
} catch {
|
|
117
|
+
print("❌ Error loading HTML: \(error.localizedDescription)")
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// MARK: - WKScriptMessageHandler
|
|
123
|
+
|
|
124
|
+
extension MarkdownViewController: WKScriptMessageHandler {
|
|
125
|
+
func userContentController(
|
|
126
|
+
_ userContentController: WKUserContentController,
|
|
127
|
+
didReceive message: WKScriptMessage
|
|
128
|
+
) {
|
|
129
|
+
if message.name == "pageReady" {
|
|
130
|
+
print("✅ WebView page is ready")
|
|
131
|
+
isHTMLLoaded = true
|
|
132
|
+
} else if message.name == "renderComplete" {
|
|
133
|
+
if let body = message.body as? [String: Any] {
|
|
134
|
+
if let success = body["success"] as? Bool {
|
|
135
|
+
if success {
|
|
136
|
+
print("✅ Render completed successfully")
|
|
137
|
+
if let height = body["height"] as? CGFloat {
|
|
138
|
+
print("📏 Content height: \(height)")
|
|
139
|
+
}
|
|
140
|
+
} else if let error = body["error"] as? String {
|
|
141
|
+
print("❌ Render failed: \(error)")
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# iOS 集成示例
|
|
2
|
+
|
|
3
|
+
这个目录包含了在 iOS 项目中集成 markdown-render 的示例代码。
|
|
4
|
+
|
|
5
|
+
## 文件说明
|
|
6
|
+
|
|
7
|
+
- `MarkdownViewController.swift` - 用于渲染 Markdown 的 UIViewController
|
|
8
|
+
|
|
9
|
+
## 快速开始
|
|
10
|
+
|
|
11
|
+
请参考项目根目录的 [QUICK_START_iOS.md](../QUICK_START_iOS.md) 获取完整的集成步骤。
|
|
12
|
+
|
|
13
|
+
## MarkdownViewController 使用方法
|
|
14
|
+
|
|
15
|
+
### 1. 添加到项目
|
|
16
|
+
|
|
17
|
+
将 `MarkdownViewController.swift` 复制到你的 Xcode 项目中。
|
|
18
|
+
|
|
19
|
+
### 2. UIKit 中使用
|
|
20
|
+
|
|
21
|
+
```swift
|
|
22
|
+
import UIKit
|
|
23
|
+
|
|
24
|
+
class MyViewController: UIViewController {
|
|
25
|
+
private let markdownVC = MarkdownViewController()
|
|
26
|
+
|
|
27
|
+
override func viewDidLoad() {
|
|
28
|
+
super.viewDidLoad()
|
|
29
|
+
|
|
30
|
+
// 添加为子视图控制器
|
|
31
|
+
addChild(markdownVC)
|
|
32
|
+
view.addSubview(markdownVC.view)
|
|
33
|
+
markdownVC.view.frame = view.bounds
|
|
34
|
+
markdownVC.didMove(toParent: self)
|
|
35
|
+
|
|
36
|
+
// 渲染 Markdown
|
|
37
|
+
let markdown = """
|
|
38
|
+
# Hello iOS! 👋
|
|
39
|
+
|
|
40
|
+
This is **bold** and this is *italic*.
|
|
41
|
+
|
|
42
|
+
```swift
|
|
43
|
+
print("Hello, World!")
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Math: $E = mc^2$
|
|
47
|
+
|
|
48
|
+
- [x] Task completed
|
|
49
|
+
- [ ] Task pending
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
markdownVC.renderMarkdown(markdown)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 3. SwiftUI 中使用
|
|
58
|
+
|
|
59
|
+
```swift
|
|
60
|
+
import SwiftUI
|
|
61
|
+
|
|
62
|
+
struct MarkdownView: UIViewControllerRepresentable {
|
|
63
|
+
let markdown: String
|
|
64
|
+
|
|
65
|
+
func makeUIViewController(context: Context) -> MarkdownViewController {
|
|
66
|
+
MarkdownViewController()
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
func updateUIViewController(_ uiViewController: MarkdownViewController, context: Context) {
|
|
70
|
+
uiViewController.renderMarkdown(markdown)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
struct ContentView: View {
|
|
75
|
+
var body: some View {
|
|
76
|
+
MarkdownView(markdown: "# Hello SwiftUI\nThis is **bold**!")
|
|
77
|
+
.edgesIgnoringSafeArea(.all)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## API 参考
|
|
83
|
+
|
|
84
|
+
### renderMarkdown(_ markdown: String)
|
|
85
|
+
|
|
86
|
+
渲染 Markdown 内容。
|
|
87
|
+
|
|
88
|
+
```swift
|
|
89
|
+
markdownVC.renderMarkdown("# Hello\nThis is **bold**")
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### getContentHeight(completion: @escaping (CGFloat) -> Void)
|
|
93
|
+
|
|
94
|
+
获取渲染内容的高度。
|
|
95
|
+
|
|
96
|
+
```swift
|
|
97
|
+
markdownVC.getContentHeight { height in
|
|
98
|
+
print("Content height: \(height)")
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### clearContent()
|
|
103
|
+
|
|
104
|
+
清空已渲染的内容。
|
|
105
|
+
|
|
106
|
+
```swift
|
|
107
|
+
markdownVC.clearContent()
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## 调试技巧
|
|
111
|
+
|
|
112
|
+
### 1. 检查文件是否正确添加
|
|
113
|
+
|
|
114
|
+
确保在 Xcode 中:
|
|
115
|
+
- ✅ 使用 "Create folder references"(蓝色文件夹图标)
|
|
116
|
+
- ✅ 文件已添加到正确的 Target
|
|
117
|
+
- ✅ fonts 目录包含所有字体文件
|
|
118
|
+
|
|
119
|
+
### 2. 查看控制台日志
|
|
120
|
+
|
|
121
|
+
`MarkdownViewController` 会输出调试信息:
|
|
122
|
+
- `✅ HTML path: ...` - HTML 文件已找到
|
|
123
|
+
- `✅ WebView page is ready` - WebView 已准备好
|
|
124
|
+
- `✅ Render completed successfully` - 渲染成功
|
|
125
|
+
|
|
126
|
+
### 3. 使用 Safari Web Inspector
|
|
127
|
+
|
|
128
|
+
1. 打开 Safari → 偏好设置 → 高级
|
|
129
|
+
2. 勾选 "在菜单栏中显示开发菜单"
|
|
130
|
+
3. 运行应用后,Safari → 开发 → [你的设备] → [WebView]
|
|
131
|
+
4. 查看 JavaScript 控制台错误
|
|
132
|
+
|
|
133
|
+
## 常见问题
|
|
134
|
+
|
|
135
|
+
**Q: 显示空白页面**
|
|
136
|
+
- 检查是否使用了 "Create folder references"
|
|
137
|
+
- 查看 Xcode 控制台是否有 "❌ HTML file not found!" 错误
|
|
138
|
+
- 确认 markdown-render-bundle 目录已正确添加
|
|
139
|
+
|
|
140
|
+
**Q: 数学公式不显示**
|
|
141
|
+
- 确认 fonts 目录已添加
|
|
142
|
+
- 检查字体文件是否完整
|
|
143
|
+
|
|
144
|
+
**Q: 代码高亮不工作**
|
|
145
|
+
- 确认 markdown-render.js 文件完整
|
|
146
|
+
- 使用 Safari Web Inspector 查看 JavaScript 错误
|
|
147
|
+
|
|
148
|
+
## 技术细节
|
|
149
|
+
|
|
150
|
+
### 文件结构
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
markdown-render-bundle/
|
|
154
|
+
├── markdown-render.html # WebView 加载的 HTML
|
|
155
|
+
├── markdown-render.js # 核心 JavaScript 库
|
|
156
|
+
├── markdown-render.css # 样式文件
|
|
157
|
+
└── fonts/ # KaTeX 数学公式字体
|
|
158
|
+
├── KaTeX_*.woff2
|
|
159
|
+
└── ...
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### iOS 与 JavaScript 通信
|
|
163
|
+
|
|
164
|
+
MarkdownViewController 使用 `WKScriptMessageHandler` 与 WebView 通信:
|
|
165
|
+
|
|
166
|
+
**从 JavaScript 到 iOS:**
|
|
167
|
+
- `pageReady` - 页面加载完成
|
|
168
|
+
- `renderComplete` - 渲染完成,包含成功状态和内容高度
|
|
169
|
+
|
|
170
|
+
**从 iOS 到 JavaScript:**
|
|
171
|
+
- `window.renderMarkdown(markdown)` - 渲染 Markdown
|
|
172
|
+
- `window.getContentHeight()` - 获取内容高度
|
|
173
|
+
- `window.clearContent()` - 清空内容
|
|
174
|
+
|
|
175
|
+
## 更新日志
|
|
176
|
+
|
|
177
|
+
### v1.0.0
|
|
178
|
+
- 初始版本
|
|
179
|
+
- 支持完整的 Markdown 渲染
|
|
180
|
+
- 支持代码高亮和数学公式
|
|
181
|
+
- 提供 UIKit 和 SwiftUI 示例
|
|
182
|
+
|
|
183
|
+
## 许可证
|
|
184
|
+
|
|
185
|
+
MIT License
|
package/package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cellgit/markdown-render",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A frontend markdown rendering library with syntax highlighting, math support, and iOS system colors adaptation",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/markdown-render.esm.js",
|
|
7
|
+
"module": "dist/markdown-render.esm.js",
|
|
8
|
+
"browser": "dist/markdown-render.js",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/markdown-render.esm.js",
|
|
12
|
+
"default": "./dist/markdown-render.esm.js"
|
|
13
|
+
},
|
|
14
|
+
"./styles": "./dist/markdown-render.css",
|
|
15
|
+
"./dist/*": "./dist/*"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"ios-example",
|
|
20
|
+
"README.md",
|
|
21
|
+
"QUICK_START_iOS.md",
|
|
22
|
+
"iOS_COLORS.md"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "rollup -c && node scripts/copy-katex-fonts.js && node scripts/copy-html-template.js",
|
|
26
|
+
"build:ios": "npm run build && node scripts/bundle-for-ios.js",
|
|
27
|
+
"prepublishOnly": "npm run build",
|
|
28
|
+
"test": "echo \"No tests specified\" && exit 0"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"markdown",
|
|
32
|
+
"render",
|
|
33
|
+
"renderer",
|
|
34
|
+
"highlight",
|
|
35
|
+
"syntax-highlighting",
|
|
36
|
+
"katex",
|
|
37
|
+
"math",
|
|
38
|
+
"latex",
|
|
39
|
+
"ios",
|
|
40
|
+
"android",
|
|
41
|
+
"webview",
|
|
42
|
+
"react",
|
|
43
|
+
"vue",
|
|
44
|
+
"browser",
|
|
45
|
+
"dark-mode",
|
|
46
|
+
"system-colors",
|
|
47
|
+
"mobile"
|
|
48
|
+
],
|
|
49
|
+
"author": "",
|
|
50
|
+
"license": "MIT",
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "https://github.com/yourusername/markdown-render.git"
|
|
54
|
+
},
|
|
55
|
+
"bugs": {
|
|
56
|
+
"url": "https://github.com/yourusername/markdown-render/issues"
|
|
57
|
+
},
|
|
58
|
+
"homepage": "https://github.com/yourusername/markdown-render#readme",
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"highlight.js": "^11.9.0",
|
|
61
|
+
"katex": "^0.16.9",
|
|
62
|
+
"markdown-it": "^14.1.0",
|
|
63
|
+
"markdown-it-task-lists": "^2.1.1",
|
|
64
|
+
"markdown-it-emoji": "^3.0.0"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@rollup/plugin-commonjs": "^25.0.7",
|
|
68
|
+
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
69
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
70
|
+
"rollup": "^4.9.6",
|
|
71
|
+
"rollup-plugin-import-css": "^3.5.2"
|
|
72
|
+
}
|
|
73
|
+
}
|