@wsxjs/wsx-marked-components 0.0.25 → 0.0.26
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/dist/index.cjs +3 -3
- package/dist/index.js +630 -619
- package/package.json +5 -5
- package/src/Heading.wsx +12 -8
- package/src/Markdown.wsx +6 -2
- package/src/marked-utils.ts +14 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wsxjs/wsx-marked-components",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.26",
|
|
4
4
|
"description": "Markdown rendering components built with WSXJS for marked library",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"marked": "^12.0.0",
|
|
22
22
|
"prismjs": "^1.30.0",
|
|
23
|
-
"@wsxjs/wsx-core": "0.0.
|
|
24
|
-
"@wsxjs/wsx-logger": "0.0.
|
|
23
|
+
"@wsxjs/wsx-core": "0.0.26",
|
|
24
|
+
"@wsxjs/wsx-logger": "0.0.26"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/prismjs": "^1.26.5",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"tsup": "^8.0.0",
|
|
32
32
|
"typescript": "^5.0.0",
|
|
33
33
|
"vite": "^5.4.19",
|
|
34
|
-
"@wsxjs/
|
|
35
|
-
"@wsxjs/
|
|
34
|
+
"@wsxjs/eslint-plugin-wsx": "0.0.26",
|
|
35
|
+
"@wsxjs/wsx-vite-plugin": "0.0.26"
|
|
36
36
|
},
|
|
37
37
|
"keywords": [
|
|
38
38
|
"wsx",
|
package/src/Heading.wsx
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Custom heading component for markdown rendering
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { LightComponent, autoRegister } from "@wsxjs/wsx-core";
|
|
7
|
+
import { LightComponent, autoRegister, state } from "@wsxjs/wsx-core";
|
|
8
8
|
import styles from "./Heading.css?inline";
|
|
9
9
|
|
|
10
10
|
@autoRegister({ tagName: "wsx-marked-heading" })
|
|
@@ -19,8 +19,10 @@ export default class Heading extends LightComponent {
|
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
@state private anchorId: string = "";
|
|
23
|
+
|
|
22
24
|
static get observedAttributes() {
|
|
23
|
-
return ["level", "text"];
|
|
25
|
+
return ["level", "text", "anchor-id"];
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
attributeChangedCallback(name: string, oldValue: string, newValue: string) {
|
|
@@ -28,17 +30,19 @@ export default class Heading extends LightComponent {
|
|
|
28
30
|
this.level = parseInt(newValue, 10) || 1;
|
|
29
31
|
} else if (name === "text") {
|
|
30
32
|
this.text = newValue;
|
|
33
|
+
} else if (name === "anchor-id") {
|
|
34
|
+
this.anchorId = newValue;
|
|
31
35
|
}
|
|
32
36
|
this.rerender();
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
render() {
|
|
36
40
|
// 使用 WSX JSX 语法,根据 level 渲染对应的标题
|
|
37
|
-
if (this.level === 1) return <h1>{this.text}</h1>;
|
|
38
|
-
if (this.level === 2) return <h2>{this.text}</h2>;
|
|
39
|
-
if (this.level === 3) return <h3>{this.text}</h3>;
|
|
40
|
-
if (this.level === 4) return <h4>{this.text}</h4>;
|
|
41
|
-
if (this.level === 5) return <h5>{this.text}</h5>;
|
|
42
|
-
return <h6>{this.text}</h6>;
|
|
41
|
+
if (this.level === 1) return <h1 id={this.anchorId}>{this.text}</h1>;
|
|
42
|
+
if (this.level === 2) return <h2 id={this.anchorId}>{this.text}</h2>;
|
|
43
|
+
if (this.level === 3) return <h3 id={this.anchorId}>{this.text}</h3>;
|
|
44
|
+
if (this.level === 4) return <h4 id={this.anchorId}>{this.text}</h4>;
|
|
45
|
+
if (this.level === 5) return <h5 id={this.anchorId}>{this.text}</h5>;
|
|
46
|
+
return <h6 id={this.anchorId}>{this.text}</h6>;
|
|
43
47
|
}
|
|
44
48
|
}
|
package/src/Markdown.wsx
CHANGED
|
@@ -16,7 +16,7 @@ import { createLogger } from "@wsxjs/wsx-logger";
|
|
|
16
16
|
import { marked } from "marked";
|
|
17
17
|
import type { Tokens } from "marked";
|
|
18
18
|
|
|
19
|
-
import { renderInlineTokens } from "./marked-utils";
|
|
19
|
+
import { renderInlineTokens, generateId } from "./marked-utils";
|
|
20
20
|
// Import WSX components so they're registered as custom elements
|
|
21
21
|
import "./Heading.wsx";
|
|
22
22
|
import "./Code.wsx";
|
|
@@ -143,10 +143,14 @@ export default class Markdown extends LightComponent {
|
|
|
143
143
|
switch (token.type) {
|
|
144
144
|
case "heading": {
|
|
145
145
|
const headingToken = token as Tokens.Heading;
|
|
146
|
+
const text = renderInlineTokens(headingToken.tokens);
|
|
147
|
+
const id = generateId(text);
|
|
148
|
+
|
|
146
149
|
return (
|
|
147
150
|
<wsx-marked-heading
|
|
148
151
|
level={headingToken.depth.toString()}
|
|
149
|
-
text={
|
|
152
|
+
text={text}
|
|
153
|
+
anchor-id={id}
|
|
150
154
|
/>
|
|
151
155
|
);
|
|
152
156
|
}
|
package/src/marked-utils.ts
CHANGED
|
@@ -109,3 +109,17 @@ export function renderInlineTokens(tokens: Tokens.Generic[] | undefined): string
|
|
|
109
109
|
})
|
|
110
110
|
.join("");
|
|
111
111
|
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Generate a clean ID from text
|
|
115
|
+
* Matches the logic in wsx-press TOC generation
|
|
116
|
+
* 保留中文等 Unicode 字符,只移除特殊符号
|
|
117
|
+
*/
|
|
118
|
+
export function generateId(text: string): string {
|
|
119
|
+
return text
|
|
120
|
+
.toLowerCase()
|
|
121
|
+
.replace(/\s+/g, "-") // 空格转连字符
|
|
122
|
+
.replace(/[^\p{L}\p{N}-]/gu, "") // 保留字母、数字、连字符(Unicode-aware)
|
|
123
|
+
.replace(/-+/g, "-") // 合并多个连字符
|
|
124
|
+
.replace(/^-+|-+$/g, ""); // 移除首尾连字符
|
|
125
|
+
}
|