timescale.info
Sign inSign up

How OpenChronology was built

Every merged pull request of openchronology/timeline-app, its first week of commits and its releases; and before them the 2020 PureScript editor, from snapshots of its deleted repositories in the Wayback Machine. Written to this server through the HTTP API.

327 moments · 2020-03-09T00:15:08Z CE – 2026-11-02T20:11:21Z CE · by @athan · @athan

#400 · Timeline descriptions render their Markdown

  • timeline-app
  • pull request

Fixes #398 A timeline's description is Markdown, like a moment's notes, but it was shown as its source: the `**Explore the story.**` under the title on https://timescale.info/athan/halloween is one example. ## Where the description renders now - **The editor header**, which covers the timeline page, the public reader, View mode, the offline HTML edition and the desktop app. The ` ` is now paired with a rendered view, `#timeline-description-view`. Readers see only the rendered view. An editor clicks the view or tabs to it to edit the Markdown source, and it renders again on blur. An empty description keeps its field open so there is somewhere to type. Clicking a link inside it opens the link without starting an edit. The embed still hides the description, as it did before. - **The timeline page's text for screen readers and search engines** (`TimelineSummary`) renders it as Markdown. - **Timeline cards** on /explore, the dashboard, profiles, landing/audience example cards and browser drafts show a one-line excerpt. The excerpt keeps strong, emphasis and code, and links show as their text. ## Where it is plain text now Page `description`, `og:description` and `twitter:description` all come from `timelineDescription`. The same plain text goes to the timeline's `opengraph-image` and the editor's community list cards. All of them use `markdownText` and contain no markup. ## How `src/rich-text.ts` is split into `parseMarkdown`/`parseInline`, which produce plain data, and the renderers that read it: - the existing DOM `renderMarkdown`, with the same output as before, used by the notes, the hover preview and the reader - `markdownText`, for plain text - a new React `platform/components/markdown.jsx` (`Markdown`, `MarkdownExcerpt`) All of them share the notes' vocabulary and sanitization. Links must pass `safeNoteLink` (https only, with no credentials). There is no raw HTML, the DOM is built directly with no innerHTML, and React escapes every string. No new dependency. Styles: `.description-view` uses the source field's type, colour and size, with strong text in `--ink`. It follows the light/dark tokens, and a mobile breakpoint and the embed rule are included. ## Tests - `test/description-markdown.test.mjs` covers the parser, the plain text, page metadata and preview excerpts, React rendering with HTML/`javascript:` escaped, and card excerpts with truncation. - `test/description-markdown-browser.mjs`, run from `test/browser.mjs`, checks the rendered header, safe links, no injected HTML, click-to-edit, re-rendering on blur, and the empty field. - `npm test`, typecheck, build and prettier pass locally. Run locally against PostgreSQL after merging main (#399): `test/browser.mjs`, `sharing-postgres`, `landing-live-postgres`, `timeline-browser-live-postgres`, `next-platform` and `next-postgres`. Moment and duration notes in entity metadata and JSON-LD are unchanged. They are Markdown only when the rich-text plugin is on.

Sources

Open #400 · Timeline descriptions render their Markdown in the timeline