-
-
Notifications
You must be signed in to change notification settings - Fork 7
Cargo subcommand to perform pluggable expansions against rustdoc #20
Description
In the GitBook that backs https://serde.rs, I use several GitBook plugins, a few of which I wrote myself.
For example I have a plugin that lets me insert playground links into code blocks. Here is an invocation right from the homepage: markdown (shown below) and rendered here with the "Run" link.
!PLAYGROUND a58fc361e02c4c0a08fd99cacd9567d1
```rust
/*
* rust code
*/
```
Similarly a file name plugin -- markdown here and rendered here.
!FILENAME Cargo.toml
```toml
[dependencies]
serde = "1.0"
serde_derive = "1.0"
```
Here is the documentation on GitBook plugins: https://toolchain.gitbook.com/plugins/create.html
The way this one of mine is implemented is by running some regex replacements against the pre-rendered and post-rendered markdown comment. The whole implementation is just a few lines of JavaScript.
"page:before": function(page) {
page.content = page.content.replace(/(!FILENAME .*)/g, '$1\n');
page.content = page.content.replace(/(!PLAYGROUND .*)/g, '$1\n');
return page;
},
"page": function(page) {
var pattern = /<p>!FILENAME (.+)<\/p>/g;
var tag = '<div><p class="code-filename">$1</p></div>';
page.content = page.content.replace(pattern, tag);
var pattern = /<p>!PLAYGROUND (.+)<\/p>\n<pre>/g;
var tag = '<pre><a class="playground-link" target="_blank" href="https://play.rust-lang.org/?gist=$1"></a>';
page.content = page.content.replace(pattern, tag);
return page;
}
I would be interested in having the same capability to run snippets of logic against my pre-rendered and post-rendered rustdoc. I would like to have a Cargo subcommand:
cargo plugin-doc
which forwards to cargo doc
but executes plugins before (on the Markdown) and after (on the HTML).
Plugins would be listed as metadata in Cargo.toml:
[package.metadata.rustdoc]
plugins = ["playground-links", "..."]
Plugins would be installed as ordinary binaries like cargo install rustdoc-plugin-playground-links
. This project also involves developing the library for writing plugins. Mirroring the GitBook system, plugin code might look something like:
use rustdoc_plugin::{Page, Plugin};
struct PlaygroundLinksPlugin;
// Both functions are optional and do nothing by default, so you can
// implement just one or the other.
impl Plugin for PlaygroundLinksPlugin {
fn page_before(page: &mut Page) {
/* ... */
}
fn page_after(page: &mut Page) {
/* ... */
}
}
fn main() {
rustdoc_plugin::main(PlaygroundLinksPlugin);
}