Convert a Markdown file into a self-contained HTML page styled with the University of Glasgow design system.
gumdhtml is a small command-line tool that reads a Markdown file and writes a single HTML file. The CSS is inlined into the output, so the result is one self-contained document you can email round, drop on a shared drive, or open offline without dragging any other files along with it.
The styling follows the University of Glasgow visual identity: Noto Sans, the navy and coral palette, an uppercase page-title banner, arrow markers on bullet lists, navy table headers, and light-grey blockquote panels. I was aiming for "looks like it belongs next to the rest of the corporate site" rather than "perfectly mimics every component on design.gla.ac.uk", so don't expect pixel parity.
It understands GitHub-flavoured Markdown (tables, task lists, strikethrough, autolinks), footnotes, definition lists, and smart punctuation. Headings get anchor IDs automatically.
If you just want to use it, grab a binary for your platform from the releases page and drop it somewhere on your PATH. That's it.
To build from source you need:
- Go 1.24 or newer.
Clone and build:
git clone [email protected]:UoGSoE/gumdhtml.git
cd gumdhtml
go build -o gumdhtml .You'll end up with a single binary, around 6MB. No CGo, no external assets at runtime.
Convert a Markdown file:
gumdhtml ROLES.mdThat writes ROLES.html next to the input.
Set the heading that appears in the navy banner at the top of the page (this also sets the browser tab title):
gumdhtml --title "Project roles" ROLES.mdWrite to a specific path:
gumdhtml -o /tmp/roles.html ROLES.mdOpen the result in your default browser as soon as it's written:
gumdhtml --open ROLES.mdPipe through stdin/stdout:
cat ROLES.md | gumdhtml --title "Project roles" > roles.html--title,-t "...": text shown in the navy banner. Also sets the browser tab title. If omitted, the banner is left empty and the browser title falls back to the first H1 in the document, then the input filename.--output,-o <path>: output file path. Default is<input>.html, or stdout when reading from stdin.--open: open the generated file in your default browser after writing (openon macOS,xdg-openon Linux, the default file handler on Windows). It's an error to combine this with stdout output, since there's no file to open.--theme <name>: use~/.config/gumdhtml/themes/<name>.cssinstead of the built-in University of Glasgow style. See Themes.--create-theme <name>: write the built-in stylesheet to~/.config/gumdhtml/themes/<name>.cssas a starting point for a new theme, then exit. Refuses to overwrite an existing theme.
Flags use GNU-style double dashes for long names, with single-letter shorthands where they help, and may appear before or after the filename — so gumdhtml ROLES.md --open works just as well as gumdhtml --open ROLES.md.
The University of Glasgow look is built in and needs no configuration. If you want something less corporate for sharing with friends, you can keep your own stylesheets in ~/.config/gumdhtml/themes/ (or $XDG_CONFIG_HOME/gumdhtml/themes/ if you set that) and pick one with --theme.
The repo ships two alternatives in themes/: letterpress for cream paper and warm serifs, and unrendered for JetBrains Mono, black, white and red, with visible Markdown punctuation. Copy a theme into your config directory and it's ready to use:
mkdir -p ~/.config/gumdhtml/themes
cp themes/letterpress.css ~/.config/gumdhtml/themes/
gumdhtml --theme letterpress ROLES.md
cp themes/unrendered.css ~/.config/gumdhtml/themes/
gumdhtml --theme unrendered --title "Project roles" ROLES.mdThe easiest way to start is to dump the built-in stylesheet out as a new theme and edit it:
gumdhtml --create-theme super-cute
# wrote /Users/you/.config/gumdhtml/themes/super-cute.css
gumdhtml --theme super-cute ROLES.mdA theme is a plain CSS file. The HTML shell is shared by every theme, so the stylesheet is the only thing that changes. Reading the file top to bottom, you'll meet:
- Fonts. The
@importon the first line pulls Noto Sans from Google Fonts. Swap it for a different font, or delete it to rely on whatever the reader has installed. The output is otherwise self-contained, so this is the one line that reaches out to the network. - Tokens. The
:rootblock holds the palette (--brand,--accent,--link,--ink,--paperand friends), the font stacks (--font-body,--font-mono), the spacing scale and the line measure. If you only want to recolour the page or change the typeface, this block is all you need to touch. - The rules that carry the look. A few blocks below the tokens decide the character of the page more than any colour does: the masthead (
.page-head,.page-heading), the headings, the list markers (ul > li::before,ol > li::before), the blockquote and the table header. The default sets a filled navy banner, uppercase headings, arrow bullets and a navy table header, all as plain rules rather than variables. A theme that wants a genuinely different feel rewrites these. - Plumbing. Code blocks, footnotes, task lists, the footer, the responsive, print and reduced-motion blocks. These mostly work in any theme and you can leave them alone until something looks off.
The page shell gives you these hooks to style:
header.page-headandh1.page-headingfor the banner set by--title.main.page-bodyfor the rendered Markdown.footer.page-foot, with.foot-titleand.foot-yearinside it.
For a worked example of a full rewrite, read themes/letterpress.css side by side with a freshly created theme. It keeps the same structure and token names as the default (adding one token, --font-display, for the heading face), so a diff between the two shows which rules were changed to get from the corporate look to a cream-paper serif one.
The default CSS lives in assets/style.css and the HTML shell in assets/template.html. Both are compiled into the binary with go:embed. That keeps the binary genuinely standalone, but it does mean any change to either file needs a rebuild before you'll see it. User themes are read from disk at run time, so they never need a rebuild.
Pushing a semver tag triggers .github/workflows/release.yml. That cross-compiles binaries for Linux, macOS, and Windows (amd64 and arm64 where appropriate), builds tarballs and a zip, generates SHA256 checksums, and attaches the lot to a GitHub release.
git tag v0.1.0
git push origin v0.1.0Clone, build, send a PR.
git clone [email protected]:UoGSoE/gumdhtml.git
cd gumdhtml
go build -o gumdhtml .
./gumdhtml ROLES.mdIf you're tweaking the look, edit assets/style.css (or assets/template.html for the page shell) and rebuild.
MIT. See LICENSE.