Orgize
一个用于解析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#"DOCUMENT@0..18
HEADLINE@0..18
HEADLINE_STARS@0..1 "*"
WHITESPACE@1..2 " "
HEADLINE_KEYWORD_DONE@2..6 "DONE"
WHITESPACE@6..7 " "
HEADLINE_TITLE@7..13
TEXT@7..13 "Title "
HEADLINE_TAGS@13..18
COLON@13..14 ":"
TEXT@14..17 "tag"
COLON@17..18 ":"
"#);
使用ParseConfig::parse
来指定自定义解析配置
use orgize::{Org, ParseConfig, ast::Headline};
let config = ParseConfig {
// 自定义待办关键词
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()
的结果不遵循语义版本控制,这意味着如果你的代码依赖于这个方法,更新可能会破坏你的代码。