1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//! Canonical token emission and byte-budget handling.
use ;
/// Upper bound on an emitted token, in bytes.
pub const MAX_TOKEN_BYTES: usize = 64;
/// Sends the assembled token, truncated to [`MAX_TOKEN_BYTES`] at a char
/// boundary. Unicode marks and word joiners are meaningful only after a
/// lexical base, so leading marks and joiners are removed without allocating.
/// Keeping either would make re-tokenization context-sensitive (for example,
/// `\u{300}word` → `word`, `_word` → `word`, and `word.` → `word`). A mark-only
/// token is retained when it has Unicode Alphabetic semantics; this keeps
/// valid standalone script marks such as U+0F71 searchable. Empty and
/// non-lexical tokens are guarded against rather than asserted.
pub
/// Removes Unicode marks that precede a lexical base without allocating.
///
/// A leading mark can be attached to a preceding segment by UAX #29, while
/// retokenizing the emitted string sees it as a standalone prefix. Removing
/// that prefix makes emission independent of the surrounding input. A token
/// made entirely of a Unicode-alphabetic mark is kept because it
/// is a valid standalone token for scripts that use such marks as letters.
/// Removes any sequence of leading marks and word joiners. The loop matters
/// for inputs such as `'.' + U+0300 + 'o'`: removing the joiner exposes a
/// leading mark that must be removed in the next pass.