#org-mode #parser #emacs

orgize

一个用于解析 org-mode 文件的 Rust 库

29 个版本

0.10.0-alpha.102024年6月11日
0.10.0-alpha.82024年4月24日
0.10.0-alpha.72024年1月9日
0.10.0-alpha.62023年12月5日
0.1.3 2019年2月8日

#123 in 解析器实现

Download history 56/week @ 2024-04-29 117/week @ 2024-05-06 48/week @ 2024-05-13 54/week @ 2024-05-20 65/week @ 2024-05-27 57/week @ 2024-06-03 139/week @ 2024-06-10 65/week @ 2024-06-17 50/week @ 2024-06-24 29/week @ 2024-07-01 33/week @ 2024-07-08 47/week @ 2024-07-15 40/week @ 2024-07-22 349/week @ 2024-07-29 41/week @ 2024-08-05 48/week @ 2024-08-12

484 每月下载
用于 3 crates

MIT 许可证

430KB
11K SLoC

Orgize

Crates.io Documentation Build status MIT licensed

一个用于解析 org-mode 文件的 Rust 库。

在线演示: https://poiscript.github.io/orgize/

解析

要解析 org-mode 字符串,只需调用 Org::parse 函数

use orgize::{Org, rowan::ast::AstNode};

let org = Org::parse("* DONE Title :tag:");
assert_eq!(
    format!("{:#?}", org.document().syntax()),
    r#"[email protected]
  [email protected]
    [email protected] "*"
    [email protected] " "
    [email protected] "DONE"
    [email protected] " "
    [email protected]
      [email protected] "Title "
    [email protected]
      [email protected] ":"
      [email protected] "tag"
      [email protected] ":"
"#);

使用 ParseConfig::parse 指定自定义解析配置

use orgize::{Org, ParseConfig, ast::Headline};

let config = ParseConfig {
    // custom todo keywords
    todo_keywords: (vec!["TASK".to_string()], vec![]),
    ..Default::default()
};
let org = config.parse("* TASK Title 1");
let hdl = org.first_node::<Headline>().unwrap();
assert_eq!(hdl.todo_keyword().unwrap(), "TASK");

遍历

使用 org.traverse(&mut traversal) 遍历语法树。

use orgize::{
    export::{from_fn, Container, Event},
    Org,
};

let mut hdl_count = 0;
let mut handler = from_fn(|event| {
    if matches!(event, Event::Enter(Container::Headline(_))) {
        hdl_count += 1;
    }
});
Org::parse("* 1\n** 2\n*** 3\n****4").traverse(&mut handler);
assert_eq!(hdl_count, 3);

修改

使用 org.replace_range(TextRange::new(start, end), "new_text") 修改语法树

use orgize::{Org, ParseConfig, ast::Headline, TextRange};

let mut org = Org::parse("hello\n* world");

let hdl = org.first_node::<Headline>().unwrap();
org.replace_range(hdl.text_range(), "** WORLD!");

let hdl = org.first_node::<Headline>().unwrap();
assert_eq!(hdl.level(), 2);

org.replace_range(TextRange::up_to(hdl.start()), "");
assert_eq!(org.to_org(), "** WORLD!");

渲染为 html

调用 Org::to_html 函数将 org 元素树导出为 html

use orgize::Org;

assert_eq!(
    Org::parse("* title\n*section*").to_html(),
    "<main><h1>title</h1><section><p><b>section</b></p></section></main>"
);

查看 examples/html-slugify.rs 了解如何自定义 html 导出过程。

特性

  • chrono:添加了将 Timestamp 转换为 chrono::NaiveDateTime 的功能,默认禁用。

  • indexmap:添加了将 PropertyDrawer 属性转换为 IndexMap 的功能,默认禁用。

API 兼容性

element.syntax() 提供了对内部语法树的访问,以及一些 rowan 最低级别 API。这对于复杂任务可能很有用。

然而,内部语法树的结构可能会在不同版本的库之间发生变化。因此,element.syntax() 的结果不遵循语义版本控制,这意味着如果您的代码依赖于此方法,更新可能会破坏您的代码。

依赖关系

~1.6–2.4MB
~40K SLoC