rfd: add freshness, inspired-by metadata and KaTeX #9

Merged
leoqi merged 27 commits from rfd/tree-and-relevance into main 2026-06-09 17:28:29 +00:00
Owner
No description provided.
Add two new YAML metadata fields to RFD documents:
- inspired-by: Array of RFD numbers that inspired this one (freshness
  forward links)
- freshness: Content relevance with values "fresh", "stale", or "rotten"

The inspired-by field can be a single number or an array:
  inspired-by: 1
  inspired-by: [1, 2, 10]

Freshness values:
  freshness: fresh    # current, actively maintained
  freshness: stale    # aging, needs review
  freshness: rotten   # obsolete

Implementation:
- Two-pass pandoc build using Lua filters (collect_inspired.lua and
  render_metadata.lua) to extract and render metadata
- Type-safe validation: invalid values (non-positive integers for
  inspired-by, invalid freshness values) are handled gracefully:
  * Invalid inspired-by values cause the entire field to be treated as
    absent (no backlinks generated)
  * Invalid freshness values display as light-gray badges
- Deduplicates inspired-by array values
- Broken links are intentionally created (e.g., referencing non-existent
  RFDs) with semantic color coding for freshness

Files changed:
- build.osh: Add pass 1 loop and use render_metadata.lua in pass 2
- collect_inspired.lua: New pass 1 filter to collect inspiration pairs
- render_metadata.lua: New pass 2 filter to render metadata
- templates/rfd.html: Add freshness, inspired, inspired-by rows
- static/styles.css: Add freshness badge and link styles
- template.md: Add commented field documentation
Rename metadata fields to match user mental model:
- YAML field `inspired-by`: RFDs that inspired this one (user-editable)
- HTML row "Inspired": Auto-generated backlinks from referencing RFDs

Previously, `inspired` was user-editable (forward links) and `inspired-by`
was auto-generated (backlinks). Now the user edits `inspired-by` to list
what documents inspired theirs, which is more intuitive.

Changes:
- templates/rfd.html: Swap row order ($if(inspired-by)$ before $if(inspired)$)
- render_metadata.lua: Swap field logic in Meta() function
- collect_inspired.lua: Update comments to reference inspired-by
- template.md: Update documentation examples
- docs/*.md: Update test RFDs to use inspired-by

Files changed:
- render_metadata.lua
- collect_inspired.lua
- templates/rfd.html
- template.md
- docs/2.md, docs/10.md, docs/11.md
- INSPIRED_AND_FRESH.md (documentation)
Changes:
- Add '|| true' after command substitutions to fix strict_errexit warnings
- Add tex_math_dollars markdown extension
- Add --katex flag to pandoc for KaTeX rendering
- Copy katex.min.js and katex.min.css to static/ directory
- Include KaTeX CSS in template HTML
- Configure KaTeX delimiters in page template ($...$ and 298$)

Files changed:
- build.osh: Fix strict_errexit warnings, add tex_math_dollars + --katex
- templates/rfd.html: Include KaTeX CSS and JS with delimiters
- templates/index.html: Include KaTeX CSS
- static/: Add katex.min.js and katex.min.css
- docs/8.md: Add examples for inline and display math

Testing shows no more TeX conversion warnings in nixlog.txt.
KaTeX properly renders inline math with single $ and display
math with double 298 delimiters.
Fix OSH strict_errexit errors by separating local declarations from
assignments (local var; var=$(cmd)) and removing || true after
ShAssignments which is prohibited by OILS-ERR-300.

Add KaTeX support for rendering TeX math in RFD documents:
- Add tex_math_dollars extension to all pandoc invocations
- Add --katex flag to pandoc for RFD and index page builds
- Copy katex.min.js, katex.min.css, and KaTeX fonts to static/
- Include katex.min.css in rfd.html and index.html templates
- Add math examples to RFD 8 for testing

Files changed:
- build.osh: Fix strict_errexit, add tex_math_dollars + --katex
- templates/rfd.html: Include katex.min.css and katex.min.js
- templates/index.html: Include katex.min.css
- static/katex.min.js, static/katex.min.css: KaTeX assets
- static/fonts/KaTeX_*: KaTeX font files
- docs/8.md: Add inline and display math examples
The katex/ directory and katex.tar.gz are build inputs already handled
by the nix derivation. nixlog.txt is a transient build log. Both are
now in .gitignore. Only the files actually needed at runtime
(katex.min.js, katex.min.css, fonts/) remain in static/.
Pandoc with --katex flag automatically injects the necessary KaTeX
JavaScript and CSS with renderMathInElement call, so the manual
script tag is redundant and causes template compilation errors.

Files changed:
- templates/rfd.html: Remove <script src="/katex.min.js"> tag
Provide absolute path to local KaTeX file via --katex=/katex.min.js
instead of relying on default CDN. Pandoc with --katex=URL automatically
injects the KaTeX JavaScript with renderMathInElement call, so manual
script tag is not needed.

Files changed:
- build.osh: Change --katex to --katex=/katex.min.js
- templates/rfd.html: Remove manual KaTeX script tag (now auto-injected)
Pass 1 only needs yaml_metadata_block to parse frontmatter and run
collect_inspired.lua. Remove all rendering extensions, template,
citeproc, katex, toc, etc. from pass 1 since output goes to /dev/null.

Pass 2 keeps all extensions and restores --citeproc for citation
processing.

Changes:
- Pass 1: --from markdown+yaml_metadata_block --to plain, no template
- Pass 2: --citeproc restored, all rendering extensions kept
- Both passes: --katex=/ for local KaTeX
Two regressions fixed:

1. extract_rfd_metadata used 'echo' which in OSH does not interpret
   \t escape sequences, outputting literal '\t' instead of tab chars.
   This broke the JSON data for the index page, causing tab-separated
   strings to appear in table cells and link hrefs. Fixed by using
   printf with %s format specifiers.

2. search.js and landing.js were in static/ but not referenced in
   templates, so Stork search never initialized. Added script tags
   for search.js (both templates) and landing.js (index template).

Files changed:
- build.osh: echo -> printf in extract_rfd_metadata
- templates/rfd.html: Add search.js script tag
- templates/index.html: Add search.js and landing.js script tags
Changed --katex=/ to --katex=katex.min.js. The --katex flag with
a URL expects the KaTeX files to be in the same directory as the
output HTML. Using the filename directly tells pandoc to look for
katex.min.js and katex.min.css in the output directory.

Without this fix, pandoc would not inject the KaTeX JavaScript
script tag, so TeX math was not rendering.
Pandoc's --katex flag for local files didn't properly inject the
JavaScript. Removed the flag and added the KaTeX script tag
manually with renderMathInElement configured with $ and 793 delimiters.

Files changed:
- build.osh: Remove --katex flags
- templates/rfd.html: Add <script src="/katex.min.js"> with delimiters
Move the renderMathInElement delimiters configuration from inline
script tag to static/katex-render.js for cleaner code organization.

Files changed:
- static/katex-render.js: New file with math rendering config
- templates/rfd.html: Include katex-render.js instead of inline script
renderMathInElement is not available at script parse time because
katex.min.js loads asynchronously. Wrap the call in DOMContentLoaded
event to ensure the function exists before calling it.

Files changed:
- static/katex-render.js: Wrap in DOMContentLoaded listener
Include auto-render.min.js for automatic math rendering and
mhchem.min.js for chemical formulae support. These are necessary
for proper KaTeX math rendering.

Files changed:
- static/auto-render.min.js: New (copied from katex/contrib)
- static/mhchem.min.js: New (copied from katex/contrib)
- templates/rfd.html: Add mhchem.min.js script
- templates/index.html: Add mhchem.min.js script
The landing page doesn't need math rendering, so remove all KaTeX-related
scripts and CSS that were only needed for RFD pages with math.\n\nFiles changed:\n- templates/index.html: Remove auto-render.min.js, mhchem.min.js, katex-render.js, katex.min.js and katex.min.css
mhchem and auto-render depend on katex.min.js being loaded first.
Move katex.min.js before its extensions to fix TypeError on
__defineMacro and ParseError.

Load order: katex.min.js -> mhchem.min.js -> auto-render.min.js -> katex-render.js
Scripts with defer execute in order after the document is parsed,
preventing render-blocking and ensuring correct load order.
main.js now calls initSearch('search-input', 'search-output') so the
search box on individual RFD pages actually triggers Stork search.
Previously only landing.js called initSearch, so search only worked
on the index page.
The IIFE in search.js never exported initSearch because the guard
'if (typeof initSearch === undefined)' checked the local variable
which was always defined. Replace with proper ES module exports.

- search.js: export initSearch, remove IIFE wrapper
- main.js: import initSearch from search.js, call it directly
- landing.js: import initSearch from search.js, call it directly
- Templates: use type="module" for main.js/landing.js, remove
  explicit search.js tag (imported by modules)
When the search input is focused and the user presses Escape,
blur the input and hide the search output.
The document-level keydown listener was likely intercepted by
main.js TOC handler which also listens for ESC. Move the listener
to the input element itself so it fires reliably.
The TOC ESC handler unconditionally called preventDefault() and
toggled the TOC, swallowing every ESC keypress. Now it returns early
when the search input is focused, letting the search handler blur it.
Remove the toggle behavior: pressing Escape when the TOC is closed
does nothing. When open, it closes.
leoqi merged commit 8d9a36ebc6 into main 2026-06-09 17:28:29 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
simplefast/rfd!9
No description provided.