Introduction
Gemini is often described as the “small web”: a space with fewer frills, less overhead, and a friendlier pace than today’s HTTP-dominated internet. For me, it’s also an excuse to play with Emacs and see how far I can bend it into being my all-in-one publishing tool.
What follows is a tour through the little pipeline I’ve cobbled together in a
single Emacs package: local/lh-gemini.el
. With it, I can:
- Spin up a brand new post with a single command
- Keep my index page tidy and up to date
- Spit out an Atom feed so folks can subscribe
- All without ever leaving the comfort of Emacs
It’s simple. But that’s very much in the spirit of Gemini so let’s dive in!
Core Variables
First, I tell Emacs a few basics about my capsule: where the files live (using TRAMP to talk to my server), what host name they serve under, and when the site was “born” so we can keep our atom feed stable.
|
|
This way, if I ever move the capsule to a new box, I just tweak these values and everything else falls in line.
Utilities
A handful of helpers keep things running smoothly:
- Turning titles into safe filenames
- Grabbing the first paragraph of a post to use as a summary
- Reading titles straight from Gemtext headers
- Formatting timestamps into nice, clean ISO8601 strings
|
|
So “Héllo, World!” becomes hello-world.gmi
. Handy, tidy, and predictable.
Building the Atom Feed
One of my goals was to let people follow my capsule without needing to check it manually. Atom is the perfect format for that: widely supported, and easy to generate.
|
|
It loops through my posts/
directory, pulls out the titles and summaries,
and emits valid Atom XML. With that, anyone can subscribe in their favorite
reader.
Rebuilding the Index
Gemini capsules all have an index.gmi
, but I like to keep a separate Gemlog
index (posts/index.gmi
) that lists posts in reverse chronological order.
Here’s the function that takes care of it:
|
|
Whenever I rebuild the index, I also call +lh/gmi-build-atom-feed
so the
feed is always fresh.
Creating New Posts
The part I touch most often is the “new post” command. It does just enough setup to get me started, then gets out of the way:
|
|
So if I type “My First Capsule Post,” it becomes
2025-09-22-my-first-capsule-post.gmi
, opens remotely via TRAMP, and comes
pre-seeded with a header and navigation links. Then I just write.
Keybindings
Because I’m on Doom Emacs, I wired everything up under the leader key:
|
|
That means SPC n g p
makes a new post, SPC n g r
refreshes the index, and
SPC n g a
regenerates the feed if I want it on demand.
Wrapping up
This isn’t some grand static site generator—and that’s exactly the charm. Gemini thrives on small, hand-rolled tools, and with just a few dozen lines of Lisp I’ve got a pipeline that feels tailor-made for me.
If you’re an Emacs user dabbling in Gemini, consider rolling your own. The nice thing is that nothing here is special: it’s just Emacs Lisp, ready for you to tweak, remix, and shape into whatever fits your corner of the small web.