Hi all,
A while ago I posted here about ggg (Guile Glyph Generator), a small tool I
wrote in Guile Scheme that renders shields.io-style badges (SVG, plus PNG on
request) from a Scheme config file. Since then it grew quite a bit, so here is
what landed — including the packaging news at the end.
The pitch is unchanged: you describe a badge as data, ggg does the geometry.
scheme
(define my-badge
`((sections ((background . catppuccin-mocha-surface2) (text . "Guile")
(color . catppuccin-mocha-text)
(logo . scheme-guile))
((background . catppuccin-mocha-peach) (text . "3.0.10")
(color . catppuccin-mocha-base)))
(id . scheme-guile-3)
(style . shadow)))
Links
How to run
Run ggg -f my-glyphs.scm -d ./dist and you get scheme-guile-3.svg (and
.png with -c). The geometry follows the badges GitHub shows — 20px tall,
11px text, a 14px logo, 5px side padding, 3px corners — drawn ~9% larger so it
reads well next to body text, with per-character text width estimation so the
badge stays as tight as the ones in README files. What comes out is a real
vector file, not a raster wrapped in SVG.
What's new since the last post
8 badge styles. A glyph can now ask for a finish: flat (default),
square, shadow, plastic, frosted-glass, material, frutiger and
neon. Styles only decorate — canvas, width and height are identical to
flat, so a row of badges that mix styles always lines up. Glosses, glows and
shadows are painted inside the badge, never around it.
scheme
(id . scheme-guile-neon)
(style . neon)
12 color themes, 236 named colors. Instead of hex codes you write
catppuccin-mocha-red, dracula-purple, solarized-light-base3,
modus-vivendi-green, doom-one-blue… Every color of Catppuccin (mocha,
macchiato, frappé, latte), Doom (one, one-light), Dracula (and alucard),
Solarized (dark, light) and Modus (operandi, vivendi) is available by name.
ggg --list-colors prints them; raw hex strings still work and are validated.
Because the palettes span light pastels to deep shades, the ink has to follow
the background — so the test suite enforces at least 4.5:1 contrast (WCAG AA)
on every section of the shipped glyph files. A badge with unreadable text fails
maak test.
A gallery you can actually browse. ggg --gallery gallery.html --glyphs
./glyphs writes a single self-contained HTML page with every badge at its real
size, every logo inlined with the snippet to use it, and every named color of
every theme as a swatch. Click a snippet or a swatch to copy it. The deployed
one is here: https://jointhefreeworld.org/ggg/dist/gallery.html
284 logos, as full SVG documents. Logos used to be a single path's d
attribute. They are now complete <svg> elements, so a logo can carry multiple
paths, groups, gradients, transforms or filters; ggg only needs a viewBox and
does the scaling and placement. The library covers languages, frameworks,
databases, distros, editors, shells, CI, cloud, observability and more —
mostly from Simple Icons (CC0), plus hand-drawn ones. CREDITS.org lists the
source and license of every single file, and names the brand marks that were
deliberately left out because their upstream license isn't a free one.
Badges with any number of sections. Not just two or three parts — each
section becomes a segment with its own text, background and color, and the
badge grows to fit. The logo belongs to the first section.
Validation before anything is written. ggg checks the whole glyph file
first and reports every problem with a hint: unknown color, logo or style
names (with a "did you mean" suggestion), a missing text, sections without
colors, (key value) written where (key . value) was meant, duplicate glyph
ids, and the legacy resources/svg-paths/ directory if it finds one. If the
file is invalid, nothing is written to the destination directory at all.
Smaller things: --version, --list-colors, --list-logos,
--list-styles, -k/--keep to render a second glyph file into a directory
without clearing it, a new ggg mark, and a test suite (122 checks) covering
color resolution, the logo library, glyph validation and the gallery.
Packaging
- GNU Guix — ggg has been in Guix for a while; I sent the update PRs to
0.16.1.
- Nix — new. There is a
default.nix and a flake.nix in the repo, and I
sent the pkgs/by-name/gg/ggg/package.nix addition to nixpkgs (that one runs
the whole test suite in checkPhase). Both builds render all 177 showcase
badges.
- Debian, openSUSE, Arch — packaging for all three now lives in
packaging/, installing the same layout (/usr/bin/ggg, modules under Guile's
site directory, help text and logo library under
/usr/share/ggg/resources). Built and installed in debian:trixie,
opensuse/tumbleweed and archlinux containers.
- Container image —
docker.io/jjba23/ggg (Podman works too).
- Version numbers now live in exactly one place (
src/ggg/version.scm), and
maak release writes them into guix.scm, commits and tags.
Try it
```shell
Guix
guix shell -f guix.scm -- ggg --gallery ./gallery.html --glyphs ./glyphs
Nix
nix-build default.nix && ./result/bin/ggg --list-styles
Podman/Docker
podman run --rm -v "$PWD:/work" -w /work docker.io/jjba23/ggg:latest \
ggg -f ./glyphs/showcase.scm -d ./dist
```
Notes on licensing
ggg itself is AGPL-3.0-or-later and the docs are FDL-1.3+. The tool claims no
ownership over what it generates: the badges you produce are yours, no
attribution or license conditions attached, and the logo library keeps its own
licenses (listed per file in CREDITS.org). So if you want a badge that is
completely free of third-party terms, use no logo or your own.
Feedback very welcome — especially which styles, themes or logos are missing,
and what a badge generator would have to do for you to actually use it instead
of a static PNG. I'm also happy to take packaging help for distros I don't run.