kota's memex

The other day, I wrote about having finally setup a gemini capsule. I've been fascinated by gemini ever since I learned of it late last year. It's a new internet protocol and markup format designed in the ways of old, but with insight from the present. Much like http/html in it's early days gemini's purpose is for sharing linked documents. It's a very simple protocol -- most novice programmers could write a basic client or server in a weekend or two. The design is nearly finished and doesn't leave much room for expansion, there are nice clients on every platform, and a small ecosystem of "capsules" has been growing steadily, forming a little community.

The goal isn't to "replace" http/html -- at least not in full. The old internet grew and grew until it stuffed every use case known to man on top of its rickety old systems. Today's internet has massive energy waste, serious privacy and security issues, baked in DRM, and is effectively controlled by an advertising monopoly with a shrinking sliver of opposition.

I don't think gemini can or will solve these issues. Resolving the core contradictions in society that lead to our internet being controlled by an advertising monopoly requires more widespread action and a multi-faceted material attack on capital. That said it would also be foolish to dismiss the internet, our shared communication medium, as void of political and social importance.

There is no way to retreat into a pre-internet era. Instead of self-flagellating and guilt-tripping, pretending we can escape our wired future by unplugging, we need to take our participation in the medium seriously and in a way that integrates well with our offline organization. -- Roderic Day

In my mind gemini exists to wall off a space away from advertisers and billionaire news sites. It exists for the rest of us. For document sharing, story telling, and interesting new ideas. A possible future would involve replacing portions of the old web with small purposeful protocols and tools that have learned from the mistakes that allowed the web to be captured. Leaving only a shrinking portion of web apps and "interactive posters" on http, while at the same time fighting the material forces that ruined our internet in the first place.

The weapon of criticism cannot, of course, replace criticism by weapons; material force must be overthrown by material force. -- Marx

Theory aside, I enjoyed browsing these little gemini capsules between fixing old computers, in my little windowless office at my last job. The discussions at the pub, rants about shitty retail jobs, stories from deep space, and notes about low-tech life got me through those slow afternoons.

When I decided to make a capsule, I considered simply writing the gemtext by hand and maintaining two separate copies. Plenty of people do this, but there were a couple of concerns I had with this approach. I didn't want the capsule to be missing anything significant from my web blog. Everything on it, except perhaps some old videos, fits neatly within gemini's restrictions. I don't want people to have to check both the web and gemini versions of my site to see if they missed anything. As such I was worried over time I would update stuff on one version and forget about the other and that it might feel too tedious to rewrite some of my older less interesting posts in gemtext. My next idea was to rewrite everything in gemtext and then use a tool to output it to html, the gemini project page does this and honestly it's a good idea if you're just starting up a new blog/capsule. I decided against it since I quite like the look and feel of my web blog. I've put great care into making it aesthetically pleasing while being very fast and light weight. My final idea was to use a tool to convert my markdown source files to gemtext.

I found a program called md2gemini which works nicely and has several options for customizing the "look" of your gemtext (where links are placed, leaving asterisks or removing them, etc). It also helped that md2gemini is developed by makeworld who created amfora, and an awesome dithering library. I quickly hacked together the following script:

# gem_gen.sh hugo/content/ gemini/ scripts/head.gmi
# by kota

cp -r "$in" "$out"
for file in "$out"/*.md; do
	[ -f "$file" ] || continue
	gmi="$out"$(basename "$file" ".md").gmi
	# ignore drafts
	if ! grep -q "draft: true" "$file"; then
		# skip existing gemini files
		! [ -f "$gmi" ] || continue
		printf '%s\n' "$gmi"
		# add gemini header
		cat "$heading" > "$gmi"
		# delete front matter
		sed -n '1{/^---$/!q};1,/^---$/d;p' "$file" | md2gemini -l "copy" >> "$gmi"

It copies your markdown files over to a gemini folder, loops through them (skipping ones that contain draft: true used by hugo to mark a file as a draft), adds a gemini header, deletes the hugo metadata, and then stores the gemtext file. I was pretty happy with this, but then I started to get picky. I wanted a bit more control. Some of my articles have lists of links, but in markdown they're considered "paragraphs", so md2gemini listed all of the links twice -- once as text and once as links which looked silly. Additionally, I couldn't easily generate a nice index page automatically and didn't have a great way to reliably pull data from hugo's "frontmatter".

I could've just expanded my script to account for these issues, but I figured I'd just use md2gemini as a python library instead. I fired up a new python script in vim and realized I had pretty much completely forgotten how to use python over the last few years. I started reading documentation, got bored and confused, decided to go climbing for a few hours, and then went to sleep.

The next morning, I decided to investigate which markdown parser hugo uses since that's the exact type of markdown I'm trying to parse. It uses goldmark which claims to be fast, easy to extend, and even has examples for parsing the hugo yaml metadata (called frontmatter). I browsed the codebase a bit. It's split up into neat little segments -- one of which is the "html renderer", but there's also a pdf renderer you can use instead. I spent the next few hours messing around in Go and was able to implement a basic gemtext renderer for goldmark. It worked shockingly well and was stupid fast, by the end of the day I had a fully fledged go module. So, I wrote a little program using that library to generate my capsule exactly as I wanted.

Sadly, that program is very specific to my site (literally hard coded to look for certain files). In the interest of making something more universally useful, I decided to write gemgen which is sorta like md2gemini but using my goldmark library. After a few more days of ironing out the kinks I made gemgen. One of the biggest differences between gemgen and md2gemini (other than the language and parser) is that I took some fairly opinionated design choices in order to generate "hand-made" looking gemtext. Meaning I wanted the default output gemtext to look as though it was originally written as gemtext. That means stripping out markup symbols by default, displaying links below a paragraph with their link text -- yet not duplicating lists of links or images. I have a number of new feature ideas for gemgen such as an option to "query" the yaml frontmatter itself, read and write files concurrently, and support something similar to hugo's shortcodes (basically a templating extension for markdown). Ideally, I'd like to be able to replace my highly specific program with a few gemgen commands in a shell script that can be used for others in my situation of converting their web blog to gemini.

As for server hosting, I'm using molly-brown at the moment, but I'm considering switching to gmnisrv. I also tried out vger on an old OpenBSD computer and loved it, but sadly it doesn't seem easy to use on my current server running Debian (which I'm using due to issues with synapse on OpenBSD). There are loads of good gemini servers to pick from as well as free gemini hosting offered by sourcehut, which is great if you don't have good home internet, time to set up a server, or money to rent a VPS. At the very least I encourage you to grab a client and explore gemini, I use amfora on my computer and ariane on my phone. You can checkout my site over gemini or any of the other links in this post, but I highly suggest a directory such as medusae as a jumping off point.