tango: dancing around literate programming@pnkfelix), Mozillatango: dancing around literate programming
tango?tango:I have been using for tutorial presentations:
(meta: written with tango; see http://bit.ly/2618VSS)
http://pnkfelix.github.io/presentations/
reveal.js + pandoc, not tangopandoc crate; "just" shells out to pandoc. (Sorry.)(meta: written with tango; see http://bit.ly/2618VSS)
http://pnkfelix.github.io/presentations/
```rust
pub fn main() { println!("Hello post `tango`"); }
```
* What is Literate Programming (LP)?
* What is `tango`'s approach to LP?
% cargo run
Compiling tango-demo v0.1.0 (file:///Users/fklock/Dev/Rust/tango-demo)
Running `target/debug/main`
Hello post `tango`
(cargo build script pushes tango onto dance floor.)
```rust
pub fn main() { println!("Hello post `tango`"); }
```
* What is Literate Programming (LP)?
* What is `tango`'s approach to LP?
pub fn main() { println!("Hello post `tango`"); }
//@ * What is Literate Programming (LP)?
//@
//@ * What is `tango`'s approach to LP?```rust
pub fn main() { println!("Hello post `tango`"); }
```
* What is Literate Programming (LP)?
* What is `tango`'s approach to LP?
pub fn main() { println!("Hello post `tango`"); }What is Literate Programming (LP)?
What is tango's approach to LP?
This is Hello World
pub fn hello_world() {println! is a macro. It prints things.
println!("Hello World");Close curly } ends the scope.
}That's all folks!
Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do.
-- Donald Knuth, 1983
http://www.literateprogramming.com/knuthweb.pdf
(Examples include TeX, Metafont, SGB.)
Programmer edits .web; utils create intermediate source
(WEB tangle output "write-only"; IMO weave is too)
Architecture motivated (in part) by language limitations
tango is neither tangle nor weave!
Edit either; tango regenerates the other
One should cargo build before switch between .rs/.md
But: editing both first will not destroy work!
cargoCargo.toml:
build = "tango-build.rs"
[build-dependencies]
tango = "0.5.0"
tango-build.rs:
extern crate tango;
fn main() { tango::process_root().unwrap() }tango'ingtwo line-oriented state machines [+ timestamp (72 loc)]
rs2md (219 loc): rust code ↦ ```rust-blocks
md2rs (195 loc): markdown ↦ //@-prefixed comments
Range of tango = domain of submap
Edits remain in domain of tango (usually)
Outside submap: content "adjusted" by tango ...
... but (tango ○ tango) idempotent
tango runs in response to cargo build
And tango updates/creates source files
cargo build to reprocess and rebuild (every time).Goal: no unnecessary cargo rebuilds
The trick
(also: timestamp separate file to detect if both modified)
Encoding attributes attached to code blocks (//@@)
e.g. //@@ { .attribute1 .attribute2 }
Playpen link integration (//@@@)
e.g. //@@@ playpen link name
//@ You can follow [stripey] to the *playpen*!
//@@ { .stripes }
#[test]
pub fn blinking_code() {
println!("This code does not actually blink");
}
//@@@ stripeytango into:You can follow stripey to the playpen!
#[test]
pub fn blinking_code() {
println!("This code does not actually blink");
}(assuming appropriate CSS definition for .stripes)
Note that above link works
(meta: written with tango; see http://bit.ly/2618VSS)