Inspiration
I was inspired by the CWEB literate-programming system written by Donald Knuth and Silvio Levy. This program would take a specially formatted text file, and produce typeset TeX documentation with one command (CWEAVE) and C code with another (CTANGLE). I've attempted to write something similar to CTANGLE, but working with Markdown and Rust, rather than TeX and C.
What it does
This program takes a Markdown file, extracts Rust code snippets, and stitches them together into Rust source files using a simple templating language. Take the following example:
// <<*>>=
fn main() {
// <<print hello>>
}
// <<print hello>>=
println!("Hello, World!");
Given this Markdown document as input, the program would process the code snippets. The comments that look like <<this>> are macros that will be expanded into source code defined in the snippet beginning with <<this>>=. In the example above, the program begins with the root snippet defined by <<*>>=, and the <<print hello>> macro is expanded to the code in the snippet defined in the block beginning with <<print hello>>=. Once the program has completed, it will have written a Rust file that looks like the following:
fn main() {
println!("Hello, World")!
}
Macros can be nested.
How we built it
This program was written in Rust. The Markdown files are found in the filesystem using glob and parsed using pulldown-cmark. The text searches and expansions are performed using regex, and the dependency graph is built using petgraph.
Challenges we ran into
If macros are included in a cyclical manner, the program would loop infinitely. To combat this, I created a dependency graph that kept track of macro inclusions and checked to see if any cycles formed. If a cycle is found, the program throws an error.
Accomplishments that we're proud of
I only started learning Rust at the beginning of the semester, so it's nice that I was able to complete a project like this.
What's next for cargo-tangle
I'd like check that the source code in each macro definition is valid before tangling it into a source code file. Some extra error handling would also be nice.
Built With
- cargo
- rust
Log in or sign up for Devpost to join the conversation.