blob: f84a797d4a9891c5f7607902aa4cf8f5518a65eb (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Moving my weblog off Gemini (without leaving it) — tjp.lol</title>
<meta name="description" content="How I mirror my Gemini capsule to the web without abandoning geminispace.">
<link rel="stylesheet" href="../style.css">
<link rel="alternate" type="application/atom+xml" title="tjp.lol" href="../feed.xml">
</head>
<body>
<div class="wrap">
<header class="site">
<h1 class="brand"><a href="../index.html">~tjp<span class="cur"> $_</span></a></h1>
<nav class="main">
<a href="../weblog/index.html" aria-current="page">weblog</a>
<a href="../notes/index.html">notes</a>
<a href="../projects/index.html">projects</a>
<a href="../about/index.html">about</a>
<a href="../feed.xml">rss</a>
</nav>
</header>
<main>
<article class="post">
<div class="post-head">
<p class="meta"><a href="../weblog/index.html" style="text-decoration:none;">← weblog</a> / <time datetime="2026-06-30">2026-06-30</time></p>
<h1>Moving my weblog off Gemini (without leaving it)</h1>
<div class="tags" style="margin-top:.5rem;">
<a href="../weblog/index.html">gemini</a><a href="../weblog/index.html">small-web</a><a href="../weblog/index.html">tools</a>
</div>
</div>
<p><em>This is placeholder text laid out so you can see how a full post reads. Replace it with the real <span class="mono">.gmi</span> content when you export the capsule — the structure below covers everything a converted Gemini post will need: headings, lists, quotes, code, and links.</em></p>
<p>I've kept a capsule at <code>gemini://gemini.ctrl-c.club/~tjp/</code> for a few years now. Gemini is a lovely place to write: the format is so constrained that there's nothing to fiddle with, and the whole thing rewards plain, linear prose. But I wanted a web presence too — one that fits in with the personal sites I keep finding in webrings.</p>
<h2>The plan</h2>
<p>The goal was never to abandon geminispace. It was to have both, from one source of truth. Gemtext is close enough to Markdown that a small converter gets you most of the way there:</p>
<ul>
<li>Keep writing <code>.gmi</code> files in my capsule.</li>
<li>Run a converter that emits HTML with the same structure.</li>
<li>Wrap each page in the site template you're reading now.</li>
</ul>
<h2>The converter</h2>
<p>Gemtext has exactly one block-level construct per line, which makes parsing almost insultingly simple. Here's the core of it:</p>
<pre><code>while IFS= read -r line; do
case "$line" in
"### "*) echo "<h3>${line#### }</h3>" ;;
"## "*) echo "<h2>${line### }</h2>" ;;
"# "*) echo "<h1>${line## }</h1>" ;;
"=> "*) emit_link "$line" ;;
"* "*) emit_list_item "$line" ;;
"> "*) echo "<blockquote>${line#> }</blockquote>" ;;
"") echo "" ;;
*) echo "<p>$line</p>" ;;
esac
done < "$1"</code></pre>
<p>That's genuinely most of it. The fiddly parts are link lines (<code>=></code> can be a bare URL or have link text) and collapsing runs of <code>* </code> lines into a single <code><ul></code>.</p>
<blockquote>The best format is the one that outlives the tool you wrote it in. Gemtext will still be readable when this converter is long gone.</blockquote>
<h2>What I kept</h2>
<p>No client-side anything. The web version renders identically with JavaScript disabled, because there is no JavaScript to disable. Fonts are whatever your system already has. The whole page is a few kilobytes.</p>
<p>If you want the source, it lives with the rest of my <a href="../projects/index.html">projects</a>. And the capsule is still there — see the <a href="../about/index.html">colophon</a> for how it all fits together.</p>
</article>
<nav class="post-nav">
<a href="../weblog/index.html">← Older</a>
<a href="../weblog/index.html">All posts</a>
<a href="../weblog/index.html">Newer →</a>
</nav>
</main>
<footer>
<div class="ring">
<span>webring:</span>
<a href="#">← prev</a><a href="#">rand</a><a href="#">next →</a>
</div>
<p>hand-written in slc · ©2026 tjp · content <a href="../about/index.html">CC BY 4.0</a> · <a href="../feed.xml">feed</a></p>
</footer>
</div>
</body>
</html>
|