fix: break capsule menus onto separate lines

Index entries were joined with soft breaks, which gemtext lifts to => lines
regardless but the inline formats collapse to spaces, so a six-item area menu
rendered as one run-on line in a browser and on a handset. Hard breaks, two
trailing spaces, become <br/> there and cost gemtext nothing.

Needs itsybitsy 088e860 or later, where a hard break between links no longer
makes the paragraph print its flattened text alongside the link lines.
This commit is contained in:
randogoth 2026-10-06 09:43:01 +03:00
parent bc89e20ee7
commit 80023b9b2e

View file

@ -27,20 +27,20 @@ setting, and every setting has a default, so a site can switch it on with just
Why link-only paragraphs rather than lists: gemtext has one kind of link, a line Why link-only paragraphs rather than lists: gemtext has one kind of link, a line
beginning `=>`, so a renderer has to lift links out of the prose. itsybitsy's beginning `=>`, so a renderer has to lift links out of the prose. itsybitsy's
gemtext renderer emits a bare `=>` line for a paragraph that holds nothing but gemtext renderer emits a bare `=>` line for a paragraph that holds nothing but
links, and tolerates soft breaks inside it, so a run of links on consecutive links, so a run of links comes out as a clean run of link lines. A Markdown list
lines comes out as a clean run of link lines. A Markdown list would instead would instead print a bullet *and* a link line for every entry, listing
print a bullet *and* a link line for every entry, listing everything twice. everything twice.
Gemini clients number link lines themselves, which means a menu of areas is Gemini clients number link lines themselves, which means a menu of areas is
dialled by number without this plugin writing a single bracket. dialled by number without this plugin writing a single bracket.
The trade-off, measured rather than assumed: that shape is exact in gemtext and The links are separated by **hard breaks**, which is two trailing spaces. gemtext
in XHTML-MP, where each link keeps its own line, but the `text` renderer used lifts each link out either way, but the inline formats lay a paragraph out as
for Nex and Gopher reflows the run into a paragraph, so an index comes out as flowing text, so with soft breaks a six-item menu renders as one run-on line in a
`RANDOM · 4 (/area/random) PLACE · 7 (/area/place) …`. A Markdown list would be browser and on a handset. A hard break becomes `<br/>` there and costs gemtext
the better answer for those two and the worse answer for the other three. Links nothing. The `text` renderer used for Nex and Gopher flattens both break kinds to
win, because gemtext is what a capsule is mostly read over; a site serving Nex a space and still reflows, which is the one format this shape does not serve; a
or Gopher as its main face should flip this. site whose main face is Gopher should emit lists instead.
""" """
import os import os
@ -266,7 +266,7 @@ class CapsuleGenerator(Generator):
index = ["# %s" % s.get("SITENAME", "index"), ""] index = ["# %s" % s.get("SITENAME", "index"), ""]
if sections: if sections:
index += ["## %s" % labels["sections"], ""] index += ["## %s" % labels["sections"], ""]
index.append("\n".join( index.append(" \n".join(
link("%s · %d" % (category, len(items)), link("%s · %d" % (category, len(items)),
"/%s/%s" % (section_dir, category.slug)) "/%s/%s" % (section_dir, category.slug))
for category, items in sections for category, items in sections
@ -278,7 +278,7 @@ class CapsuleGenerator(Generator):
link(labels["archive"], "/archive"), ""] link(labels["archive"], "/archive"), ""]
if pages: if pages:
index += ["## %s" % labels["pages"], "", index += ["## %s" % labels["pages"], "",
"\n".join(link(p.title, "/%s" % p.slug) for p in pages), ""] " \n".join(link(p.title, "/%s" % p.slug) for p in pages), ""]
tagline = s.get("SMOLNET_TAGLINE") tagline = s.get("SMOLNET_TAGLINE")
if tagline: if tagline:
index += ["---", "", tagline, ""] index += ["---", "", tagline, ""]
@ -306,7 +306,11 @@ class CapsuleGenerator(Generator):
if getattr(doc, "date", None): if getattr(doc, "date", None):
label = "%s · %s" % (doc.date.strftime("%d %b %y"), doc.title) label = "%s · %s" % (doc.date.strftime("%d %b %y"), doc.title)
rows.append(link(label, "/%s" % doc.slug)) rows.append(link(label, "/%s" % doc.slug))
return "\n".join(rows) # Hard breaks, which is two trailing spaces in CommonMark. gemtext lifts
# each link to its own => line either way, but the inline formats lay a
# paragraph out as flowing text, so without these the whole menu renders
# as one run-on line in a browser and on a handset.
return " \n".join(rows)
def _read(self, doc): def _read(self, doc):
with open(doc.source_path, encoding="utf-8") as fh: with open(doc.source_path, encoding="utf-8") as fh: