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 解析器实现

MIT 许可协议

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