# @mlightcad/cad-html-plugin [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![npm version](https://img.shields.io/npm/v/@mlightcad/cad-html-plugin.svg)](https://www.npmjs.com/package/@mlightcad/cad-html-plugin) HTML **export** for [`@mlightcad/cad-simple-viewer`](../cad-simple-viewer): snapshot format, offline viewer runtime, and optional plugin integration. | Command | Description | |---------|-------------| | `-chtml` | Export via **command-line prompts** (no dialog; AutoCAD-style `-` prefix) | | `chtml` | Same as `-chtml` when no UI command is registered (e.g. `cad-simple-viewer` only). In [`cad-viewer`](../cad-viewer), `chtml` opens an **export options dialog** instead | The plugin path is designed for **lazy loading** so the export bundle is only downloaded when a user runs `-chtml` or confirms export from the `chtml` dialog (or runs `chtml` in a host that has no dialog command). Low-level APIs (`packHtml`, snapshot types, scene collectors) are also exported for custom pipelines and the headless CLI [`@mlightcad/cad-html-exporter-cli`](../cad-html-exporter-cli). ## Key features - **Display-only snapshot** — layers, layouts, line/mesh batches, extents, and drawing units (no editable DXF/DWG payload) - **Self-contained HTML** — gzip/base64 snapshot + inline viewer runtime; opens offline in any modern browser - **Offline viewer** — pan/zoom (OrbitControls), layer panel, layout switching, measurement, object snap (OSNAP) - **i18n** — embedded English / Chinese / Czech / Turkish UI; initial language follows the browser (`zh*` → Chinese, `cs*` → Czech, `tr*` → Turkish, otherwise English); the toolbar language button cycles through the supported locales, and the choice persists in `localStorage` - **Plugin API** — implements `AcApPlugin`; register once with `registerLazyHtmlPlugin` - **Composable API** — build snapshots from your own pipeline or call `packHtml` with a pre-built snapshot ## Installation ```bash pnpm add @mlightcad/cad-html-plugin ``` Peer dependencies: - `@mlightcad/cad-simple-viewer` (for `-chtml` / scene snapshot builder) - `@mlightcad/data-model` - `@mlightcad/three-renderer` - `three` Runtime dependency (bundled with this package): - `fflate` ## Build The package produces two artifacts: | Output | Description | |--------|-------------| | `dist/index.js` | Library entry (snapshot types, codec, `packHtml`, `createHtmlPlugin`, …) | | `dist/register.js` | Lightweight lazy-registration entry (safe for static import in app bundles) | | `dist/viewer-runtime.iife.js` | Offline viewer bootstrap (loaded/inlined into exported HTML) | ```bash pnpm --filter @mlightcad/cad-html-plugin build ``` Copy or serve `viewer-runtime.iife.js` from your app assets when using the browser export path (see **Integration** below). ## Usage ### Lazy registration (recommended) Register the plugin with the document manager's plugin manager. Import from the `/register` subpath so only the registration stub enters your initial bundle; the main plugin chunk loads on first use of `-chtml` or `chtml` (see command table above): ```typescript import { AcApDocManager } from '@mlightcad/cad-simple-viewer' import { registerLazyHtmlPlugin } from '@mlightcad/cad-html-plugin/register' AcApDocManager.createInstance({ container: document.getElementById('cad-container')!, htmlViewerRuntimeUrl: './viewer-runtime.iife.js' }) registerLazyHtmlPlugin(AcApDocManager.instance.pluginManager) ``` Do **not** import `registerLazyHtmlPlugin` from the package root (`@mlightcad/cad-html-plugin`) in application code — that resolves to the full library build and defeats lazy loading. After registration (command-line export): ```typescript await AcApDocManager.instance.editor.executeCommand('-chtml') // or AcApDocManager.instance.sendStringToExecute('-chtml') ``` In [`cad-viewer`](../cad-viewer), use `chtml` to open the export options dialog; `-chtml` remains available on the command line for prompt-based export. `cad-viewer` registers this plugin automatically via `registerLazyPlugins()` in its app bootstrap and registers the `chtml` dialog command separately. ### End-to-end export (command or convertor) ```typescript import { AcApHtmlConvertor } from '@mlightcad/cad-html-plugin' await new AcApHtmlConvertor().convert('my-drawing.dwg') ``` ### Low-level snapshot assembly ```typescript import { ACEX_SNAPSHOT_VERSION, type AcExSnapshotV1, buildViewerMetadata, collectBatchesFromObject3D, buildOsnapCatalog, packHtml, HTML_VIEWER_RUNTIME_FILE } from '@mlightcad/cad-html-plugin' const snapshot: AcExSnapshotV1 = /* built via AcApHtmlSnapshotBuilder or manually */ const runtime = await fetch(`./${HTML_VIEWER_RUNTIME_FILE}`).then(r => r.text()) const html = packHtml(snapshot, { title: 'My Drawing', viewerRuntime: runtime }) ``` ### Scene → snapshot (viewer integration) ```typescript import { AcApHtmlSnapshotBuilder } from '@mlightcad/cad-html-plugin' const snapshot = await new AcApHtmlSnapshotBuilder().buildAsync( view.cadScene, document.database, { title: 'Drawing', background: view.backgroundColor } ) ``` ### Headless / CLI For DXF/DWG → HTML without a browser UI, use [`@mlightcad/cad-html-exporter-cli`](../cad-html-exporter-cli). It runs the same snapshot + `packHtml` pipeline inside Playwright. ## Integration checklist When embedding HTML export in a web app: 1. Build `@mlightcad/cad-html-plugin` and expose `viewer-runtime.iife.js` at a URL your app can `fetch` (e.g. Vite `public/` copy — see `cad-viewer-example` / `cad-simple-viewer-example` vite configs). 2. Register via `@mlightcad/cad-html-plugin/register` (or load the plugin eagerly). 3. Optionally set `htmlViewerRuntimeUrl` on `AcApDocManager.createInstance()` to override the default `./viewer-runtime.iife.js` path. 4. Ensure fonts used by the drawing are reachable during export if you rely on web-font substitution. The generated HTML itself needs **no backend**; only the export step may fetch the runtime bundle and fonts. Subpath exports: ```typescript import { registerLazyHtmlPlugin } from '@mlightcad/cad-html-plugin/register' import '@mlightcad/cad-html-plugin/viewer-runtime' // dist/viewer-runtime.iife.js ``` ## Main exports | Export | Role | |--------|------| | `createHtmlPlugin` | Async factory used by the lazy loader | | `HTML_PLUGIN_NAME`, `HTML_PLUGIN_TRIGGERS` | Plugin id and command triggers | | `@mlightcad/cad-html-plugin/register` | `registerLazyHtmlPlugin` and registration constants | | `AcApExportHtmlCmd`, `AcApHtmlConvertor` | `-chtml` command and full export workflow | | `AcApHtmlSnapshotBuilder` | Live Three.js scene → `AcExSnapshotV1` | | `packHtml`, `AcExPackHtmlOptions` | Assemble HTML from snapshot + runtime source | | `HTML_VIEWER_RUNTIME_FILE` | Default runtime filename (`viewer-runtime.iife.js`) | | `AcExSnapshotV1`, `ACEX_SNAPSHOT_VERSION`, batch/layer types | Snapshot schema | | `encodeSnapshot`, `decodeSnapshot` | Gzip/base64 codec for embedded payloads | | `collectBatchesFromObject3D` | THREE.js scene → line/mesh batches | | `buildViewerMetadata` | Database → viewer meta (units, extents, background, …) | | `buildOsnapCatalog`, OSNAP primitive helpers | Analytic snap geometry for the offline viewer | | `AcExHtmlI18n`, `detectAcExHtmlLocale`, `detectBrowserAcExHtmlLocale`, `resolveAcExHtmlLocale` | Viewer UI strings and locale detection | ## Project layout | Path | Role | |------|------| | `src/register.ts` | Lazy plugin registration (`/register` entry) and `createHtmlPlugin` | | `src/AcApHtmlPlugin.ts` | Plugin lifecycle (`onLoad` / `onUnload`) | | `src/AcApExportHtmlCmd.ts` | `-chtml` command (command-line prompts) | | `src/AcApHtmlConvertor.ts` | Export orchestration (snapshot, runtime fetch, download) | | `src/AcApHtmlSnapshotBuilder.ts` | Three.js scene → snapshot builder | | `src/AcExSnapshotTypes.ts` | Snapshot schema (v1) | | `src/AcExSnapshotCodec.ts` | Encode/decode embedded snapshot script tag | | `src/AcExSceneBatchCollector.ts` | THREE.js traversal → export batches | | `src/AcExHtmlPackager.ts` | `packHtml` — shell + snapshot + runtime | | `src/AcExHtmlViewerRuntime.ts` | Offline viewer (built as IIFE) | | `src/AcExHtmlShell.ts` | Static HTML/CSS shell markup | | `src/AcExOsnap*.ts` | Object snap index and primitives | | `src/AcExMeasurement.ts` | Distance/area measurement in the offline viewer | | `src/AcExHtmlI18n.ts` | English / Chinese / Czech / Turkish UI messages | ## Role in MLightCAD This package combines the **export format / offline viewer runtime** with **viewer integration** (plugin, snapshot builder, `-chtml` command). `@mlightcad/cad-simple-viewer` stays free of HTML export code; heavy export logic can be lazy-loaded. [`cad-viewer`](../cad-viewer) adds a `chtml` dialog command on top. `@mlightcad/cad-html-exporter-cli` provides a Node/Playwright entry point for batch conversion. ## License MIT