Skip to main content

docvortex_core/
text_projection.rs

1//! 文字投影只处理自有 Unicode 标量和源位置;分类与连字映射继续由 Python 提供。
2
3/// 扫描原始字符串的 Unicode 索引,跳过首个匹配闭合标记内的圆括号公式。
4pub fn visible_tokens(content: &str) -> Vec<(usize, char, bool)> {
5    let chars: Vec<_> = content.chars().collect();
6    let mut cursor = 0;
7    let mut gap = false;
8    let mut tokens = Vec::new();
9    while cursor < chars.len() {
10        if chars[cursor] == '\\' && chars.get(cursor + 1) == Some(&'(') {
11            if let Some(end) = (cursor + 2..chars.len().saturating_sub(1))
12                .find(|&i| chars[i] == '\\' && chars[i + 1] == ')')
13            {
14                cursor = end + 2;
15                gap = true;
16                continue;
17            }
18        }
19        tokens.push((cursor, chars[cursor], gap));
20        gap = false;
21        cursor += 1;
22    }
23    tokens
24}
25
26/// 空白或零宽字符不消费公式间隙;连字展开后的第一字符保留该间隙。
27pub fn project_tokens(
28    tokens: &[(usize, char, bool)],
29    forms: &std::collections::HashMap<char, String>,
30) -> Vec<(char, usize, usize, bool)> {
31    let mut pending = false;
32    let mut output = Vec::new();
33    for &(position, original, gap) in tokens {
34        pending |= gap;
35        let fragment = &forms[&original];
36        for (i, value) in fragment.chars().enumerate() {
37            output.push((value, position, position + 1, pending && i == 0));
38        }
39        if !fragment.is_empty() {
40            pending = false;
41        }
42    }
43    output
44}