Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: monthly

- package-ecosystem: nix
directory: /
schedule:
interval: monthly
31 changes: 31 additions & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Pages
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25 # v22
- uses: DeterminateSystems/magic-nix-cache-action@908b263ff629f4cc17666315b7fd3ec127c6244d # v14
- run: nix build
- uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: result
deploy:
if: github.event_name == 'push'
needs: build
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
book/
result
19 changes: 19 additions & 0 deletions book.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[book]
title = "Fungi Protocol Suite"
language = "en"
src = "src"

[preprocessor.graphviz]
command = "mdbook-graphviz"
after = ["links"]

[preprocessor.mermaid]
command = "python3 contrib/mermaid_ssr.py"
after = ["links", "graphviz"]

[preprocessor.katex]
command = "mdbook-katex"
after = ["links"]

[output.html]
additional-css = ["theme/diagrams.css"]
80 changes: 80 additions & 0 deletions contrib/mermaid_ssr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#!/usr/bin/env python3
"""mdbook preprocessor: render ```mermaid blocks to inline SVG with mmdc.

Expects the `mmdc` from nix/mermaid.nix, which comes wrapped with the
headless chromium it drives.
"""
import json
import os
import re
import subprocess
import sys
import tempfile

# Fence length varies: preprocessors that re-serialize the markdown (mdbook-graphviz)
# emit four backticks, so the closing fence has to match the opening one.
FENCE = re.compile(
r"^(?P<fence>`{3,})mermaid[^\n]*\n(?P<body>.*?)^(?P=fence)[ \t]*$",
re.S | re.M,
)


def render(source, theme, svg_id):
with tempfile.TemporaryDirectory() as tmp:
mmd = os.path.join(tmp, "in.mmd")
svg = os.path.join(tmp, "out.svg")
with open(mmd, "w") as f:
f.write(source)
result = subprocess.run(
["mmdc", "-i", mmd, "-o", svg,
"-b", "transparent", "-t", theme, "-I", svg_id],
capture_output=True,
text=True,
)
if result.returncode != 0:
sys.stderr.write(result.stdout + result.stderr)
sys.exit(1)
with open(svg) as f:
return f.read()


def block(source, index):
"""Both themes of one diagram; css picks which to show.

The svg is emitted inside a div because `svg` is not a block-level tag
in commonmark, so bare svg markup would be parsed as inline html and
escaped. Each svg needs its own id: mermaid scopes the stylesheet it
embeds by id, so two diagrams sharing one would style each other.
"""
return "\n\n" + "\n".join(
'<div class="mermaid mermaid-%s">\n%s\n</div>'
% (name, render(source, theme, "mermaid-%d-%s" % (index, name)))
for name, theme in (("light", "default"), ("dark", "dark"))
) + "\n\n"


def walk(items, counter):
for item in items:
chapter = item.get("Chapter")
if not chapter:
continue

def substitute(match):
counter[0] += 1
return block(match.group("body"), counter[0])

chapter["content"] = FENCE.sub(substitute, chapter["content"])
walk(chapter["sub_items"], counter)


def main():
if len(sys.argv) > 1 and sys.argv[1] == "supports":
sys.exit(0)
_context, book = json.load(sys.stdin)
# mdbook 0.5 renamed the top level key from `sections` to `items`.
walk(book.get("items", book.get("sections")), [0])
json.dump(book, sys.stdout)


if __name__ == "__main__":
main()
61 changes: 61 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
flake-parts.url = "github:hercules-ci/flake-parts";
};

outputs =
inputs:
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
systems = [
"aarch64-darwin"
"aarch64-linux"
"x86_64-linux"
];

imports = [
./nix/mermaid.nix
./nix/preprocessors.nix
./nix/site.nix
./nix/devshell.nix
];
};
}
16 changes: 16 additions & 0 deletions nix/devshell.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{ ... }:
{
perSystem =
{ pkgs, mmdc, ... }:
{
devShells.default = pkgs.mkShell {
packages = [ mmdc ] ++ (with pkgs; [
mdbook
mdbook-graphviz
mdbook-katex
graphviz
python3
]);
};
};
}
29 changes: 29 additions & 0 deletions nix/mermaid.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{ ... }:
{
# The only chromium nixpkgs has for darwin sits inside playwright's prebuilt
# browsers, under a directory whose name changes with every bump. Resolve it
# once and bake it in, so no caller has to export a path.
perSystem =
{ pkgs, ... }:
{
_module.args.mmdc = pkgs.symlinkJoin {
name = "mmdc-with-browser";
paths = [ pkgs.mermaid-cli ];
nativeBuildInputs = [ pkgs.makeWrapper ];
postBuild = ''
browser=$(find -L ${pkgs.playwright-driver.browsers} \
\( -name chrome-headless-shell -o -name headless_shell \) \
-type f | head -1)
test -n "$browser" || { echo "no chromium in playwright browsers"; exit 1; }

# --no-sandbox: chromium's own sandbox cannot nest inside the nix
# build sandbox.
echo "{\"executablePath\":\"$browser\",\"args\":[\"--no-sandbox\"]}" \
> $out/puppeteer.json

wrapProgram $out/bin/mmdc \
--add-flags "--puppeteerConfigFile $out/puppeteer.json"
'';
};
};
}
45 changes: 45 additions & 0 deletions nix/preprocessors.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{ inputs, ... }:
{
# nixpkgs ships mdbook 0.5 alongside preprocessor releases that predate it
# and still speak the 0.4 protocol, so the packaged set cannot build a book.
# Take the upstream releases that added 0.5 support instead. Drop this file
# once nixpkgs catches up.
perSystem =
{ system, ... }:
{
_module.args.pkgs = import inputs.nixpkgs {
inherit system;
overlays = [
(final: prev: {
mdbook-graphviz = prev.mdbook-graphviz.overrideAttrs (old: rec {
version = "0.3.1";
src = final.fetchFromGitHub {
owner = "dylanowen";
repo = "mdbook-graphviz";
tag = "v${version}";
hash = "sha256-uqNgP1rRgP6NecReqpinsg7u01gNDpIxX2qag8IyklY=";
};
cargoDeps = final.rustPlatform.fetchCargoVendor {
inherit src;
hash = "sha256-OBCECv9ZN9xjkOestZbjCXNAA/hAl2u0AtfqxA+cV78=";
};
});

mdbook-katex = prev.mdbook-katex.overrideAttrs (old: rec {
version = "0.10.0";
src = final.fetchFromGitHub {
owner = "lzanini";
repo = "mdbook-katex";
tag = "v${version}";
hash = "sha256-bS8SUzpTqQNYKeGPBf1QD4/AL0TWn3NE4M7A8WLEjUE=";
};
cargoDeps = final.rustPlatform.fetchCargoVendor {
inherit src;
hash = "sha256-YqQ8Uai2mCG+1X/TmWJPszLYumOjF455Aa5WldgGXF0=";
};
});
})
];
};
};
}
33 changes: 33 additions & 0 deletions nix/site.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{ ... }:
{
perSystem =
{ pkgs, mmdc, ... }:
let
site = pkgs.stdenvNoCC.mkDerivation {
name = "fungi-docs";
src = ../.;

nativeBuildInputs = [ mmdc ] ++ (with pkgs; [
mdbook
mdbook-graphviz
mdbook-katex
graphviz
python3
]);

buildPhase = ''
# mmdc writes a chromium profile under $HOME.
export HOME=$(mktemp -d)
mdbook build -d $out
'';

dontInstall = true;
};
in
{
packages = {
inherit site;
default = site;
};
};
}
1 change: 1 addition & 0 deletions src/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{#include ../README.md}}
3 changes: 3 additions & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Summary

[Introduction](README.md)
Loading
Loading