Live Preview & Rendering UI
Relevant source files
The following files were used as context for generating this wiki page:
The Live Preview & Rendering UI is a core component of the cheMD platform, responsible for transforming structured chemical data and Markdown source into a high-fidelity, interactive visual representation. It operates as part of a multi-stage pipeline that converts a single source document into human-readable HTML, machine-readable JSON, and exportable formats like DOCX and SVG.
Sources: chemd-v0.1-architecture.md:52-66, apps/web/src/app/page.tsx:135-150
Architecture & Data Flow
The rendering system follows a "pipeline architecture" where syntax parsing is decoupled from semantic resolution and visual styling. In the web application, this is implemented using a reactive workbench layout consisting of a source editor and an output preview panel.
The diagram shows the flow from raw source through the compiler to the browser-side hydration process.
Sources: chemd-v0.1-architecture.md:68-80, apps/web/src/features/chem-preview/hooks/useRenderedPreview.ts:60-100
Rendering Components
PreviewShell
The PreviewShell component serves as the primary container for all output formats. It manages a tabbed interface allowing users to toggle between the live HTML preview, the normalized JSON output, and the DOCX bridge payload.
| Feature | Description |
|---|---|
| Tabbed View | Supports "preview", "json", and "docxBridge" modes. |
| Freshness Check | Disables export and editing if the preview is out of sync with the source. |
| Sandboxing | Uses an <iframe> with strict Content Security Policy (CSP) to render the preview. |
| Communication | Listens for MessageEvent from the iframe to trigger molecule editing. |
Sources: apps/web/src/features/preview/components/PreviewShell.tsx:29-140
useRenderedPreview Hook
This hook handles the client-side "hydration" of the preview. While the initial HTML is generated by the server or compiler, the hook performs secondary processing:
- Injection: Injects "Edit structure" buttons into molecule blocks.
- SMILES Parsing: Extracts SMILES strings from the rendered HTML blocks.
- Dynamic Rendering: Calls the
/api/chem/renderendpoint for each molecule to fetch high-quality SVG representations. - Replacement: Replaces placeholder graphics in the HTML with the fetched SVGs.
Sources: apps/web/src/features/chem-preview/hooks/useRenderedPreview.ts:61-110
Implementation Details
HTML Rendering Engine
The renderHtml function transforms the ChemdDocument into a semantic HTML structure. It iterates through AST nodes such as reaction, molecule, and analysis, applying specific templates to each.
// packages/renderer-html/src/index.ts:705-725
export const renderHtml = (
document: ChemdDocument,
options: RenderOptions,
adapterPayload?: RenderAdapterPayload
): string => {
const resolvedAdapterPayload = adapterPayload ?? mapRenderOptionsToAdapterPayload(options);
const body = document.children.map((child) => renderNode(child, options, resolvedAdapterPayload)).join("\n");
const diagnostics = document.diagnostics.length
? `<ul class="diagnostics">${document.diagnostics
.map(
(diagnostic) =>
`<li data-severity="${diagnostic.severity}">${escapeHtml(diagnostic.code)}: ${escapeHtml(diagnostic.message)}</li>`
)
.join("")}</ul>`
: "";
return [
`<article class="chemd-document" data-profile="${escapeHtml(options.profileId)}">`,
`<header><h1>${escapeHtml(String(document.meta.title))}</h1><p>${escapeHtml(String(document.meta.date))}</p></header>`,
`<section class="chemd-body">${body}</section>`,
diagnostics,
`</article>`
].join("");
};
Sources: packages/renderer-html/src/index.ts:705-730
Styling & Sandboxing
The preview is styled using a predefined CSS sheet (PREVIEW_DOCUMENT_STYLE) that defines the visual identity for chemical blocks, grids, and inline chemistry (:chem[...]). To ensure security and prevent style leakage, the document is wrapped in a sandboxed environment.
The sequence diagram illustrates how the preview content is prepared and loaded into the isolated iframe.
Sources: apps/web/src/features/preview/styles/preview-document.ts:108-116, apps/web/src/features/chem-preview/hooks/useRenderedPreview.ts:65-90
Interactive Features: Structure Editing
The Rendering UI enables bidirectional interaction. Molecules rendered in the preview contain metadata (via data-node-id) and a bridge script (PREVIEW_BRIDGE_SCRIPT). When a user clicks "Edit structure", the bridge script captures the SMILES and block ID, sending it back to the main UI via window.parent.postMessage.
Sources: apps/web/src/features/chem-preview/hooks/useRenderedPreview.ts:11-40, apps/web/src/app/page.tsx:151-175
Summary
The Live Preview & Rendering UI translates complex chemical Markdown into a professional ELN interface. By utilizing a sandboxed iframe and a reactive hydration hook, it provides a secure and highly responsive environment that supports both visual inspection and interactive chemical structure editing.
Sources: chemd-v0.1-architecture.md:245-255