c063 1.4.6 → 1.4.8
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/components/CodeBlock.d.ts +1 -0
- package/dist/components/CodeBlock.js +1 -0
- package/dist/components/CodeLine.d.ts +1 -0
- package/dist/components/CodeLine.js +2 -1
- package/dist/components/CodeToken.d.ts +1 -0
- package/dist/components/CodeToken.js +1 -0
- package/dist/types/index.d.ts +0 -1
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js +11 -1
- package/package.json +1 -1
- package/src/components/CodeBlock.tsx +1 -0
- package/src/components/CodeLine.tsx +2 -1
- package/src/components/CodeToken.tsx +1 -0
- package/src/types/index.ts +0 -1
- package/src/utils/index.tsx +22 -3
- package/src/utils/parser.tsx +0 -103
|
@@ -6,6 +6,7 @@ import { CodeBlockProps } from "../types/index";
|
|
|
6
6
|
* @param props.tokenLines 所有程式碼行的 token 陣列
|
|
7
7
|
* @param props.showLineNumbers 是否顯示行號,預設為 true
|
|
8
8
|
* @param props.lineNumberStyle 行號的自訂樣式
|
|
9
|
+
* @param props.theme 主題
|
|
9
10
|
* @param rest 其他傳遞給 <pre> 的屬性
|
|
10
11
|
* @returns JSX 元素,呈現語法高亮的程式碼區塊
|
|
11
12
|
*/
|
|
@@ -7,6 +7,7 @@ import { CodeLine } from "./CodeLine";
|
|
|
7
7
|
* @param props.tokenLines 所有程式碼行的 token 陣列
|
|
8
8
|
* @param props.showLineNumbers 是否顯示行號,預設為 true
|
|
9
9
|
* @param props.lineNumberStyle 行號的自訂樣式
|
|
10
|
+
* @param props.theme 主題
|
|
10
11
|
* @param rest 其他傳遞給 <pre> 的屬性
|
|
11
12
|
* @returns JSX 元素,呈現語法高亮的程式碼區塊
|
|
12
13
|
*/
|
|
@@ -5,6 +5,7 @@ import { CodeLineProps } from "../types/index";
|
|
|
5
5
|
* @template T 元件渲染類型,例如 <code>、<span> 等
|
|
6
6
|
* @param props.tokens 該行所包含的語法 token 陣列
|
|
7
7
|
* @param props.style 自訂樣式,會與 whiteSpace: pre-wrap 合併
|
|
8
|
+
* @param props.theme 主題
|
|
8
9
|
* @param rest 其他 HTMLAttributes
|
|
9
10
|
* @returns JSX 元素,呈現語法 token 的單行程式碼
|
|
10
11
|
*/
|
|
@@ -6,6 +6,7 @@ import { CodeToken } from "./CodeToken";
|
|
|
6
6
|
* @template T 元件渲染類型,例如 <code>、<span> 等
|
|
7
7
|
* @param props.tokens 該行所包含的語法 token 陣列
|
|
8
8
|
* @param props.style 自訂樣式,會與 whiteSpace: pre-wrap 合併
|
|
9
|
+
* @param props.theme 主題
|
|
9
10
|
* @param rest 其他 HTMLAttributes
|
|
10
11
|
* @returns JSX 元素,呈現語法 token 的單行程式碼
|
|
11
12
|
*/
|
|
@@ -13,6 +14,6 @@ export const CodeLine = ({ style, tokens, theme, ...rest }) => {
|
|
|
13
14
|
return (_jsx("code", { ...rest, style: {
|
|
14
15
|
whiteSpace: "pre-wrap",
|
|
15
16
|
...style,
|
|
16
|
-
}, children: tokens.map((token, index) => (_jsx(CodeToken, { theme: theme, ...token },
|
|
17
|
+
}, children: tokens.map((token, index) => (_jsx(CodeToken, { theme: theme, ...token }, index))) }));
|
|
17
18
|
};
|
|
18
19
|
CodeLine.displayName = "CodeLine";
|
package/dist/types/index.d.ts
CHANGED
package/dist/utils/index.d.ts
CHANGED
|
@@ -29,4 +29,3 @@ declare const c063: Record<CodeTokenType, CodeTokenBuilder>;
|
|
|
29
29
|
export declare const whiteSpace: (count?: number) => CodeTokenProps<"span">;
|
|
30
30
|
export declare const extractTokenContent: <T extends React.ElementType>(token: CodeTokenProps<T>) => string;
|
|
31
31
|
export default c063;
|
|
32
|
-
export * from "./parser";
|
package/dist/utils/index.js
CHANGED
|
@@ -53,4 +53,14 @@ export const extractTokenContent = (token) => {
|
|
|
53
53
|
return _extract(token.children);
|
|
54
54
|
};
|
|
55
55
|
export default c063;
|
|
56
|
-
|
|
56
|
+
/**
|
|
57
|
+
* 待實現
|
|
58
|
+
*/
|
|
59
|
+
const _parseTokens = new Proxy({}, {
|
|
60
|
+
get: (_, prop) => {
|
|
61
|
+
const parser = (content) => {
|
|
62
|
+
return [];
|
|
63
|
+
};
|
|
64
|
+
return parser;
|
|
65
|
+
},
|
|
66
|
+
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "c063",
|
|
4
|
-
"version": "1.4.
|
|
4
|
+
"version": "1.4.8",
|
|
5
5
|
"description": "A React component for displaying code snippets with syntax highlighting.",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -7,6 +7,7 @@ import { CodeLine } from "./CodeLine";
|
|
|
7
7
|
* @param props.tokenLines 所有程式碼行的 token 陣列
|
|
8
8
|
* @param props.showLineNumbers 是否顯示行號,預設為 true
|
|
9
9
|
* @param props.lineNumberStyle 行號的自訂樣式
|
|
10
|
+
* @param props.theme 主題
|
|
10
11
|
* @param rest 其他傳遞給 <pre> 的屬性
|
|
11
12
|
* @returns JSX 元素,呈現語法高亮的程式碼區塊
|
|
12
13
|
*/
|
|
@@ -6,6 +6,7 @@ import { CodeToken } from "./CodeToken";
|
|
|
6
6
|
* @template T 元件渲染類型,例如 <code>、<span> 等
|
|
7
7
|
* @param props.tokens 該行所包含的語法 token 陣列
|
|
8
8
|
* @param props.style 自訂樣式,會與 whiteSpace: pre-wrap 合併
|
|
9
|
+
* @param props.theme 主題
|
|
9
10
|
* @param rest 其他 HTMLAttributes
|
|
10
11
|
* @returns JSX 元素,呈現語法 token 的單行程式碼
|
|
11
12
|
*/
|
|
@@ -24,7 +25,7 @@ export const CodeLine = <T extends React.ElementType = "span">({
|
|
|
24
25
|
}}
|
|
25
26
|
>
|
|
26
27
|
{tokens.map((token, index) => (
|
|
27
|
-
<CodeToken key={
|
|
28
|
+
<CodeToken key={index} theme={theme} {...token} />
|
|
28
29
|
))}
|
|
29
30
|
</code>
|
|
30
31
|
);
|
package/src/types/index.ts
CHANGED
package/src/utils/index.tsx
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
CodeTokenBuilder,
|
|
4
|
+
CodeTokenProps,
|
|
5
|
+
CodeTokenType,
|
|
6
|
+
ParsableLanguage,
|
|
7
|
+
} from "../types";
|
|
4
8
|
|
|
5
9
|
/**
|
|
6
10
|
* 語法 token 的建構器集合,每個 key 對應一種語法類型(如 `keyword-blue`, `string`, `comment` 等),
|
|
@@ -65,4 +69,19 @@ export const extractTokenContent = <T extends React.ElementType>(
|
|
|
65
69
|
};
|
|
66
70
|
|
|
67
71
|
export default c063;
|
|
68
|
-
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 待實現
|
|
76
|
+
*/
|
|
77
|
+
const _parseTokens = new Proxy(
|
|
78
|
+
{},
|
|
79
|
+
{
|
|
80
|
+
get: (_, prop: ParsableLanguage) => {
|
|
81
|
+
const parser = (content: string): CodeTokenProps<"span">[][] => {
|
|
82
|
+
return [];
|
|
83
|
+
};
|
|
84
|
+
return parser;
|
|
85
|
+
},
|
|
86
|
+
}
|
|
87
|
+
) as Record<ParsableLanguage, (content: string) => CodeTokenProps<"span">[][]>;
|
package/src/utils/parser.tsx
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { parsableLanguages } from "../libs";
|
|
2
|
-
import {
|
|
3
|
-
CodeTokenProps,
|
|
4
|
-
CodeTokenType,
|
|
5
|
-
ParsableLanguage,
|
|
6
|
-
} from "../types/index";
|
|
7
|
-
|
|
8
|
-
export const isParsableLanguage = (lang: string): lang is ParsableLanguage => {
|
|
9
|
-
return parsableLanguages.includes(lang as ParsableLanguage);
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
const regexMap: Record<
|
|
13
|
-
ParsableLanguage,
|
|
14
|
-
{ type: CodeTokenType; regex: RegExp }[]
|
|
15
|
-
> = {
|
|
16
|
-
javascript: [
|
|
17
|
-
{ type: "comment", regex: /^\/\/.*/ },
|
|
18
|
-
{ type: "string", regex: /^(['"])(?:\\.|[^\\])*?\1/ },
|
|
19
|
-
{ type: "number", regex: /^\d+(\.\d+)?/ },
|
|
20
|
-
{
|
|
21
|
-
type: "keyword1",
|
|
22
|
-
regex:
|
|
23
|
-
/^(?:const|let|var|function|class|interface|type|enum|extends|implements|new|this|super)\b/,
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
type: "keyword2",
|
|
27
|
-
regex:
|
|
28
|
-
/^(?:return|import|from|for|while|as|await|async|export|if|else|switch|case|break|continue)\b/,
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
type: "type",
|
|
32
|
-
regex: /^(?:string|number|boolean|void|any|unknown|never|Record|Array)\b/,
|
|
33
|
-
},
|
|
34
|
-
{ type: "operator", regex: /^(===|!==|==|!=|<=|>=|=>|<|>|\+|-|\*|\/|=)/ },
|
|
35
|
-
{ type: "constant", regex: /^[A-Z_][A-Z0-9_]*/ },
|
|
36
|
-
{ type: "variable", regex: /^[a-zA-Z_$][a-zA-Z0-9_$]*/ },
|
|
37
|
-
{ type: "default", regex: /^[:;,.?]/ },
|
|
38
|
-
],
|
|
39
|
-
};
|
|
40
|
-
// 解析單行 CodeTokenProps
|
|
41
|
-
const _parseTokenLine = (
|
|
42
|
-
line: string,
|
|
43
|
-
lang: ParsableLanguage
|
|
44
|
-
): CodeTokenProps<"span">[] => {
|
|
45
|
-
if (!isParsableLanguage(lang)) return [];
|
|
46
|
-
|
|
47
|
-
const result: CodeTokenProps<"span">[] = [];
|
|
48
|
-
let remaining = line;
|
|
49
|
-
let bracketDepth = 0;
|
|
50
|
-
|
|
51
|
-
const bracketLevels = { "(": 1, "{": 1, "[": 1, ")": -1, "}": -1, "]": -1 };
|
|
52
|
-
const bracketRegex = /^[\[\]{}()]/;
|
|
53
|
-
const rules = regexMap[lang];
|
|
54
|
-
|
|
55
|
-
outer: while (remaining.length > 0) {
|
|
56
|
-
const whitespaceMatch = remaining.match(/^\s+/);
|
|
57
|
-
if (whitespaceMatch) {
|
|
58
|
-
result.push({ type: "default", children: whitespaceMatch[0] });
|
|
59
|
-
remaining = remaining.slice(whitespaceMatch[0].length);
|
|
60
|
-
continue outer;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// 括號處理(根據深度標記 brackets1 / 2 / 3)
|
|
64
|
-
const bracketMatch = remaining.match(bracketRegex);
|
|
65
|
-
if (bracketMatch) {
|
|
66
|
-
const bracket = bracketMatch[0];
|
|
67
|
-
bracketDepth += bracketLevels[bracket as keyof typeof bracketLevels] || 0;
|
|
68
|
-
const depth = Math.max(1, Math.min(3, Math.abs(bracketDepth)));
|
|
69
|
-
result.push({
|
|
70
|
-
type: `brackets${depth}` as CodeTokenType,
|
|
71
|
-
children: bracket,
|
|
72
|
-
});
|
|
73
|
-
remaining = remaining.slice(1);
|
|
74
|
-
continue outer;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// 用 regexMap 中的每個語法規則嘗試匹配
|
|
78
|
-
for (const { type, regex } of rules) {
|
|
79
|
-
const match = remaining.match(regex);
|
|
80
|
-
if (match) {
|
|
81
|
-
result.push({ type, children: match[0] });
|
|
82
|
-
remaining = remaining.slice(match[0].length);
|
|
83
|
-
continue outer;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// 如果沒有任何規則匹配,就當作 default 一個字元
|
|
88
|
-
result.push({ type: "default", children: remaining[0] });
|
|
89
|
-
remaining = remaining.slice(1);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return result;
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
const parseTokenLines = new Proxy(
|
|
96
|
-
{},
|
|
97
|
-
{
|
|
98
|
-
get:
|
|
99
|
-
(_, prop: ParsableLanguage) =>
|
|
100
|
-
(content: string): CodeTokenProps<"span">[][] =>
|
|
101
|
-
content.split("\n").map((line) => _parseTokenLine(line, prop)),
|
|
102
|
-
}
|
|
103
|
-
) as Record<ParsableLanguage, (content: string) => CodeTokenProps<"span">[][]>;
|