@@ -75,30 +75,42 @@ export type Validation = {
75
75
76
76
const adjustedFullwidthPunctuations = `“”‘’`
77
77
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 )
80
80
let fullwidthCount = 0
81
81
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 )
84
95
if (
85
96
charType === CharType . CJK_CHAR ||
86
97
( isFullwidthPunctuationType ( charType ) &&
87
- adjustedFullwidthPunctuations . indexOf ( prefix [ i ] ) === - 1 )
98
+ adjustedFullwidthPunctuations . indexOf ( char ) === - 1 )
88
99
) {
89
100
fullwidthCount ++
90
101
} else if (
91
102
charType === CharType . WESTERN_LETTER ||
92
- ( isHalfwidthPunctuationType ( charType ) &&
93
- adjustedFullwidthPunctuations . indexOf ( prefix [ i ] ) !== - 1 ) ||
103
+ isHalfwidthPunctuationType ( charType ) ||
104
+ adjustedFullwidthPunctuations . indexOf ( char ) !== - 1 ||
94
105
charType === CharType . SPACE
95
106
) {
96
107
halfwidthCount ++
97
108
}
98
109
}
99
110
return (
100
111
' ' . repeat ( halfwidthCount ) +
101
- ' ' . repeat ( fullwidthCount ) +
112
+ FULLWIDTH_SPACE . repeat ( fullwidthCount ) +
113
+ EMOJI_PLACEHOLDER . repeat ( emojiWidthCount ) +
102
114
`${ chalk . red ( '^' ) } `
103
115
)
104
116
}
0 commit comments