#!/usr/bin/env python3 """ Render a D2 diagram in both light and dark themes, upload the two SVGs to static.rerun.io, and print a `
` HTML block that can be pasted directly into the docs markdown. The rendered SVGs match the look the rerun.io docs site produces for D2 diagrams: monospaced uppercase labels, muted strokes, transparent node fills, emerald accent for `` runs inside labels. Requires: - the `d2` CLI on PATH (https://d2lang.com). - `scripts/upload_image.py` (same directory) and its dependencies; see that file's docstring for GCS authentication setup. Usage: python3 scripts/render_d2.py path/to/diagram.d2 cat diagram.d2 | python3 scripts/render_d2.py or via pixi: pixi run python scripts/render_d2.py path/to/diagram.d2 The final HTML block is printed to stdout (and stderr when interactive), mirroring how `upload_image.py` reports its results. Per theme, this is roughly equivalent to: cat diagram.d2 | d2 --pad=0 --scale=0.8 --stdout-format=svg - - followed by SVG post-processing: - Strip D2's embedded " body = re.sub(r"", _wrap, body, count=1, flags=re.DOTALL) return '\n' + body def main() -> None: ap = argparse.ArgumentParser( description="Render a D2 diagram in light+dark, upload both SVGs to " "static.rerun.io, print an HTML
block ready to paste " "into docs markdown.", ) ap.add_argument( "source", nargs="?", type=Path, help="Path to a .d2 source file. If omitted, source is read from stdin.", ) args = ap.parse_args() import logging import sys import tempfile logging.basicConfig(level=logging.INFO) if args.source is None: if sys.stdin.isatty(): ap.error("no source file given and stdin is a tty") source_text = sys.stdin.read() else: source_text = args.source.read_text() # Imported lazily so the render API can be used as a library without # pulling in upload_image's heavier dependency tree (PIL, gcloud, …). from upload_image import Uploader uploader = Uploader() urls: dict[str, str] = {} with tempfile.TemporaryDirectory() as td: for theme in ("light", "dark"): logging.info(f"rendering {theme} theme") svg_path = Path(td) / f"d2-{theme}.svg" svg_path.write_text(render(source_text, theme)) object_name = uploader.upload_file(svg_path) urls[theme] = f"https://static.rerun.io/{object_name}" html = ( '
\n' f' \n' f' \n' "
" ) print(f"\n{html}", file=sys.stderr) if not sys.stdout.isatty(): # Allow piping into pbcopy/xclip without the stderr banner. print(html) if __name__ == "__main__": main()