Commit graph

10 commits

Author SHA1 Message Date
randogoth
cf29dd7174 fix: smolnet drops a callout marker that has no label
A `> [!kind]` with no title and an empty default label now loses the
marker line entirely, leaving a plain blockquote, instead of printing
an empty bold label.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 11:29:03 +03:00
randogoth
b6418b090f feat: smolnet rewrites > [!kind] callout markers
With SMOLNET_CALLOUTS (kind -> label), the marker line becomes a bold
label and the passage stays a blockquote, instead of the literal
"[!ontology]" printing in the capsule. Unlisted kinds are left alone.
Default {} keeps other sites unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 11:25:13 +03:00
randogoth
a873ef23ea feat: emit capsule entries as lists, with no separator after the date 2026-10-11 16:27:45 +03:00
randogoth
e025f32f61 Fix rewrite_html_links for sites whose URL isn't a bare {slug}.html
It derived the slug to match against by stripping ".html" off a
hardcoded link's basename, which only equals the real slug on a site
whose ARTICLE_URL/PAGE_URL *is* "{slug}.html" -- true for randogoth.com,
where this was first written and verified, false for sublunar.space's
ARTICLE_URL ("{date:%Y}-{date:%m}-{slug}.html": "chaxiraxi"'s real link
target is "2018-06-chaxiraxi.html", whose basename-minus-extension is
"2018-06-chaxiraxi", never equal to the slug "chaxiraxi"). Every such
article-to-article link passed smolnet's own "no match" branch and
reached the capsule unrewritten, pointing at a path itsybitsy has no
document for.

Matches against each document's own rendered .url instead, which is
correct for any ARTICLE_URL/PAGE_URL shape rather than one specific
one. Verified against sublunar.space's full content: the reported
broken link and 160+ others like it across the corpus now resolve;
every remaining unrewritten .html link left in the capsule traces to a
target genuinely absent from it (a tag-index page, a draft, a hidden
page) or to a pre-existing dead link already broken on the live HTML
site, unrelated to this fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-10 15:39:26 +03:00
randogoth
bfb54d3ffa Add footnote support to smolnet
itsybitsy's Markdown parser has no footnote extension enabled, so a
[^key] reference and its [^key]: definition were passing through as
literal bracket text in every capsule. SMOLNET_FOOTNOTES, off by
default, rewrites references into numbered [N] markers in order of
first appearance and relocates definitions to a trailing "## Notes"
section.

Verified against sublunar.space's real content (the first site to turn
this on), which surfaced three cases synthetic test data would not
have:

- A definition whose citation link lazy-wraps onto an unindented
  second physical line (ordinary CommonMark paragraph continuation)
  was truncated at the first newline, leaving the wrapped half as
  orphaned, bracket-broken text in the body. FOOTNOTE_DEF now consumes
  lazy-continuation lines up to the next blank line or next
  definition, and joins them back into one line.
- A reference immediately followed by an ordinary colon in the
  author's own prose ("Gnosis[^gnosis]: collective critique...") was
  being skipped by a now-redundant negative lookahead that existed to
  avoid confusing a reference with a definition's own opening bracket
  -- a confusion FOOTNOTE_DEF already resolves upstream by stripping
  every genuine definition line before FOOTNOTE_REF ever runs.
- An assigned footnote number could collide with a pre-existing bare-
  integer reference-link id already used elsewhere in the same
  article (sixnames.md cites sources that way); CommonMark would
  silently resolve the collision into an unrelated hyperlink. Numbers
  are now assigned skipping any integer a "[N]: url" definition
  already owns in the same document.

randogoth.com has no footnotes in its content (grep confirmed), so it
is unaffected either way; zonetoast.com's content could not be checked
from here, which is why this stays opt-in rather than on by default.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-10 15:24:39 +03:00
randogoth
9817e7190c feat: make the capsule subscribable over Gemini
Link labels in every capsule index are now ISO 8601 and lead with the date,
which is what Gemini's subscription convention reads a feed entry from: the
first ten characters of a label must parse as YYYY-MM-DD or the line is
ignored. The board's `09 Oct 26` parsed as nothing, so the front page, the
archive and all six areas registered zero entries and the capsule was
invisible to every aggregator in Geminispace. `/archive` now carries 36.

The Connect page advertised `/feeds/all.rss.xml` and `/feeds/all.atom.xml`,
which exist only in the HTML build and 404 over Gemini. That paragraph now
sits behind an itsybitsy `only html` format gate, with prose outside it that
is true on both faces. The gate can only cut that way round: Pelican does not
implement the directive and renders it as an inert comment, so a gate
subtracts from the capsule and never from the site.

Also adds dormant `SMOLNET_COMMENTS` support, for a per-article thread link
gated to the text formats. Off until kapara is deployed, since setting it
would put a dead link under every article.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-09 17:19:50 +03:00
randogoth
0d7e98a0d9 feat: make smolnet usable by a site that is not randogoth.com
Three changes, each found by pointing it at zonetoast, which files by tag
rather than category and writes its links by hand.

A single-bucket taxonomy is dropped. Pelican gives every uncategorised article
its DEFAULT_CATEGORY, so a tag-filed site still has one category holding
everything, and offering "misc, 14" as the only way in is worse than offering
nothing at all. Below SMOLNET_MIN_SECTIONS the whole section index goes.
randogoth.com still gets its six areas.

Links written against the HTML build are rewritten. {filename} is the portable
form, but content predating that knowledge hardcodes the output URL instead,
and zonetoast is full of ](/go-west.html). A capsule has no .html and the
daemon resolves a name carrying an extension literally, so all seventeen of
them 404'd. They now map onto the flat capsule slug, /pages/glossary.html
included, and a target matching no document is reported rather than silently
rewritten into a second broken link.

The line under an article title is a setting. Date and category is the right
default, but a site whose category is always `misc` has something better to
say: zonetoast carries `era`, which is what it is actually organised around,
so its articles read "17 May 2026 · 1996".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-06 12:21:46 +03:00
randogoth
4efe975599 fix: recover one hotlinked image, retire the other eleven
Twelve images across seven articles were hotlinked from servers that no longer
exist, so they were broken on the live sites. Checked every one against the
Wayback Machine, patiently enough to trust the answer: an earlier pass appeared
to find seven, but that was a test treating an empty response as a hit.

One survives. visualberlin.org's p1010789, a 2011 capture of the projector set
up against Mannheim city hall during the Flimmerkiste wildscreening, is now a
local asset in flux.vision/content/library/ and the reference points at it.

The other eleven were never captured. Both dead domains are archived, so this is
not a gap in coverage: of 8,438 visualberlin.org URLs and 204 for mutanten.org,
only that one image is there. mutanten.org's archive does not reach back to its
fp-content era at all, which is where the Logan's Run stills lived.

So lostimages.py learns about dead hosts, which it matches rather than fetching,
because a build must not depend on the network and a dead host is a fact about
the world rather than about the document. The references stay in the Markdown,
as the existing ones do: the reference records what was there.

It matters more on the capsule than on the web. A browser shows a broken image
as a silent gap, but gemtext has no inline images, so every one becomes a
visible => link line and the page would advertise a dead host as somewhere worth
going. smolnet.py therefore strips them too, reading the same host list, since
it works on the Markdown source and never sees Pelican's output.

lostimages.py moves to the repo-level plugins/ directory beside smolnet. It was
shared already, with flux.vision reaching into tobias.raayoni-last.com for it,
and randogoth.com now needs it too; a shared plugin living inside one site was
the wrong shape for three consumers.

Left alone deliberately: the two mutanten.org links in mutantenkino-website.md.
That entry is about having built the site, so the link is its subject rather
than decoration, and a dead link does not make the record wrong.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-06 11:04:28 +03:00
randogoth
80023b9b2e 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.
2026-10-06 09:43:01 +03:00
randogoth
5131f1f53f feat: render randogoth.com as a small-net capsule
A Pelican generator that writes a capsule beside the HTML build: plain
Markdown plus per-directory .itsybitsy.toml sidecars, which a protocol daemon
converts per request to gemtext, XHTML-MP, WML or plain text.

The obstacle was recorded in the README as "smolweb reads YAML frontmatter
while Pelican uses bare Title: lines". Both halves turned out to be wrong:
itsybitsy parses no frontmatter at all, by design, and metadata lives outside
the document. So the transform is not a translation between dialects, it is a
removal, and a protocol daemon stays ignorant of one static generator.

Nothing in plugins/smolnet.py is specific to this site. Every difference is a
setting and every setting has a default, so another site enables it with
PLUGINS = ['smolnet']. It sits at the repo root for the same reason
flux.vision reaches into tobias.raayoni-last.com for lostimages.

Index entries are emitted as link-only paragraphs rather than Markdown lists,
which is not a style choice: the gemtext renderer prints a bare => line for a
paragraph holding nothing but links, and a bullet *and* a => line for a list
item, so a list would publish every entry twice. Gemini clients number link
lines themselves, so the board's dial-an-area-by-number idiom survives into
the capsule without emitting a single bracket. The trade-off is in the
docstring: the text renderer reflows such a run into prose, which costs
nothing here because randogoth.com is not getting Nex or Gopher.

Also drops a Zemanta tracking pixel that came in with a 2012 blog import and
is live on the site today, firing a third-party request on every view of that
article. It would have been worse in the capsule, where an image becomes a
visible link line advertising a dead tracker. It was the only one across all
three sites.

Verified by serving the output with the real daemon: 41 articles, 2 pages, 6
area indexes and an archive, no metadata surviving, no {filename} left,
trl@posteo.net revealed on Connect where the renderer would otherwise have
dropped it with its enclosing HTML, images served as image/png, and the index
rendering as a clean run of => lines in gemtext and as XHTML Mobile over HTTP.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-06 08:24:18 +03:00