rehype-instui-markdown 0.0.6
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/README.md +23 -0
- package/dist/index.d.mts +77 -0
- package/dist/index.mjs +126 -0
- package/package.json +32 -0
package/README.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# vite-plus-starter
|
|
2
|
+
|
|
3
|
+
A starter for creating a Vite Plus project.
|
|
4
|
+
|
|
5
|
+
## Development
|
|
6
|
+
|
|
7
|
+
- Install dependencies:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
vp install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
- Run the unit tests:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
vp test
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- Build the library:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
vp pack
|
|
23
|
+
```
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
//#region src/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Base shape shared by all nodes handled by these transforms.
|
|
4
|
+
*/
|
|
5
|
+
interface HastBaseNode {
|
|
6
|
+
/** Unist node type. */
|
|
7
|
+
type?: string;
|
|
8
|
+
/** Optional HTML tag name. */
|
|
9
|
+
tagName?: string;
|
|
10
|
+
/** Optional text node value. */
|
|
11
|
+
value?: string;
|
|
12
|
+
/** Optional child nodes. */
|
|
13
|
+
children?: HastNode[];
|
|
14
|
+
/** Optional element properties. */
|
|
15
|
+
properties?: Record<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Minimal text-node representation used by plugin transforms.
|
|
19
|
+
*/
|
|
20
|
+
interface HastTextNode extends HastBaseNode {
|
|
21
|
+
type: "text";
|
|
22
|
+
value: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Minimal element-node representation used by plugin transforms.
|
|
26
|
+
*/
|
|
27
|
+
interface HastElementNode extends HastBaseNode {
|
|
28
|
+
type: "element";
|
|
29
|
+
tagName: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Minimal root-node representation used by plugin transforms.
|
|
33
|
+
*/
|
|
34
|
+
interface HastRootNode extends HastBaseNode {
|
|
35
|
+
type: "root";
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Generic fallback node shape.
|
|
39
|
+
*/
|
|
40
|
+
interface HastUnknownNode extends HastBaseNode {}
|
|
41
|
+
/**
|
|
42
|
+
* Supported node variants handled by these plugins.
|
|
43
|
+
*/
|
|
44
|
+
type HastNode = HastTextNode | HastElementNode | HastRootNode | HastUnknownNode;
|
|
45
|
+
/**
|
|
46
|
+
* Signature for the tree transformer returned by each plugin factory.
|
|
47
|
+
*/
|
|
48
|
+
type HastTransformer = (tree: HastNode) => void;
|
|
49
|
+
/**
|
|
50
|
+
* Regex used to detect color tokens in markdown text nodes.
|
|
51
|
+
*/
|
|
52
|
+
declare const COLOR_TOKEN_REGEX: RegExp;
|
|
53
|
+
/**
|
|
54
|
+
* Regex used to detect icon tokens in markdown text nodes.
|
|
55
|
+
*/
|
|
56
|
+
declare const ICON_TOKEN_REGEX: RegExp;
|
|
57
|
+
/**
|
|
58
|
+
* Rehype plugin that unwraps bare paragraph nodes inside blockquotes.
|
|
59
|
+
*
|
|
60
|
+
* This avoids invalid nesting when markdown blockquote content later renders
|
|
61
|
+
* through components that expect inline children.
|
|
62
|
+
*/
|
|
63
|
+
declare function rehypeUnwrapBlockquoteParagraphs(): HastTransformer;
|
|
64
|
+
/**
|
|
65
|
+
* Rehype plugin that wraps color tokens in a span with color metadata.
|
|
66
|
+
*
|
|
67
|
+
* It skips code and preformatted blocks to avoid mutating code examples.
|
|
68
|
+
*/
|
|
69
|
+
declare function rehypeColorCodes(): HastTransformer;
|
|
70
|
+
/**
|
|
71
|
+
* Rehype plugin that wraps :icon: and :icon|color: tokens in span metadata.
|
|
72
|
+
*
|
|
73
|
+
* It skips code and preformatted blocks to avoid mutating code examples.
|
|
74
|
+
*/
|
|
75
|
+
declare function rehypeInstUIIconTokens(): HastTransformer;
|
|
76
|
+
//#endregion
|
|
77
|
+
export { COLOR_TOKEN_REGEX, HastElementNode, HastNode, HastRootNode, HastTextNode, HastTransformer, HastUnknownNode, ICON_TOKEN_REGEX, rehypeColorCodes, rehypeInstUIIconTokens, rehypeUnwrapBlockquoteParagraphs };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { visit } from "unist-util-visit";
|
|
2
|
+
//#region src/index.ts
|
|
3
|
+
/**
|
|
4
|
+
* Regex used to detect color tokens in markdown text nodes.
|
|
5
|
+
*/
|
|
6
|
+
const COLOR_TOKEN_REGEX = /#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b|rgba?\(\s*(?:\d{1,3}\s*,\s*){2}\d{1,3}(?:\s*,\s*(?:0|1|0?\.\d+))?\s*\)|hsla?\(\s*\d{1,3}(?:\.\d+)?\s*,\s*\d{1,3}%\s*,\s*\d{1,3}%\s*(?:,\s*(?:0|1|0?\.\d+))?\s*\)/gi;
|
|
7
|
+
/**
|
|
8
|
+
* Regex used to detect icon tokens in markdown text nodes.
|
|
9
|
+
*/
|
|
10
|
+
const ICON_TOKEN_REGEX = /:([a-zA-Z][a-zA-Z0-9]*)(?:\|([^:]+))?:/g;
|
|
11
|
+
function isElementNode(node, tagName) {
|
|
12
|
+
return node.type === "element" && (tagName ? node.tagName === tagName : true);
|
|
13
|
+
}
|
|
14
|
+
function shouldSkipInlineTokenTransform(parent) {
|
|
15
|
+
return isElementNode(parent, "pre") || isElementNode(parent, "code");
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Rehype plugin that unwraps bare paragraph nodes inside blockquotes.
|
|
19
|
+
*
|
|
20
|
+
* This avoids invalid nesting when markdown blockquote content later renders
|
|
21
|
+
* through components that expect inline children.
|
|
22
|
+
*/
|
|
23
|
+
function rehypeUnwrapBlockquoteParagraphs() {
|
|
24
|
+
return (tree) => {
|
|
25
|
+
visit(tree, "element", (node) => {
|
|
26
|
+
if (!isElementNode(node, "blockquote")) return;
|
|
27
|
+
node.children = (node.children ?? []).flatMap((child) => {
|
|
28
|
+
if (isElementNode(child, "p")) return child.children ?? [];
|
|
29
|
+
return [child];
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Rehype plugin that wraps color tokens in a span with color metadata.
|
|
36
|
+
*
|
|
37
|
+
* It skips code and preformatted blocks to avoid mutating code examples.
|
|
38
|
+
*/
|
|
39
|
+
function rehypeColorCodes() {
|
|
40
|
+
return (tree) => {
|
|
41
|
+
visit(tree, "text", (node, index, parent) => {
|
|
42
|
+
if (node.type !== "text" || !parent || index === void 0 || shouldSkipInlineTokenTransform(parent)) return;
|
|
43
|
+
const value = node.value ?? "";
|
|
44
|
+
const matches = [...value.matchAll(COLOR_TOKEN_REGEX)];
|
|
45
|
+
if (matches.length === 0) return;
|
|
46
|
+
const nextChildren = [];
|
|
47
|
+
let lastIndex = 0;
|
|
48
|
+
for (const match of matches) {
|
|
49
|
+
const [matchText] = match;
|
|
50
|
+
const start = match.index ?? 0;
|
|
51
|
+
if (start > lastIndex) nextChildren.push({
|
|
52
|
+
type: "text",
|
|
53
|
+
value: value.slice(lastIndex, start)
|
|
54
|
+
});
|
|
55
|
+
nextChildren.push({
|
|
56
|
+
type: "element",
|
|
57
|
+
tagName: "span",
|
|
58
|
+
properties: {
|
|
59
|
+
className: ["color-code"],
|
|
60
|
+
"data-color": matchText
|
|
61
|
+
},
|
|
62
|
+
children: [{
|
|
63
|
+
type: "text",
|
|
64
|
+
value: matchText
|
|
65
|
+
}]
|
|
66
|
+
});
|
|
67
|
+
lastIndex = start + matchText.length;
|
|
68
|
+
}
|
|
69
|
+
if (lastIndex < value.length) nextChildren.push({
|
|
70
|
+
type: "text",
|
|
71
|
+
value: value.slice(lastIndex)
|
|
72
|
+
});
|
|
73
|
+
(parent.children ?? []).splice(index, 1, ...nextChildren);
|
|
74
|
+
return index + nextChildren.length;
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Rehype plugin that wraps :icon: and :icon|color: tokens in span metadata.
|
|
80
|
+
*
|
|
81
|
+
* It skips code and preformatted blocks to avoid mutating code examples.
|
|
82
|
+
*/
|
|
83
|
+
function rehypeInstUIIconTokens() {
|
|
84
|
+
return (tree) => {
|
|
85
|
+
visit(tree, "text", (node, index, parent) => {
|
|
86
|
+
if (node.type !== "text" || !parent || index === void 0 || shouldSkipInlineTokenTransform(parent)) return;
|
|
87
|
+
const value = node.value ?? "";
|
|
88
|
+
const matches = [...value.matchAll(ICON_TOKEN_REGEX)];
|
|
89
|
+
if (matches.length === 0) return;
|
|
90
|
+
const nextChildren = [];
|
|
91
|
+
let lastIndex = 0;
|
|
92
|
+
for (const match of matches) {
|
|
93
|
+
const [matchText, iconName, rawIconColor] = match;
|
|
94
|
+
const iconColor = rawIconColor?.trim();
|
|
95
|
+
const start = match.index ?? 0;
|
|
96
|
+
if (start > lastIndex) nextChildren.push({
|
|
97
|
+
type: "text",
|
|
98
|
+
value: value.slice(lastIndex, start)
|
|
99
|
+
});
|
|
100
|
+
const properties = {
|
|
101
|
+
className: ["icon-token"],
|
|
102
|
+
"data-icon": iconName
|
|
103
|
+
};
|
|
104
|
+
if (iconColor) properties["data-icon-color"] = iconColor;
|
|
105
|
+
nextChildren.push({
|
|
106
|
+
type: "element",
|
|
107
|
+
tagName: "span",
|
|
108
|
+
properties,
|
|
109
|
+
children: [{
|
|
110
|
+
type: "text",
|
|
111
|
+
value: matchText
|
|
112
|
+
}]
|
|
113
|
+
});
|
|
114
|
+
lastIndex = start + matchText.length;
|
|
115
|
+
}
|
|
116
|
+
if (lastIndex < value.length) nextChildren.push({
|
|
117
|
+
type: "text",
|
|
118
|
+
value: value.slice(lastIndex)
|
|
119
|
+
});
|
|
120
|
+
(parent.children ?? []).splice(index, 1, ...nextChildren);
|
|
121
|
+
return index + nextChildren.length;
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
//#endregion
|
|
126
|
+
export { COLOR_TOKEN_REGEX, ICON_TOKEN_REGEX, rehypeColorCodes, rehypeInstUIIconTokens, rehypeUnwrapBlockquoteParagraphs };
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "rehype-instui-markdown",
|
|
3
|
+
"version": "0.0.6",
|
|
4
|
+
"description": "Rehype plugins for InstUI markdown rendering",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"type": "module",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": "./dist/index.mjs",
|
|
12
|
+
"./package.json": "./package.json"
|
|
13
|
+
},
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "vp pack",
|
|
19
|
+
"dev": "vp pack --watch",
|
|
20
|
+
"test": "vp test",
|
|
21
|
+
"check": "vp check",
|
|
22
|
+
"prepublishOnly": "vp run build"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"unist-util-visit": "^5.0.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/node": "catalog:",
|
|
29
|
+
"typescript": "catalog:",
|
|
30
|
+
"vite-plus": "catalog:"
|
|
31
|
+
}
|
|
32
|
+
}
|