A small browser-based AsciiDoc viewer that renders
.adoc/.asciidocfiles in the browser using Asciidoctor.js. This repository also includes a plugin-mode HTML that accepts AsciiDoc content from a host (QuickLook, WebView2, etc.) so you can embed the renderer in a native host.
The UI shell mirrors chm: toolbar, Contents sidebar, Shadow DOM content pane, and host messaging.
- Requirements: Node.js (20+ recommended for
@asciidoctor/corev4) and npm. - Clone the repository and install dependencies:
cd src/adoc
npm install- Run development server (hot-reload):
npm run devOpen http://localhost:5173 (Vite default) and use the UI to open a .adoc file.
- Standard build (multi-file output):
npm run buildThis produces dist/index.html, dist/plugin.html and a dist/assets/ folder with JS/CSS bundles.
- Produce self-contained single-file HTML outputs (inlines assets into each HTML):
npm run build:allAfter npm run build:all, dist/index.html and dist/plugin.html will be inlined (single-file) for easy distribution. The intermediate dist/assets/ folder is removed automatically after the assets are inlined.
Files of interest:
- Main app entry: src/app.ts
- Converter: src/lib/convert.ts
- Plugin HTML: plugin.html
- Build helper that inlines assets: scripts/make-singlefiles.js
- Build config: vite.config.ts
The plugin page is dist/plugin.html. In plugin mode the page hides the regular "Open" UI and waits for the host to provide an AsciiDoc file to render. There are multiple ways a host can provide content:
- Query parameters (quick tests)
- Provide a remote URL to fetch (subject to CORS):
dist/plugin.html?adoc=https://example.com/foo.adoc&name=Foo.adoc
- Provide base64-encoded AsciiDoc inline:
dist/plugin.html?adocBase64=<BASE64_DATA>&name=Foo.adoc
- Host → Page messaging (preferred for embedded hosts)
Send a postMessage (or WebView2 message) with type: 'open-adoc' and a payload object. The renderer accepts the following payload fields:
base64— file bytes as a base64 string (recommended for local files)text— raw AsciiDoc stringurl— HTTP(S) URL to fetch (requires CORS)path— treated likeurl(use with caution)name— optional display name for the document
Example (page postMessage):
window.postMessage({
type: 'open-adoc',
payload: { url: 'https://example.com/foo.adoc', name: 'Foo.adoc' }
}, '*');
window.postMessage({
type: 'open-adoc',
payload: { text: '= Title\n\nHello *world*.', name: 'hello.adoc' }
}, '*');
window.postMessage({
type: 'open-adoc',
payload: { base64: '<BASE64_DATA>', name: 'Foo.adoc' }
}, '*');- WebView2 (C#) example (recommended on Windows hosts)
using System.IO;
using System.Text.Json;
var bytes = File.ReadAllBytes(@"C:\path\to\file.adoc");
var base64 = Convert.ToBase64String(bytes);
var msgObj = new {
type = "open-adoc",
payload = new { base64 = base64, name = Path.GetFileName(@"C:\path\to\file.adoc") }
};
var json = JsonSerializer.Serialize(msgObj);
webView.CoreWebView2.PostWebMessageAsJson(json);Notes:
- Using base64 / text avoids CORS and
file://restrictions. - Relative
image::/include::targets are resolved only when the conversion environment can fetch them (typically not available for a lone dropped file). Prefer embedding images as data URIs or having the host expand includes beforehand.
{
"type": "open-adoc",
"payload": { "base64": "...", "name": "Foo.adoc" }
}Internal navigation from rendered content:
{ "type": "adoc-navigate", "href": "#_section_id" }Default is Auto (follow OS light/dark). Use the toolbar sun/moon button to toggle Light ↔ Dark; the choice is saved in localStorage (adoc-theme).
Also supported:
- Query:
?theme=auto|light|dark - Host message:
window.postMessage({ type: 'set-theme', payload: { theme: 'dark' } }, '*');- If fetching via
urlfails: check CORS on the server or prefer sendingbase64/textfrom the host. - If conversion fails: ensure the file is UTF-8 AsciiDoc; check the toolbar status message and browser console.
- If the host webview doesn't forward messages: verify
PostWebMessageAsJson(WebView2) and that CoreWebView2 is initialized.
- Dev server:
npm run dev - Entry: src/app.ts — host-message handling and plugin-mode detection (
window.__adoc_PLUGINor?plugin=1) - Regenerate single-file HTMLs:
npm run build:all