Skip to content

Commit 6c1ef20

Browse files
committed
feat: add syntax highlighting with Prism.js integration
- Add syntaxHighlight utility with Prism.js for code highlighting - Update CodeDebugger component to use new syntax highlighting - Fix CSS module scoping for Prism token classes using :global - Add property-based tests for syntax highlighting - Add syntax-highlighting spec documentation
1 parent a8ddcb0 commit 6c1ef20

File tree

8 files changed

+931
-63
lines changed

8 files changed

+931
-63
lines changed
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# Design Document
2+
3+
## Overview
4+
5+
本设计文档描述了 Two Sum 可视化器中代码调试器组件的语法高亮功能实现。项目已使用 Prism.js 作为语法高亮引擎,但当前高亮效果可能未正确显示。本设计将确保 Java、Python、Go 和 JavaScript 四种语言都能正确显示语法高亮。
6+
7+
## Architecture
8+
9+
```mermaid
10+
graph TD
11+
A[CodeDebugger Component] --> B[Prism.js Highlighter]
12+
B --> C[Language Grammar]
13+
C --> D[Java Grammar]
14+
C --> E[Python Grammar]
15+
C --> F[Go Grammar]
16+
C --> G[JavaScript Grammar]
17+
B --> H[Token Stream]
18+
H --> I[HTML with Token Classes]
19+
I --> J[CSS Theme Styles]
20+
J --> K[Rendered Highlighted Code]
21+
```
22+
23+
### 核心流程
24+
25+
1. CodeDebugger 组件接收代码字符串和语言类型
26+
2. 调用 Prism.highlight() 方法解析代码
27+
3. Prism.js 根据语言语法生成带有 token 类名的 HTML
28+
4. CSS 样式根据 token 类名应用颜色
29+
30+
## Components and Interfaces
31+
32+
### 1. Prism.js 配置
33+
34+
```typescript
35+
// 语言导入
36+
import Prism from 'prismjs'
37+
import 'prismjs/components/prism-java'
38+
import 'prismjs/components/prism-python'
39+
import 'prismjs/components/prism-go'
40+
import 'prismjs/components/prism-javascript'
41+
42+
// 语言映射
43+
const PRISM_LANGUAGE_MAP: Record<CodeLanguage, string> = {
44+
java: 'java',
45+
python: 'python',
46+
golang: 'go',
47+
javascript: 'javascript',
48+
}
49+
```
50+
51+
### 2. 高亮函数接口
52+
53+
```typescript
54+
/**
55+
* 高亮单行代码
56+
* @param line - 代码行字符串
57+
* @param language - 编程语言
58+
* @returns 带有 token span 标签的 HTML 字符串
59+
*/
60+
function highlightLine(line: string, language: CodeLanguage): string
61+
```
62+
63+
### 3. Token 类型映射
64+
65+
| Token 类型 | 颜色 | 示例 |
66+
|-----------|------|------|
67+
| keyword | #569cd6 (蓝色) | public, def, func, const |
68+
| class-name | #4ec9b0 (青色) | Map, List, int |
69+
| string | #ce9178 (橙色) | "hello", 'world' |
70+
| number | #b5cea8 (浅绿) | 42, 3.14 |
71+
| function | #dcdcaa (黄色) | twoSum, enumerate |
72+
| comment | #6a9955 (绿色) | // comment |
73+
| punctuation | #d4d4d4 (灰白) | {, }, (, ) |
74+
| operator | #d4d4d4 (灰白) | =, +, - |
75+
76+
## Data Models
77+
78+
### CodeLanguage 类型
79+
80+
```typescript
81+
type CodeLanguage = 'java' | 'python' | 'golang' | 'javascript'
82+
```
83+
84+
### Token 结构 (Prism.js 内部)
85+
86+
```typescript
87+
interface PrismToken {
88+
type: string // token 类型,如 'keyword', 'string'
89+
content: string // token 内容
90+
alias?: string // 别名
91+
}
92+
```
93+
94+
## Correctness Properties
95+
96+
*A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.*
97+
98+
### Property 1: Keyword Token Classification
99+
100+
*For any* code string containing language keywords, when highlighted by Prism.js, the output HTML SHALL contain span elements with class "token keyword" wrapping those keywords.
101+
102+
**Validates: Requirements 1.1, 2.1, 3.1, 4.1**
103+
104+
### Property 2: Type/Class-name Token Classification
105+
106+
*For any* code string containing type names or class names, when highlighted by Prism.js, the output HTML SHALL contain span elements with class "token class-name" or "token builtin" wrapping those type names.
107+
108+
**Validates: Requirements 1.2, 2.2, 3.2, 4.2**
109+
110+
### Property 3: String Literal Token Classification
111+
112+
*For any* code string containing string literals, when highlighted by Prism.js, the output HTML SHALL contain span elements with class "token string" wrapping those string literals.
113+
114+
**Validates: Requirements 1.3, 2.3, 3.3, 4.3**
115+
116+
### Property 4: Number Literal Token Classification
117+
118+
*For any* code string containing numeric literals, when highlighted by Prism.js, the output HTML SHALL contain span elements with class "token number" wrapping those numbers.
119+
120+
**Validates: Requirements 1.4, 2.4, 3.4, 4.4**
121+
122+
### Property 5: Function Name Token Classification
123+
124+
*For any* code string containing function definitions or calls, when highlighted by Prism.js, the output HTML SHALL contain span elements with class "token function" wrapping those function names.
125+
126+
**Validates: Requirements 1.5, 2.5, 3.5, 4.5**
127+
128+
### Property 6: Cross-Language Token Consistency
129+
130+
*For any* equivalent token type across different languages, the CSS styling SHALL apply the same color to that token type regardless of the source language.
131+
132+
**Validates: Requirements 5.1**
133+
134+
## Error Handling
135+
136+
### Prism.js 解析失败
137+
138+
Prism.js 无法解析代码时,系统应优雅降级:
139+
140+
```typescript
141+
const highlightLine = (line: string): string => {
142+
if (!line.trim()) return '&nbsp;'
143+
try {
144+
const prismLang = PRISM_LANGUAGE_MAP[language]
145+
const grammar = Prism.languages[prismLang]
146+
if (grammar) {
147+
return Prism.highlight(line, grammar, prismLang)
148+
}
149+
return escapeHtml(line) // 降级为纯文本
150+
} catch {
151+
return escapeHtml(line) // 错误时降级为纯文本
152+
}
153+
}
154+
```
155+
156+
### 语言不支持
157+
158+
如果请求的语言语法未加载,返回未高亮的代码而不是抛出错误。
159+
160+
## Testing Strategy
161+
162+
### 单元测试
163+
164+
使用 Vitest 测试框架:
165+
166+
1. 测试 highlightLine 函数对各语言的基本高亮
167+
2. 测试错误处理(无效输入、未知语言)
168+
3. 测试空行和特殊字符处理
169+
170+
### 属性测试
171+
172+
使用 fast-check 库进行属性测试:
173+
174+
1. 验证关键字 token 分类的正确性
175+
2. 验证字符串 token 分类的正确性
176+
3. 验证数字 token 分类的正确性
177+
4. 验证跨语言 token 一致性
178+
179+
每个属性测试配置运行 100 次迭代。
180+
181+
测试文件命名:`*.property.test.ts`
182+
183+
测试注释格式:`**Feature: syntax-highlighting, Property {number}: {property_text}**`
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Requirements Document
2+
3+
## Introduction
4+
5+
本功能旨在为 Two Sum 可视化器的代码调试器组件实现完整的语法高亮支持。当前项目使用 Prism.js 作为语法高亮库,支持 Java、Python、Go 和 JavaScript 四种语言。需要确保每种语言都能正确显示语法高亮,包括关键字、字符串、数字、注释、函数名、类型等不同的代码元素。
6+
7+
## Glossary
8+
9+
- **Prism.js**: 一个轻量级、可扩展的语法高亮库
10+
- **Token**: Prism.js 解析代码后生成的语法单元,如关键字、字符串、注释等
11+
- **CodeDebugger**: 代码调试器组件,负责展示代码和执行状态
12+
- **语法高亮主题**: 定义不同 token 类型颜色的 CSS 样式集合
13+
- **CodeLanguage**: 支持的编程语言类型,包括 java、python、golang、javascript
14+
15+
## Requirements
16+
17+
### Requirement 1
18+
19+
**User Story:** As a developer, I want to see syntax highlighting for Java code, so that I can easily distinguish different code elements like keywords, types, and strings.
20+
21+
#### Acceptance Criteria
22+
23+
1. WHEN Java code is displayed in the CodeDebugger THEN the system SHALL highlight keywords (public, int, return, if, for, new) in blue color
24+
2. WHEN Java code is displayed in the CodeDebugger THEN the system SHALL highlight type names (Map, Integer, HashMap) in teal color
25+
3. WHEN Java code is displayed in the CodeDebugger THEN the system SHALL highlight string literals in orange color
26+
4. WHEN Java code is displayed in the CodeDebugger THEN the system SHALL highlight numeric literals in light green color
27+
5. WHEN Java code is displayed in the CodeDebugger THEN the system SHALL highlight method names in yellow color
28+
29+
### Requirement 2
30+
31+
**User Story:** As a developer, I want to see syntax highlighting for Python code, so that I can easily read and understand the algorithm implementation.
32+
33+
#### Acceptance Criteria
34+
35+
1. WHEN Python code is displayed in the CodeDebugger THEN the system SHALL highlight keywords (def, for, in, if, return) in blue color
36+
2. WHEN Python code is displayed in the CodeDebugger THEN the system SHALL highlight built-in functions and types (List, int, enumerate) in teal color
37+
3. WHEN Python code is displayed in the CodeDebugger THEN the system SHALL highlight string literals in orange color
38+
4. WHEN Python code is displayed in the CodeDebugger THEN the system SHALL highlight numeric literals in light green color
39+
5. WHEN Python code is displayed in the CodeDebugger THEN the system SHALL highlight function names in yellow color
40+
41+
### Requirement 3
42+
43+
**User Story:** As a developer, I want to see syntax highlighting for Go code, so that I can follow the algorithm logic with visual cues.
44+
45+
#### Acceptance Criteria
46+
47+
1. WHEN Go code is displayed in the CodeDebugger THEN the system SHALL highlight keywords (func, for, range, if, return, make) in blue color
48+
2. WHEN Go code is displayed in the CodeDebugger THEN the system SHALL highlight type names (int, map, bool) in teal color
49+
3. WHEN Go code is displayed in the CodeDebugger THEN the system SHALL highlight string literals in orange color
50+
4. WHEN Go code is displayed in the CodeDebugger THEN the system SHALL highlight numeric literals in light green color
51+
5. WHEN Go code is displayed in the CodeDebugger THEN the system SHALL highlight function names in yellow color
52+
53+
### Requirement 4
54+
55+
**User Story:** As a developer, I want to see syntax highlighting for JavaScript code, so that I can understand the code structure at a glance.
56+
57+
#### Acceptance Criteria
58+
59+
1. WHEN JavaScript code is displayed in the CodeDebugger THEN the system SHALL highlight keywords (function, const, let, for, if, return, new) in blue color
60+
2. WHEN JavaScript code is displayed in the CodeDebugger THEN the system SHALL highlight built-in objects (Map) in teal color
61+
3. WHEN JavaScript code is displayed in the CodeDebugger THEN the system SHALL highlight string literals in orange color
62+
4. WHEN JavaScript code is displayed in the CodeDebugger THEN the system SHALL highlight numeric literals in light green color
63+
5. WHEN JavaScript code is displayed in the CodeDebugger THEN the system SHALL highlight function names in yellow color
64+
65+
### Requirement 5
66+
67+
**User Story:** As a user, I want consistent syntax highlighting across all languages, so that switching between languages provides a familiar visual experience.
68+
69+
#### Acceptance Criteria
70+
71+
1. WHEN switching between languages THEN the system SHALL apply the same color scheme for equivalent token types (keywords, strings, numbers)
72+
2. WHEN code is highlighted THEN the system SHALL maintain readability with sufficient contrast against the dark background
73+
3. WHEN Prism.js fails to parse a line THEN the system SHALL display the code in default text color without breaking the UI
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Implementation Plan
2+
3+
- [x] 1. 验证并修复 Prism.js 配置
4+
- [x] 1.1 检查 Prism.js 语言组件是否正确加载
5+
- 验证 prism-java, prism-python, prism-go, prism-javascript 组件导入
6+
- 确认 Prism.languages 对象包含所有需要的语言语法
7+
- _Requirements: 1.1, 2.1, 3.1, 4.1_
8+
- [x] 1.2 创建语法高亮工具函数
9+
- 将高亮逻辑抽取为独立的工具函数 `src/utils/syntaxHighlight.ts`
10+
- 实现 `highlightCode(code: string, language: CodeLanguage): string` 函数
11+
- 添加错误处理和降级逻辑
12+
- _Requirements: 5.3_
13+
- [x] 1.3 编写属性测试:关键字 Token 分类
14+
- **Property 1: Keyword Token Classification**
15+
- **Validates: Requirements 1.1, 2.1, 3.1, 4.1**
16+
- [x] 1.4 编写属性测试:字符串 Token 分类
17+
- **Property 3: String Literal Token Classification**
18+
- **Validates: Requirements 1.3, 2.3, 3.3, 4.3**
19+
- [x] 1.5 编写属性测试:数字 Token 分类
20+
- **Property 4: Number Literal Token Classification**
21+
- **Validates: Requirements 1.4, 2.4, 3.4, 4.4**
22+
23+
- [x] 2. 完善 CSS 语法高亮主题
24+
- [x] 2.1 审查并更新 Prism token CSS 样式
25+
- 确保所有 token 类型都有对应的颜色定义
26+
- 验证 :global() 选择器正确应用于 CSS Modules
27+
- 添加缺失的 token 类型样式
28+
- _Requirements: 1.1-1.5, 2.1-2.5, 3.1-3.5, 4.1-4.5_
29+
- [x] 2.2 编写属性测试:跨语言 Token 一致性
30+
- **Property 6: Cross-Language Token Consistency**
31+
- **Validates: Requirements 5.1**
32+
33+
- [x] 3. 更新 CodeDebugger 组件
34+
- [x] 3.1 重构 CodeDebugger 使用新的高亮工具函数
35+
- 导入并使用 `highlightCode` 函数
36+
- 移除组件内的重复高亮逻辑
37+
- _Requirements: 1.1-1.5, 2.1-2.5, 3.1-3.5, 4.1-4.5_
38+
- [x] 3.2 编写属性测试:类型/类名 Token 分类
39+
- **Property 2: Type/Class-name Token Classification**
40+
- **Validates: Requirements 1.2, 2.2, 3.2, 4.2**
41+
- [x] 3.3 编写属性测试:函数名 Token 分类
42+
- **Property 5: Function Name Token Classification**
43+
- **Validates: Requirements 1.5, 2.5, 3.5, 4.5**
44+
45+
- [x] 4. Checkpoint - 确保所有测试通过
46+
- Ensure all tests pass, ask the user if questions arise.

public/video.mp4

44.3 MB
Binary file not shown.

0 commit comments

Comments
 (0)