A Chrome (MV3) extension that renders .geml and .gemlhistory documents in the
browser — locally (file://) and on the web (http(s)://) — using the GEML
reference parser, so what you see matches the spec exactly.
note callouts, code,
and inline markup (*em*, **strong**, `code`, ~~strike~~, links,
[[#id]] auto-references with the target’s label, footnotes, media embeds).spans, and
external data — a src="data.csv" table is fetched at render time, inlined,
and then computed/charted like any inline table.diagram {format=geml-chart …} is drawn as an inline SVG
(bar / line / area / pie / scatter) straight from the table it references.$…$ and === math via KaTeX.format=mermaid via Mermaid. graphviz / d2 / plantuml
are shown as labelled source blocks (no extra engines bundled).#id, a non-table chart data=, etc. show up instead of silently
breaking. This is the part a generic text viewer can’t give you.The extension bundles the parser’s compiled output, so build it first:
cd geml-parser && npm install && npm run build && cd ..
cd integrations/geml-viewer && npm install && npm run build
npm run build writes dist/viewer.bundle.js and copies KaTeX fonts to
dist/fonts/. npm run package additionally produces
geml-viewer-<version>.zip — manifest at the zip root, ready to upload to the
Chrome Web Store.
chrome://extensions, enable Developer mode.integrations/geml-viewer/ directory..geml file over file:// (e.g. file:///…/GEML-spec.geml), or a
raw .geml URL — the raw file, not the GitHub blob page (that one is HTML).
Try the showcase
(a computed table, four charts, a Mermaid flow, and math) or the
GEML spec itself.
For the interactive geml-code-graph, open playground/sample.geml
with its codemap/ folder over file://..geml URL ─▶ content.js (guard: path ends .geml / plain-text page)
─▶ read original text (fetch, fallback to the page's <pre>)
─▶ parse() [geml-parser core, bundled for the browser]
─▶ renderDocument(model, document) [pure DOM, src/render.js]
─▶ replace the page + inject CSS
─▶ upgrade: KaTeX (math), Mermaid (diagrams), inline SVG (geml-chart)
src/render.js is a pure model→DOM function (no KaTeX/Mermaid), so it is unit
tested under linkedom (npm test). Math/mermaid become placeholder elements
that content.js upgrades after injection.alias node:* → src/node-stub.js, define process.argv → []).
The core parse() chain itself uses no Node APIs.The extension collects no data — no telemetry, no page content, nothing transmitted anywhere. Details: PRIVACY.md.
src= tables over file://: fetching a sibling .csv from a file://
page is blocked by CORS (unique origin), so an src table shows a “data not
loaded” placeholder. It works over http(s). Inlining the data avoids this..geml with
Content-Disposition: attachment, the browser downloads it and no content
script runs. Most raw text URLs are fine.graphviz / d2 / plantuml: shown as source (rendering them would mean
bundling large extra engines — out of scope, matching §7’s “preserve the body”
stance)..geml/.md files can’t have their anchors
checked. The parser’s resulting “not checked (no document resolver)” warnings
are a viewer limitation, not a document problem, so they are hidden. A real
broken internal #id is still reported as an error.dist/fonts/ via web_accessible_resources; if
math glyphs look off, re-run npm run build so the fonts are copied.npm test # builds, then runs the linkedom renderer tests