61ec340e40
- apt: yq (YAML query), pandoc (doc converter), graphviz (dot rendering) - tealdeer: tldr command as ~5MB static musl binary (TEALDEER_VERSION arg) - dot-watch: auto-render .dot to PNG on save (graphviz-only, no imagemagick) - README: document new tools - smoke-test: presence assertions for yq, pandoc, dot, tldr, dot-watch Excludes socat, imagemagick, studio-expose (pi-studio-specific).
60 lines
1.9 KiB
Bash
Executable File
60 lines
1.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# dot-watch — auto-rerender a graphviz .dot file to PNG on every save.
|
|
#
|
|
# WHY THIS EXISTS
|
|
# pi-studio renders mermaid natively but has no graphviz/DOT renderer.
|
|
# Its markdown preview DOES render local image links (.png/.jpg/.gif/.webp),
|
|
# and the editor offers "refresh from disk". This helper closes the loop:
|
|
# edit a .dot file -> dot-watch regenerates <name>.png -> hit refresh in
|
|
# Studio to see the update. Uses mtime polling (no inotify dependency,
|
|
# which isn't in the trixie-slim base).
|
|
#
|
|
# USAGE
|
|
# dot-watch <file.dot> [layout] [dpi]
|
|
# layout: dot|neato|fdp|circo|twopi (default: dot)
|
|
# dpi: output resolution (default: 150)
|
|
# env: DOT_WATCH_INTERVAL=<seconds> poll interval (default: 1)
|
|
#
|
|
# EXAMPLES
|
|
# dot-watch /workspace/graph.dot
|
|
# dot-watch graph.dot neato 200
|
|
|
|
set -euo pipefail
|
|
|
|
SRC="${1:?usage: dot-watch <file.dot> [layout] [dpi]}"
|
|
LAYOUT="${2:-dot}"
|
|
DPI="${3:-150}"
|
|
|
|
[[ -f "$SRC" ]] || { echo "error: no such file: $SRC" >&2; exit 1; }
|
|
command -v "$LAYOUT" >/dev/null || { echo "error: layout engine '$LAYOUT' not found" >&2; exit 1; }
|
|
|
|
OUT="${SRC%.dot}.png"
|
|
INTERVAL="${DOT_WATCH_INTERVAL:-1}" # seconds between polls
|
|
ERRLOG="$(mktemp -t dot-watch.XXXXXX.err)"
|
|
trap 'rm -f "$ERRLOG"' EXIT
|
|
|
|
render() {
|
|
if "$LAYOUT" -Tpng -Gdpi="$DPI" "$SRC" -o "$OUT" 2> "$ERRLOG"; then
|
|
printf '[%s] rendered -> %s\n' "$(date +%H:%M:%S)" "$OUT"
|
|
else
|
|
printf '[%s] DOT error:\n' "$(date +%H:%M:%S)"
|
|
sed 's/^/ /' "$ERRLOG"
|
|
fi
|
|
}
|
|
|
|
# portable mtime (GNU stat, fallback to BSD stat)
|
|
mtime() { stat -c %Y "$1" 2>/dev/null || stat -f %m "$1" 2>/dev/null; }
|
|
|
|
echo "watching $SRC ($LAYOUT, ${DPI}dpi) -> $OUT [Ctrl-C to stop]"
|
|
render
|
|
last="$(mtime "$SRC")"
|
|
while true; do
|
|
sleep "$INTERVAL"
|
|
[[ -f "$SRC" ]] || continue
|
|
now="$(mtime "$SRC")"
|
|
if [[ "$now" != "$last" ]]; then
|
|
last="$now"
|
|
render
|
|
fi
|
|
done
|