Skip to content
This repository was archived by the owner on Jul 9, 2023. It is now read-only.
This repository was archived by the owner on Jul 9, 2023. It is now read-only.

Cargo subcommand to perform pluggable expansions against rustdoc #20

Description

@dtolnay

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);
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions