tiptap-extension-shiki 1.0.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.
@@ -0,0 +1,32 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ # 触发ci/cd的代码分支
7
+ - master
8
+
9
+ jobs:
10
+ build_and_publish:
11
+ runs-on: ubuntu-latest
12
+ # 必须添加这个权限,否则无法获取临时身份证明
13
+ permissions:
14
+ contents: read
15
+ id-token: write
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ - uses: actions/setup-node@v4
20
+ with:
21
+ node-version: '20'
22
+ # 注意:这里不再需要配置 registry-url 或 NODE_AUTH_TOKEN
23
+
24
+ - name: Install dependencies
25
+ run: npm install
26
+
27
+ - name: Build package
28
+ run: npm run build
29
+
30
+ - name: Publish to NPM
31
+ # 使用专用 Action,它会自动识别 OIDC 身份并完成发布
32
+ run: npm publish --provenance --access public
package/README.md ADDED
@@ -0,0 +1,146 @@
1
+ # Tiptap Extension Shiki
2
+
3
+ [📖 View Chinese Version](./README_CN.md)
4
+
5
+ ### Installation
6
+
7
+ ```bash
8
+ npm install shiki tiptap-extension-shiki
9
+ ```
10
+
11
+ ### Usage
12
+
13
+ ```typescript
14
+ new Editor({
15
+ content: "",
16
+ extensions: [
17
+ TiptapShiki.configure({
18
+ // Must have a default theme for fallback
19
+ defaultTheme: "dracula",
20
+ // Must have a default language for fallback
21
+ defaultLanguage: "javascript",
22
+ // Since the renderer is asynchronous, the highlighter instance must be passed in the extension configuration
23
+ highlighter: await createHighlighter({
24
+ // You can only use the themes and languages loaded by your highlighter, otherwise it will throw an error
25
+ // Since the main purpose is to provide it for background editor usage, I won't consider asynchronously loading additional languages and themes
26
+ themes: ["dracula", "dark-plus"],
27
+ langs: ["javascript", "typescript", "html", "css", "python", "json"],
28
+ }),
29
+ }),
30
+ StarterKit.configure({
31
+ codeBlock: false,
32
+ }),
33
+ ],
34
+ });
35
+ ```
36
+
37
+ ### Tiptap getHTML Returns Highlighted HTML
38
+
39
+ ```typescript
40
+ TiptapShiki.configure({
41
+ // After passing the configuration, using tiptap's getHTML will return highlighted HTML
42
+ // Note: If getHighlighHTML is enabled, the returned HTML cannot be used for setContent backfill, so please store getJSON for editing, and use HTML only for frontend display
43
+ getHighlighHTML: true,
44
+ }),
45
+ ```
46
+
47
+ ### Custom Toolbar
48
+
49
+ ```typescript
50
+ // You can import the built-in stylesheet or write your own styles
51
+ import "tiptap-extension-shiki/dist/style.css";
52
+
53
+ TiptapShiki.configure({
54
+ renderToolbar: ({ language, theme, toolbarDOM, setTheme, setLanguage }) => {
55
+ // Here, you can insert DOM elements into toolbarDOM in your own way (React/VUE).
56
+ // For example, you can use renderer(VNode,toolbarDOM)
57
+
58
+ // Example: Create toolbar using native DOM
59
+ // Create language selection dropdown
60
+ const languageSelect = document.createElement("select");
61
+ languageSelect.style.cssText =
62
+ "width: 200px; padding: 4px 8px; margin-right: 8px;";
63
+ languageSelect.innerHTML = `
64
+ <option value="javascript">JavaScript</option>
65
+ <option value="typescript">TypeScript</option>
66
+ <option value="html">HTML</option>
67
+ <option value="css">CSS</option>
68
+ <option value="python">Python</option>
69
+ <option value="json">JSON</option>
70
+ <option value="c++">C++</option>
71
+ `;
72
+
73
+ // Create theme selection dropdown
74
+ const themeSelect = document.createElement("select");
75
+ themeSelect.style.cssText = "width: 200px; padding: 4px 8px;";
76
+ themeSelect.innerHTML = `
77
+ <option value="dracula">Dracula</option>
78
+ <option value="dark-plus">DarkPlus</option>
79
+ `;
80
+
81
+ // Add language change event listener
82
+ languageSelect.addEventListener("change", (event) => {
83
+ // Set selected language
84
+ setLanguage((event.target as HTMLSelectElement).value);
85
+ });
86
+
87
+ // Add theme change event listener
88
+ themeSelect.addEventListener("change", (event) => {
89
+ // Set selected theme
90
+ setTheme((event.target as HTMLSelectElement).value);
91
+ });
92
+
93
+ // Add DOM elements to toolbar container
94
+ toolbarDOM.appendChild(languageSelect);
95
+ toolbarDOM.appendChild(themeSelect);
96
+ },
97
+ });
98
+ ```
99
+
100
+ ### Features
101
+
102
+ - ✨ Support for multiple programming languages
103
+ - 🎨 Support for multiple theme switching
104
+ - 🛠️ Customizable toolbar interface
105
+ - 🚀 Real-time syntax highlighting rendering
106
+ - 🔧 High-performance syntax highlighting engine based on Shiki
107
+
108
+ ### Configuration Options
109
+
110
+ | Option | Type | Default | Description |
111
+ | ----------------- | ------------- | -------------- | ------------------------------------ |
112
+ | `defaultTheme` | `string` | `'dracula'` | Default syntax highlighting theme (Required) |
113
+ | `defaultLanguage` | `string` | `'javascript'` | Default programming language (Required) |
114
+ | `highlighter` | `Highlighter` | `undefined` | Shiki highlighter instance (Required) |
115
+ | `getHighlighHTML` | `boolean` | `false` | Whether to generate static highlighted HTML |
116
+ | `renderToolbar` | `function` | `undefined` | Custom toolbar rendering function |
117
+
118
+ ### Custom Styling
119
+
120
+ You can customize the appearance of code blocks through CSS:
121
+
122
+ ```css
123
+ .tiptap-shiki--container {
124
+ border-radius: 8px;
125
+ font-family: "Fira Code", monospace;
126
+ }
127
+
128
+ .tiptap-shiki--toolbar {
129
+ background: rgba(0, 0, 0, 0.05);
130
+ border-radius: 6px 6px 0 0;
131
+ }
132
+ ```
133
+
134
+ ### Contributing
135
+ This plugin references the original highlighting plugin
136
+ [extension-code-block-lowlight](https://github.com/ueberdosis/tiptap/tree/main/packages/extension-code-block-lowlight)
137
+
138
+ ### Notes
139
+
140
+ 1. You must create and configure a Shiki highlighter instance before use
141
+ 2. DOM operations in custom toolbar functions are safe, the editor will handle conflicts
142
+ 3. Make sure to install all dependencies before use
143
+
144
+ ### License
145
+
146
+ MIT License
package/README_CN.md ADDED
@@ -0,0 +1,146 @@
1
+ # Tiptap Shiki 语法高亮扩展
2
+
3
+ [📖 View English Version](./README.md)
4
+
5
+ ### 安装
6
+
7
+ ```bash
8
+ npm install shiki tiptap-extension-shiki
9
+ ```
10
+
11
+ ### 使用方法
12
+
13
+ ```typescript
14
+ new Editor({
15
+ content: "",
16
+ extensions: [
17
+ TiptapShiki.configure({
18
+ // 必须有一个默认主题来进行回退
19
+ defaultTheme: "dracula",
20
+ // 必须有一个默认语言来进行回退
21
+ defaultLanguage: "javascript",
22
+ // 由于渲染器是异步的,所以必须在扩展配置中传递高亮器实例
23
+ highlighter: await createHighlighter({
24
+ // 你只能使用你高亮器加载的主题和语言,否则会报错
25
+ // 因为主要目的是提供给后台的编辑器使用所以我不会考虑异步去加载额外的语言和主题
26
+ themes: ["dracula", "dark-plus"],
27
+ langs: ["javascript", "typescript", "html", "css", "python", "json"],
28
+ }),
29
+ }),
30
+ StarterKit.configure({
31
+ codeBlock: false,
32
+ }),
33
+ ],
34
+ });
35
+ ```
36
+
37
+ ### Tiptap getHTML 返回高亮后的 html
38
+
39
+ ```typescript
40
+ TiptapShiki.configure({
41
+ // 传递配置项之后 使用tiptap的 getHTML将会返回高亮后的 html
42
+ // 注意:如果启用了 getHighlighHTML,返回的 HTML 不能用于setContent 回填,所以请储存getJSON用来编辑,而 html 只用来做前台展示
43
+ getHighlighHTML: true,
44
+ }),
45
+ ```
46
+
47
+ ### 自定义工具栏
48
+
49
+ ```typescript
50
+ // 你可以导入预制的样式文件来使用,也可以自行编写样式
51
+ import "tiptap-extension-shiki/dist/style.css";
52
+
53
+ TiptapShiki.configure({
54
+ renderToolbar: ({ language, theme, toolbarDOM, setTheme, setLanguage }) => {
55
+ // 在这里,您可以按照自己的方式(React/VUE)插入 DOM 到 toolbarDOM 中。
56
+ // 例如,您可以使用 renderer(VNode,toolbarDOM)
57
+
58
+ // 示例用原生 dom 来创建工具栏
59
+ // Create language selection dropdown
60
+ const languageSelect = document.createElement("select");
61
+ languageSelect.style.cssText =
62
+ "width: 200px; padding: 4px 8px; margin-right: 8px;";
63
+ languageSelect.innerHTML = `
64
+ <option value="javascript">JavaScript</option>
65
+ <option value="typescript">TypeScript</option>
66
+ <option value="html">HTML</option>
67
+ <option value="css">CSS</option>
68
+ <option value="python">Python</option>
69
+ <option value="json">JSON</option>
70
+ <option value="c++">C++</option>
71
+ `;
72
+
73
+ // Create theme selection dropdown
74
+ const themeSelect = document.createElement("select");
75
+ themeSelect.style.cssText = "width: 200px; padding: 4px 8px;";
76
+ themeSelect.innerHTML = `
77
+ <option value="dracula">Dracula</option>
78
+ <option value="dark-plus">DarkPlus</option>
79
+ `;
80
+
81
+ // Add language change event listener
82
+ languageSelect.addEventListener("change", (event) => {
83
+ // 设置选中的语言
84
+ setLanguage((event.target as HTMLSelectElement).value);
85
+ });
86
+
87
+ // Add theme change event listener
88
+ themeSelect.addEventListener("change", (event) => {
89
+ // 设置选中的主题
90
+ setTheme((event.target as HTMLSelectElement).value);
91
+ });
92
+
93
+ // 在工具栏容器中添加DOM
94
+ toolbarDOM.appendChild(languageSelect);
95
+ toolbarDOM.appendChild(themeSelect);
96
+ },
97
+ });
98
+ ```
99
+
100
+ ### 功能特性
101
+
102
+ - ✨ 支持多种编程语言切换
103
+ - 🎨 支持多种主题切换
104
+ - 🛠️ 可自定义工具栏界面
105
+ - 🚀 实时语法高亮渲染
106
+ - 🔧 基于 Shiki 的高性能语法高亮引擎
107
+
108
+ ### 配置选项
109
+
110
+ | 选项 | 类型 | 默认值 | 描述 |
111
+ | ----------------- | ------------- | -------------- | ------------------------- |
112
+ | `defaultTheme` | `string` | `'dracula'` | 默认语法高亮主题 (必需) |
113
+ | `defaultLanguage` | `string` | `'javascript'` | 默认编程语言 (必需) |
114
+ | `highlighter` | `Highlighter` | `undefined` | Shiki 高亮器实例(必需) |
115
+ | `getHighlighHTML` | `boolean` | `false` | 是否生成静态高亮 HTML |
116
+ | `renderToolbar` | `function` | `undefined` | 自定义工具栏渲染函数 |
117
+
118
+ ### 自定义样式
119
+
120
+ 你可以通过 CSS 自定义代码块的外观:
121
+
122
+ ```css
123
+ .tiptap-shiki--container {
124
+ border-radius: 8px;
125
+ font-family: "Fira Code", monospace;
126
+ }
127
+
128
+ .tiptap-shiki--toolbar {
129
+ background: rgba(0, 0, 0, 0.05);
130
+ border-radius: 6px 6px 0 0;
131
+ }
132
+ ```
133
+
134
+ ### 贡献
135
+ 这个插件参考了原有的高亮插件
136
+ [extension-code-block-lowlight](https://github.com/ueberdosis/tiptap/tree/main/packages/extension-code-block-lowlight)
137
+
138
+ ### 注意事项
139
+
140
+ 1. 使用前必须创建并配置 Shiki 高亮器实例
141
+ 2. 自定义工具栏函数中的 DOM 操作是安全的,编辑器会处理冲突
142
+ 3. 确保在使用前安装所有依赖包
143
+
144
+ ### 许可证
145
+
146
+ MIT License
@@ -0,0 +1,19 @@
1
+ import { Plugin } from "@tiptap/pm/state";
2
+ import type { BundledLanguage, BundledTheme, HighlighterGeneric, SpecialLanguage, StringLiteralUnion, ThemeRegistrationAny } from "shiki";
3
+ /**
4
+ * 创建Shiki轻量级语法高亮插件
5
+ * 该插件负责在ProseMirror编辑器中为代码块提供实时的语法高亮显示
6
+ * 通过ProseMirror的装饰器系统实现高性能的语法高亮渲染
7
+ *
8
+ * @param name - 插件名称
9
+ * @param highlighter - Shiki语法高亮器实例
10
+ * @param defaultTheme - 默认主题
11
+ * @param defaultLanguage - 默认编程语言
12
+ * @returns ProseMirror插件实例
13
+ */
14
+ export declare function ShikiLightPlugin({ name, highlighter, defaultTheme, defaultLanguage, }: {
15
+ name: string;
16
+ highlighter: HighlighterGeneric<BundledLanguage, BundledTheme>;
17
+ defaultTheme: ThemeRegistrationAny | StringLiteralUnion<string>;
18
+ defaultLanguage: StringLiteralUnion<SpecialLanguage>;
19
+ }): Plugin<any>;
@@ -0,0 +1 @@
1
+ .tiptap-shiki--container{border-radius:.4rem;font-size:.875em;pre{max-height:400px;overflow:auto;padding:20px}}.tiptap-shiki--toolbar{align-items:center;display:flex;padding:10px}