#cluster #grapheme #nom #unicode #string #spans #character

nom-grapheme-clusters

允许nom处理Unicode字符簇的适配器

9个版本 (4个重大更新)

0.5.2 2023年9月29日
0.5.1 2023年9月24日
0.5.0 2023年5月21日
0.4.1 2023年5月20日
0.1.0 2022年12月22日

#266文本处理

每月下载量35

自定义许可

105KB
3K SLoC

nom-grapheme-clusters

一个库,为字符串添加了对nom的支持,使得

  1. 这种字符串的"元素"是一个字符簇/片段,而不是字节或UTF-8字符。字符簇是一系列字符,它们被显示为人类感觉应该是一个字符的样子。例如,"m̤̊"是一个单独的字符簇,但不是一个单独的字符,尽管它看起来像一个单独书写的字符。

  2. 字符簇在输入字符串(即"源代码")中的位置是通过它们的绝对位置、行和列来追踪的。这三个数据都是以字符簇为单位计算的。例如,在字符串"m̤̊ef"中,字符簇"e"位于位置1,行0和列1(所有这些都从0开始),因为"m̤̊"被视为一个单独的事物。

主分支文档

https://brunoczim.github.io/nom-grapheme-clusters/nom_grapheme_clusters/

示例

use nom_grapheme_clusters::{Source, Span, SpanContent, tag_table};
use nom::{IResult, bytes::complete::tag, combinator::map};

#[derive(Debug, Clone)]
struct Tags {
    smth: Span,
    atn: Span,
}

#[derive(Debug, Clone, PartialEq, Eq)]
struct ParsedAtn {
    span: Span,
}

#[derive(Debug, Clone, PartialEq, Eq)]
struct ParsedSmth {
    span: Span,
}

fn parse_smth<'a>(
    tags: &'a Tags
) -> impl FnMut(Span) -> IResult<Span, ParsedAtn> + 'a {
    map(tag(&tags.smth), |span| ParsedAtn { span })
}

fn parse_atn<'a>(
    tags: &'a Tags
) -> impl FnMut(Span) -> IResult<Span, ParsedAtn> + 'a {
    map(tag(&tags.atn), |span| ParsedAtn { span })
}

fn main() {
    let tags = tag_table! {
        Tags {
            smth: "smth",
            atn: "atn̩̊",
        }
    };
    let source = Source::new("file.txt", "atn̩̊smtha");
   
    let span0 = source.full_span();
    let (span1, parsed) = parse_atn(&tags)(span0).unwrap();
    assert_eq!(parsed.span.as_str(), "atn̩̊");
    assert_eq!(parsed.span.start().position(), 0);
    assert_eq!(parsed.span.start().line(), 0);
    assert_eq!(parsed.span.start().column(), 0);
    assert_eq!(parsed.span.len(), 3);
    assert_eq!(parsed.span.end().position(), 3);
    assert_eq!(parsed.span.end().line(), 0);
    assert_eq!(parsed.span.end().column(), 3);
   
    let (span2, parsed) = parse_smth(&tags)(span1).unwrap();
    assert_eq!(parsed.span.as_str(), "smth");
    assert_eq!(parsed.span.start().position(), 3);
    assert_eq!(parsed.span.start().line(), 0);
    assert_eq!(parsed.span.start().column(), 3);
    assert_eq!(parsed.span.len(), 4);
    assert_eq!(parsed.span.end().position(), 7);
    assert_eq!(parsed.span.end().line(), 0);
    assert_eq!(parsed.span.end().column(), 7);
   
    let result = parse_atn(&tags)(span2);
    assert!(result.is_err());
    println!("{}", result.unwrap_err());
}

依赖项

~490–760KB
~12K SLoC