Reading and Writing Gemini Capsules With Emacs Org Mode

Before the internet as we know it today came into existence there was Gopher. This protocol allows users to access plain text menus to view writing, images, and enjoy other digital resources. When Brenners-Lee released the Wold Wide Web in 1991, Gopher slowly faded away in favour of a more graphical web. The world wide web was in these early days an exciting place where people shared ideas and connected with each other. Almost forty years later, AI-generated content and advertising dominates the digital world and we have lost its human dimension.

Gemini is a modern protocol that is similar to Gopher, emphasising simplicity and security. Gemini extends Gopher's original functionality with modern features. The Gemini protocol is a minimalist, text-first alternative to the modern world-wide web. Gemini does not rely on scripts and complex styling and focuses on content. In this ecosystem, you don’t browse websites; you explore "capsules".

Given Gemini's focus on plain-text, Emacs is the ideal environment for both reading and writing within the Gemini space. This article explains how to use Emacs for reading and writing Gemini capsules.

Browsing Gemini capsules

The Elpher Client is an Emacs plugin to view Gopher holes and Gemini capsules. Some configuration are available to change the way Elpher presents information, such as:

(use-package elpher
  :custom
  (elpher-gemini-link-string "🔗 ")
  (elpher-gemini-bullet-string "- "))

Start browsing with M-x elpher-go and enter a Gemini or Gopher address. Some useful keybindings are (press ? for more):

  • O: Back to capsule root page
  • R: Reload the current page
  • ^: Back to previous page
  • TAB and S-TAB: Next and previous link

Writing a Gemlog

If you want to become an active participant in the world of Gemlogs, then Emacs also has you covered. Two methods are available to create a Gemini Capsule with Emacs:

  1. Write directly in Gemtext
  2. Write in Org mode and publish to Gemtext

Write directly in Gemtext

You can write Gemtext files directly in Emacs with Gemini Mode by Jason McBrayer. This package provides a major mode for editing Gemini files (.gmi, .gemini and .geminimap) and provides some convenient keyboard shortcuts:

  • gemini-insert-link: Insert a Gemini Link (C-c C-l)
  • gemini-insert-list-item: Start a new list item (C-c RET)
  • gemini-insert-time-stamp: Insert a timestamp (C-c C-t) in accordance with the gemini-timestamp-format template
  • gemini-open-link-at-point: Open a link in Elpher (C-c C-o)

I have remapped the function to insert list items to C-c -, for Org mode similarity.

(use-package gemini-mode
  :ensure t
  :custom
  (gemini-timestamp-format "%d %B %Y, %H:%M")
  :bind (:map gemini-mode-map
              ("C-c -" . gemini-insert-list-item)))

A Gemini capsule is sometimes also called a Gemlog. Each Gemlog needs to at least have an index.gmi page and the rest is up to you.

Publish a Capsule with Org mode

While writing Gemtext in Emacs is easy, using Org mode adds more flexibility because you can export the same files as a website, ebook, or even a print-ready PDF for a book. The Org publishing functionality also provides some powerful abilities to add dynamic content and automatically generate sitemaps and other embellishments.

The ox-gemini package by Justin Abrams provides an Org mode export backend to either convert individual Org files, or publish a complete capsule. Most Org mode functionality doesn't translate to Gemtext, such as front matter keywords, and image captions, and the export module as such ignores them.

You can add sections that are only included when exporting to Gemtext by wrapping them in a source code structure template, which appears with C-c C-, E gemini. Any text written inside the export block only appears in Gemini exports. Alternatively, you can also add text in an exort_html block so that it only appears in all the web version of your page, and so on.

#+begin_export gemini
```
⠀⠀⠀⠀⡄⠀⢻⡄⢠⡛⠀⢠⠀⠀⠀⠀
⠀⠀⠀⠀⠘⣧⠸⠇⠸⠇⣼⠃⠀⠀⠀⠀
⠀⠘⠶⠶⡄⣠⣶⣿⣿⣶⣄⢠⠶⠶⠃⠀
⠰⠶⣤⡄⣼⣿⣿⣿⣿⣿⣿⣧⢠⣤⠶⠆
```
#+end_export

Exporting individual pages works through the usual org-export-dispatch menu (C-c C-e) and selecting the appropriate menu options.

Exporting each page individually can be tedious, so Org mode's publishing function has you covered. With this functionality you point Org mode to your source files and provide it with a destination, indicate the export format, and Emacs does the rest.

To publish a complete Gemini capsule written in Org, create a project directory to start writing content, for example ~/projects/gemini/content/. This directory will contain your capsule in Org mode, including any images or other attachments. For each project component, the following minimal options are available:

  • :base-directory: Location of the source files
  • :publishing-directory: destination of the exported files
  • :publishing-function: how the files are exported. Some options are:
    • org-html-publish-to-gemini: converts org files to Gentext
    • org-publish-attachment: copies files verbatim
  • :recursive: Set to non-nil when you have files in subdirectories

The example configuration below has two components: the Gemini pages and any related images, each using different source and target directories and publishing functions. For the static files, the targeted files a regular expression indicates the relevant file extensions without the dot. The two components combine to create the "gemini" project. This project will be available for publishing with (org-publish "gemini"), or the dispatch menu with C-c C-e P x.

(require 'ox-publish)

(setq org-publish-project-alist
      (list '("gemini-pages"
              :base-directory "~/projects/gemini/content/"
              :publishing-directory "~/projects/gemini/gemini/"
              :recursive t
              :publishing-function org-gemini-publish-to-gemini)
            '("gemini-images"
              :base-directory "~/projects/gemini/org/images"
              :base-extension "png\\|jpg\\|webp"
              :publishing-directory "~/projects/gemini/gemini/images"
              :recursive t
              :publishing-function org-publish-attachment)
            '("gemini"
              :components ("gemini-pages" "gemini-images"))))

Advanced publishing options

This article only discusses the basics of using Org mode to publish a Gemini capsule. Read the three-part series on publishing websites with Org mode to learn more about its powers.

The code I used to publish this capsule and associated website are available on GitHub. It includes enhancements to the ox-gemini packages for a frictionless experience.