8 个版本
0.3.0 | 2020年5月30日 |
---|---|
0.2.5 | 2020年5月8日 |
0.2.1 | 2020年4月30日 |
0.1.0 | 2020年4月28日 |
#1200 in 解析器实现
170KB
3.5K SLoC
tweep
Tweep 是用于 Twee 3 交互式小说格式的解析器
什么是 Twee?
Twee 是“用于标记 Twine 故事源代码的文本格式。”它是一种为 Twine 2 平台产生交互式小说故事的替代方式,使用纯文本文件而不是图形环境。Tweep 支持的 Twee 3 规范可以在这里找到 此处
目标
tweep 的目标是提供一个完全符合标准的 Twee 3 解析器,为不良实践和常见错误提供有用的警告和错误消息,它可以作为一个编译器的后端,也可以用于 Twee 3 格式的其他创新应用。
它不是什么
- 一个编译器 - 虽然正在开发相应的编译器前端,但这不是它。tweep 只产生 Rust 对象,不产生 HTML
- Twee v1 或 v2 解析器 - 目前没有计划支持 Twee 规范的任何版本,除了 Twee 3
开始使用
要在 Rust 项目中使用 tweep,只需将以下内容添加到您的 Cargo.toml 文件中
[dependencies]
tweep = "0.2"
对于基本解析,tweep 的主要入口点是 Story
结构体,它提供从 String
或表示文件或目录的 Path
中解析完整故事的实用方法。当提供一个目录时,tweep 将解析所有以 .tw
或 .twee
结尾的文件,并将它们合并成一个输出故事。对于更高级的解析,例如需要特殊段落附加的标签或元数据,StoryPassages
提供相同的接口,但在通常不需要信息的地方提供了 Passage
对象。
示例
use tweep::Story;
let input = r#":: StoryTitle
RustDoc Sample Story
:: StoryData
{
"ifid": "D674C58C-DEFA-4F70-B7A2-27742230C0FC",
"format": "SugarCube",
"format-version": "2.28.2",
"start": "My Starting Passage",
"tag-colors": {
"tag1": "green",
"tag2": "red",
"tag3": "blue"
},
"zoom": 0.25
}
:: My Starting Passage [ tag1 tag2 ]
This is the starting passage, specified by the start attribute of StoryData.
Alternately, we could remove that attribute and rename the passage to Start.
It has tags and links to:
[[Another passage]]
[[Here too!|Another passage]]
[[A third passage<-And a different passage]]
:: Another passage {"position":"600,400","size":"100,200"}
This passage has some metadata attached to it
:: A third passage [tag3] { "position": "400,600" }
This passage has both tags and metadata. The size attribute of the metadata
isn't overridden, so it will be set to the default value.
"#.to_string();
// Parse the input into an Output<Result<Story, ErrorList>>
let out = Story::from_string(input);
assert!(!out.has_warnings());
// Move the Result out of the Output
let (res, _) = out.take();
assert!(res.is_ok());
// Get the Story object
let story = res.ok().unwrap();
// StoryTitle and StoryData contents are parsed into special fields
assert_eq!(story.title.unwrap(), "RustDoc Sample Story");
assert_eq!(story.data.unwrap().ifid, "D674C58C-DEFA-4F70-B7A2-27742230C0FC");
// Other passages are parsed into a map, keyed by the passage name
assert_eq!(story.passages["My Starting Passage"].tags(), &vec!["tag1", "tag2"]);
let metadata = story.passages["A third passage"].metadata();
assert_eq!(metadata["size"], "100,100");
assert_eq!(metadata["position"], "400,600");
许可证:MIT
依赖关系
~0.7–1.4MB
~33K SLoC