Skip to content

feat(viewer): render Markdown with marked#8

Open
amitrega01 wants to merge 1 commit into
AlmanacCode:devfrom
amitrega01:feat/viewer-marked-renderer
Open

feat(viewer): render Markdown with marked#8
amitrega01 wants to merge 1 commit into
AlmanacCode:devfrom
amitrega01:feat/viewer-marked-renderer

Conversation

@amitrega01

@amitrega01 amitrega01 commented May 16, 2026

Copy link
Copy Markdown

What and why

The serve viewer used a hand-rolled, line-based Markdown renderer that only handled headings, fenced code, and flat - items (emitted as paragraphs). Lists, nested lists, tables, **bold**/*italic*, blockquotes, ---, and multi-line paragraphs were unsupported — almanac pages rendered poorly.

Change

Replace the renderer with marked v18, vendored at viewer/vendor/marked.esm.js (the viewer ships as static assets with no build step) and wrapped by viewer/markdown.js.

Behaviour preserved from the old renderer:

  • [[wikilink]] resolution via a custom inline extension
  • [text](pages/x.md) links resolved to in-app page routes; http(s) links opened in a new tab; unresolvable targets rendered as plain text
  • raw inline/block HTML escaped rather than passed through
  • the first # heading keeps its decorated title + summary + ornament; other level-1 headings demoted to h2

Adds .ca-prose CSS for the newly-rendered elements (lists, tables, blockquotes, hr, strong/em, task-list checkboxes, images).

Testing

  • viewer/markdown.js exercised with a Node render test across all paths (title, wikilink, page-link, dead-link, external link, nested lists, tables, blockquote, escaped <script>, code blocks).
  • test/viewer-ui-assets.test.ts updated for the new architecture.
  • npm test — 479/479 passing, tsc --noEmit clean.

The serve viewer used a hand-rolled line-based renderer that only
handled headings, fenced code, and flat `- ` items (emitted as
paragraphs). Lists, nested lists, tables, bold/italic, blockquotes,
horizontal rules, and multi-line paragraphs were unsupported, so
almanac pages rendered poorly.

Replace it with `marked` v18, vendored at viewer/vendor/marked.esm.js
(the viewer ships as static assets with no build step) and wrapped by
viewer/markdown.js. Behaviour preserved from the old renderer:

- `[[wikilink]]` resolution via a custom inline extension
- `[text](pages/x.md)` links resolved to in-app page routes, http(s)
  links opened in a new tab, unresolvable targets rendered as plain text
- raw inline/block HTML escaped rather than passed through
- the first `# heading` keeps its decorated title + summary + ornament;
  other level-1 headings demoted to h2

Adds ca-prose CSS for the newly-rendered elements (lists, tables,
blockquotes, hr, strong/em, task-list checkboxes, images).
@divitsheth

Copy link
Copy Markdown
Collaborator

Thanks for this, this is a strong direction. The old viewer renderer was intentionally tiny, but it now underserves real Almanac pages pretty badly, so moving markdown rendering into a dedicated wrapper around marked makes sense to me.

I’d like to get two things tightened before merge:

  1. Please add an explicit image renderer / image URL policy. The custom link() renderer routes normal markdown links through the viewer policy, but markdown images currently fall through to marked’s default renderer. That means image targets bypass the same deliberate URL handling we apply to links. Since the viewer renders AI-authored markdown via innerHTML, images should have an explicit policy too: allow the safe image targets we intend to support, and render unsafe or unsupported targets as escaped alt text/plain text.

  2. Please add behavior tests for viewer/markdown.js. The current asset test proves the files exist and are wired, but it doesn’t exercise the renderer behavior. A focused test importing createMarkdown() would make this much safer. I’d cover: decorated first heading, wikilinks, page links, external links, dead links, escaped raw HTML, code blocks, nested lists/tables/blockquotes, and unsafe/unsupported image URLs.

Overall: feature direction looks useful and worth merging once the image policy and renderer tests are in place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants