mirror of
https://github.com/penpot/penpot.git
synced 2026-08-06 04:48:39 +00:00
145 lines
5.1 KiB
Bash
Executable File
145 lines
5.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Visual review helper for the SVG exporter's `insta` snapshots.
|
|
#
|
|
# This script renders the insta snapshots into an HTML gallery
|
|
# so you can judge whether a change is *visually* valid
|
|
# before accepting it.
|
|
#
|
|
# Usage:
|
|
# ./preview-snapshots # build the gallery and print its path
|
|
# ./preview-snapshots --open # also open it in the default browser
|
|
#
|
|
# Text snapshots reference `fonts/sourcesanspro-regular.ttf`; this script copies
|
|
# the bundled font into `target/svg-preview/fonts/` so the gallery renders text.
|
|
#
|
|
# When a test produced a pending change there will be a `*.snap.new` next to the
|
|
# accepted `*.snap`; the gallery then shows "accepted" vs "new" side by side.
|
|
# Once a change looks correct, accept it (rename `*.snap.new` -> `*.snap`, or
|
|
# `cargo insta accept`) and re-run the tests.
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
SNAP_DIR="$SCRIPT_DIR/src/render/svg/tests/snapshots"
|
|
OUT_DIR="$SCRIPT_DIR/target/svg-preview"
|
|
OUT="$OUT_DIR/index.html"
|
|
FONT_SRC="$SCRIPT_DIR/src/fonts/sourcesanspro-regular.ttf"
|
|
FONT_DIR="$OUT_DIR/fonts"
|
|
|
|
mkdir -p "$OUT_DIR"
|
|
mkdir -p "$FONT_DIR"
|
|
cp "$FONT_SRC" "$FONT_DIR/"
|
|
|
|
# Prints the SVG body of a snapshot file: everything after the second `---`
|
|
# line (the YAML front matter insta writes).
|
|
extract_body() {
|
|
awk 'd>=2{print} /^---$/{d++}' "$1"
|
|
}
|
|
|
|
# Embeds a snapshot's SVG via <object> pointing at a standalone .svg file.
|
|
#
|
|
# Snapshots must NOT be inlined together into one HTML document: each SVG
|
|
# restarts its def ids at `clip0`/`blur0`/..., so inlining several in the same
|
|
# document makes `url(#clip0)` collide and resolve to the wrong (or empty) clip
|
|
# path. Writing each SVG to its own file isolates ids per document.
|
|
# We use <object> (not <img>) so linked @font-face rules and other external
|
|
# resources resolve inside the SVG document.
|
|
svg_counter=0
|
|
read_svg_dims() {
|
|
local file="$1"
|
|
local tag
|
|
tag=$(grep -m1 '<svg' "$file" | sed 's/>.*//')
|
|
SVG_W=$(echo "$tag" | sed -n 's/.*[[:space:]]width="\([^"]*\)".*/\1/p')
|
|
SVG_H=$(echo "$tag" | sed -n 's/.*[[:space:]]height="\([^"]*\)".*/\1/p')
|
|
}
|
|
emit_svg_box() {
|
|
local body_file="$OUT_DIR/svg-$svg_counter.svg"
|
|
local name
|
|
svg_counter=$((svg_counter + 1))
|
|
name="$(basename "$body_file")"
|
|
extract_body "$1" > "$body_file"
|
|
read_svg_dims "$body_file"
|
|
echo "<div class=\"cb\"><object data=\"$name\" type=\"image/svg+xml\" width=\"$SVG_W\" height=\"$SVG_H\"></object></div>"
|
|
}
|
|
|
|
{
|
|
cat <<'HTML'
|
|
<!doctype html>
|
|
<meta charset="utf-8">
|
|
<title>render-wasm SVG snapshot preview</title>
|
|
<style>
|
|
:root { color-scheme: light dark; }
|
|
body { font-family: system-ui, sans-serif; margin: 24px; }
|
|
h1 { font-size: 20px; }
|
|
section { border: 1px solid #8884; border-radius: 8px; padding: 12px 16px; margin: 16px 0; }
|
|
h2 { font-size: 14px; font-family: monospace; margin: 0 0 8px; word-break: break-all; }
|
|
.cols { display: flex; gap: 24px; flex-wrap: wrap; }
|
|
figure { margin: 0; }
|
|
figcaption { font-size: 12px; color: #888; margin-bottom: 4px; }
|
|
/* Checkerboard so transparency / opacity / blend are visible. */
|
|
.cb {
|
|
display: inline-block;
|
|
line-height: 0;
|
|
background-image:
|
|
linear-gradient(45deg, #ccc 25%, transparent 25%),
|
|
linear-gradient(-45deg, #ccc 25%, transparent 25%),
|
|
linear-gradient(45deg, transparent 75%, #ccc 75%),
|
|
linear-gradient(-45deg, transparent 75%, #ccc 75%);
|
|
background-size: 16px 16px;
|
|
background-position: 0 0, 0 8px, 8px -8px, -8px 0;
|
|
border: 1px solid #8884;
|
|
}
|
|
.cb object {
|
|
display: block;
|
|
}
|
|
.changed { color: #c60; font-weight: bold; font-size: 13px; }
|
|
details { margin-top: 8px; }
|
|
pre { background: #8881; padding: 8px; overflow: auto; font-size: 12px; }
|
|
</style>
|
|
<h1>render-wasm SVG snapshot preview</h1>
|
|
HTML
|
|
|
|
shopt -s nullglob
|
|
|
|
for snap in "$SNAP_DIR"/*.snap; do
|
|
name="$(basename "$snap" .snap)"
|
|
new="$snap.new"
|
|
echo "<section><h2>$name</h2>"
|
|
if [ -f "$new" ]; then
|
|
echo '<p class="changed">Pending change: review before accepting</p>'
|
|
echo '<div class="cols">'
|
|
echo '<figure><figcaption>accepted (current .snap)</figcaption>'
|
|
emit_svg_box "$snap"
|
|
echo '</figure>'
|
|
echo '<figure><figcaption>new (.snap.new)</figcaption>'
|
|
emit_svg_box "$new"
|
|
echo '</figure>'
|
|
echo '</div>'
|
|
echo '<details><summary>text diff</summary><pre>'
|
|
diff -u "$snap" "$new" | sed 's/&/\&/g; s/</\</g; s/>/\>/g' || true
|
|
echo '</pre></details>'
|
|
else
|
|
emit_svg_box "$snap"
|
|
fi
|
|
echo '</section>'
|
|
done
|
|
|
|
# New tests whose snapshot has never been accepted yet.
|
|
for new in "$SNAP_DIR"/*.snap.new; do
|
|
base="${new%.new}"
|
|
[ -f "$base" ] && continue
|
|
name="$(basename "$new" .snap.new)"
|
|
echo "<section><h2>$name</h2>"
|
|
echo '<p class="changed">new snapshot (no accepted version yet)</p>'
|
|
emit_svg_box "$new"
|
|
echo '</section>'
|
|
done
|
|
} > "$OUT"
|
|
|
|
echo "Wrote $OUT"
|
|
|
|
if [ "${1:-}" = "--open" ]; then
|
|
xdg-open "$OUT" >/dev/null 2>&1 || open "$OUT" >/dev/null 2>&1 || true
|
|
fi
|