bobe-dom 0.0.61 → 0.0.63

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.
@@ -1,24 +1,213 @@
1
1
  import { marked } from 'marked';
2
+ import path, { dirname, resolve } from 'path';
3
+ import fs from 'fs';
4
+ import hljs from 'highlight.js';
5
+
6
+ function highlight(code, lang) {
7
+ try {
8
+ return hljs.highlight(code, {
9
+ language: lang
10
+ }).value;
11
+ } catch {
12
+ return code.replace(/</g, '&lt;').replace(/>/g, '&gt;');
13
+ }
14
+ }
15
+ async function resolveImportTree(importPath, currentPath, vResolve, walked = new Set()) {
16
+ const resolved = await vResolve(importPath, currentPath);
17
+ const absPath = resolved?.id;
18
+ if (!absPath || absPath.includes('node_modules') || absPath.startsWith('\0') || walked.has(absPath)) {
19
+ return [];
20
+ }
21
+ walked.add(absPath);
22
+ let content = '';
23
+ try {
24
+ content = await fs.promises.readFile(absPath, 'utf-8');
25
+ } catch (error) {
26
+ console.warn(`Failed to read file: ${absPath}`);
27
+ }
28
+ if (!content) {
29
+ return [];
30
+ }
31
+ const langMap = {
32
+ ts: 'typescript',
33
+ tsx: 'typescript',
34
+ mts: 'typescript',
35
+ js: 'javascript',
36
+ jsx: 'javascript',
37
+ mjs: 'javascript',
38
+ css: 'css',
39
+ html: 'xml',
40
+ json: 'json'
41
+ };
42
+ const ext = path.extname(absPath).slice(1);
43
+ const lang = langMap[ext];
44
+ const item = {
45
+ path: absPath,
46
+ name: path.basename(absPath),
47
+ lang: lang,
48
+ html: lang ? highlight(content, lang) : content
49
+ };
50
+ const importRegex = /import\s+(?:[\w*\s{},]*\s+from\s+)?['"]([^'"]+)['"]/g;
51
+ let match;
52
+ const dependencies = [];
53
+ while ((match = importRegex.exec(content)) !== null) {
54
+ const importPath = match[1];
55
+ if (!importPath.startsWith('http')) {
56
+ dependencies.push(resolveImportTree(importPath, absPath, vResolve, walked));
57
+ }
58
+ }
59
+ if (!dependencies.length) {
60
+ return [item];
61
+ }
62
+ const deps = await Promise.all(dependencies);
63
+ return [item, ...deps.flat()];
64
+ }
65
+
66
+ function registerBobeLang() {
67
+ hljs.registerLanguage('bobe', hljs => {
68
+ const ATTRS = ['class', 'id', 'text', 'html', 'style', 'href', 'src', 'alt', 'title', 'ref', 'type', 'placeholder', 'value', 'name', 'foo', 'disabled', 'readonly', 'checked', 'selected', 'hidden', 'role', 'target', 'rel', 'width', 'height', 'tabindex', 'data-[\\w-]+', 'aria-[\\w-]+', 'onclick', 'oninput', 'onchange', 'onsubmit', 'onreset', 'onkeydown', 'onkeyup', 'onkeypress', 'onfocus', 'onblur', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseover', 'onmouseout', 'onload', 'onerror', 'onscroll', 'onresize', 'ondrag', 'ondragstart', 'ondragend', 'ondragover', 'ondrop', 'ontouchstart', 'ontouchend', 'ontouchmove'].join('|');
69
+ return {
70
+ name: 'bobe',
71
+ keywords: ['if', 'else', 'for', 'tp', 'context'],
72
+ contains: [hljs.COMMENT('#', '$', {
73
+ relevance: 0
74
+ }), {
75
+ className: 'template-substitution',
76
+ begin: /\$\{/,
77
+ end: /\}/,
78
+ contains: [{
79
+ begin: /\$\{/,
80
+ end: /\}/,
81
+ skip: true
82
+ }],
83
+ subLanguage: 'javascript'
84
+ }, {
85
+ className: 'template-substitution',
86
+ begin: /(?<==)\{/,
87
+ end: /\}/,
88
+ contains: [{
89
+ begin: /\{/,
90
+ end: /\}/,
91
+ skip: true
92
+ }],
93
+ subLanguage: 'javascript'
94
+ }, {
95
+ className: 'string',
96
+ begin: /"/,
97
+ end: /"/,
98
+ contains: [{
99
+ begin: /\$\{/,
100
+ end: /\}/,
101
+ subLanguage: 'javascript'
102
+ }]
103
+ }, {
104
+ className: 'selector-tag',
105
+ begin: /^[ \t]*(?!(?:if|else|for|tp)\b)[a-z][\w-]*(?:-[a-z][\w-]*)*\b/m,
106
+ relevance: 2
107
+ }, {
108
+ className: 'attr',
109
+ begin: new RegExp(`\\b(?:${ATTRS})\\b(?=\\s*=)`),
110
+ relevance: 1
111
+ }, {
112
+ className: 'attr',
113
+ begin: /\b(?:disabled|readonly|checked|selected|hidden)\b(?!\s*=)/,
114
+ relevance: 0
115
+ }, {
116
+ className: 'variable',
117
+ begin: /(?<=for\s+)\w+(?=\s*;)/,
118
+ relevance: 0
119
+ }, {
120
+ className: 'params',
121
+ begin: /(?<=for\s+\S+\s*;\s*)\w+/,
122
+ relevance: 0
123
+ }, {
124
+ className: 'params',
125
+ begin: /(?<=for\s+\S+\s*;\s*\w+\s+)\w+/,
126
+ relevance: 0
127
+ }, hljs.NUMBER_MODE]
128
+ };
129
+ });
130
+ function patchJsFamily(name) {
131
+ const fn = hljs.getLanguage(name)?.rawDefinition;
132
+ if (!fn) return;
133
+ const def = fn(hljs);
134
+ if (def.contains.some(c => c.begin?.toString?.().includes('bobe'))) return;
135
+ const SUBST = {
136
+ className: 'subst',
137
+ begin: /\$\{/,
138
+ end: /\}/,
139
+ keywords: def.keywords
140
+ };
141
+ def.contains.push({
142
+ begin: /\.?bobe`/,
143
+ end: '',
144
+ starts: {
145
+ end: '`',
146
+ returnEnd: false,
147
+ contains: [hljs.BACKSLASH_ESCAPE, SUBST],
148
+ subLanguage: 'bobe'
149
+ }
150
+ });
151
+ hljs.registerLanguage(name, () => def);
152
+ }
153
+ patchJsFamily('javascript');
154
+ patchJsFamily('typescript');
155
+ }
2
156
 
3
157
  function esc(s) {
4
158
  return s.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$/g, '\\$');
5
159
  }
6
- function gen(html, headers) {
7
- const code = [`import { bobe } from 'bobe';`, `const mdHtml = \`${esc(html)}\`;`, `export default bobe\``, ` div class="markdown" style="display: flex;"`, ` main class="markdown-main" style="overflow-y: auto;" html=\${mdHtml}`, ` if showAside`, ` div class="markdown-aside" style="display: flex; flex-direction: column; overflow-y: auto;"`, ...headers.map(({
8
- depth,
9
- id,
10
- text
11
- }) => {
12
- return ` a href="#${id}" text="${text}" class="markdown-aside-item markdown-aside-depth-${depth}"`;
13
- }), `\`;`].join('\n');
14
- return code;
160
+ function gen(html, headers, previewEntries, codeTrees = []) {
161
+ const hasCode = codeTrees.length > 0;
162
+ const lines = [`import { bobe, Store } from 'bobe';`];
163
+ if (hasCode) {
164
+ lines.push(`import Code from 'bobe-dom/plugin-markdown/code';`);
165
+ previewEntries.forEach((src, i) => {
166
+ lines.push(`import $Bobe_Comp_${i} from '${src}';`);
167
+ });
168
+ }
169
+ lines.push(`const mdHtml = \`${esc(html)}\`;`);
170
+ if (hasCode) {
171
+ for (let i = 0; i < codeTrees.length; i++) {
172
+ lines.push(`const codeTree${i} = ${JSON.stringify(codeTrees[i])};`);
173
+ }
174
+ }
175
+ lines.push(`class Markdown extends Store {`);
176
+ lines.push(` mdRef = null;`);
177
+ lines.push(` ui = bobe\``);
178
+ lines.push(` div class="markdown" style="display: flex;"`);
179
+ lines.push(` main ref={mdRef} class="markdown-body" style="overflow-y: auto;" html=\${mdHtml}`);
180
+ lines.push(` if showAside`);
181
+ lines.push(` div class="markdown-aside" style="flex: none; display: flex; flex-direction: column; overflow-y: auto;"`);
182
+ for (const _ref of headers) {
183
+ const depth = _ref.depth;
184
+ const id = _ref.id;
185
+ const text = _ref.text;
186
+ lines.push(` a href="#${id}" text="${esc(text)}" class="markdown-aside-item markdown-aside-depth-${depth}"`);
187
+ }
188
+ if (hasCode) {
189
+ for (let i = 0; i < codeTrees.length; i++) {
190
+ const previewProp = previewEntries[i] ? `preview=\${() => $Bobe_Comp_${i}}` : '';
191
+ lines.push(` tp node={mdRef?.querySelector?.('#code-${i}')}`);
192
+ lines.push(` \${Code} files=\${codeTree${i}} ${previewProp}`);
193
+ }
194
+ }
195
+ lines.push(` \`;`);
196
+ lines.push(`}`);
197
+ lines.push(`export default Markdown;`);
198
+ return lines.join('\n');
15
199
  }
200
+ const CODE_TAG_RE = /<code\s+src="([^"]+)"(\s+preview)?\s*\/>/g;
16
201
  function markdownPlugin(opt = {}) {
17
202
  let headers = [];
203
+ const headClassMap = {
204
+ '1': 'cyber-title'
205
+ };
18
206
  return {
19
207
  name: 'bobe-markdown',
20
208
  enforce: 'pre',
21
209
  configResolved() {
210
+ registerBobeLang();
22
211
  marked.use({
23
212
  gfm: true,
24
213
  renderer: {
@@ -27,27 +216,47 @@ function markdownPlugin(opt = {}) {
27
216
  depth
28
217
  }) {
29
218
  const text = this.parser.parseInline(tokens);
30
- const id = text.toLowerCase().replace(/[^\w\u4e00-\u9fff]+/g, '-');
31
- if (depth <= opt.asideDeep || 3) {
219
+ const id = text.toLowerCase().replace(/[^\w一-鿿]+/g, '-');
220
+ if (depth <= (opt.asideDeep || 3)) {
32
221
  headers.push({
33
222
  depth,
34
223
  id,
35
224
  text
36
225
  });
37
226
  }
38
- return `<h${depth} id="${id}">${text}</h${depth}>`;
227
+ return `<h${depth} class="${headClassMap[depth]}" data-text="${text}" id="${id}">${text}</h${depth}>`;
228
+ },
229
+ code({
230
+ text,
231
+ lang
232
+ }) {
233
+ return `<pre><code class="hljs">${hljs.highlight(text, {
234
+ language: lang
235
+ }).value}</code></pre>`;
39
236
  }
40
237
  }
41
238
  });
42
239
  if (opt.marked) marked.use(opt.marked);
43
240
  },
44
- transform(code, id) {
241
+ async transform(code, id) {
45
242
  if (!id.match(/\.mdx?$/)) return;
46
243
  headers = [];
47
244
  try {
48
245
  const html = marked.parse(code);
246
+ const codeTags = [];
247
+ const previewEntries = [];
248
+ let idx = 0;
249
+ const finalHtml = html.replace(CODE_TAG_RE, (_, src, preview) => {
250
+ codeTags.push(src);
251
+ if (preview) {
252
+ previewEntries[idx] = src;
253
+ }
254
+ return `<div id="code-${idx++}"></div>`;
255
+ });
256
+ const fileDir = dirname(id);
257
+ const codeTrees = await Promise.all(codeTags.map(tag => resolveImportTree(resolve(fileDir, tag), id, this.resolve.bind(this))));
49
258
  return {
50
- code: gen(html, headers),
259
+ code: gen(finalHtml, headers, previewEntries, codeTrees),
51
260
  moduleSideEffects: false
52
261
  };
53
262
  } catch (e) {
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.esm.js","sources":["../src/plugins/markdown/index.ts"],"sourcesContent":["import type { Plugin } from 'vite';\nimport type { MarkedExtension } from 'marked';\nimport { marked } from 'marked';\n\nexport interface MarkdownPluginOptions {\n /** 传递给 marked.use() 的扩展配置 */\n marked?: MarkedExtension;\n /** 侧边栏的深度,默认为 3,表示提取 h1 - h3 到侧边栏做导航 */\n asideDeep?: number;\n}\n\n/** 对要嵌入模板字面量的字符串进行转义(` $ \\) */\nfunction esc(s: string): string {\n return s.replace(/\\\\/g, '\\\\\\\\').replace(/`/g, '\\\\`').replace(/\\$/g, '\\\\$');\n}\n\n/** 将 HTML 字符串编译为 bobe 组件模块源码 */\nfunction gen(html: string, headers: HeadItem[]): string {\n const code = [\n `import { bobe } from 'bobe';`,\n `const mdHtml = \\`${esc(html)}\\`;`,\n `export default bobe\\``,\n ` div class=\"markdown\" style=\"display: flex;\"`,\n ` main class=\"markdown-main\" style=\"overflow-y: auto;\" html=\\${mdHtml}`,\n ` if showAside`,\n ` div class=\"markdown-aside\" style=\"display: flex; flex-direction: column; overflow-y: auto;\"`,\n ...headers.map(({ depth, id, text }) => {\n return ` a href=\"#${id}\" text=\"${text}\" class=\"markdown-aside-item markdown-aside-depth-${depth}\"`;\n }),\n `\\`;`\n ].join('\\n');\n return code;\n}\n\n/**\n * bobe-markdown Vite 插件。\n *\n * 将 .md / .mdx 文件编译为 bobe 组件:\n * import Readme from './README.md';\n */\n\nexport type HeadItem = {\n depth: number;\n id: string;\n text: string;\n};\nexport default function markdownPlugin(opt: MarkdownPluginOptions = {}): Plugin {\n let headers: HeadItem[] = [];\n return {\n name: 'bobe-markdown',\n enforce: 'pre',\n\n configResolved() {\n marked.use({\n gfm: true, // GitHub Flavored Markdown\n renderer: {\n heading({ tokens, depth }) {\n const text = this.parser.parseInline(tokens);\n const id = text.toLowerCase().replace(/[^\\w\\u4e00-\\u9fff]+/g, '-');\n if(depth <= opt.asideDeep || 3) {\n headers.push({ depth, id, text });\n }\n return `<h${depth} id=\"${id}\">${text}</h${depth}>`;\n }\n }\n });\n if (opt.marked) marked.use(opt.marked);\n },\n\n transform(code, id) {\n if (!id.match(/\\.mdx?$/)) return;\n headers = [];\n try {\n const html = marked.parse(code) as string;\n return { code: gen(html, headers), moduleSideEffects: false };\n } catch (e: any) {\n this.error(`[bobe-markdown] 解析失败: ${id}\\n${e.message}`);\n }\n }\n };\n}\n"],"names":["esc","s","replace","gen","html","headers","code","map","depth","id","text","join","markdownPlugin","opt","name","enforce","configResolved","marked","use","gfm","renderer","heading","tokens","parser","parseInline","toLowerCase","asideDeep","push","transform","match","parse","moduleSideEffects","e","error","message"],"mappings":";;AAYA,SAASA,GAAGA,CAACC,CAAS,EAAU;EAC9B,OAAOA,CAAC,CAACC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAACA,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAACA,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;AAC5E;AAGA,SAASC,GAAGA,CAACC,IAAY,EAAEC,OAAmB,EAAU;EACtD,MAAMC,IAAI,GAAG,CACX,CAAA,4BAAA,CAA8B,EAC9B,CAAA,iBAAA,EAAoBN,GAAG,CAACI,IAAI,CAAC,CAAA,GAAA,CAAK,EAClC,CAAA,qBAAA,CAAuB,EACvB,CAAA,6CAAA,CAA+C,EAC/C,CAAA,wEAAA,CAA0E,EAC1E,CAAA,gBAAA,CAAkB,EAClB,CAAA,iGAAA,CAAmG,EACnG,GAAGC,OAAO,CAACE,GAAG,CAAC,CAAC;IAAEC,KAAK;IAAEC,EAAE;AAAEC,IAAAA;AAAK,GAAC,KAAK;AACtC,IAAA,OAAO,oBAAoBD,EAAE,CAAA,QAAA,EAAWC,IAAI,CAAA,kDAAA,EAAqDF,KAAK,CAAA,CAAA,CAAG;EAC3G,CAAC,CAAC,EACF,CAAA,GAAA,CAAK,CACN,CAACG,IAAI,CAAC,IAAI,CAAC;AACZ,EAAA,OAAOL,IAAI;AACb;AAce,SAASM,cAAcA,CAACC,GAA0B,GAAG,EAAE,EAAU;EAC9E,IAAIR,OAAmB,GAAG,EAAE;EAC5B,OAAO;AACLS,IAAAA,IAAI,EAAE,eAAe;AACrBC,IAAAA,OAAO,EAAE,KAAK;AAEdC,IAAAA,cAAcA,GAAG;MACfC,MAAM,CAACC,GAAG,CAAC;AACTC,QAAAA,GAAG,EAAE,IAAI;AACTC,QAAAA,QAAQ,EAAE;AACRC,UAAAA,OAAOA,CAAC;YAAEC,MAAM;AAAEd,YAAAA;AAAM,WAAC,EAAE;YACzB,MAAME,IAAI,GAAG,IAAI,CAACa,MAAM,CAACC,WAAW,CAACF,MAAM,CAAC;AAC5C,YAAA,MAAMb,EAAE,GAAGC,IAAI,CAACe,WAAW,EAAE,CAACvB,OAAO,CAAC,sBAAsB,EAAE,GAAG,CAAC;AAClE,YAAA,IAAGM,KAAK,IAAIK,GAAG,CAACa,SAAS,IAAI,CAAC,EAAE;cAC9BrB,OAAO,CAACsB,IAAI,CAAC;gBAAEnB,KAAK;gBAAEC,EAAE;AAAEC,gBAAAA;AAAK,eAAC,CAAC;AACnC,YAAA;YACA,OAAO,CAAA,EAAA,EAAKF,KAAK,CAAA,KAAA,EAAQC,EAAE,KAAKC,IAAI,CAAA,GAAA,EAAMF,KAAK,CAAA,CAAA,CAAG;AACpD,UAAA;AACF;AACF,OAAC,CAAC;MACF,IAAIK,GAAG,CAACI,MAAM,EAAEA,MAAM,CAACC,GAAG,CAACL,GAAG,CAACI,MAAM,CAAC;IACxC,CAAC;AAEDW,IAAAA,SAASA,CAACtB,IAAI,EAAEG,EAAE,EAAE;AAClB,MAAA,IAAI,CAACA,EAAE,CAACoB,KAAK,CAAC,SAAS,CAAC,EAAE;AAC1BxB,MAAAA,OAAO,GAAG,EAAE;MACZ,IAAI;AACF,QAAA,MAAMD,IAAI,GAAGa,MAAM,CAACa,KAAK,CAACxB,IAAI,CAAW;QACzC,OAAO;AAAEA,UAAAA,IAAI,EAAEH,GAAG,CAACC,IAAI,EAAEC,OAAO,CAAC;AAAE0B,UAAAA,iBAAiB,EAAE;SAAO;MAC/D,CAAC,CAAC,OAAOC,CAAM,EAAE;QACf,IAAI,CAACC,KAAK,CAAC,CAAA,sBAAA,EAAyBxB,EAAE,KAAKuB,CAAC,CAACE,OAAO,CAAA,CAAE,CAAC;AACzD,MAAA;AACF,IAAA;GACD;AACH;;;;"}
1
+ {"version":3,"file":"markdown.esm.js","sources":["../src/plugins/markdown/my-resolve.ts","../src/plugins/markdown/components/bobe-lang.ts","../src/plugins/markdown/index.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\nimport hljs from 'highlight.js';\nfunction highlight(code: string, lang: string): string {\n try {\n return hljs.highlight(code, { language: lang }).value;\n } catch {\n return code.replace(/</g, '&lt;').replace(/>/g, '&gt;');\n }\n}\n\ntype ResolveFn = (id: string, importer?: string) => Promise<{ id: string } | null>;\nexport type FileItem = {\n path: string;\n name: string;\n lang: string;\n html: string;\n};\nexport async function resolveImportTree(\n importPath: string,\n currentPath: string,\n vResolve: ResolveFn,\n walked = new Set<string>()\n): Promise<FileItem[]> {\n const resolved = await vResolve(importPath, currentPath);\n const absPath = resolved?.id;\n\n if (!absPath || absPath.includes('node_modules') || absPath.startsWith('\\0') || walked.has(absPath)) {\n return [];\n }\n\n walked.add(absPath);\n\n let content = '';\n try {\n content = await fs.promises.readFile(absPath, 'utf-8');\n } catch (error) {\n console.warn(`Failed to read file: ${absPath}`);\n }\n if (!content) {\n return [];\n }\n\n const langMap: Record<string, string> = {\n ts: 'typescript',\n tsx: 'typescript',\n mts: 'typescript',\n js: 'javascript',\n jsx: 'javascript',\n mjs: 'javascript',\n css: 'css',\n html: 'xml',\n json: 'json'\n };\n const ext = path.extname(absPath).slice(1);\n const lang = langMap[ext];\n\n const item: FileItem = {\n path: absPath,\n name: path.basename(absPath),\n lang: lang,\n // html: highlight(content, lang)\n html: lang ? highlight(content, lang) : content\n };\n\n // 4. 正则匹配出文件中的静态 import 语句\n const importRegex = /import\\s+(?:[\\w*\\s{},]*\\s+from\\s+)?['\"]([^'\"]+)['\"]/g;\n let match: RegExpExecArray | null;\n const dependencies: Promise<FileItem[]>[] = [];\n\n while ((match = importRegex.exec(content)) !== null) {\n const importPath = match[1];\n // 排除绝对路径网络请求(如 https://)\n if (!importPath.startsWith('http')) {\n dependencies.push(resolveImportTree(importPath, absPath, vResolve, walked));\n }\n }\n if (!dependencies.length) {\n return [item];\n }\n const deps = await Promise.all(dependencies);\n return [item, ...deps.flat()];\n}\n","import hljs, { Language } from 'highlight.js';\n\n/**\n * 注册 bobe DSL 语法高亮。\n *\n * 1. 注册 `bobe` 独立语言(用于 markdown 中 ```bobe 代码块)\n * 2. 给 JavaScript grammar 打补丁,让 `bobe`...`` 标签模板被 TS/JS 代码块自动识别\n *\n * bobe 采用类似 Pug 的缩进风格,语法要素:\n * - 元素标签:div, span, h1-h6, a, p, ul, li, button, input ...\n * - 属性:class=\"...\", id=\"...\", text=\"...\", onclick={...}, ref={...}\n * - 控制流:if, else, for, tp\n * - 响应式绑定:{expr}\n * - 模板插值:${expr}\n * - 字符串:\"hello\"\n * - 注释:# comment\n */\nexport function registerBobeLang() {\n // ================================================================\n // Part 1: 注册 bobe 独立语言\n // ================================================================\n hljs.registerLanguage('bobe', (hljs) => {\n // 属性名列表(含事件处理器和布尔属性)\n const ATTRS = [\n 'class', 'id', 'text', 'html', 'style', 'href', 'src', 'alt', 'title',\n 'ref', 'type', 'placeholder', 'value', 'name', 'foo',\n 'disabled', 'readonly', 'checked', 'selected', 'hidden',\n 'role', 'target', 'rel', 'width', 'height', 'tabindex',\n 'data-[\\\\w-]+', 'aria-[\\\\w-]+',\n 'onclick', 'oninput', 'onchange', 'onsubmit', 'onreset',\n 'onkeydown', 'onkeyup', 'onkeypress',\n 'onfocus', 'onblur', 'onmouseenter', 'onmouseleave',\n 'onmousemove', 'onmouseover', 'onmouseout',\n 'onload', 'onerror', 'onscroll', 'onresize',\n 'ondrag', 'ondragstart', 'ondragend', 'ondragover', 'ondrop',\n 'ontouchstart', 'ontouchend', 'ontouchmove',\n ].join('|');\n\n return {\n name: 'bobe',\n // keywords: {\n // $pattern: /\\b(if|else|for|tp)\\b/,\n // keyword: 'if else for tp'\n // },\n keywords: ['if','else','for','tp','context'],\n contains: [\n // ----------------------------------------------------------\n // 1. 行注释 — # 到行尾\n // ----------------------------------------------------------\n hljs.COMMENT('#', '$', { relevance: 0 }),\n\n // ----------------------------------------------------------\n // 2. 模板插值 ${expr} — bobe 组件/表达式嵌入\n // ----------------------------------------------------------\n {\n className: 'template-substitution',\n begin: /\\$\\{/,\n end: /\\}/,\n contains: [\n { begin: /\\$\\{/, end: /\\}/, skip: true },\n ],\n subLanguage: 'javascript',\n },\n\n // ----------------------------------------------------------\n // 3. 响应式绑定 {expr} — 跟在 = 后面(不含 $)\n // ----------------------------------------------------------\n {\n className: 'template-substitution',\n begin: /(?<==)\\{/,\n end: /\\}/,\n contains: [\n { begin: /\\{/, end: /\\}/, skip: true },\n ],\n subLanguage: 'javascript',\n },\n\n // ----------------------------------------------------------\n // 4. 双引号字符串 — 内部可含 ${} 插值\n // ----------------------------------------------------------\n {\n className: 'string',\n begin: /\"/,\n end: /\"/,\n contains: [\n {\n begin: /\\$\\{/,\n end: /\\}/,\n subLanguage: 'javascript',\n }\n ]\n },\n\n // ----------------------------------------------------------\n // 5. 元素标签 — 行首缩进后的第一个标识符(排除关键字)\n // 泛化匹配:bobe 缩进语法中每行首个标识符必是标签或关键字\n // ----------------------------------------------------------\n {\n className: 'selector-tag',\n begin: /^[ \\t]*(?!(?:if|else|for|tp)\\b)[a-z][\\w-]*(?:-[a-z][\\w-]*)*\\b/m,\n relevance: 2,\n },\n\n // ----------------------------------------------------------\n // 6. 属性名 — key=value 形式\n // ----------------------------------------------------------\n {\n className: 'attr',\n begin: new RegExp(`\\\\b(?:${ATTRS})\\\\b(?=\\\\s*=)`),\n relevance: 1,\n },\n\n // ----------------------------------------------------------\n // 7. 布尔属性 — 独立出现,不跟 =\n // ----------------------------------------------------------\n {\n className: 'attr',\n begin: /\\b(?:disabled|readonly|checked|selected|hidden)\\b(?!\\s*=)/,\n relevance: 0,\n },\n\n // ----------------------------------------------------------\n // 8. for 循环变量 — for items; item i\n // ----------------------------------------------------------\n {\n className: 'variable',\n begin: /(?<=for\\s+)\\w+(?=\\s*;)/,\n relevance: 0,\n },\n {\n className: 'params',\n begin: /(?<=for\\s+\\S+\\s*;\\s*)\\w+/,\n relevance: 0,\n },\n {\n className: 'params',\n begin: /(?<=for\\s+\\S+\\s*;\\s*\\w+\\s+)\\w+/,\n relevance: 0,\n },\n\n // ----------------------------------------------------------\n // 9. 数字字面量\n // ----------------------------------------------------------\n hljs.NUMBER_MODE,\n ]\n } as Language;\n });\n\n // ================================================================\n // Part 2: 给 JS-family grammars 打补丁,让 `bobe`...`` 标签模板被识别\n // ================================================================\n function patchJsFamily(name: string) {\n const fn = (hljs.getLanguage(name) as any)?.rawDefinition as\n | ((hljs: any) => any)\n | undefined;\n if (!fn) return;\n\n const def = fn(hljs);\n\n // 避免重复注册\n if (def.contains.some((c: any) =>\n c.begin?.toString?.().includes('bobe')\n )) return;\n\n // 复刻该 grammar 的 keywords(用于 SUBST 中的 JS 表达式高亮)\n const SUBST = {\n className: 'subst',\n begin: /\\$\\{/,\n end: /\\}/,\n keywords: def.keywords,\n };\n\n def.contains.push({\n begin: /\\.?bobe`/, // 匹配 bobe` 或 .bobe`\n end: '',\n starts: {\n end: '`',\n returnEnd: false,\n contains: [hljs.BACKSLASH_ESCAPE, SUBST],\n subLanguage: 'bobe',\n },\n });\n\n hljs.registerLanguage(name, () => def);\n }\n\n patchJsFamily('javascript');\n patchJsFamily('typescript');\n}\n","import type { Plugin } from 'vite';\nimport type { MarkedExtension } from 'marked';\nimport { marked } from 'marked';\nimport { resolve, dirname } from 'path';\nimport { FileItem, resolveImportTree } from './my-resolve';\nimport hljs from 'highlight.js';\nimport { registerBobeLang } from './components/bobe-lang';\n\nexport interface MarkdownPluginOptions {\n /** 传递给 marked.use() 的扩展配置 */\n marked?: MarkedExtension;\n /** 侧边栏的深度,默认为 3,表示提取 h1 - h3 到侧边栏做导航 */\n asideDeep?: number;\n}\n\n/** 对要嵌入模板字面量的字符串进行转义(` $ \\) */\nfunction esc(s: string): string {\n return s.replace(/\\\\/g, '\\\\\\\\').replace(/`/g, '\\\\`').replace(/\\$/g, '\\\\$');\n}\n\n/** 将 HTML 字符串编译为 bobe 组件模块源码 */\nfunction gen(html: string, headers: HeadItem[], previewEntries: string[], codeTrees: FileItem[][] = []): string {\n const hasCode = codeTrees.length > 0;\n const lines = [`import { bobe, Store } from 'bobe';`];\n\n if (hasCode) {\n lines.push(`import Code from 'bobe-dom/plugin-markdown/code';`);\n previewEntries.forEach((src, i) => {\n lines.push(`import $Bobe_Comp_${i} from '${src}';`);\n });\n }\n\n lines.push(`const mdHtml = \\`${esc(html)}\\`;`);\n\n // 代码树数据\n if (hasCode) {\n for (let i = 0; i < codeTrees.length; i++) {\n lines.push(`const codeTree${i} = ${JSON.stringify(codeTrees[i])};`);\n }\n }\n\n // Markdown Store 组件\n lines.push(`class Markdown extends Store {`);\n lines.push(` mdRef = null;`);\n lines.push(` ui = bobe\\``);\n lines.push(` div class=\"markdown\" style=\"display: flex;\"`);\n lines.push(` main ref={mdRef} class=\"markdown-body\" style=\"overflow-y: auto;\" html=\\${mdHtml}`);\n lines.push(` if showAside`);\n lines.push(` div class=\"markdown-aside\" style=\"flex: none; display: flex; flex-direction: column; overflow-y: auto;\"`);\n for (const { depth, id, text } of headers) {\n lines.push(\n ` a href=\"#${id}\" text=\"${esc(text)}\" class=\"markdown-aside-item markdown-aside-depth-${depth}\"`\n );\n }\n // tp + Code 组件\n if (hasCode) {\n for (let i = 0; i < codeTrees.length; i++) {\n const previewProp = previewEntries[i] ? `preview=\\${() => $Bobe_Comp_${i}}` : '';\n lines.push(` tp node={mdRef?.querySelector?.('#code-${i}')}`);\n lines.push(` \\${Code} files=\\${codeTree${i}} ${previewProp}`);\n }\n }\n lines.push(` \\`;`);\n lines.push(`}`);\n lines.push(`export default Markdown;`);\n return lines.join('\\n');\n}\n\n/**\n * bobe-markdown Vite 插件。\n *\n * 将 .md / .mdx 文件编译为 bobe 组件:\n * import Readme from './README.md';\n *\n * 支持 <code src=\"xxx.ts\" /> 引入代码文件及 import 树(非 node_modules),\n * 以 Code 组件 + tp 传送方式渲染。\n */\n\nexport type HeadItem = {\n depth: number;\n id: string;\n text: string;\n};\n\nconst CODE_TAG_RE = /<code\\s+src=\"([^\"]+)\"(\\s+preview)?\\s*\\/>/g;\n\nexport default function markdownPlugin(opt: MarkdownPluginOptions = {}): Plugin {\n let headers: HeadItem[] = [];\n const headClassMap = {\n '1': 'cyber-title'\n }\n return {\n name: 'bobe-markdown',\n enforce: 'pre',\n\n configResolved() {\n registerBobeLang(); // 注册 bobe DSL 语法高亮(支持 markdown 中的 ```bobe 代码块)\n marked.use({\n gfm: true, // GitHub Flavored Markdown\n renderer: {\n heading({ tokens, depth }) {\n const text = this.parser.parseInline(tokens);\n const id = text.toLowerCase().replace(/[^\\w一-鿿]+/g, '-');\n if (depth <= (opt.asideDeep || 3)) {\n headers.push({ depth, id, text });\n }\n return `<h${depth} class=\"${headClassMap[depth]}\" data-text=\"${text}\" id=\"${id}\">${text}</h${depth}>`;\n },\n code({ text, lang }) {\n return `<pre><code class=\"hljs\">${hljs.highlight(text, { language: lang }).value}</code></pre>`;\n }\n }\n });\n if (opt.marked) marked.use(opt.marked);\n },\n\n async transform(code, id) {\n if (!id.match(/\\.mdx?$/)) return;\n headers = [];\n try {\n const html = marked.parse(code) as string;\n\n // 匹配 <code src=\"xxx.ts\"> → <div id=\"code-N\">\n const codeTags: string[] = [];\n const previewEntries: string[] = [];\n let idx = 0;\n const finalHtml = html.replace(CODE_TAG_RE, (_, src, preview) => {\n codeTags.push(src);\n if (preview) {\n previewEntries[idx] = src;\n }\n return `<div id=\"code-${idx++}\"></div>`;\n });\n\n // 解析每个 code block 的 import 树\n const fileDir = dirname(id);\n const codeTrees = await Promise.all(\n codeTags.map(tag => resolveImportTree(resolve(fileDir, tag), id, this.resolve.bind(this)))\n );\n\n return { code: gen(finalHtml, headers, previewEntries, codeTrees), moduleSideEffects: false };\n } catch (e: any) {\n this.error(`[bobe-markdown] 解析失败: ${id}\\n${e.message}`);\n }\n }\n };\n}\n"],"names":["highlight","code","lang","hljs","language","value","replace","resolveImportTree","importPath","currentPath","vResolve","walked","Set","resolved","absPath","id","includes","startsWith","has","add","content","fs","promises","readFile","error","console","warn","langMap","ts","tsx","mts","js","jsx","mjs","css","html","json","ext","path","extname","slice","item","name","basename","importRegex","match","dependencies","exec","push","length","deps","Promise","all","flat","registerBobeLang","registerLanguage","ATTRS","join","keywords","contains","COMMENT","relevance","className","begin","end","skip","subLanguage","RegExp","NUMBER_MODE","patchJsFamily","fn","getLanguage","rawDefinition","def","some","c","toString","SUBST","starts","returnEnd","BACKSLASH_ESCAPE","esc","s","gen","headers","previewEntries","codeTrees","hasCode","lines","forEach","src","i","JSON","stringify","_ref","depth","text","previewProp","CODE_TAG_RE","markdownPlugin","opt","headClassMap","enforce","configResolved","marked","use","gfm","renderer","heading","tokens","parser","parseInline","toLowerCase","asideDeep","transform","parse","codeTags","idx","finalHtml","_","preview","fileDir","dirname","map","tag","resolve","bind","moduleSideEffects","e","message"],"mappings":"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"}
package/package.json CHANGED
@@ -1,14 +1,16 @@
1
1
  {
2
2
  "name": "bobe-dom",
3
- "version": "0.0.61",
3
+ "version": "0.0.63",
4
4
  "main": "dist/bobe-dom.cjs.js",
5
5
  "module": "dist/bobe-dom.esm.js",
6
6
  "browser": "dist/bobe-dom.umd.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "private": false,
9
9
  "dependencies": {
10
+ "highlight.js": "^11.11.1",
11
+ "htmlparser2": "^12.0.0",
10
12
  "marked": "^18.0.4",
11
- "bobe": "0.0.61"
13
+ "bobe": "0.0.63"
12
14
  },
13
15
  "devDependencies": {
14
16
  "vitest": "^4.1.7"
@@ -23,7 +25,14 @@
23
25
  "types": "./dist/markdown.d.ts",
24
26
  "import": "./dist/markdown.esm.js",
25
27
  "require": "./dist/markdown.cjs.js"
26
- }
28
+ },
29
+ "./plugin-markdown/code": {
30
+ "types": "./dist/code.d.ts",
31
+ "import": "./dist/code.esm.js",
32
+ "require": "./dist/code.cjs.js"
33
+ },
34
+ "./plugin-markdown/index.css": "./dist/index.css",
35
+ "./plugin-markdown/code.css": "./dist/code.css"
27
36
  },
28
37
  "files": [
29
38
  "dist"