@hejiayue/x-markdown-test 0.0.1-beta.112 → 0.0.1-beta.115

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.
Files changed (117) hide show
  1. package/dist/style.css +1 -1
  2. package/dist/x-markdown.cjs.js +1 -1
  3. package/dist/x-markdown.cjs10.js +2 -0
  4. package/dist/x-markdown.cjs10.js.map +1 -0
  5. package/dist/x-markdown.cjs11.js +2 -0
  6. package/dist/x-markdown.cjs11.js.map +1 -0
  7. package/dist/x-markdown.cjs13.js +2 -0
  8. package/dist/x-markdown.cjs13.js.map +1 -0
  9. package/dist/x-markdown.cjs14.js +2 -0
  10. package/dist/x-markdown.cjs14.js.map +1 -0
  11. package/dist/x-markdown.cjs15.js +2 -0
  12. package/dist/x-markdown.cjs15.js.map +1 -0
  13. package/dist/x-markdown.cjs16.js +2 -0
  14. package/dist/x-markdown.cjs16.js.map +1 -0
  15. package/dist/x-markdown.cjs17.js +2 -0
  16. package/dist/x-markdown.cjs17.js.map +1 -0
  17. package/dist/x-markdown.cjs18.js +2 -0
  18. package/dist/x-markdown.cjs18.js.map +1 -0
  19. package/dist/x-markdown.cjs19.js +2 -0
  20. package/dist/x-markdown.cjs19.js.map +1 -0
  21. package/dist/x-markdown.cjs2.js +2 -0
  22. package/dist/x-markdown.cjs2.js.map +1 -0
  23. package/dist/x-markdown.cjs21.js +2 -0
  24. package/dist/x-markdown.cjs21.js.map +1 -0
  25. package/dist/x-markdown.cjs22.js +2 -0
  26. package/dist/x-markdown.cjs22.js.map +1 -0
  27. package/dist/x-markdown.cjs24.js +2 -0
  28. package/dist/x-markdown.cjs24.js.map +1 -0
  29. package/dist/x-markdown.cjs26.js +2 -0
  30. package/dist/x-markdown.cjs26.js.map +1 -0
  31. package/dist/x-markdown.cjs27.js +2 -0
  32. package/dist/x-markdown.cjs27.js.map +1 -0
  33. package/dist/x-markdown.cjs28.js +2 -0
  34. package/dist/x-markdown.cjs28.js.map +1 -0
  35. package/dist/x-markdown.cjs3.js +2 -0
  36. package/dist/x-markdown.cjs3.js.map +1 -0
  37. package/dist/x-markdown.cjs30.js +2 -0
  38. package/dist/x-markdown.cjs30.js.map +1 -0
  39. package/dist/x-markdown.cjs31.js +2 -0
  40. package/dist/x-markdown.cjs31.js.map +1 -0
  41. package/dist/x-markdown.cjs33.js +2 -0
  42. package/dist/x-markdown.cjs33.js.map +1 -0
  43. package/dist/x-markdown.cjs4.js +2 -0
  44. package/dist/x-markdown.cjs4.js.map +1 -0
  45. package/dist/x-markdown.cjs5.js +2 -0
  46. package/dist/x-markdown.cjs5.js.map +1 -0
  47. package/dist/x-markdown.cjs6.js +2 -0
  48. package/dist/x-markdown.cjs6.js.map +1 -0
  49. package/dist/x-markdown.cjs7.js +2 -0
  50. package/dist/x-markdown.cjs7.js.map +1 -0
  51. package/dist/x-markdown.cjs8.js +2 -0
  52. package/dist/x-markdown.cjs8.js.map +1 -0
  53. package/dist/x-markdown.cjs9.js +2 -0
  54. package/dist/x-markdown.cjs9.js.map +1 -0
  55. package/dist/x-markdown.es.js +26 -17
  56. package/dist/x-markdown.es.js.map +1 -1
  57. package/dist/x-markdown.es10.js +49 -0
  58. package/dist/x-markdown.es10.js.map +1 -0
  59. package/dist/x-markdown.es11.js +54 -0
  60. package/dist/x-markdown.es11.js.map +1 -0
  61. package/dist/x-markdown.es13.js +89 -0
  62. package/dist/x-markdown.es13.js.map +1 -0
  63. package/dist/x-markdown.es14.js +34 -0
  64. package/dist/x-markdown.es14.js.map +1 -0
  65. package/dist/x-markdown.es15.js +5 -0
  66. package/dist/x-markdown.es15.js.map +1 -0
  67. package/dist/x-markdown.es16.js +6 -0
  68. package/dist/x-markdown.es16.js.map +1 -0
  69. package/dist/x-markdown.es17.js +8 -0
  70. package/dist/x-markdown.es17.js.map +1 -0
  71. package/dist/x-markdown.es18.js +8 -0
  72. package/dist/x-markdown.es18.js.map +1 -0
  73. package/dist/x-markdown.es19.js +207 -0
  74. package/dist/x-markdown.es19.js.map +1 -0
  75. package/dist/x-markdown.es2.js +83 -0
  76. package/dist/x-markdown.es2.js.map +1 -0
  77. package/dist/x-markdown.es21.js +11 -0
  78. package/dist/x-markdown.es21.js.map +1 -0
  79. package/dist/x-markdown.es22.js +75 -0
  80. package/dist/x-markdown.es22.js.map +1 -0
  81. package/dist/{index-SElRorTo.js → x-markdown.es24.js} +7 -139
  82. package/dist/x-markdown.es24.js.map +1 -0
  83. package/dist/x-markdown.es26.js +160 -0
  84. package/dist/x-markdown.es26.js.map +1 -0
  85. package/dist/x-markdown.es27.js +8 -0
  86. package/dist/x-markdown.es27.js.map +1 -0
  87. package/dist/x-markdown.es28.js +142 -0
  88. package/dist/x-markdown.es28.js.map +1 -0
  89. package/dist/x-markdown.es3.js +94 -0
  90. package/dist/x-markdown.es3.js.map +1 -0
  91. package/dist/x-markdown.es30.js +78 -0
  92. package/dist/x-markdown.es30.js.map +1 -0
  93. package/dist/x-markdown.es31.js +125 -0
  94. package/dist/x-markdown.es31.js.map +1 -0
  95. package/dist/x-markdown.es33.js +6 -0
  96. package/dist/x-markdown.es33.js.map +1 -0
  97. package/dist/x-markdown.es4.js +150 -0
  98. package/dist/x-markdown.es4.js.map +1 -0
  99. package/dist/x-markdown.es5.js +40 -0
  100. package/dist/x-markdown.es5.js.map +1 -0
  101. package/dist/x-markdown.es6.js +24 -0
  102. package/dist/x-markdown.es6.js.map +1 -0
  103. package/dist/x-markdown.es7.js +279 -0
  104. package/dist/x-markdown.es7.js.map +1 -0
  105. package/dist/x-markdown.es8.js +27 -0
  106. package/dist/x-markdown.es8.js.map +1 -0
  107. package/dist/x-markdown.es9.js +409 -0
  108. package/dist/x-markdown.es9.js.map +1 -0
  109. package/package.json +84 -84
  110. package/LICENSE +0 -21
  111. package/dist/index-D9u8JldH.cjs +0 -2
  112. package/dist/index-D9u8JldH.cjs.map +0 -1
  113. package/dist/index-SElRorTo.js.map +0 -1
  114. package/dist/index-lQ_FQFr2.js +0 -1882
  115. package/dist/index-lQ_FQFr2.js.map +0 -1
  116. package/dist/index-nZ5iH1aN.cjs +0 -2
  117. package/dist/index-nZ5iH1aN.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x-markdown.es31.js","sources":["../src/components/CodeBlock/SyntaxCodeBlock.vue"],"sourcesContent":["<template>\r\n <div class=\"x-md-syntax-code-block\">\r\n <pre v-if=\"showFallback\" :style=\"codeContainerStyle\"><code>{{ code }}</code></pre>\r\n <pre v-else :class=\"['shiki', actualTheme]\" :style=\"codeContainerStyle\" tabindex=\"0\">\r\n <code class=\"x-md-code-content\">\r\n <span v-for=\"(line, i) in lines\" :key=\"i\" class=\"x-md-code-line\">\r\n <span v-if=\"!line.length\">&nbsp;</span>\r\n <span \r\n v-else \r\n v-for=\"(token, j) in line\" \r\n :key=\"j\" \r\n :style=\"getTokenStyle(token)\"\r\n :class=\"{ 'x-md-animated-word': props.enableAnimate }\"\r\n >{{ token.content }}</span>\r\n </span>\r\n </code>\r\n </pre>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, type CSSProperties } from 'vue'\r\nimport { useHighlight } from '../../hooks/useHighlight'\r\nimport type { SyntaxCodeBlockProps } from './types'\r\n\r\ninterface HighlightToken {\r\n content?: string\r\n color?: string\r\n fontStyle?: 'italic' | null\r\n fontWeight?: 'normal' | 'bold' | null\r\n htmlStyle?: Record<string, string>\r\n}\r\n\r\ndefineOptions({\r\n name: 'SyntaxCodeBlock',\r\n})\r\n\r\nconst props = withDefaults(defineProps<SyntaxCodeBlockProps>(), {\r\n lightTheme: 'vitesse-light',\r\n darkTheme: 'vitesse-dark',\r\n isDark: false,\r\n enableAnimate: false,\r\n})\r\n\r\nconst code = computed(() => props.code.trim())\r\n\r\nconst language = computed(() => props.language || 'text')\r\n\r\nconst actualTheme = computed(() => (props.isDark ? props.darkTheme : props.lightTheme))\r\n\r\nconst { lines, preStyle } = useHighlight(code, {\r\n language,\r\n theme: actualTheme,\r\n colorReplacements: props.colorReplacements,\r\n})\r\n\r\nconst applyColorReplacement = (color: string, replacements?: Record<string, string>) => {\r\n if (!replacements) return color\r\n return replacements[color.toLowerCase()] || color\r\n}\r\n\r\nconst normalizeStyleKeys = (style: Record<string, string | number>): CSSProperties => {\r\n const normalized: CSSProperties = {}\r\n Object.entries(style).forEach(([key, value]) => {\r\n const camelKey = key.replace(/-([a-z])/g, (_, char) => char.toUpperCase())\r\n ;(normalized as Record<string, string | number>)[camelKey] = value\r\n })\r\n return normalized\r\n}\r\n\r\nconst getTokenStyle = (token: HighlightToken | null | undefined): CSSProperties => {\r\n // 处理 null/undefined token\r\n if (!token) {\r\n return {}\r\n }\r\n\r\n // 优先使用 htmlStyle(如果存在)\r\n if (token.htmlStyle) {\r\n const baseStyle = normalizeStyleKeys(token.htmlStyle)\r\n\r\n if (!props.colorReplacements) return baseStyle\r\n\r\n const style = { ...baseStyle }\r\n\r\n if (style.color && typeof style.color === 'string') {\r\n style.color = applyColorReplacement(style.color, props.colorReplacements)\r\n }\r\n if (style.backgroundColor && typeof style.backgroundColor === 'string') {\r\n style.backgroundColor = applyColorReplacement(style.backgroundColor, props.colorReplacements)\r\n }\r\n\r\n return style\r\n }\r\n\r\n // 直接使用 token 的 color、fontStyle、fontWeight 属性\r\n const style: CSSProperties = {}\r\n\r\n if (token.color) {\r\n style.color = props.colorReplacements\r\n ? applyColorReplacement(token.color, props.colorReplacements)\r\n : token.color\r\n }\r\n\r\n if (token.fontStyle === 'italic') {\r\n style.fontStyle = 'italic'\r\n }\r\n\r\n if (token.fontWeight) {\r\n style.fontWeight = token.fontWeight\r\n }\r\n\r\n return style\r\n}\r\n\r\nconst showFallback = computed(() => !lines.value?.length)\r\n\r\nconst codeContainerStyle = computed(() => ({\r\n ...preStyle.value,\r\n maxHeight: props.codeMaxHeight,\r\n}))\r\n\r\ndefineExpose({\r\n lines,\r\n code,\r\n language,\r\n actualTheme,\r\n})\r\n</script>\r\n\r\n<style scoped>\r\n.x-md-syntax-code-block {\r\n width: 100%;\r\n}\r\n\r\n.x-md-syntax-code-block pre {\r\n margin: 0;\r\n padding: 16px;\r\n overflow: auto;\r\n background: transparent !important;\r\n}\r\n\r\n.x-md-code-content {\r\n display: flex;\r\n flex-direction: column;\r\n}\r\n\r\n.x-md-code-line {\r\n width: 100%;\r\n font-size: 14px;\r\n line-height: 1.5;\r\n display: flex;\r\n}\r\n</style>"],"names":["style","_openBlock","_createElementBlock","_createElementVNode","_Fragment","_renderList","_unref","_normalizeStyle","_normalizeClass","_toDisplayString"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import _sfc_main from "./x-markdown.es28.js";
2
+ /* empty css */
3
+ export {
4
+ _sfc_main as default
5
+ };
6
+ //# sourceMappingURL=x-markdown.es33.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x-markdown.es33.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -0,0 +1,150 @@
1
+ import { find, svg, html } from "property-information";
2
+ import { h, toValue } from "vue";
3
+ function render(hast, attrs, slots, customAttrs) {
4
+ const keyCounter = {};
5
+ return h(
6
+ "div",
7
+ attrs,
8
+ renderChildren(
9
+ hast.children,
10
+ { listDepth: -1, listOrdered: false, listItemIndex: -1, svg: false },
11
+ hast,
12
+ slots ?? {},
13
+ toValue(customAttrs) ?? {},
14
+ keyCounter
15
+ )
16
+ );
17
+ }
18
+ function renderChildren(nodeList, ctx, parent, slots, customAttrs, keyCounter) {
19
+ return nodeList.map((node) => {
20
+ switch (node.type) {
21
+ case "text":
22
+ return node.value;
23
+ case "raw":
24
+ return node.value;
25
+ case "root":
26
+ return renderChildren(node.children, ctx, parent, slots, customAttrs, keyCounter);
27
+ case "element": {
28
+ const { attrs, context, aliasList, vnodeProps } = getVNodeInfos(node, parent, ctx, keyCounter, customAttrs);
29
+ for (let i = aliasList.length - 1; i >= 0; i--) {
30
+ const targetSlot = slots[aliasList[i]];
31
+ if (typeof targetSlot === "function") {
32
+ return targetSlot({
33
+ ...vnodeProps,
34
+ ...attrs,
35
+ children: () => renderChildren(node.children, context, node, slots, customAttrs, keyCounter)
36
+ });
37
+ }
38
+ }
39
+ return h(node.tagName, attrs, renderChildren(node.children, context, node, slots, customAttrs, keyCounter));
40
+ }
41
+ default:
42
+ return null;
43
+ }
44
+ });
45
+ }
46
+ function getVNodeInfos(node, parent, context, keyCounter, customAttrs) {
47
+ const aliasList = [];
48
+ let attrs = {};
49
+ const vnodeProps = {};
50
+ const ctx = { ...context };
51
+ if (node.type === "element") {
52
+ aliasList.push(node.tagName);
53
+ keyCounter[node.tagName] = node.tagName in keyCounter ? keyCounter[node.tagName] + 1 : 0;
54
+ vnodeProps.key = `${node.tagName}-${keyCounter[node.tagName]}`;
55
+ node.properties = node.properties || {};
56
+ if (node.tagName === "svg") {
57
+ ctx.svg = true;
58
+ }
59
+ attrs = Object.entries(node.properties).reduce((acc, [hastKey, value]) => {
60
+ const attrInfo = find(ctx.svg ? svg : html, hastKey);
61
+ acc[attrInfo.attribute] = value;
62
+ return acc;
63
+ }, {});
64
+ switch (node.tagName) {
65
+ case "h1":
66
+ case "h2":
67
+ case "h3":
68
+ case "h4":
69
+ case "h5":
70
+ case "h6":
71
+ vnodeProps.level = Number.parseFloat(node.tagName.slice(1));
72
+ aliasList.push("heading");
73
+ break;
74
+ case "code":
75
+ vnodeProps.languageOriginal = Array.isArray(attrs.class) ? attrs.class.find((cls) => cls.startsWith("language-")) : "";
76
+ vnodeProps.language = vnodeProps.languageOriginal ? vnodeProps.languageOriginal.replace("language-", "") : "";
77
+ vnodeProps.inline = "tagName" in parent && parent.tagName !== "pre";
78
+ vnodeProps.content = node.children[0]?.value ?? "";
79
+ aliasList.push(vnodeProps.inline ? "inline-code" : "block-code");
80
+ break;
81
+ case "thead":
82
+ case "tbody":
83
+ ctx.currentContext = node.tagName;
84
+ break;
85
+ case "td":
86
+ case "th":
87
+ case "tr":
88
+ vnodeProps.isHead = context.currentContext === "thead";
89
+ break;
90
+ case "ul":
91
+ case "ol":
92
+ ctx.listDepth = context.listDepth + 1;
93
+ ctx.listOrdered = node.tagName === "ol";
94
+ ctx.listItemIndex = -1;
95
+ vnodeProps.ordered = ctx.listOrdered;
96
+ vnodeProps.depth = ctx.listDepth;
97
+ aliasList.push("list");
98
+ break;
99
+ case "li":
100
+ ctx.listItemIndex++;
101
+ vnodeProps.ordered = ctx.listOrdered;
102
+ vnodeProps.depth = ctx.listDepth;
103
+ vnodeProps.index = ctx.listItemIndex;
104
+ aliasList.push("list-item");
105
+ break;
106
+ case "slot":
107
+ if (typeof node.properties["slot-name"] === "string") {
108
+ aliasList.push(`${node.properties["slot-name"]}`);
109
+ delete node.properties["slot-name"];
110
+ }
111
+ break;
112
+ }
113
+ attrs = computeAttrs(
114
+ node,
115
+ aliasList,
116
+ vnodeProps,
117
+ { ...attrs },
118
+ // TODO: fix this
119
+ customAttrs
120
+ );
121
+ }
122
+ return {
123
+ attrs,
124
+ context: ctx,
125
+ aliasList,
126
+ vnodeProps
127
+ };
128
+ }
129
+ function computeAttrs(node, aliasList, vnodeProps, attrs, customAttrs) {
130
+ const result = {
131
+ ...attrs
132
+ };
133
+ for (let i = aliasList.length - 1; i >= 0; i--) {
134
+ const name = aliasList[i];
135
+ if (name in customAttrs) {
136
+ const customAttr = customAttrs[name];
137
+ return {
138
+ ...result,
139
+ ...typeof customAttr === "function" ? customAttr(node, { ...attrs, ...vnodeProps }) : customAttr
140
+ };
141
+ }
142
+ }
143
+ return result;
144
+ }
145
+ export {
146
+ getVNodeInfos,
147
+ render,
148
+ renderChildren
149
+ };
150
+ //# sourceMappingURL=x-markdown.es4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x-markdown.es4.js","sources":["../src/core/hast-to-vnode.ts"],"sourcesContent":["import type { Element, Root, RootContent, Text } from 'hast'\r\nimport type { MaybeRefOrGetter, Slots, VNode, VNodeArrayChildren } from 'vue'\r\nimport type { AliasList, Attributes, Context, CustomAttrs, CustomAttrsObjectResult } from './types'\r\nimport { find, html, svg } from 'property-information'\r\nimport { h, toValue } from 'vue'\r\n\r\nexport function render(\r\n hast: Root,\r\n attrs: Record<string, unknown>,\r\n slots?: Slots,\r\n customAttrs?: MaybeRefOrGetter<CustomAttrs>,\r\n): VNode {\r\n const keyCounter: { [key: string]: number } = {}\r\n return h(\r\n 'div',\r\n attrs,\r\n renderChildren(\r\n hast.children,\r\n { listDepth: -1, listOrdered: false, listItemIndex: -1, svg: false },\r\n hast,\r\n slots ?? {},\r\n toValue(customAttrs) ?? {},\r\n keyCounter,\r\n ),\r\n )\r\n}\r\n\r\nexport function renderChildren(\r\n nodeList: (RootContent | Root)[],\r\n ctx: Context,\r\n parent: Element | Root,\r\n slots: Slots,\r\n customAttrs: CustomAttrs,\r\n keyCounter: { [key: string]: number },\r\n): VNodeArrayChildren {\r\n return nodeList.map((node) => {\r\n switch (node.type) {\r\n case 'text':\r\n return node.value\r\n case 'raw':\r\n return node.value\r\n case 'root':\r\n return renderChildren(node.children, ctx, parent, slots, customAttrs, keyCounter)\r\n case 'element': {\r\n const { attrs, context, aliasList, vnodeProps } = getVNodeInfos(node, parent, ctx, keyCounter, customAttrs)\r\n for (let i = aliasList.length - 1; i >= 0; i--) {\r\n const targetSlot = slots[aliasList[i]]\r\n if (typeof targetSlot === 'function') {\r\n return targetSlot({\r\n ...vnodeProps,\r\n ...attrs,\r\n children: () => renderChildren(node.children, context, node, slots, customAttrs, keyCounter),\r\n })\r\n }\r\n }\r\n\r\n return h(node.tagName, attrs, renderChildren(node.children, context, node, slots, customAttrs, keyCounter))\r\n }\r\n default:\r\n return null\r\n }\r\n })\r\n}\r\n\r\nexport function getVNodeInfos(\r\n node: RootContent,\r\n parent: Element | Root,\r\n context: Context,\r\n keyCounter: Record<string, number>,\r\n customAttrs: CustomAttrs,\r\n): {\r\n attrs: Record<string, unknown>\r\n context: Context\r\n aliasList: AliasList\r\n vnodeProps: Record<string, any>\r\n} {\r\n const aliasList: AliasList = []\r\n\r\n let attrs: Record<string, unknown> = {}\r\n const vnodeProps: Record<string, any> = {}\r\n const ctx = { ...context }\r\n\r\n if (node.type === 'element') {\r\n aliasList.push(node.tagName)\r\n keyCounter[node.tagName] = node.tagName in keyCounter ? keyCounter[node.tagName] + 1 : 0\r\n vnodeProps.key = `${node.tagName}-${keyCounter[node.tagName]}`\r\n node.properties = node.properties || {}\r\n\r\n if (node.tagName === 'svg') {\r\n ctx.svg = true\r\n }\r\n\r\n attrs = Object.entries(node.properties).reduce<Record<string, any>>((acc, [hastKey, value]) => {\r\n const attrInfo = find(ctx.svg ? svg : html, hastKey)\r\n acc[attrInfo.attribute] = value\r\n\r\n return acc\r\n }, {})\r\n\r\n switch (node.tagName) {\r\n case 'h1':\r\n case 'h2':\r\n case 'h3':\r\n case 'h4':\r\n case 'h5':\r\n case 'h6':\r\n vnodeProps.level = Number.parseFloat(node.tagName.slice(1))\r\n aliasList.push('heading')\r\n break\r\n // TODO: maybe use <pre> instead for customizing from <pre> not <code> ?\r\n case 'code':\r\n vnodeProps.languageOriginal = Array.isArray(attrs.class)\r\n ? attrs.class.find((cls) => cls.startsWith('language-'))\r\n : ''\r\n vnodeProps.language = vnodeProps.languageOriginal ? vnodeProps.languageOriginal.replace('language-', '') : ''\r\n vnodeProps.inline = 'tagName' in parent && parent.tagName !== 'pre'\r\n\r\n // when tagName is code, it definitely has children and the first child is text\r\n // https://github.com/syntax-tree/mdast-util-to-hast/blob/main/lib/handlers/code.js\r\n vnodeProps.content = (node.children[0] as unknown as Text)?.value ?? ''\r\n\r\n aliasList.push(vnodeProps.inline ? 'inline-code' : 'block-code')\r\n break\r\n case 'thead':\r\n case 'tbody':\r\n ctx.currentContext = node.tagName\r\n break\r\n case 'td':\r\n case 'th':\r\n case 'tr':\r\n vnodeProps.isHead = context.currentContext === 'thead'\r\n break\r\n\r\n case 'ul':\r\n case 'ol':\r\n ctx.listDepth = context.listDepth + 1\r\n ctx.listOrdered = node.tagName === 'ol'\r\n ctx.listItemIndex = -1\r\n vnodeProps.ordered = ctx.listOrdered\r\n vnodeProps.depth = ctx.listDepth\r\n\r\n aliasList.push('list')\r\n break\r\n\r\n case 'li':\r\n ctx.listItemIndex++\r\n\r\n vnodeProps.ordered = ctx.listOrdered\r\n vnodeProps.depth = ctx.listDepth\r\n vnodeProps.index = ctx.listItemIndex\r\n aliasList.push('list-item')\r\n\r\n break\r\n case 'slot':\r\n if (typeof node.properties['slot-name'] === 'string') {\r\n aliasList.push(`${node.properties['slot-name']}`)\r\n delete node.properties['slot-name']\r\n }\r\n break\r\n default:\r\n break\r\n }\r\n\r\n attrs = computeAttrs(\r\n node,\r\n aliasList,\r\n vnodeProps,\r\n { ...attrs } as Attributes, // TODO: fix this\r\n customAttrs,\r\n )\r\n }\r\n\r\n return {\r\n attrs,\r\n context: ctx,\r\n aliasList,\r\n vnodeProps,\r\n }\r\n}\r\n\r\n/**\r\n * TODO:\r\n * @param node - hast node\r\n * @param aliasList - html tag list. The earlier alias has higher priority. ?\r\n * @param attrs - attrs\r\n * @param customAttrs - custom attrs object\r\n * @returns attrs\r\n */\r\nfunction computeAttrs(\r\n node: Element,\r\n aliasList: AliasList,\r\n vnodeProps: Record<string, any>,\r\n attrs: Attributes,\r\n customAttrs: CustomAttrs,\r\n): CustomAttrsObjectResult {\r\n const result: CustomAttrsObjectResult = {\r\n ...attrs,\r\n }\r\n for (let i = aliasList.length - 1; i >= 0; i--) {\r\n const name = aliasList[i]\r\n // console.log(Object.keys(customAttrs))\r\n if (name in customAttrs) {\r\n const customAttr = customAttrs[name]\r\n return {\r\n ...result,\r\n ...(typeof customAttr === 'function' ? customAttr(node, { ...attrs, ...vnodeProps }) : customAttr),\r\n }\r\n }\r\n }\r\n return result\r\n}\r\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import deepmerge from "deepmerge";
2
+ import rehypeSanitize, { defaultSchema } from "rehype-sanitize";
3
+ import remarkParse from "remark-parse";
4
+ import remarkRehype from "remark-rehype";
5
+ import { unified } from "unified";
6
+ import { computed, toValue } from "vue";
7
+ function useMarkdownProcessor(options) {
8
+ const processor = computed(() => {
9
+ return createProcessor({
10
+ prePlugins: [remarkParse, ...toValue(options?.remarkPlugins) ?? []],
11
+ rehypePlugins: toValue(options?.rehypePlugins),
12
+ rehypeOptions: toValue(options?.rehypeOptions),
13
+ sanitize: toValue(options?.sanitize),
14
+ sanitizeOptions: toValue(options?.sanitizeOptions)
15
+ });
16
+ });
17
+ return { processor };
18
+ }
19
+ function createProcessor(options) {
20
+ return unified().use(options?.prePlugins ?? []).use(remarkRehype, {
21
+ allowDangerousHtml: true,
22
+ ...options?.rehypeOptions || {}
23
+ }).use(options?.rehypePlugins ?? []).use(
24
+ options?.sanitize ? [
25
+ [
26
+ rehypeSanitize,
27
+ deepmerge(
28
+ defaultSchema,
29
+ options?.sanitizeOptions?.sanitizeOptions || {},
30
+ options?.sanitizeOptions?.mergeOptions || {}
31
+ )
32
+ ]
33
+ ] : []
34
+ );
35
+ }
36
+ export {
37
+ createProcessor,
38
+ useMarkdownProcessor
39
+ };
40
+ //# sourceMappingURL=x-markdown.es5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x-markdown.es5.js","sources":["../src/core/useProcessor.ts"],"sourcesContent":["import type { Root } from 'hast'\r\nimport type { Root as MdastRoot } from 'mdast'\r\nimport type { Options as TRehypeOptions } from 'mdast-util-to-hast'\r\nimport type { PluggableList, Processor } from 'unified'\r\nimport type { ComputedRef, MaybeRefOrGetter } from 'vue'\r\nimport type { SanitizeOptions } from './types'\r\nimport deepmerge from 'deepmerge'\r\nimport rehypeSanitize, { defaultSchema } from 'rehype-sanitize'\r\nimport remarkParse from 'remark-parse'\r\nimport remarkRehype from 'remark-rehype'\r\nimport { unified } from 'unified'\r\nimport { computed, toValue } from 'vue'\r\n\r\nexport interface TUseMarkdownProcessorOptions {\r\n remarkPlugins?: MaybeRefOrGetter<PluggableList>\r\n rehypePlugins?: MaybeRefOrGetter<PluggableList>\r\n rehypeOptions?: MaybeRefOrGetter<Omit<TRehypeOptions, 'file'>>\r\n sanitize?: MaybeRefOrGetter<boolean>\r\n sanitizeOptions?: MaybeRefOrGetter<SanitizeOptions>\r\n}\r\nexport function useMarkdownProcessor(options?: TUseMarkdownProcessorOptions): {\r\n processor: ComputedRef<Processor<MdastRoot, MdastRoot, Root, undefined, undefined>>\r\n} {\r\n const processor = computed(() => {\r\n return createProcessor({\r\n prePlugins: [remarkParse, ...(toValue(options?.remarkPlugins) ?? [])],\r\n rehypePlugins: toValue(options?.rehypePlugins),\r\n rehypeOptions: toValue(options?.rehypeOptions),\r\n sanitize: toValue(options?.sanitize),\r\n sanitizeOptions: toValue(options?.sanitizeOptions),\r\n })\r\n })\r\n return { processor }\r\n}\r\n\r\nexport function createProcessor(options?: {\r\n prePlugins?: PluggableList\r\n rehypePlugins?: PluggableList\r\n rehypeOptions?: Omit<TRehypeOptions, 'file'>\r\n sanitize?: boolean\r\n sanitizeOptions?: SanitizeOptions\r\n // TODO: fix types\r\n}): Processor<any, any, any, any, any> {\r\n return unified()\r\n .use(options?.prePlugins ?? [])\r\n .use(remarkRehype, {\r\n allowDangerousHtml: true,\r\n ...(options?.rehypeOptions || {}),\r\n })\r\n .use(options?.rehypePlugins ?? [])\r\n .use(\r\n options?.sanitize\r\n ? [\r\n [\r\n rehypeSanitize,\r\n deepmerge(\r\n defaultSchema,\r\n options?.sanitizeOptions?.sanitizeOptions || {},\r\n options?.sanitizeOptions?.mergeOptions || {},\r\n ),\r\n ],\r\n ]\r\n : [],\r\n )\r\n}\r\n"],"names":[],"mappings":";;;;;;AAoBO,SAAS,qBAAqB,SAEnC;AACA,QAAM,YAAY,SAAS,MAAM;AAC/B,WAAO,gBAAgB;AAAA,MACrB,YAAY,CAAC,aAAa,GAAI,QAAQ,SAAS,aAAa,KAAK,EAAG;AAAA,MACpE,eAAe,QAAQ,SAAS,aAAa;AAAA,MAC7C,eAAe,QAAQ,SAAS,aAAa;AAAA,MAC7C,UAAU,QAAQ,SAAS,QAAQ;AAAA,MACnC,iBAAiB,QAAQ,SAAS,eAAe;AAAA,IAAA,CAClD;AAAA,EACH,CAAC;AACD,SAAO,EAAE,UAAA;AACX;AAEO,SAAS,gBAAgB,SAOO;AACrC,SAAO,QAAA,EACJ,IAAI,SAAS,cAAc,EAAE,EAC7B,IAAI,cAAc;AAAA,IACjB,oBAAoB;AAAA,IACpB,GAAI,SAAS,iBAAiB,CAAA;AAAA,EAAC,CAChC,EACA,IAAI,SAAS,iBAAiB,CAAA,CAAE,EAChC;AAAA,IACC,SAAS,WACL;AAAA,MACE;AAAA,QACE;AAAA,QACA;AAAA,UACE;AAAA,UACA,SAAS,iBAAiB,mBAAmB,CAAA;AAAA,UAC7C,SAAS,iBAAiB,gBAAgB,CAAA;AAAA,QAAC;AAAA,MAC7C;AAAA,IACF,IAEF,CAAA;AAAA,EAAC;AAEX;"}
@@ -0,0 +1,24 @@
1
+ import { h } from "vue";
2
+ import _sfc_main from "./x-markdown.es13.js";
3
+ function useComponents(props) {
4
+ const components = {
5
+ code: (raw) => h(_sfc_main, {
6
+ raw,
7
+ codeXRender: props?.codeXRender,
8
+ isDark: props?.isDark,
9
+ shikiTheme: props?.shikiTheme,
10
+ enableAnimate: props?.enableAnimate,
11
+ showCodeBlockHeader: props?.showCodeBlockHeader,
12
+ stickyCodeBlockHeader: props?.stickyCodeBlockHeader,
13
+ codeMaxHeight: props?.codeMaxHeight,
14
+ codeBlockActions: props?.codeBlockActions,
15
+ mermaidActions: props?.mermaidActions,
16
+ mermaidConfig: props?.mermaidConfig
17
+ })
18
+ };
19
+ return components;
20
+ }
21
+ export {
22
+ useComponents
23
+ };
24
+ //# sourceMappingURL=x-markdown.es6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x-markdown.es6.js","sources":["../src/hooks/useComponents.ts"],"sourcesContent":["import { h } from 'vue'\r\nimport type { CodeBlockAction } from '../components/CodeBlock/types'\r\nimport type { MermaidAction } from '../components/Mermaid/types'\r\nimport CodeX from '../components/CodeX/index.vue'\r\n\r\n// Shiki 主题类型(本地定义,避免直接依赖 shiki)\r\ntype ShikiThemeName =\r\n | 'vitesse-light' | 'vitesse-dark'\r\n | 'github-light' | 'github-dark'\r\n | 'nord' | 'one-dark-pro'\r\n | string // 允许其他自定义主题名称\r\n\r\ninterface UseComponentsOptions {\r\n codeXRender?: Record<string, any>\r\n isDark?: boolean\r\n shikiTheme?: [ShikiThemeName, ShikiThemeName]\r\n enableAnimate?: boolean\r\n showCodeBlockHeader?: boolean\r\n stickyCodeBlockHeader?: boolean\r\n codeMaxHeight?: string\r\n codeBlockActions?: CodeBlockAction[]\r\n mermaidActions?: MermaidAction[]\r\n mermaidConfig?: Record<string, any>\r\n}\r\n\r\nfunction useComponents(props?: UseComponentsOptions) {\r\n const components = {\r\n code: (raw: any) =>\r\n h(CodeX, {\r\n raw,\r\n codeXRender: props?.codeXRender,\r\n isDark: props?.isDark,\r\n shikiTheme: props?.shikiTheme,\r\n enableAnimate: props?.enableAnimate,\r\n showCodeBlockHeader: props?.showCodeBlockHeader,\r\n stickyCodeBlockHeader: props?.stickyCodeBlockHeader,\r\n codeMaxHeight: props?.codeMaxHeight,\r\n codeBlockActions: props?.codeBlockActions,\r\n mermaidActions: props?.mermaidActions,\r\n mermaidConfig: props?.mermaidConfig,\r\n }),\r\n }\r\n return components\r\n}\r\n\r\nexport { useComponents }\r\n"],"names":["CodeX"],"mappings":";;AAyBA,SAAS,cAAc,OAA8B;AACnD,QAAM,aAAa;AAAA,IACjB,MAAM,CAAC,QACL,EAAEA,WAAO;AAAA,MACP;AAAA,MACA,aAAa,OAAO;AAAA,MACpB,QAAQ,OAAO;AAAA,MACf,YAAY,OAAO;AAAA,MACnB,eAAe,OAAO;AAAA,MACtB,qBAAqB,OAAO;AAAA,MAC5B,uBAAuB,OAAO;AAAA,MAC9B,eAAe,OAAO;AAAA,MACtB,kBAAkB,OAAO;AAAA,MACzB,gBAAgB,OAAO;AAAA,MACvB,eAAe,OAAO;AAAA,IAAA,CACvB;AAAA,EAAA;AAEL,SAAO;AACT;"}
@@ -0,0 +1,279 @@
1
+ import { ref, computed, isRef, toValue, watch, onUnmounted } from "vue";
2
+ let shikiModulePromise = null;
3
+ let shikiStreamModulePromise = null;
4
+ let hasShownDependencyHint = false;
5
+ const showDependencyHint = () => {
6
+ if (hasShownDependencyHint) return;
7
+ hasShownDependencyHint = true;
8
+ console.log(
9
+ "%c[x-markdown]%c 代码高亮功能已降级为纯文本模式",
10
+ "font-weight: bold; color: #0066cc;",
11
+ "color: #666;"
12
+ );
13
+ console.log(
14
+ "%c如需语法高亮功能,请安装以下依赖:",
15
+ "color: #666; font-weight: bold;"
16
+ );
17
+ console.log(
18
+ "%c pnpm add shiki shiki-stream",
19
+ "color: #00aa00; font-family: monospace;"
20
+ );
21
+ console.log(
22
+ "%c安装后请重启开发服务器",
23
+ "color: #999; font-size: 12px;"
24
+ );
25
+ };
26
+ const loadShiki = async () => {
27
+ if (!shikiModulePromise) {
28
+ shikiModulePromise = (async () => {
29
+ try {
30
+ const mod = await import("shiki");
31
+ return mod;
32
+ } catch {
33
+ showDependencyHint();
34
+ return null;
35
+ }
36
+ })();
37
+ }
38
+ return shikiModulePromise;
39
+ };
40
+ const loadShikiStream = async () => {
41
+ if (!shikiStreamModulePromise) {
42
+ shikiStreamModulePromise = (async () => {
43
+ try {
44
+ const mod = await import("shiki-stream");
45
+ return mod;
46
+ } catch {
47
+ showDependencyHint();
48
+ return null;
49
+ }
50
+ })();
51
+ }
52
+ return shikiStreamModulePromise;
53
+ };
54
+ const tokensToLineTokens = (tokens) => {
55
+ if (!tokens.length) return [[]];
56
+ const lines = [[]];
57
+ let currentLine = lines[0];
58
+ const startNewLine = () => {
59
+ currentLine = [];
60
+ lines.push(currentLine);
61
+ };
62
+ tokens.forEach((token) => {
63
+ const content = token.content ?? "";
64
+ if (content === "\n") {
65
+ startNewLine();
66
+ return;
67
+ }
68
+ if (!content.includes("\n")) {
69
+ currentLine.push(token);
70
+ return;
71
+ }
72
+ const segments = content.split("\n");
73
+ segments.forEach((segment, index) => {
74
+ if (segment) {
75
+ currentLine.push({
76
+ ...token,
77
+ content: segment
78
+ });
79
+ }
80
+ if (index < segments.length - 1) {
81
+ startNewLine();
82
+ }
83
+ });
84
+ });
85
+ return lines.length === 0 ? [[]] : lines;
86
+ };
87
+ const createPreStyle = (bg, fg) => {
88
+ if (!bg && !fg) return void 0;
89
+ return {
90
+ backgroundColor: bg,
91
+ color: fg
92
+ };
93
+ };
94
+ function useHighlight(text, options) {
95
+ const streaming = ref();
96
+ const isLoading = ref(false);
97
+ const error = ref(null);
98
+ let tokenizer = null;
99
+ let previousText = "";
100
+ let highlighter = null;
101
+ let currentUsedLang = "";
102
+ let lastRequestedLang = "";
103
+ const effectiveTheme = computed(() => {
104
+ const theme = isRef(options.theme) ? options.theme.value : options.theme;
105
+ return theme || "slack-dark";
106
+ });
107
+ const effectiveLanguage = computed(() => {
108
+ return toValue(options.language) || "text";
109
+ });
110
+ const lines = computed(() => streaming.value?.lines || [[]]);
111
+ const preStyle = computed(() => streaming.value?.preStyle);
112
+ const updateTokens = async (nextText, forceReset = false) => {
113
+ if (!tokenizer) return;
114
+ if (forceReset) {
115
+ tokenizer.clear();
116
+ previousText = "";
117
+ }
118
+ const canAppend = !forceReset && nextText.startsWith(previousText);
119
+ let chunk = nextText;
120
+ if (canAppend) {
121
+ chunk = nextText.slice(previousText.length);
122
+ } else if (!forceReset) {
123
+ tokenizer.clear();
124
+ }
125
+ previousText = nextText;
126
+ if (!chunk) {
127
+ const mergedTokens = [...tokenizer.tokensStable, ...tokenizer.tokensUnstable];
128
+ streaming.value = {
129
+ colorReplacements: options.colorReplacements,
130
+ lines: mergedTokens.length ? tokensToLineTokens(mergedTokens) : [[]],
131
+ preStyle: streaming.value?.preStyle
132
+ };
133
+ return;
134
+ }
135
+ try {
136
+ await tokenizer.enqueue(chunk);
137
+ const mergedTokens = [...tokenizer.tokensStable, ...tokenizer.tokensUnstable];
138
+ streaming.value = {
139
+ colorReplacements: options.colorReplacements,
140
+ lines: tokensToLineTokens(mergedTokens),
141
+ preStyle: streaming.value?.preStyle
142
+ };
143
+ } catch (err) {
144
+ console.error("[x-markdown] Streaming highlighting failed:", err);
145
+ error.value = err;
146
+ }
147
+ };
148
+ const initHighlighter = async () => {
149
+ isLoading.value = true;
150
+ error.value = null;
151
+ let currentLang = effectiveLanguage.value;
152
+ const currentTheme = effectiveTheme.value;
153
+ try {
154
+ const mod = await loadShiki();
155
+ if (!mod) {
156
+ console.warn("[x-markdown] Shiki not available, falling back to plain text mode");
157
+ streaming.value = {
158
+ colorReplacements: options.colorReplacements,
159
+ lines: [[{ content: text.value }]],
160
+ preStyle: void 0
161
+ };
162
+ return;
163
+ }
164
+ highlighter = await mod.getSingletonHighlighter({
165
+ langs: [],
166
+ themes: [currentTheme]
167
+ });
168
+ lastRequestedLang = currentLang;
169
+ try {
170
+ await highlighter.loadLanguage(currentLang);
171
+ currentUsedLang = currentLang;
172
+ } catch {
173
+ console.warn(`[x-markdown] Failed to load language: ${currentLang}, falling back to plaintext`);
174
+ currentLang = "plaintext";
175
+ currentUsedLang = "plaintext";
176
+ }
177
+ const StreamMod = await loadShikiStream();
178
+ if (!StreamMod) {
179
+ console.warn("[x-markdown] shiki-stream not available, using non-streaming mode");
180
+ const tokens = highlighter.codeToThemedTokens(text.value, currentLang, currentTheme);
181
+ streaming.value = {
182
+ colorReplacements: options.colorReplacements,
183
+ lines: tokensToLineTokens(tokens),
184
+ preStyle: createPreStyle(
185
+ highlighter.getTheme(currentTheme)?.bg,
186
+ highlighter.getTheme(currentTheme)?.fg
187
+ )
188
+ };
189
+ return;
190
+ }
191
+ const ShikiStreamTokenizer = StreamMod.ShikiStreamTokenizer || StreamMod.default;
192
+ tokenizer = new ShikiStreamTokenizer({
193
+ highlighter,
194
+ lang: currentLang,
195
+ theme: currentTheme
196
+ });
197
+ previousText = "";
198
+ const themeInfo = highlighter.getTheme(currentTheme);
199
+ const preStyleValue = createPreStyle(themeInfo?.bg, themeInfo?.fg);
200
+ if (text.value) {
201
+ await updateTokens(text.value, true);
202
+ if (streaming.value) {
203
+ streaming.value.preStyle = preStyleValue;
204
+ }
205
+ } else {
206
+ streaming.value = {
207
+ colorReplacements: options.colorReplacements,
208
+ lines: [[]],
209
+ preStyle: preStyleValue
210
+ };
211
+ }
212
+ } catch (err) {
213
+ console.error("[x-markdown] Highlighter initialization failed:", err);
214
+ error.value = err;
215
+ streaming.value = {
216
+ colorReplacements: options.colorReplacements,
217
+ lines: [[{ content: text.value }]],
218
+ preStyle: void 0
219
+ };
220
+ } finally {
221
+ isLoading.value = false;
222
+ }
223
+ };
224
+ watch(
225
+ () => [effectiveLanguage.value, effectiveTheme.value],
226
+ async ([newLang]) => {
227
+ const requestedLang = newLang;
228
+ if (highlighter && currentUsedLang === "plaintext" && requestedLang !== lastRequestedLang && requestedLang !== "plaintext") {
229
+ try {
230
+ await highlighter.loadLanguage(requestedLang);
231
+ initHighlighter();
232
+ return;
233
+ } catch {
234
+ lastRequestedLang = requestedLang;
235
+ return;
236
+ }
237
+ }
238
+ initHighlighter();
239
+ },
240
+ { immediate: true }
241
+ );
242
+ watch(text, async (newText) => {
243
+ const requestedLang = effectiveLanguage.value;
244
+ if (highlighter && currentUsedLang === "plaintext" && requestedLang !== lastRequestedLang && requestedLang !== "plaintext") {
245
+ try {
246
+ await highlighter.loadLanguage(requestedLang);
247
+ await initHighlighter();
248
+ return;
249
+ } catch {
250
+ lastRequestedLang = requestedLang;
251
+ }
252
+ }
253
+ if (tokenizer) {
254
+ updateTokens(newText);
255
+ } else if (!highlighter) {
256
+ streaming.value = {
257
+ colorReplacements: options.colorReplacements,
258
+ lines: [[{ content: newText }]],
259
+ preStyle: streaming.value?.preStyle
260
+ };
261
+ }
262
+ });
263
+ onUnmounted(() => {
264
+ tokenizer?.clear();
265
+ tokenizer = null;
266
+ previousText = "";
267
+ });
268
+ return {
269
+ streaming,
270
+ lines,
271
+ preStyle,
272
+ isLoading,
273
+ error
274
+ };
275
+ }
276
+ export {
277
+ useHighlight
278
+ };
279
+ //# sourceMappingURL=x-markdown.es7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x-markdown.es7.js","sources":["../src/hooks/useHighlight.ts"],"sourcesContent":["import { ref, watch, onUnmounted, computed, isRef, toValue, type Ref, type MaybeRef, type CSSProperties } from 'vue'\r\n\r\ninterface HighlightToken {\r\n content?: string\r\n color?: string\r\n fontStyle?: 'italic' | null\r\n fontWeight?: 'normal' | 'bold' | null\r\n htmlStyle?: Record<string, string>\r\n}\r\n\r\ninterface StreamingHighlightResult {\r\n colorReplacements?: Record<string, string>\r\n lines: HighlightToken[][]\r\n preStyle?: CSSProperties\r\n}\r\n\r\ninterface UseHighlightOptions {\r\n language: MaybeRef<string>\r\n theme?: string | Ref<string>\r\n colorReplacements?: Record<string, string>\r\n}\r\n\r\nlet shikiModulePromise: Promise<any | null> | null = null\r\nlet shikiStreamModulePromise: Promise<any | null> | null = null\r\nlet hasShownDependencyHint = false\r\n\r\nconst showDependencyHint = () => {\r\n if (hasShownDependencyHint) return\r\n hasShownDependencyHint = true\r\n\r\n console.log(\r\n '%c[x-markdown]%c 代码高亮功能已降级为纯文本模式',\r\n 'font-weight: bold; color: #0066cc;',\r\n 'color: #666;'\r\n )\r\n console.log(\r\n '%c如需语法高亮功能,请安装以下依赖:',\r\n 'color: #666; font-weight: bold;'\r\n )\r\n console.log(\r\n '%c pnpm add shiki shiki-stream',\r\n 'color: #00aa00; font-family: monospace;'\r\n )\r\n console.log(\r\n '%c安装后请重启开发服务器',\r\n 'color: #999; font-size: 12px;'\r\n )\r\n}\r\n\r\nconst loadShiki = async () => {\r\n if (!shikiModulePromise) {\r\n shikiModulePromise = (async () => {\r\n try {\r\n // 直接静态导入,让 Vite/Rollup 在构建时处理\r\n const mod = await import('shiki')\r\n return mod\r\n } catch {\r\n showDependencyHint()\r\n return null\r\n }\r\n })()\r\n }\r\n return shikiModulePromise\r\n}\r\n\r\nconst loadShikiStream = async () => {\r\n if (!shikiStreamModulePromise) {\r\n shikiStreamModulePromise = (async () => {\r\n try {\r\n const mod = await import('shiki-stream')\r\n return mod\r\n } catch {\r\n showDependencyHint()\r\n return null\r\n }\r\n })()\r\n }\r\n return shikiStreamModulePromise\r\n}\r\n\r\nconst tokensToLineTokens = (tokens: HighlightToken[]): HighlightToken[][] => {\r\n if (!tokens.length) return [[]]\r\n\r\n const lines: HighlightToken[][] = [[]]\r\n let currentLine = lines[0]\r\n\r\n const startNewLine = () => {\r\n currentLine = []\r\n lines.push(currentLine)\r\n }\r\n\r\n tokens.forEach((token) => {\r\n const content = token.content ?? ''\r\n\r\n if (content === '\\n') {\r\n startNewLine()\r\n return\r\n }\r\n\r\n if (!content.includes('\\n')) {\r\n currentLine.push(token)\r\n return\r\n }\r\n\r\n const segments = content.split('\\n')\r\n segments.forEach((segment, index) => {\r\n if (segment) {\r\n currentLine.push({\r\n ...token,\r\n content: segment,\r\n })\r\n }\r\n\r\n if (index < segments.length - 1) {\r\n startNewLine()\r\n }\r\n })\r\n })\r\n\r\n return lines.length === 0 ? [[]] : lines\r\n}\r\n\r\nconst createPreStyle = (bg?: string, fg?: string): CSSProperties | undefined => {\r\n if (!bg && !fg) return undefined\r\n return {\r\n backgroundColor: bg,\r\n color: fg,\r\n }\r\n}\r\n\r\nexport function useHighlight(text: Ref<string>, options: UseHighlightOptions) {\r\n const streaming = ref<StreamingHighlightResult>()\r\n const isLoading = ref(false)\r\n const error = ref<Error | null>(null)\r\n\r\n let tokenizer: any | null = null\r\n let previousText = ''\r\n let highlighter: any | null = null\r\n let currentUsedLang = ''\r\n let lastRequestedLang = ''\r\n\r\n const effectiveTheme = computed(() => {\r\n const theme = isRef(options.theme) ? options.theme.value : options.theme\r\n return theme || 'slack-dark'\r\n })\r\n\r\n const effectiveLanguage = computed(() => {\r\n return toValue(options.language) || 'text'\r\n })\r\n\r\n const lines = computed(() => streaming.value?.lines || [[]])\r\n const preStyle = computed(() => streaming.value?.preStyle)\r\n\r\n const updateTokens = async (nextText: string, forceReset = false) => {\r\n if (!tokenizer) return\r\n\r\n if (forceReset) {\r\n tokenizer.clear()\r\n previousText = ''\r\n }\r\n\r\n const canAppend = !forceReset && nextText.startsWith(previousText)\r\n let chunk = nextText\r\n\r\n if (canAppend) {\r\n chunk = nextText.slice(previousText.length)\r\n } else if (!forceReset) {\r\n tokenizer.clear()\r\n }\r\n\r\n previousText = nextText\r\n\r\n if (!chunk) {\r\n const mergedTokens = [...tokenizer.tokensStable, ...tokenizer.tokensUnstable]\r\n streaming.value = {\r\n colorReplacements: options.colorReplacements,\r\n lines: mergedTokens.length ? tokensToLineTokens(mergedTokens) : [[]],\r\n preStyle: streaming.value?.preStyle,\r\n }\r\n return\r\n }\r\n\r\n try {\r\n await tokenizer.enqueue(chunk)\r\n\r\n const mergedTokens = [...tokenizer.tokensStable, ...tokenizer.tokensUnstable]\r\n\r\n streaming.value = {\r\n colorReplacements: options.colorReplacements,\r\n lines: tokensToLineTokens(mergedTokens),\r\n preStyle: streaming.value?.preStyle,\r\n }\r\n } catch (err) {\r\n console.error('[x-markdown] Streaming highlighting failed:', err)\r\n error.value = err as Error\r\n }\r\n }\r\n\r\n const initHighlighter = async () => {\r\n isLoading.value = true\r\n error.value = null\r\n\r\n let currentLang = effectiveLanguage.value\r\n const currentTheme = effectiveTheme.value\r\n\r\n try {\r\n const mod = await loadShiki()\r\n if (!mod) {\r\n console.warn('[x-markdown] Shiki not available, falling back to plain text mode')\r\n streaming.value = {\r\n colorReplacements: options.colorReplacements,\r\n lines: [[{ content: text.value }]],\r\n preStyle: undefined,\r\n }\r\n return\r\n }\r\n\r\n highlighter = await mod.getSingletonHighlighter({\r\n langs: [],\r\n themes: [currentTheme],\r\n })\r\n\r\n lastRequestedLang = currentLang\r\n\r\n try {\r\n await highlighter.loadLanguage(currentLang as any)\r\n currentUsedLang = currentLang\r\n } catch {\r\n console.warn(`[x-markdown] Failed to load language: ${currentLang}, falling back to plaintext`)\r\n currentLang = 'plaintext'\r\n currentUsedLang = 'plaintext'\r\n }\r\n\r\n const StreamMod = await loadShikiStream()\r\n if (!StreamMod) {\r\n console.warn('[x-markdown] shiki-stream not available, using non-streaming mode')\r\n const tokens = highlighter.codeToThemedTokens(text.value, currentLang, currentTheme)\r\n streaming.value = {\r\n colorReplacements: options.colorReplacements,\r\n lines: tokensToLineTokens(tokens),\r\n preStyle: createPreStyle(\r\n highlighter.getTheme(currentTheme)?.bg,\r\n highlighter.getTheme(currentTheme)?.fg\r\n ),\r\n }\r\n return\r\n }\r\n\r\n const ShikiStreamTokenizer = StreamMod.ShikiStreamTokenizer || StreamMod.default\r\n tokenizer = new ShikiStreamTokenizer({\r\n highlighter: highlighter,\r\n lang: currentLang,\r\n theme: currentTheme,\r\n })\r\n\r\n previousText = ''\r\n\r\n const themeInfo = highlighter.getTheme(currentTheme)\r\n const preStyleValue = createPreStyle(themeInfo?.bg, themeInfo?.fg)\r\n\r\n if (text.value) {\r\n await updateTokens(text.value, true)\r\n if (streaming.value) {\r\n streaming.value.preStyle = preStyleValue\r\n }\r\n } else {\r\n streaming.value = {\r\n colorReplacements: options.colorReplacements,\r\n lines: [[]],\r\n preStyle: preStyleValue,\r\n }\r\n }\r\n } catch (err) {\r\n console.error('[x-markdown] Highlighter initialization failed:', err)\r\n error.value = err as Error\r\n streaming.value = {\r\n colorReplacements: options.colorReplacements,\r\n lines: [[{ content: text.value }]],\r\n preStyle: undefined,\r\n }\r\n } finally {\r\n isLoading.value = false\r\n }\r\n }\r\n\r\n watch(\r\n () => [effectiveLanguage.value, effectiveTheme.value],\r\n async ([newLang]) => {\r\n const requestedLang = newLang as string\r\n\r\n if (\r\n highlighter &&\r\n currentUsedLang === 'plaintext' &&\r\n requestedLang !== lastRequestedLang &&\r\n requestedLang !== 'plaintext'\r\n ) {\r\n try {\r\n await highlighter.loadLanguage(requestedLang as any)\r\n initHighlighter()\r\n return\r\n } catch {\r\n lastRequestedLang = requestedLang\r\n return\r\n }\r\n }\r\n\r\n initHighlighter()\r\n },\r\n { immediate: true },\r\n )\r\n\r\n watch(text, async (newText) => {\r\n const requestedLang = effectiveLanguage.value\r\n if (\r\n highlighter &&\r\n currentUsedLang === 'plaintext' &&\r\n requestedLang !== lastRequestedLang &&\r\n requestedLang !== 'plaintext'\r\n ) {\r\n try {\r\n await highlighter.loadLanguage(requestedLang as any)\r\n await initHighlighter()\r\n return\r\n } catch {\r\n lastRequestedLang = requestedLang\r\n }\r\n }\r\n\r\n if (tokenizer) {\r\n updateTokens(newText)\r\n } else if (!highlighter) {\r\n streaming.value = {\r\n colorReplacements: options.colorReplacements,\r\n lines: [[{ content: newText }]],\r\n preStyle: streaming.value?.preStyle,\r\n }\r\n }\r\n })\r\n\r\n onUnmounted(() => {\r\n tokenizer?.clear()\r\n tokenizer = null\r\n previousText = ''\r\n })\r\n\r\n return {\r\n streaming,\r\n lines,\r\n preStyle,\r\n isLoading,\r\n error,\r\n }\r\n}\r\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { flow } from "lodash-es";
2
+ function useProcessMarkdown(markdown) {
3
+ return preprocessLaTeX(markdown);
4
+ }
5
+ function preprocessLaTeX(markdown) {
6
+ if (typeof markdown !== "string") return markdown;
7
+ const codeBlockRegex = /```[\s\S]*?```/g;
8
+ const codeBlocks = markdown.match(codeBlockRegex) || [];
9
+ const escapeReplacement = (str) => str.replace(/\$/g, "_ELX_DOLLAR_");
10
+ let processedMarkdown = markdown.replace(codeBlockRegex, "ELX_CODE_BLOCK_PLACEHOLDER");
11
+ processedMarkdown = flow([
12
+ (str) => str.replace(/\\\[(.*?)\\\]/g, (_, equation) => `$$${equation}$$`),
13
+ (str) => str.replace(/\\\[([\s\S]*?)\\\]/g, (_, equation) => `$$${equation}$$`),
14
+ (str) => str.replace(/\\\((.*?)\\\)/g, (_, equation) => `$$${equation}$$`),
15
+ (str) => str.replace(/(^|[^\\])\$(.+?)\$/g, (_, prefix, equation) => `${prefix}$${equation}$`)
16
+ ])(processedMarkdown);
17
+ codeBlocks.forEach((block) => {
18
+ processedMarkdown = processedMarkdown.replace("ELX_CODE_BLOCK_PLACEHOLDER", escapeReplacement(block));
19
+ });
20
+ processedMarkdown = processedMarkdown.replace(/_ELX_DOLLAR_/g, "$");
21
+ return processedMarkdown;
22
+ }
23
+ export {
24
+ preprocessLaTeX,
25
+ useProcessMarkdown
26
+ };
27
+ //# sourceMappingURL=x-markdown.es8.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x-markdown.es8.js","sources":["../src/hooks/useMarkdown.ts"],"sourcesContent":["import { flow } from 'lodash-es'\r\n\r\nexport function useProcessMarkdown(markdown: string) {\r\n return preprocessLaTeX(markdown)\r\n}\r\n\r\nexport function preprocessLaTeX(markdown: string) {\r\n if (typeof markdown !== 'string') return markdown\r\n\r\n const codeBlockRegex = /```[\\s\\S]*?```/g\r\n const codeBlocks = markdown.match(codeBlockRegex) || []\r\n const escapeReplacement = (str: string) => str.replace(/\\$/g, '_ELX_DOLLAR_')\r\n let processedMarkdown = markdown.replace(codeBlockRegex, 'ELX_CODE_BLOCK_PLACEHOLDER')\r\n\r\n processedMarkdown = flow([\r\n (str: string) => str.replace(/\\\\\\[(.*?)\\\\\\]/g, (_, equation) => `$$${equation}$$`),\r\n (str: string) => str.replace(/\\\\\\[([\\s\\S]*?)\\\\\\]/g, (_, equation) => `$$${equation}$$`),\r\n (str: string) => str.replace(/\\\\\\((.*?)\\\\\\)/g, (_, equation) => `$$${equation}$$`),\r\n (str: string) => str.replace(/(^|[^\\\\])\\$(.+?)\\$/g, (_, prefix, equation) => `${prefix}$${equation}$`),\r\n ])(processedMarkdown)\r\n\r\n codeBlocks.forEach((block) => {\r\n processedMarkdown = processedMarkdown.replace('ELX_CODE_BLOCK_PLACEHOLDER', escapeReplacement(block))\r\n })\r\n\r\n processedMarkdown = processedMarkdown.replace(/_ELX_DOLLAR_/g, '$')\r\n\r\n return processedMarkdown\r\n}\r\n"],"names":[],"mappings":";AAEO,SAAS,mBAAmB,UAAkB;AACnD,SAAO,gBAAgB,QAAQ;AACjC;AAEO,SAAS,gBAAgB,UAAkB;AAChD,MAAI,OAAO,aAAa,SAAU,QAAO;AAEzC,QAAM,iBAAiB;AACvB,QAAM,aAAa,SAAS,MAAM,cAAc,KAAK,CAAA;AACrD,QAAM,oBAAoB,CAAC,QAAgB,IAAI,QAAQ,OAAO,cAAc;AAC5E,MAAI,oBAAoB,SAAS,QAAQ,gBAAgB,4BAA4B;AAErF,sBAAoB,KAAK;AAAA,IACvB,CAAC,QAAgB,IAAI,QAAQ,kBAAkB,CAAC,GAAG,aAAa,KAAK,QAAQ,IAAI;AAAA,IACjF,CAAC,QAAgB,IAAI,QAAQ,uBAAuB,CAAC,GAAG,aAAa,KAAK,QAAQ,IAAI;AAAA,IACtF,CAAC,QAAgB,IAAI,QAAQ,kBAAkB,CAAC,GAAG,aAAa,KAAK,QAAQ,IAAI;AAAA,IACjF,CAAC,QAAgB,IAAI,QAAQ,uBAAuB,CAAC,GAAG,QAAQ,aAAa,GAAG,MAAM,IAAI,QAAQ,GAAG;AAAA,EAAA,CACtG,EAAE,iBAAiB;AAEpB,aAAW,QAAQ,CAAC,UAAU;AAC5B,wBAAoB,kBAAkB,QAAQ,8BAA8B,kBAAkB,KAAK,CAAC;AAAA,EACtG,CAAC;AAED,sBAAoB,kBAAkB,QAAQ,iBAAiB,GAAG;AAElE,SAAO;AACT;"}