Skip to content

Commit 5046a57

Browse files
authored
Merge pull request #165 from zhlint-project/fix-marker-emoji-halfwidth
fix: improve generateMarker for emoji and halfwidth punctuation, add …
2 parents c2f791d + 79a84b2 commit 5046a57

File tree

2 files changed

+50
-8
lines changed

2 files changed

+50
-8
lines changed

src/report.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,30 +75,42 @@ export type Validation = {
7575

7676
const adjustedFullwidthPunctuations = `“”‘’`
7777

78-
const generateMarker = (str: string, index: number): string => {
79-
const prefix = str.substring(0, index)
78+
export const generateMarker = (str: string, index: number): string => {
79+
const prefix = Array.from(str).slice(0, index)
8080
let fullwidthCount = 0
8181
let halfwidthCount = 0
82-
for (let i = 0; i < prefix.length; i++) {
83-
const charType = checkCharType(prefix[i])
82+
let emojiWidthCount = 0
83+
const EMOJI_PLACEHOLDER = '\u2B1C' // ⬜
84+
const FULLWIDTH_SPACE = '\u3000' // 全角空格
85+
function isEmoji(char: string): boolean {
86+
const cp = char.codePointAt(0)
87+
return cp !== undefined && cp >= 0x1F600 && cp <= 0x1F64F
88+
}
89+
for (const char of prefix) {
90+
if (isEmoji(char)) {
91+
emojiWidthCount++
92+
continue
93+
}
94+
const charType = checkCharType(char)
8495
if (
8596
charType === CharType.CJK_CHAR ||
8697
(isFullwidthPunctuationType(charType) &&
87-
adjustedFullwidthPunctuations.indexOf(prefix[i]) === -1)
98+
adjustedFullwidthPunctuations.indexOf(char) === -1)
8899
) {
89100
fullwidthCount++
90101
} else if (
91102
charType === CharType.WESTERN_LETTER ||
92-
(isHalfwidthPunctuationType(charType) &&
93-
adjustedFullwidthPunctuations.indexOf(prefix[i]) !== -1) ||
103+
isHalfwidthPunctuationType(charType) ||
104+
adjustedFullwidthPunctuations.indexOf(char) !== -1 ||
94105
charType === CharType.SPACE
95106
) {
96107
halfwidthCount++
97108
}
98109
}
99110
return (
100111
' '.repeat(halfwidthCount) +
101-
' '.repeat(fullwidthCount) +
112+
FULLWIDTH_SPACE.repeat(fullwidthCount) +
113+
EMOJI_PLACEHOLDER.repeat(emojiWidthCount) +
102114
`${chalk.red('^')}`
103115
)
104116
}

test/report.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { describe, test, expect } from 'vitest'
2+
import { generateMarker } from '../src/report.js'
3+
import chalk from 'chalk'
4+
5+
const EMOJI_PLACEHOLDER = String.fromCharCode(0x2B1C) // ⬜
6+
const FULLWIDTH_SPACE = String.fromCharCode(0x3000) // 全角空格
7+
8+
describe('generateMarker', () => {
9+
test('纯英文', () => {
10+
expect(generateMarker('hello world', 6)).toBe(' ' + chalk.red('^'))
11+
})
12+
test('中英文混排', () => {
13+
expect(generateMarker('你a好', 2)).toBe(' ' + FULLWIDTH_SPACE + chalk.red('^'))
14+
})
15+
test('全角标点', () => {
16+
expect(generateMarker('你好,世界', 3)).toBe(FULLWIDTH_SPACE + FULLWIDTH_SPACE + FULLWIDTH_SPACE + chalk.red('^'))
17+
})
18+
test('半角标点', () => {
19+
expect(generateMarker('hello, world', 6)).toBe(' ' + chalk.red('^'))
20+
})
21+
test('空格', () => {
22+
expect(generateMarker('a b', 2)).toBe(' ' + chalk.red('^'))
23+
})
24+
// test('Tab', () => {
25+
// expect(generateMarker('a\tb', 2)).toBe(' ' + chalk.red('^')) // 暂时不需要测试 Tab
26+
// })
27+
test('emoji', () => {
28+
expect(generateMarker('a😀b', 2)).toBe(' ' + EMOJI_PLACEHOLDER + chalk.red('^'))
29+
})
30+
})

0 commit comments

Comments
 (0)