@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
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# iOS 快速开始指南
|
|
2
|
+
|
|
3
|
+
快速 5 步集成 markdown-render 到你的 iOS 项目。
|
|
4
|
+
|
|
5
|
+
## 第 1 步:打包文件
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
cd markdown-render
|
|
9
|
+
npm install
|
|
10
|
+
npm run build:ios
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
✅ 完成后会在 `ios-bundle/` 目录生成所有需要的文件
|
|
14
|
+
(模板源文件位于 `templates/markdown-render.html`,如需修改请编辑后重新运行上述命令。)
|
|
15
|
+
|
|
16
|
+
## 第 2 步:添加文件到 Xcode
|
|
17
|
+
|
|
18
|
+
1. 打开你的 Xcode 项目
|
|
19
|
+
2. 在项目导航器中右键点击 → New Group
|
|
20
|
+
3. 命名为 `markdown-render-bundle`
|
|
21
|
+
4. 将 `ios-bundle/` 目录下的**所有文件**拖入该分组
|
|
22
|
+
- ✅ markdown-render.html
|
|
23
|
+
- ✅ markdown-render.js
|
|
24
|
+
- ✅ markdown-render.css
|
|
25
|
+
- ✅ fonts/ 目录
|
|
26
|
+
5. **重要**:在弹出的对话框中:
|
|
27
|
+
- ✅ 勾选 "Copy items if needed"
|
|
28
|
+
- ✅ 选择 "Create folder references" (蓝色文件夹图标)
|
|
29
|
+
- ✅ 确保添加到正确的 Target
|
|
30
|
+
|
|
31
|
+
## 第 3 步:添加 Swift 代码
|
|
32
|
+
|
|
33
|
+
将 `ios-example/MarkdownViewController.swift` 复制到你的项目中。
|
|
34
|
+
|
|
35
|
+
或者在终端运行:
|
|
36
|
+
```bash
|
|
37
|
+
cp ios-example/MarkdownViewController.swift /path/to/your/xcode/project/
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 第 4 步:使用
|
|
41
|
+
|
|
42
|
+
### UIKit
|
|
43
|
+
|
|
44
|
+
```swift
|
|
45
|
+
import UIKit
|
|
46
|
+
|
|
47
|
+
class MyViewController: UIViewController {
|
|
48
|
+
private let markdownVC = MarkdownViewController()
|
|
49
|
+
|
|
50
|
+
override func viewDidLoad() {
|
|
51
|
+
super.viewDidLoad()
|
|
52
|
+
|
|
53
|
+
// 添加子视图控制器
|
|
54
|
+
addChild(markdownVC)
|
|
55
|
+
view.addSubview(markdownVC.view)
|
|
56
|
+
markdownVC.view.frame = view.bounds
|
|
57
|
+
markdownVC.didMove(toParent: self)
|
|
58
|
+
|
|
59
|
+
// 渲染 Markdown
|
|
60
|
+
let markdown = """
|
|
61
|
+
# Hello iOS! 👋
|
|
62
|
+
|
|
63
|
+
This is **bold** and this is *italic*.
|
|
64
|
+
|
|
65
|
+
```swift
|
|
66
|
+
print("Hello, World!")
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Math: $E = mc^2$
|
|
70
|
+
|
|
71
|
+
- [x] Task completed
|
|
72
|
+
- [ ] Task pending
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
markdownVC.renderMarkdown(markdown)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### SwiftUI
|
|
81
|
+
|
|
82
|
+
```swift
|
|
83
|
+
import SwiftUI
|
|
84
|
+
|
|
85
|
+
struct MarkdownView: UIViewControllerRepresentable {
|
|
86
|
+
let markdown: String
|
|
87
|
+
|
|
88
|
+
func makeUIViewController(context: Context) -> MarkdownViewController {
|
|
89
|
+
MarkdownViewController()
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
func updateUIViewController(_ uiViewController: MarkdownViewController, context: Context) {
|
|
93
|
+
uiViewController.renderMarkdown(markdown)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
struct ContentView: View {
|
|
98
|
+
var body: some View {
|
|
99
|
+
MarkdownView(markdown: "# Hello SwiftUI\nThis is **bold**!")
|
|
100
|
+
.edgesIgnoringSafeArea(.all)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## 第 5 步:运行测试
|
|
106
|
+
|
|
107
|
+
1. 在模拟器或设备上运行应用
|
|
108
|
+
2. 如果看不到内容,检查:
|
|
109
|
+
- [ ] 文件是否正确添加到 Target
|
|
110
|
+
- [ ] 是否使用了 "Create folder references"
|
|
111
|
+
- [ ] 查看 Xcode 控制台是否有错误
|
|
112
|
+
|
|
113
|
+
## 调试技巧
|
|
114
|
+
|
|
115
|
+
### 文件路径问题
|
|
116
|
+
|
|
117
|
+
如果提示找不到 HTML 文件,检查文件路径:
|
|
118
|
+
|
|
119
|
+
```swift
|
|
120
|
+
// 在 MarkdownViewController 的 loadHTMLFile() 方法中添加调试输出
|
|
121
|
+
guard let htmlPath = Bundle.main.path(forResource: "markdown-render", ofType: "html", inDirectory: "markdown-render-bundle") else {
|
|
122
|
+
print("❌ HTML file not found!")
|
|
123
|
+
print("Bundle path: \(Bundle.main.bundlePath)")
|
|
124
|
+
return
|
|
125
|
+
}
|
|
126
|
+
print("✅ HTML path: \(htmlPath)")
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Safari Web Inspector
|
|
130
|
+
|
|
131
|
+
1. 打开 Safari → 偏好设置 → 高级
|
|
132
|
+
2. 勾选 "在菜单栏中显示开发菜单"
|
|
133
|
+
3. 在设备/模拟器运行应用
|
|
134
|
+
4. Safari → 开发 → [你的设备] → [WebView]
|
|
135
|
+
5. 查看 JavaScript 控制台错误
|
|
136
|
+
|
|
137
|
+
### 常见问题
|
|
138
|
+
|
|
139
|
+
**问题:白屏无内容**
|
|
140
|
+
- 检查是否使用了 "Create folder references" 而不是 "Create groups"
|
|
141
|
+
- 确认 fonts 目录包含所有字体文件
|
|
142
|
+
|
|
143
|
+
**问题:数学公式不显示**
|
|
144
|
+
- 确认 fonts 目录正确添加
|
|
145
|
+
- 检查 CSS 文件是否加载
|
|
146
|
+
|
|
147
|
+
**问题:代码高亮不工作**
|
|
148
|
+
- 确认 markdown-render.js 文件完整
|
|
149
|
+
- 查看浏览器控制台是否有 JavaScript 错误
|
|
150
|
+
|
|
151
|
+
## 进阶功能
|
|
152
|
+
|
|
153
|
+
### 动态调整高度
|
|
154
|
+
|
|
155
|
+
```swift
|
|
156
|
+
markdownVC.renderMarkdown(markdown)
|
|
157
|
+
|
|
158
|
+
// 渲染完成后获取高度
|
|
159
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
|
160
|
+
markdownVC.getContentHeight { height in
|
|
161
|
+
print("Content height: \(height)")
|
|
162
|
+
// 更新约束或 frame
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 清空内容
|
|
168
|
+
|
|
169
|
+
```swift
|
|
170
|
+
markdownVC.clearContent()
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### 监听渲染完成
|
|
174
|
+
|
|
175
|
+
在 `MarkdownViewController` 中已经实现了 `renderComplete` 消息处理,你可以修改代码添加回调:
|
|
176
|
+
|
|
177
|
+
```swift
|
|
178
|
+
var onRenderComplete: ((Bool) -> Void)?
|
|
179
|
+
|
|
180
|
+
extension MarkdownViewController: WKScriptMessageHandler {
|
|
181
|
+
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
|
182
|
+
if message.name == "renderComplete" {
|
|
183
|
+
if let body = message.body as? [String: Any],
|
|
184
|
+
let success = body["success"] as? Bool {
|
|
185
|
+
onRenderComplete?(success)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## 完整文档
|
|
193
|
+
|
|
194
|
+
- 详细集成指南:[ios-example/README.md](ios-example/README.md)
|
|
195
|
+
- Swift 源码参考:[ios-example/MarkdownViewController.swift](ios-example/MarkdownViewController.swift)
|
|
196
|
+
- 功能演示:在浏览器打开 `test.html`
|
|
197
|
+
|
|
198
|
+
## 更新库
|
|
199
|
+
|
|
200
|
+
当 markdown-render 有更新时:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
git pull
|
|
204
|
+
npm install
|
|
205
|
+
npm run build:ios
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
然后在 Xcode 中替换 `markdown-render-bundle` 目录下的文件。
|
|
209
|
+
|
|
210
|
+
## 技术支持
|
|
211
|
+
|
|
212
|
+
有问题?
|
|
213
|
+
- 查看 [完整文档](README.md)
|
|
214
|
+
- 参考 [iOS 集成指南](ios-example/README.md)
|
|
215
|
+
- 查看 [test.html](test.html) 浏览器演示
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
🎉 完成!现在你的 iOS 应用已经支持完整的 Markdown 渲染功能了!
|
package/README.md
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
# markdown-render
|
|
2
|
+
|
|
3
|
+
一个功能完整的前端 Markdown 渲染库,基于 markdown-it,支持语法高亮、数学公式、任务列表、Emoji 等特性。完美兼容 WebView、Web、React Native 和 Electron。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
✅ **基于 markdown-it** - 使用业界标准的 markdown-it 解析器
|
|
8
|
+
✅ **语法高亮** - 内置 highlight.js,支持 180+ 编程语言
|
|
9
|
+
✅ **数学公式** - KaTeX 集成,支持行内和块级数学公式
|
|
10
|
+
✅ **任务列表** - 支持 `- [x]` 和 `- [ ]` 语法
|
|
11
|
+
✅ **嵌套列表** - 支持多层嵌套列表(有序/无序)
|
|
12
|
+
✅ **Emoji** - 支持 emoji shortcode,如 `:smile:` :smile:
|
|
13
|
+
✅ **表格** - 完整的 markdown 表格支持
|
|
14
|
+
✅ **代码块增强** - 带语言标签和复制按钮的代码块
|
|
15
|
+
✅ **主题支持** - 内置明暗主题自动切换
|
|
16
|
+
✅ **单文件输出** - 所有依赖打包在一个 JS 文件中
|
|
17
|
+
✅ **Pipeline 架构** - 可扩展的后处理机制
|
|
18
|
+
|
|
19
|
+
## 安装
|
|
20
|
+
|
|
21
|
+
### 从 npm 安装(推荐)
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install markdown-render
|
|
25
|
+
# 或
|
|
26
|
+
yarn add markdown-render
|
|
27
|
+
# 或
|
|
28
|
+
pnpm add markdown-render
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 从源码构建
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
git clone <repository-url>
|
|
35
|
+
cd markdown-render
|
|
36
|
+
npm install
|
|
37
|
+
npm run build
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 使用方法
|
|
41
|
+
|
|
42
|
+
### 在 npm 项目中使用
|
|
43
|
+
|
|
44
|
+
**React 示例:**
|
|
45
|
+
```jsx
|
|
46
|
+
import { renderMarkdown } from 'markdown-render';
|
|
47
|
+
import 'markdown-render/styles';
|
|
48
|
+
|
|
49
|
+
function App() {
|
|
50
|
+
const html = renderMarkdown('# Hello **React**!');
|
|
51
|
+
return <div dangerouslySetInnerHTML={{ __html: html }} />;
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Vue 示例:**
|
|
56
|
+
```vue
|
|
57
|
+
<template>
|
|
58
|
+
<div v-html="html"></div>
|
|
59
|
+
</template>
|
|
60
|
+
|
|
61
|
+
<script setup>
|
|
62
|
+
import { renderMarkdown } from 'markdown-render';
|
|
63
|
+
import 'markdown-render/styles';
|
|
64
|
+
|
|
65
|
+
const html = renderMarkdown('# Hello **Vue**!');
|
|
66
|
+
</script>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Vanilla JS:**
|
|
70
|
+
```javascript
|
|
71
|
+
import { renderMarkdown } from 'markdown-render';
|
|
72
|
+
import 'markdown-render/styles';
|
|
73
|
+
|
|
74
|
+
const html = renderMarkdown('# Hello **World**!');
|
|
75
|
+
document.getElementById('app').innerHTML = html;
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
📚 **完整文档:**
|
|
79
|
+
- [NPM 使用指南](NPM_USAGE.md) - 详细的 npm 使用说明
|
|
80
|
+
- [示例代码](examples/) - React、Vue、Vanilla JS 完整示例
|
|
81
|
+
|
|
82
|
+
### 在 iOS 项目中使用
|
|
83
|
+
|
|
84
|
+
专为 iOS 打包:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npm run build:ios
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
这会在 `ios-bundle/` 目录生成适用于 iOS 的文件包。详细集成步骤请查看 [iOS 集成指南](ios-example/README.md)。
|
|
91
|
+
|
|
92
|
+
快速开始:
|
|
93
|
+
1. 运行 `npm run build:ios`
|
|
94
|
+
2. 将 `ios-bundle/` 中的文件添加到 Xcode 项目
|
|
95
|
+
3. 使用 `MarkdownViewController` 渲染 Markdown
|
|
96
|
+
|
|
97
|
+
> 需要自定义 WebView 模板?请编辑 `templates/markdown-render.html`,然后重新运行 `npm run build` 或 `npm run build:ios`,生成的 `dist/markdown-render.html` 会自动更新并被后续打包脚本使用。
|
|
98
|
+
|
|
99
|
+
```swift
|
|
100
|
+
let markdownVC = MarkdownViewController()
|
|
101
|
+
markdownVC.renderMarkdown("# Hello iOS\nThis is **bold** text!")
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
完整示例代码请参考 `ios-example/MarkdownViewController.swift`。
|
|
105
|
+
|
|
106
|
+
### 在 HTML 中使用
|
|
107
|
+
|
|
108
|
+
```html
|
|
109
|
+
<!DOCTYPE html>
|
|
110
|
+
<html>
|
|
111
|
+
<head>
|
|
112
|
+
<meta charset="UTF-8">
|
|
113
|
+
<title>Markdown Render Example</title>
|
|
114
|
+
</head>
|
|
115
|
+
<body>
|
|
116
|
+
<div id="output"></div>
|
|
117
|
+
|
|
118
|
+
<script src="dist/markdown-render.js"></script>
|
|
119
|
+
<script>
|
|
120
|
+
const markdown = `
|
|
121
|
+
# Hello World
|
|
122
|
+
|
|
123
|
+
This is **bold** and this is *italic*.
|
|
124
|
+
|
|
125
|
+
\`\`\`javascript
|
|
126
|
+
console.log("Hello, World!");
|
|
127
|
+
\`\`\`
|
|
128
|
+
|
|
129
|
+
Math: $E = mc^2$
|
|
130
|
+
`;
|
|
131
|
+
|
|
132
|
+
const html = MarkdownRender.renderMarkdown(markdown);
|
|
133
|
+
document.getElementById('output').innerHTML = html;
|
|
134
|
+
</script>
|
|
135
|
+
</body>
|
|
136
|
+
</html>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### 在 ES Module 中使用
|
|
140
|
+
|
|
141
|
+
```javascript
|
|
142
|
+
import { renderMarkdown } from './dist/markdown-render.js';
|
|
143
|
+
|
|
144
|
+
const html = renderMarkdown('# Hello World');
|
|
145
|
+
console.log(html);
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### 添加复制代码功能
|
|
149
|
+
|
|
150
|
+
```javascript
|
|
151
|
+
document.addEventListener('click', function(e) {
|
|
152
|
+
if (e.target.classList.contains('code-copy-button') ||
|
|
153
|
+
e.target.closest('.code-copy-button')) {
|
|
154
|
+
const button = e.target.classList.contains('code-copy-button')
|
|
155
|
+
? e.target
|
|
156
|
+
: e.target.closest('.code-copy-button');
|
|
157
|
+
|
|
158
|
+
const wrapper = button.closest('.code-block-wrapper');
|
|
159
|
+
if (!wrapper) return;
|
|
160
|
+
|
|
161
|
+
const codeNode = wrapper.querySelector('code');
|
|
162
|
+
const codeText = codeNode ? codeNode.textContent : '';
|
|
163
|
+
|
|
164
|
+
navigator.clipboard.writeText(codeText).then(() => {
|
|
165
|
+
const copyTextSpan = button.querySelector('.copy-text');
|
|
166
|
+
copyTextSpan.textContent = 'Copied!';
|
|
167
|
+
setTimeout(() => {
|
|
168
|
+
copyTextSpan.textContent = 'Copy code';
|
|
169
|
+
}, 2000);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## 功能示例
|
|
176
|
+
|
|
177
|
+
### 代码块
|
|
178
|
+
|
|
179
|
+
\`\`\`javascript
|
|
180
|
+
function hello() {
|
|
181
|
+
console.log("Hello, World!");
|
|
182
|
+
}
|
|
183
|
+
\`\`\`
|
|
184
|
+
|
|
185
|
+
### 数学公式
|
|
186
|
+
|
|
187
|
+
行内数学:$E = mc^2$
|
|
188
|
+
|
|
189
|
+
块级数学:
|
|
190
|
+
|
|
191
|
+
$$
|
|
192
|
+
\\int_{-\\infty}^{\\infty} e^{-x^2} dx = \\sqrt{\\pi}
|
|
193
|
+
$$
|
|
194
|
+
|
|
195
|
+
### 任务列表
|
|
196
|
+
|
|
197
|
+
- [x] 已完成的任务
|
|
198
|
+
- [ ] 未完成的任务
|
|
199
|
+
|
|
200
|
+
### 嵌套列表
|
|
201
|
+
|
|
202
|
+
- 第一层
|
|
203
|
+
- 第二层
|
|
204
|
+
- 第三层
|
|
205
|
+
|
|
206
|
+
### 表格
|
|
207
|
+
|
|
208
|
+
| 列1 | 列2 | 列3 |
|
|
209
|
+
|-----|-----|-----|
|
|
210
|
+
| A | B | C |
|
|
211
|
+
| 1 | 2 | 3 |
|
|
212
|
+
|
|
213
|
+
### Emoji
|
|
214
|
+
|
|
215
|
+
支持 emoji shortcode::smile: :heart: :rocket:
|
|
216
|
+
|
|
217
|
+
## 项目结构
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
markdown-render/
|
|
221
|
+
├── src/
|
|
222
|
+
│ ├── index.js # 主入口
|
|
223
|
+
│ ├── markdown.js # markdown-it 配置
|
|
224
|
+
│ ├── highlight.js # 代码高亮
|
|
225
|
+
│ ├── math.js # 数学公式渲染
|
|
226
|
+
│ ├── utils.js # 工具函数
|
|
227
|
+
│ ├── styles.css # 样式表
|
|
228
|
+
│ └── pipeline/ # Pipeline 后处理
|
|
229
|
+
│ ├── index.js # Pipeline 编排
|
|
230
|
+
│ ├── copy-button.js # 复制按钮
|
|
231
|
+
│ └── link-handler.js # 链接处理
|
|
232
|
+
├── dist/
|
|
233
|
+
│ └── markdown-render.js # 构建产物
|
|
234
|
+
├── package.json
|
|
235
|
+
├── rollup.config.js
|
|
236
|
+
└── test.html # 测试页面
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Pipeline 机制
|
|
240
|
+
|
|
241
|
+
本库采用 Pipeline 架构,可以轻松扩展后处理功能:
|
|
242
|
+
|
|
243
|
+
```javascript
|
|
244
|
+
// src/pipeline/index.js
|
|
245
|
+
const pipelines = [
|
|
246
|
+
addCopyButton, // 添加复制按钮
|
|
247
|
+
handleLinks // 处理链接
|
|
248
|
+
];
|
|
249
|
+
|
|
250
|
+
export function applyPipeline(html) {
|
|
251
|
+
return pipelines.reduce((currentHtml, processor) => {
|
|
252
|
+
return processor(currentHtml);
|
|
253
|
+
}, html);
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## 自定义 Pipeline
|
|
258
|
+
|
|
259
|
+
你可以添加自己的 pipeline 处理器:
|
|
260
|
+
|
|
261
|
+
```javascript
|
|
262
|
+
// src/pipeline/my-processor.js
|
|
263
|
+
export function myProcessor(html) {
|
|
264
|
+
// 处理 html
|
|
265
|
+
return html;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// 在 src/pipeline/index.js 中添加
|
|
269
|
+
import { myProcessor } from './my-processor.js';
|
|
270
|
+
|
|
271
|
+
const pipelines = [
|
|
272
|
+
addCopyButton,
|
|
273
|
+
handleLinks,
|
|
274
|
+
myProcessor // 添加你的处理器
|
|
275
|
+
];
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## 版本依赖
|
|
279
|
+
|
|
280
|
+
- **markdown-it**: ^14.1.0
|
|
281
|
+
- **highlight.js**: ^11.9.0 (匹配 GPTDemo)
|
|
282
|
+
- **katex**: ^0.16.9 (匹配 GPTDemo)
|
|
283
|
+
- **markdown-it-task-lists**: ^2.1.1
|
|
284
|
+
- **markdown-it-emoji**: ^3.0.0
|
|
285
|
+
|
|
286
|
+
## 构建
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
npm run build
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
构建产物:`dist/markdown-render.js` (约 1.3MB)
|
|
293
|
+
|
|
294
|
+
## 测试
|
|
295
|
+
|
|
296
|
+
在浏览器中打开 `test.html` 查看所有功能演示。
|
|
297
|
+
|
|
298
|
+
## CSS 变量
|
|
299
|
+
|
|
300
|
+
可通过 CSS 变量自定义主题:
|
|
301
|
+
|
|
302
|
+
```css
|
|
303
|
+
:root {
|
|
304
|
+
--chat-text-color: #1C1C1E;
|
|
305
|
+
--chat-link-color: #0A5EFF;
|
|
306
|
+
--chat-background: #FFFFFF;
|
|
307
|
+
--chat-code-bg: var(--chat-background);
|
|
308
|
+
--chat-inline-code-bg: rgba(175, 184, 193, 0.2);
|
|
309
|
+
--chat-table-border: #D1D5DB;
|
|
310
|
+
--chat-copy-button-bg: rgba(0, 0, 0, 0.65);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
@media (prefers-color-scheme: dark) {
|
|
314
|
+
:root {
|
|
315
|
+
--chat-text-color: #ECECEC;
|
|
316
|
+
--chat-link-color: #0A84FF;
|
|
317
|
+
--chat-background: #1C1C1E;
|
|
318
|
+
/* ... */
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
## 浏览器兼容性
|
|
324
|
+
|
|
325
|
+
- Chrome/Edge: ✅
|
|
326
|
+
- Safari: ✅
|
|
327
|
+
- Firefox: ✅
|
|
328
|
+
- iOS Safari: ✅
|
|
329
|
+
- Android Chrome: ✅
|
|
330
|
+
|
|
331
|
+
## License
|
|
332
|
+
|
|
333
|
+
MIT
|
|
334
|
+
|
|
335
|
+
## 致谢
|
|
336
|
+
|
|
337
|
+
本项目基于以下优秀开源项目:
|
|
338
|
+
|
|
339
|
+
- [markdown-it](https://github.com/markdown-it/markdown-it)
|
|
340
|
+
- [highlight.js](https://highlightjs.org/)
|
|
341
|
+
- [KaTeX](https://katex.org/)
|
|
342
|
+
- [markdown-it-task-lists](https://github.com/revin/markdown-it-task-lists)
|
|
343
|
+
- [markdown-it-emoji](https://github.com/markdown-it/markdown-it-emoji)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|