|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +FORMAT="svg" |
| 4 | + |
| 5 | +SOURCE_DIR=$(dirname "$0") |
| 6 | +TARGET_DIR=$(realpath "$(dirname "$0")/") |
| 7 | + |
| 8 | +OS=$(uname) |
| 9 | +case "$OS" in |
| 10 | +"Darwin") # Mac |
| 11 | + DRAW_IO="/Applications/draw.io.app/Contents/MacOS/draw.io" |
| 12 | + ;; |
| 13 | +"Linux") # Linux |
| 14 | + DRAW_IO="drawio" |
| 15 | + ;; |
| 16 | +esac |
| 17 | + |
| 18 | +# Unset Electron env vars that interfere with draw.io when running from VSCode |
| 19 | +unset ELECTRON_RUN_AS_NODE ELECTRON_NO_ATTACH_CONSOLE |
| 20 | + |
| 21 | +if ! command -v "$DRAW_IO" &>/dev/null; then |
| 22 | + echo "Error: draw.io executable not found. Please install draw.io and make sure it's in your PATH." |
| 23 | + exit 1 |
| 24 | +fi |
| 25 | + |
| 26 | +SOURCE="$SOURCE_DIR/diagrams.drawio" |
| 27 | + |
| 28 | +# Extract page names from uncompressed XML |
| 29 | +TMPFILE=$(mktemp) |
| 30 | +"$DRAW_IO" --export --format xml --no-sandbox --uncompressed -o "$TMPFILE" "$SOURCE" 2>/dev/null |
| 31 | + |
| 32 | +# Read page names into an array |
| 33 | +mapfile -t PAGES < <(grep -oP '<diagram[^>]*name="\K[^"]*' "$TMPFILE") |
| 34 | +rm "$TMPFILE" |
| 35 | + |
| 36 | +for i in "${!PAGES[@]}"; do |
| 37 | + name="${PAGES[$i]}" |
| 38 | + page_num=$((i + 1)) |
| 39 | + for theme in "dark" "light"; do |
| 40 | + TARGET="${TARGET_DIR}/${theme}/${name}.${FORMAT}" |
| 41 | + # Only convert if the source is more recent than the target |
| 42 | + if [[ "$SOURCE" -nt "${TARGET}" ]]; then |
| 43 | + echo "Exporting page $page_num ($name) -> $theme/$name.$FORMAT" |
| 44 | + "$DRAW_IO" --export --format ${FORMAT} --scale 2.5 --svg-theme "${theme}" --no-sandbox --page-index "$page_num" -o "${TARGET}" "$SOURCE" |
| 45 | + # Remove DOCTYPE to prevent SVGO entity count errors during build |
| 46 | + sed -i '/<!DOCTYPE/d' "${TARGET}" |
| 47 | + # Fix embedded SVG icons for dark theme: draw.io can't resolve |
| 48 | + # currentColor inside base64-encoded SVG images, so we replace |
| 49 | + # it with an explicit color after export. |
| 50 | + if [[ "$theme" == "dark" ]]; then |
| 51 | + node -e ' |
| 52 | + const fs = require("fs"); |
| 53 | + const file = process.argv[1]; |
| 54 | + let svg = fs.readFileSync(file, "utf8"); |
| 55 | + svg = svg.replace(/xlink:href="data:image\/svg\+xml;base64,([^"]+)"/g, (m, b64) => { |
| 56 | + const dec = Buffer.from(b64, "base64").toString("utf8"); |
| 57 | + let fixed = dec.replace(/currentColor/g, "#ffffff"); |
| 58 | + if (fixed === dec) return m; |
| 59 | + return "xlink:href=\"data:image/svg+xml;base64," + Buffer.from(fixed).toString("base64") + "\""; |
| 60 | + }); |
| 61 | + fs.writeFileSync(file, svg); |
| 62 | + ' "${TARGET}" |
| 63 | + fi |
| 64 | + fi |
| 65 | + done |
| 66 | +done |
0 commit comments