feat(booth): render .md/.txt/.log inline in the gallery, collapsible + closable
Docs used to render as a clumsy link that navigated to a separate page. They now render in place: build_gallery pre-renders each doc (markdown -> HTML, plain text raw) and the gallery shows it inside a native <details open> disclosure that spans the full grid width so prose has a readable measure. The doc bar carries: a collapse chevron (the whole <details> summary toggles, works with JS off), a full-page link (still reaches the standalone viewer), a download link, and a session-close ✕. The ✕ needed stopPropagation + preventDefault because it lives inside <summary> — otherwise its click would toggle the disclosure instead of hiding the item. Close is JS (progressive enhancement); collapse is native. Two design points: - Plain text is returned RAW from build_gallery and escaped by the template inside <pre>. Pre-escaping in Python plus Jinja autoescape would double-encode angle brackets; a test pins the single-escape. - Inlining is bounded by DOC_MAX_BYTES. A doc over the limit keeps the old link-out behaviour rather than being rendered into every index load; a test covers the fallback. The shared .markdown-body / .textview typography moved from doc.html's scoped <style> into base.html so the inline body and the full-page view render identically; doc.html keeps only its page-layout wrapper. Updated the pre-existing test_gallery_links_docs_to_view: it asserted the old link-out behaviour the operator asked to change, so it now asserts the inline render plus the surviving full-page and download affordances. 61 pass. Verified live: markdown renders with headings/table/blockquote/code, txt preserves whitespace and single-escapes, collapse and ✕-close both work.
This commit is contained in:
+19
-1
@@ -269,13 +269,31 @@ def build_gallery(child: Path) -> list[dict]:
|
||||
if rel in sidecars:
|
||||
continue
|
||||
p = by_rel[rel]
|
||||
dkind = doc_kind(p.name)
|
||||
rendered = None
|
||||
rendered_html = False
|
||||
# Pre-render docs so the gallery can show them INLINE (collapsible)
|
||||
# instead of linking out to a separate page. Bounded by DOC_MAX_BYTES:
|
||||
# a giant log stays a download link rather than being inlined into every
|
||||
# index render. Markdown → HTML (marked safe in the template); plain text
|
||||
# is returned RAW and the template escapes it inside <pre> — pre-escaping
|
||||
# here would double-encode under Jinja autoescape.
|
||||
if dkind is not None:
|
||||
try:
|
||||
if p.stat().st_size <= DOC_MAX_BYTES:
|
||||
text = p.read_text(errors="replace")
|
||||
rendered, rendered_html = render_doc(text, dkind)
|
||||
except OSError:
|
||||
rendered = None
|
||||
items.append(
|
||||
{
|
||||
"name": rel,
|
||||
"kind": classify(p.name),
|
||||
"doc": doc_kind(p.name),
|
||||
"doc": dkind,
|
||||
"url": quote(rel, safe="/"),
|
||||
"caption": caption.get(rel),
|
||||
"rendered": rendered,
|
||||
"rendered_html": rendered_html,
|
||||
}
|
||||
)
|
||||
return items
|
||||
|
||||
Reference in New Issue
Block a user