MDViewer

Feature tour

2026-07-27 1342 words 7 min read

A complete account of rendering, reading comfort, search, editing, export and how it all works.

Features

Rendering

Markdown syntax

On top of CommonMark and GitHub Flavored Markdown, these are also supported:

Syntax How to write it Notes
Tables | a | b | Three alignments; headers can sort
Task lists - [x] done Completed items get a strikethrough
Strikethrough ~~text~~ GFM
Highlight ==text== Yellow highlighter effect
Insert ++text++ Underline
Subscript H~2~O
Superscript x^2^
Footnotes text[^1] Links both ways
Definition lists term, newline, : explanation
Abbreviations *[HTML]: HyperText... Full form on hover
Emoji :rocket: Names become emoji
Autolinks <https://…> Bare URLs are detected too

Math

Rendered by KaTeX , which is far faster than MathJax.

  • Inline: $E = mc^2$ or \(E = mc^2\)
  • Display: $$…$$ or \[…\]
  • Matrices, aligned multi-line alignment, cases piecewise functions, sums and integrals, Greek letters and the symbols from the common packages

The reader guards the $ character, so prices like $100 and $5 - $10 are not mistaken for formulas.

Diagrams

Rendered by Mermaid ; just write them inside a ```mermaid code block. Flowcharts, sequence, class, state, ER, Gantt, pie, user journey, mind map, Git graph, quadrant and timeline diagrams are all supported.

Diagram themes are bound to the site theme variables, so switching to dark mode re-renders them in matching colours. Hover over a diagram to copy its source or download the SVG from the top-right corner.

Syntax highlighting

  • Chroma highlights on the server (documentation pages); highlight.js highlights on the client (the reader). Both use the same colour variables, so the result looks identical
  • Every code block offers a language label, a copy button, a line-number toggle and a soft-wrap toggle
  • Blocks longer than 24 lines collapse automatically; click to expand
  • A title can label the file name:
1
2
3
```js {title="app.js"}
const a = 1;
```

Callouts

Both notations work. GitHub style (available in these docs and in the reader):

1
2
3
4
5
6
7
8
> [!NOTE]
> A general remark

> [!TIP]
> A practical suggestion

> [!WARNING]
> Something to watch out for

Container style (reader only; the documentation pages do not parse it):

1
2
3
::: tip Custom title
The container syntax supports note / tip / important / warning / caution / danger / details
:::

Six types: NOTE TIP IMPORTANT WARNING CAUTION DANGER.

Front matter

YAML (---), TOML (+++) and JSON ({}) are all recognised. title, description, date, author, tags and categories are lifted into the document header; everything else is folded into a “Front matter” card.

Reading comfort

Themes

  • Light, dark and follow-system; press D to cycle
  • An inline script applies the theme before the first paint, so there is no white flash
  • In dark mode the code colours, diagram colours and formula colours all adjust together

Typography

Press , to open the settings panel:

Setting Range
Body text size 13 – 22 px
Line height 1.40 – 2.40
Column width Narrow / normal / wide / full
Body typeface Sans / serif
Code line numbers Show / hide

Settings live in the browser’s localStorage and persist across pages and sessions.

  • File tree: collapsible directories with live filtering by file name
  • Outline: levels 2 to 4, using IntersectionObserver to highlight the current section as you scroll; the outline itself scrolls to follow
  • Reading progress: a gradient bar at the top, plus a back-to-top button once you pass 600 px
  • Position memory: each document’s scroll position is stored as a ratio and restored when you return
  • Previous / next: J and K move through the file list

Images

Click to open the lightbox: scroll to zoom, drag to pan, double-click to toggle 1×/2×, + - 0 for keyboard control, and a direct download.

Cross-file search in the reader

Press / or Ctrl+K. Once a folder is loaded, every Markdown file is read in the background to build a Fuse.js fuzzy index, weighted title > file name > body > path. Results show the file path and a highlighted context snippet; arrow keys select, Enter opens.

Find within a document

Press F or Ctrl+F to highlight matches one by one in the current document. Enter goes to the next, Shift+Enter to the previous, with an “n of m” counter.

The documentation pages are indexed ahead of time, so the search box queries that index entirely in the browser — no backend request.

Editing

Press M to enter edit mode: Markdown source on the left, live preview on the right (debounced at 260 ms), with a draggable divider whose position is remembered in your settings.

  • Toolbar: headings, bold, italic, strikethrough, inline code, three kinds of list, blockquote, link, image, table, code block, formula, Mermaid, callout and horizontal rule. Click again to remove a format you have already applied
  • Keyboard: Ctrl+B/I/K for bold, italic and link; Tab indents a multi-line selection; Enter continues a list and increments the number, and ends the list when pressed on an empty item. Every operation goes through execCommand, so the browser’s native undo stack keeps working
  • Saving: Ctrl+S writes back to the original local file. On the first save the browser asks for permission, upgrading the earlier read-only grant to read-write
  • Drafts: the content is stored in IndexedDB after 1.2 s of idle time. Switching files, closing the workspace or closing the page all prompt for confirmation if there are unsaved changes; next time you open the file, you are offered the draft back
  • Mermaid cache: the preview caches rendered diagrams by source, so typing does not redraw them repeatedly

Note

Writing back to the original file relies on the File System Access API, which only Chrome, Edge and similar browsers support. In Firefox and Safari — and for workspaces opened by drag-and-drop — saving falls back to downloading a .md file.

Export

Method Shortcut Result
Export HTML E One .html file with CSS inlined and images as data URIs; it opens offline
Export PDF P An options dialog, then the browser print pipeline, producing vector text you can select and search

The PDF export lets you set paper size (A4 / Letter / A5), orientation, margins, text scale, a title page, a clickable contents page, whether H1 or H2 starts a new page, whether code wraps, and whether external link URLs are printed. In dark mode, Mermaid diagrams are temporarily re-rendered in light colours so you don’t print pale text on a dark background.

Important

The last step is the browser’s print dialog: set “Destination” to “Save as PDF”. Page numbers and headers are controlled by that dialog’s “Headers and footers” option — Chrome does not support CSS @page margin boxes, so page numbers cannot be drawn with CSS alone.

How it works

Dependencies and size

Module Purpose Size Loaded
Main bundle markdown-it + plugins, highlight.js, Fuse.js, app code ~505 KB On first paint
Docs bundle Enhancement script + search ~60 KB On first paint
KaTeX Formulas ~261 KB + 660 KB of fonts When a formula appears
Mermaid Diagrams ~3.3 MB When a diagram appears

Every dependency is bundled into the output at build time, so no third-party CDN is contacted at runtime. The site can be deployed fully offline, and no external resource can be blocked.

Privacy

  • All file reading and writing happens inside the browser; nothing is ever uploaded
  • No third-party scripts, no analytics, no tracking, no cookies
  • Settings live in localStorage; directory handles, reading positions and editing drafts live in IndexedDB — all on your own machine

Languages

The interface is available in English, Simplified Chinese, Traditional Chinese, Japanese, Spanish and French. English lives at the root; the others sit under /zh/, /zh-hant/, /ja/, /es/ and /fr/, each with its own shareable URL. The globe icon in the header switches at any time, landing on the matching translation of the current page where one exists.

Interface strings live in data/i18n/<lang>.toml, shared by the templates and the browser scripts; a page only loads the strings for its own language. On a first visit, if your browser language differs from the page you are on, a switch prompt appears at the bottom — dismissible for good.