Tweep is a parser for the Twee 3 interactive fiction format
Twee is "a text format for marking up the source code of Twine stories." It is an alternate way to produce interactive fiction stories for the [Twine 2] platform, using plain text files instead of a graphical environment. The specification for Twee 3, supported by tweep, can be found [here]
The goal of tweep is to provide a fully standards-compliant Twee 3 parser that provides helpful warning and error messages for bad practices and common mistakes, which can be used as a backend for a compiler as well as other novel applications of the Twee 3 format.
To use tweep in your Rust project, simply add the following to your Cargo.toml:
toml
[dependencies]
tweep = "0.2"
For basic parsing, the main entry point into tweep is through the [Story
]
struct, which provides utility methods for parsing out a complete story from
a String
or a Path
representing a file or directory. When given a
directory, tweep will parse all files ending in .tw
or .twee
and merge
them into a single output story. For more advanced parsing, such as if the
tags or metadata attached to a special passage is needed, [StoryPassages
]
provides the same interface, but provides [Passage
] objects in places
where usually unnecessary information is stripped out.
```rust 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
// Move the Result out of the Output let (res, ) = out.take(); assert!(res.isok());
// Get the Story object let story = res.ok().unwrap();
// StoryTitle and StoryData contents are parsed into special fields asserteq!(story.title.unwrap(), "RustDoc Sample Story"); asserteq!(story.data.unwrap().ifid, "D674C58C-DEFA-4F70-B7A2-27742230C0FC");
// Other passages are parsed into a map, keyed by the passage name asserteq!(story.passages["My Starting Passage"].tags(), &vec!["tag1", "tag2"]); let metadata = story.passages["A third passage"].metadata(); asserteq!(metadata["size"], "100,100"); assert_eq!(metadata["position"], "400,600"); ```
License: MIT