@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wsxjs/wsx-marked-components",
3
- "version": "0.0.25",
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.25",
24
- "@wsxjs/wsx-logger": "0.0.25"
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/wsx-vite-plugin": "0.0.25",
35
- "@wsxjs/eslint-plugin-wsx": "0.0.25"
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={renderInlineTokens(headingToken.tokens)}
152
+ text={text}
153
+ anchor-id={id}
150
154
  />
151
155
  );
152
156
  }
@@ -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
+ }