feat: emit capsule entries as lists, with no separator after the date
This commit is contained in:
parent
e025f32f61
commit
a873ef23ea
1 changed files with 31 additions and 36 deletions
|
|
@ -32,23 +32,18 @@ setting, and every setting has a default, so a site can switch it on with just
|
||||||
every site using this plugin has been
|
every site using this plugin has been
|
||||||
checked for footnotes
|
checked for footnotes
|
||||||
|
|
||||||
Why link-only paragraphs rather than lists: gemtext has one kind of link, a line
|
Every run of links here is a **Markdown list**, which is what each format needs:
|
||||||
beginning `=>`, so a renderer has to lift links out of the prose. itsybitsy's
|
Mews Profile reads a dated link as a feed entry only when it starts a list item
|
||||||
gemtext renderer emits a bare `=>` line for a paragraph that holds nothing but
|
(mews.page/spec 6.1), and the `text` renderer used for Nex and Gopher keeps one
|
||||||
links, so a run of links comes out as a clean run of link lines. A Markdown list
|
item per line instead of reflowing a paragraph into a run-on line. gemtext has
|
||||||
would instead print a bullet *and* a link line for every entry, listing
|
one kind of link, a line beginning `=>`, and itsybitsy prints only those lines
|
||||||
everything twice.
|
for a list item that holds nothing but links, so no entry is listed twice.
|
||||||
|
|
||||||
|
That last part is a floor on the daemon version: an itsybitsy before the fix in
|
||||||
|
its gemtext renderer prints a bullet *and* a link line for every entry here.
|
||||||
|
|
||||||
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 links are separated by **hard breaks**, which is two trailing spaces. gemtext
|
|
||||||
lifts each link out either way, but the inline formats lay a paragraph out as
|
|
||||||
flowing text, so with soft breaks a six-item menu renders as one run-on line in a
|
|
||||||
browser and on a handset. A hard break becomes `<br/>` there and costs gemtext
|
|
||||||
nothing. The `text` renderer used for Nex and Gopher flattens both break kinds to
|
|
||||||
a space and still reflows, which is the one format this shape does not serve; a
|
|
||||||
site whose main face is Gopher should emit lists instead.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
@ -350,6 +345,11 @@ def link(label, href):
|
||||||
return "[%s](%s)" % (label.replace("]", ""), href)
|
return "[%s](%s)" % (label.replace("]", ""), href)
|
||||||
|
|
||||||
|
|
||||||
|
def bullets(items):
|
||||||
|
"""A Markdown list, one item per line. See the module header."""
|
||||||
|
return "\n".join("- %s" % item for item in items)
|
||||||
|
|
||||||
|
|
||||||
def gate(block, formats):
|
def gate(block, formats):
|
||||||
"""Wrap a block in an itsybitsy format gate.
|
"""Wrap a block in an itsybitsy format gate.
|
||||||
|
|
||||||
|
|
@ -490,7 +490,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(bullets(
|
||||||
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
|
||||||
|
|
@ -502,7 +502,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), ""]
|
bullets(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, ""]
|
||||||
|
|
@ -514,10 +514,7 @@ class CapsuleGenerator(Generator):
|
||||||
self._copy_assets(out)
|
self._copy_assets(out)
|
||||||
|
|
||||||
def _links(self, docs):
|
def _links(self, docs):
|
||||||
"""One link per line in a single paragraph.
|
"""A list of dated links, one entry per item.
|
||||||
|
|
||||||
Deliberately not a Markdown list: a list item renders as a bullet *and*
|
|
||||||
a link line, so every entry would appear twice.
|
|
||||||
|
|
||||||
Targets are root-relative. A section index sits one directory down, so
|
Targets are root-relative. A section index sits one directory down, so
|
||||||
relative targets would need `../` and would break again at any further
|
relative targets would need `../` and would break again at any further
|
||||||
|
|
@ -525,29 +522,27 @@ class CapsuleGenerator(Generator):
|
||||||
against the site root.
|
against the site root.
|
||||||
|
|
||||||
The date is ISO 8601 and it leads the label, which is protocol surface
|
The date is ISO 8601 and it leads the label, which is protocol surface
|
||||||
rather than a style choice. Gemini's subscription convention takes a
|
rather than a style choice. Both subscription conventions this capsule
|
||||||
link line for a feed entry when the first ten characters of its label
|
is read through take a link as a feed entry when its label begins with
|
||||||
are a `YYYY-MM-DD` date, reads the rest as the title, and ignores every
|
a `YYYY-MM-DD` date and read the rest as the title: Gemini's over the
|
||||||
line where they are not, so this one format is what makes each index a
|
`=>` lines, Mews Profile's over the list items (6.1). That one format is
|
||||||
feed: the front page, the archive and all six areas, subscribable in a
|
what makes each index a feed: the front page, the archive and all six
|
||||||
client and submittable to an aggregator. A board's `09 Oct 26` parses
|
areas, subscribable in a client and submittable to an aggregator. A
|
||||||
as nothing and registers zero entries.
|
board's `09 Oct 26` parses as nothing and registers zero entries.
|
||||||
|
|
||||||
The separator is the one the convention's own examples use. Clients are
|
Nothing separates the date from the title. Gemini's examples put a dash
|
||||||
asked to sanitise whatever sits between the date and the title, but not
|
there and ask clients to strip whatever they find, but Mews reads the
|
||||||
all of them do, and a `·` that survives arrives as part of the title.
|
label from the date to the end of the line, so a separator arrives as
|
||||||
|
part of the title -- as does a `·` in a Gemini client that skips the
|
||||||
|
sanitising step.
|
||||||
"""
|
"""
|
||||||
rows = []
|
rows = []
|
||||||
for doc in docs:
|
for doc in docs:
|
||||||
label = doc.title
|
label = doc.title
|
||||||
if getattr(doc, "date", None):
|
if getattr(doc, "date", None):
|
||||||
label = "%s - %s" % (doc.date.strftime("%Y-%m-%d"), doc.title)
|
label = "%s %s" % (doc.date.strftime("%Y-%m-%d"), doc.title)
|
||||||
rows.append(link(label, "/%s" % doc.slug))
|
rows.append(link(label, "/%s" % doc.slug))
|
||||||
# Hard breaks, which is two trailing spaces in CommonMark. gemtext lifts
|
return bullets(rows)
|
||||||
# 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:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue