CAD97 / katex-doc

XaaS for KaTeX on docs.rs
12 stars 1 forks source link

Getting cargo doc to work with dependencies #4

Open NewbiZ opened 1 year ago

NewbiZ commented 1 year ago

Just wanted to share a trick I use to have my doc building with a plain cargo doc. I used to have:

[build]
rustdocflags = ["--html-in-header", "katex.html"]

in my .cargo/config.toml.

The problem with this is that dependencies documentation will not build since the current working directory is changed and katex.html is not found. I was not able to find a way to automatically provide an absolute path there (even though you could hardcode it and it will work).

So I ended up writing a simple wrapper rustdoc.sh at the root of the project:

#!/bin/bash

SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
rustdoc --html-in-header "${SCRIPT_DIR}/katex.html" $@

And changing the rustdoc command to use it (relative path work) in .cargo/config.toml:

[build]
rustdoc = "./rustdoc.sh"

This way I have --html-in-header always provided to rustdoc with an absolute path, so building dependencies work, and a naive cargo doc in the project directory works like a charm.

Hope that helps

NewbiZ commented 1 year ago

By the way I also ended up updating katex to the latest version and adding mermaid.js and viz.js to the documentation, so that I can have mathematical formulas and nice diagrams :)

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.3/dist/katex.min.css" crossorigin="anonymous">
<style>
pre.language-math, code.language-inline-math, pre.language-mermaid, pre.language-mermaid code {
  background-color: white;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/katex@0.16.3/dist/katex.min.js" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/viz.js/2.1.2/viz.js" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/viz.js/2.1.2/full.render.js" crossorigin="anonymous"></script>
<script>
  "use strict";
  document.addEventListener("DOMContentLoaded", function () {
      // Mermaid
      mermaid.init({startOnLoad:true}, ".language-mermaid code");

      // Viz
      var viz = new Viz();

      var renderGraph = function(el) {
          viz.renderSVGElement(el.getElementsByTagName("code")[0].innerText)
            .then(function(element) {
                el.replaceWith(element);
            })
            .catch(error => {
                viz = new Viz();
                console.error(error);
            });
      }

      var graphs = document.getElementsByClassName("language-graphviz");
      for (var i=0; i<graphs.length; i++) {
          renderGraph(graphs[i]);
      }

      // Katex
      var maths = document.getElementsByClassName("language-math");
      for (var i=0; i<maths.length; i++) {
          var el = maths[i];
          katex.render(el.innerText, el, {displayMode: true});
      }

      var codes = document.getElementsByTagName("code");
      for (i=0; i<codes.length; i++) {
          el = codes[i];
          if (el.classList.contains("language-math")) continue;
          if (el.classList.contains("language-inline-math")) {
              katex.render(el.innerText, el);
              continue;
          }

          var parent = el.parentNode;
          if (parent.nodeName.toLowerCase() === "pre") continue;
          // TODO: Can this be done with DOM manipulation rather than string manipulation?
          // https://stackoverflow.com/q/48438067/3019990
          var inlineMath = "$" + el.outerHTML + "$";
          if (parent.innerHTML.indexOf(inlineMath) !== -1) {
              el.classList.add("language-inline-math");
              parent.innerHTML = parent.innerHTML.replace("$" + el.outerHTML + "$", el.outerHTML);
              i--;
          }
      }
  });
</script>