dylanowen / mdbook-graphviz

Mozilla Public License 2.0
42 stars 9 forks source link

Adding additional code->svg tools #133

Open dylanowen opened 1 month ago

dylanowen commented 1 month ago

I've been working on an mdbook d2 renderer lately and most of the code is exactly the same as the graphviz code. It would be great to share some of the logic / backport the improvements I've made (svg zoom and pan) back to this repo.

I think there are a few ways we could do this:

  1. Make this a mono repo, rename it to mdbook-preprocessors, have a shared crate mdbook-inline-svg-preprocessor, then have each preprocessor inherit from mdbook-inline-svg-preprocessor.
  2. Have the same crate structure but in 3 different repos.
  3. Wrap everything up into 1 executable but still rename the repo.

Right now I'm inclined to go with Option 1. Option 2 seems too tedious to be reasonable. Option 3 seems compelling but I've been calling d2 via their golang library instead of the CLI which (while very powerful) introduces some interesting compilation requirements in osx. I wouldn't want to break graphviz rendering for any consumers outside of osx, especially if it proves challenging to setup the correct install for consumers without golang installs.

Cypher1 commented 1 month ago

I support 1 though I wonder if there's a Rust binding to D2 we could benefit from.

If we head in this direction, would we be open to adding other renderers to the family or prefer to keep it small? I'm thinking of things like d3.

There's definitely maintenance burden associated with all three approaches but I think crates are a great isolation unit for encouraging seperation of concerns. Happy to be a part of it :)

Cypher1 commented 1 month ago

Oh, looked at the rust to go build setting. Not nearly as complex as I was reading from the initial description, seems perfectly acceptable.

dylanowen commented 1 month ago

Better bindings would be great but I didn't find any (I didn't search that hard), right now I've just been serializing to json to simplify it / only implementing exactly what I need. Another option would be something like https://github.com/mozilla/uniffi-rs but that might be more annoying than json.

Right now my build.rs looks like:

const BUILD_DIR: &str = "build";
const LIB_NAME: &str = "d2-sys";

fn main() {
    let manifest_dir = env!("CARGO_MANIFEST_DIR");
    let build_path = format!("{}/{}", manifest_dir, BUILD_DIR);

    let status = Command::new("go")
        .args(["build", "-buildmode=c-archive"])
        .args(["-o", &format!("{build_path}/lib{LIB_NAME}.a")])
        .arg("lib.go")
        .status()
        .expect("Failed to build Go library");

    if !status.success() {
        panic!("Go library build failed");
    }

    println!("cargo:rustc-link-search=native={build_path}");
    println!("cargo:rustc-link-lib=static={LIB_NAME}");
}

This will definitely cause issues for consumers without golang installed. https://github.com/ryanfowler/cgo-rs/blob/main/src/lib.rs#L184 seems like it would do more but also still have issues for people without golang.

dylanowen commented 1 month ago

I'd be open to adding more renderers but as showcased by my slow upkeep of the graphviz renderer I can't promise any support for them. But that's part of the beauty of open source right? 😄

I'll work on combining what I have in my local repo to the latest master and get a PR up for some review