Skip to content

Commit f99c1ca

Browse files
committed
fix: 修复 ANSI 256 渲染失败的问题
1 parent 096f8a9 commit f99c1ca

1 file changed

Lines changed: 61 additions & 0 deletions

File tree

src/apps/logger.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,56 @@ const LOG_LEVEL_COLOR_CODE: Record<string, string> = {
4646
MARK: '\x1b[90m', // 灰色
4747
}
4848

49+
/**
50+
* 将 ANSI 256 色索引转换为 RGB 字符串
51+
* 兼容 xterm 256 色标准:
52+
* - 0-15: 基本/高亮颜色
53+
* - 16-231: 6x6x6 色彩立方体
54+
* - 232-255: 灰度
55+
*/
56+
const ansi256ToRgb = (idx: number): string | null => {
57+
if (idx < 0 || idx > 255 || Number.isNaN(idx)) return null
58+
59+
// 0-15 映射到基础前景色,尽量与 ANSI_COLOR_MAP 保持接近
60+
const basicPalette: string[] = [
61+
'#020617', // 0: black
62+
'#ef4444', // 1: red
63+
'#22c55e', // 2: green
64+
'#eab308', // 3: yellow
65+
'#3b82f6', // 4: blue
66+
'#ec4899', // 5: magenta
67+
'#06b6d4', // 6: cyan
68+
'#e5e7eb', // 7: white (light gray)
69+
'#6b7280', // 8: bright black (gray)
70+
'#f97373', // 9: bright red
71+
'#4ade80', // 10: bright green
72+
'#fde047', // 11: bright yellow
73+
'#60a5fa', // 12: bright blue
74+
'#a855f7', // 13: bright magenta
75+
'#38bdf8', // 14: bright cyan
76+
'#f9fafb', // 15: bright white
77+
]
78+
79+
if (idx <= 15) {
80+
return basicPalette[idx]
81+
}
82+
83+
// 16-231: 6x6x6 色彩立方体
84+
if (idx >= 16 && idx <= 231) {
85+
const n = idx - 16
86+
const r = Math.floor(n / 36)
87+
const g = Math.floor((n % 36) / 6)
88+
const b = n % 6
89+
90+
const conv = (c: number) => (c === 0 ? 0 : 55 + c * 40)
91+
return `rgb(${conv(r)}, ${conv(g)}, ${conv(b)})`
92+
}
93+
94+
// 232-255: 灰度
95+
const gray = 8 + (idx - 232) * 10
96+
return `rgb(${gray}, ${gray}, ${gray})`
97+
}
98+
4999
/**
50100
* 将 ANSI 颜色码转换为带样式的 HTML 片段
51101
*/
@@ -85,6 +135,17 @@ const ansiToHtml = (text: string): string => {
85135
return ''
86136
}
87137

138+
// 256 色: 38;5;n
139+
if (codes[0] === 38 && codes[1] === 5 && codes.length >= 3) {
140+
const idx = codes[2]
141+
const rgb = ansi256ToRgb(idx)
142+
if (rgb) {
143+
openSpan = `color: ${rgb}`
144+
result += `<span style="${openSpan}">`
145+
}
146+
return ''
147+
}
148+
88149
// 重置 (0) 或 默认前景色 (39)
89150
// 仅当它们是唯一的代码时才视为重置,避免误伤 24bit 颜色中的 0 分量
90151
if (codes.length === 1 && (codes[0] === 0 || codes[0] === 39)) {

0 commit comments

Comments
 (0)