orz-markdown 1.2.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -87,6 +87,25 @@ The bundled themes cover the parser's custom output, including:
87
87
 
88
88
  For a full list of provided themes and the underlying CSS class reference for theme authors, please read the [Themes Documentation](themes/README.md).
89
89
 
90
+ ### Embedding with your own CSS
91
+
92
+ Building a host app that renders with `md.render()` but supplies its **own**
93
+ stylesheet and page shell — a slide engine, a document viewer, an editor? Read
94
+ the **[embedding guide](orz-markdown-skills/references/embedding.md)**. It gathers
95
+ the full integration contract in one checklist: the CSS classes you must style
96
+ (and the gotcha where a host CSS reset, e.g. reveal.js, strips `strong`/`em`/
97
+ `sub`/`sup`), the JavaScript you must wire (the browser runtime for tabs/QR/copy,
98
+ plus loading and drawing mermaid/smiles/Chart.js yourself), and exactly what
99
+ copy-as-Markdown needs (the runtime, `.markdown-body`, and preserved `data-md`
100
+ breadcrumbs and plugin classes).
101
+
102
+ If your host mounts the rendered output in an `<iframe>`, the
103
+ `orz-markdown/preview-frame` export gives you a one-call helper —
104
+ `getPreviewFrameAssets()` returns the pinned CDN URLs, the browser runtime,
105
+ `headLinks(scheme)` / `bodyScripts()` strings, and a `window.__orzEnhance()` that
106
+ highlights code and draws Mermaid / SMILES / charts — so every host wires the
107
+ preview identically instead of re-deriving it.
108
+
90
109
  ## Packaging
91
110
 
92
111
  To rebuild distributable assets locally:
@@ -146,6 +165,7 @@ We utilize a generalized and uniform `{{plugin_name ...}}` syntax for all custom
146
165
  | **QR Code** | `qr` | `{{qr https://example.com}}` | Transforms text inline implicitly into an internally generated SVG QR Code natively. |
147
166
  | **Mermaid** | `mm` | `{{mermaid\ngraph LR\nA-->B\n}}` | Compiles logic into a specific preconfigured payload targeted for Mermaid client-side rendering. |
148
167
  | **SMILES Chemistry**| `sm` | `{{smiles C1=CC=CC=C1}}` | Embeds SMILES chemical formulas parsed specifically for `smilesDrawer` visualization. |
168
+ | **Chart** | N/A | `{{chart\ntype: bar\nlabels: A, B\ndata: 1, 2\n}}` | Declarative bar/line/pie/doughnut charts from a small line-based config (`type`, `labels`, `series: Name = …` or `data: …`, optional `title`). Rendered client-side with Chart.js. |
149
169
  | **YAML Objects** | `yml` | `{{yaml\ntitle: Doc\n}}` | Embeds the multiline YAML configuration blindly into an invisible `<script type="application/yaml">` block. |
150
170
  | **NYML Parser** | N/A | `{{nyml\nkey: value\n}}` | NYML-specific parser logic. Evaluates and injects the resulting properties as an invisible `<script type="application/json">` block. |
151
171
  | **Test** | N/A | `{{test-block}}` | Reserved testing elements for structural plugin resolution constraints. |
package/dist/index.d.ts CHANGED
@@ -6,6 +6,7 @@ import './plugins/space.js';
6
6
  import './plugins/youtube.js';
7
7
  import './plugins/mermaid.js';
8
8
  import './plugins/smiles.js';
9
+ import './plugins/chart.js';
9
10
  import './plugins/qrcode.js';
10
11
  import './plugins/yaml.js';
11
12
  import './plugins/nyml.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAC9B,OAAO,UAAU,MAAM,aAAa,CAAC;AAkBrC,OAAO,mBAAmB,CAAC;AAC3B,OAAO,oBAAoB,CAAC;AAC5B,OAAO,oBAAoB,CAAC;AAC5B,OAAO,sBAAsB,CAAC;AAC9B,OAAO,sBAAsB,CAAC;AAC9B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,mBAAmB,CAAC;AAC3B,OAAO,mBAAmB,CAAC;AAE3B,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,QAAA,MAAM,EAAE,YAMN,CAAC;AAsIH,eAAe,EAAE,CAAC;AAClB,OAAO,EAAE,EAAE,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAC9B,OAAO,UAAU,MAAM,aAAa,CAAC;AAkBrC,OAAO,mBAAmB,CAAC;AAC3B,OAAO,oBAAoB,CAAC;AAC5B,OAAO,oBAAoB,CAAC;AAC5B,OAAO,sBAAsB,CAAC;AAC9B,OAAO,sBAAsB,CAAC;AAC9B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,oBAAoB,CAAC;AAC5B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,mBAAmB,CAAC;AAC3B,OAAO,mBAAmB,CAAC;AAE3B,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,QAAA,MAAM,EAAE,YAMN,CAAC;AAsIH,eAAe,EAAE,CAAC;AAClB,OAAO,EAAE,EAAE,EAAE,CAAC"}
package/dist/index.js CHANGED
@@ -29,6 +29,7 @@ require("./plugins/space.js");
29
29
  require("./plugins/youtube.js");
30
30
  require("./plugins/mermaid.js");
31
31
  require("./plugins/smiles.js");
32
+ require("./plugins/chart.js");
32
33
  require("./plugins/qrcode.js");
33
34
  require("./plugins/yaml.js");
34
35
  require("./plugins/nyml.js");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=chart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart.d.ts","sourceRoot":"","sources":["../../src/plugins/chart.ts"],"names":[],"mappings":""}
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const registry_js_1 = require("../registry.js");
4
+ /*
5
+ * {{chart …}} — declarative chart blocks.
6
+ *
7
+ * The plugin parses a tiny, line-based config into a Chart.js-style config
8
+ * object and emits a single <canvas class="orz-chart"> carrying that config as
9
+ * HTML-escaped JSON in `data-chart`. It does NOT draw anything: the host's
10
+ * client runtime is expected to read `data-chart` and call Chart.js, exactly
11
+ * like smiles canvases are painted by smiles-drawer. A `data-md` breadcrumb
12
+ * carries the original {{chart …}} source so copy-as-markdown can recover it.
13
+ *
14
+ * Syntax (one directive per line, `key: value`):
15
+ *
16
+ * type: bar # bar | line | pie | doughnut | ... (default: bar)
17
+ * title: My Chart # optional chart title
18
+ * labels: Q1, Q2, Q3 # comma-separated x-axis / slice labels
19
+ * series: Revenue = 10, 14, 9, 17 # a named dataset (repeatable)
20
+ * series: Cost = 6, 7, 8, 9
21
+ *
22
+ * Single-series shorthand (no name needed):
23
+ *
24
+ * type: pie
25
+ * labels: A, B, C
26
+ * data: 30, 50, 20
27
+ *
28
+ * Unknown keys are ignored. Numbers parse with parseFloat; non-numeric values
29
+ * become null (a gap). On any parse failure the plugin degrades gracefully and
30
+ * emits an empty canvas carrying an `data-chart-error` attribute rather than
31
+ * throwing.
32
+ */
33
+ // Encode a value for a double-quoted HTML attribute, preserving newlines (as
34
+ // &#10;) so multi-line source survives in `data-md`.
35
+ function escapeAttr(str) {
36
+ return str
37
+ .replace(/&/g, '&amp;')
38
+ .replace(/"/g, '&quot;')
39
+ .replace(/</g, '&lt;')
40
+ .replace(/>/g, '&gt;')
41
+ .replace(/\n/g, '&#10;');
42
+ }
43
+ function parseNumberList(value) {
44
+ return value
45
+ .split(',')
46
+ .map((part) => part.trim())
47
+ .filter((part) => part.length > 0)
48
+ .map((part) => {
49
+ const n = Number.parseFloat(part);
50
+ return Number.isNaN(n) ? null : n;
51
+ });
52
+ }
53
+ function parseList(value) {
54
+ return value
55
+ .split(',')
56
+ .map((part) => part.trim())
57
+ .filter((part) => part.length > 0);
58
+ }
59
+ function parseChart(body) {
60
+ let type = 'bar';
61
+ let title = '';
62
+ let labels = [];
63
+ const datasets = [];
64
+ for (const rawLine of body.split('\n')) {
65
+ const line = rawLine.trim();
66
+ if (!line)
67
+ continue;
68
+ const colon = line.indexOf(':');
69
+ if (colon === -1)
70
+ continue;
71
+ const key = line.slice(0, colon).trim().toLowerCase();
72
+ const value = line.slice(colon + 1).trim();
73
+ switch (key) {
74
+ case 'type':
75
+ if (value)
76
+ type = value.toLowerCase();
77
+ break;
78
+ case 'title':
79
+ title = value;
80
+ break;
81
+ case 'labels':
82
+ labels = parseList(value);
83
+ break;
84
+ case 'data':
85
+ // single-series shorthand
86
+ datasets.push({ data: parseNumberList(value) });
87
+ break;
88
+ case 'series': {
89
+ const eq = value.indexOf('=');
90
+ if (eq === -1) {
91
+ datasets.push({ data: parseNumberList(value) });
92
+ }
93
+ else {
94
+ const name = value.slice(0, eq).trim();
95
+ const nums = parseNumberList(value.slice(eq + 1));
96
+ datasets.push({ label: name || undefined, data: nums });
97
+ }
98
+ break;
99
+ }
100
+ default:
101
+ // ignore unknown keys
102
+ break;
103
+ }
104
+ }
105
+ const config = {
106
+ type,
107
+ data: { labels, datasets },
108
+ };
109
+ if (title) {
110
+ config.options = {
111
+ plugins: { title: { display: true, text: title } },
112
+ };
113
+ }
114
+ return config;
115
+ }
116
+ (0, registry_js_1.register)({
117
+ type: 'block',
118
+ aliases: ['chart'],
119
+ render(_args, body, _env) {
120
+ const source = body?.trim() ?? '';
121
+ // `data-md` lets copy-as-markdown recover the source after the client
122
+ // runtime paints the <canvas> (which has no recoverable text content).
123
+ const directive = `{{chart\n${source}\n}}`;
124
+ const md = escapeAttr(directive);
125
+ let config;
126
+ try {
127
+ config = parseChart(source);
128
+ }
129
+ catch {
130
+ // Degrade gracefully: emit an empty, erroring canvas rather than throwing.
131
+ return `<canvas class="orz-chart" data-chart-error="parse error" data-md="${md}" width="600" height="400"></canvas>\n`;
132
+ }
133
+ const json = escapeAttr(JSON.stringify(config));
134
+ return `<canvas class="orz-chart" data-chart="${json}" data-md="${md}" width="600" height="400"></canvas>\n`;
135
+ },
136
+ });
137
+ //# sourceMappingURL=chart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart.js","sourceRoot":"","sources":["../../src/plugins/chart.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Preview-frame assets — one place that wires the orz-markdown preview the way
3
+ * `references/embedding.md` prescribes, so every host app (mdhtml, slides, paged,
4
+ * the editor) loads identical, tested CDN versions and runs the same
5
+ * highlight / mermaid / SMILES / chart / runtime steps instead of each
6
+ * re-deriving them (and drifting).
7
+ *
8
+ * Usage in a host that mounts rendered HTML in an <iframe>:
9
+ *
10
+ * import { getPreviewFrameAssets } from 'orz-markdown/preview-frame';
11
+ * const pa = getPreviewFrameAssets();
12
+ * const html =
13
+ * '<!doctype html><html><head><meta charset=utf8>' +
14
+ * '<link rel=stylesheet href="' + myThemeHref + '">' +
15
+ * pa.headLinks(scheme) + // KaTeX + highlight.js CSS
16
+ * '</head><body><article class="markdown-body" id="doc"></article>' +
17
+ * pa.bodyScripts() + // libs + runtime + __orzEnhance
18
+ * '</body></html>';
19
+ * // mount html in the iframe, then on every render:
20
+ * iframeWindow.__orzSmilesTheme = scheme; // 'dark' on dark themes
21
+ * doc.querySelector('.markdown-body').innerHTML = md.render(src);
22
+ * iframeWindow.__orzEnhance();
23
+ * // on theme change, swap the highlight.js stylesheet:
24
+ * doc.getElementById('orz-hljs').href = pa.hljsCss(scheme);
25
+ */
26
+ export type ColorScheme = 'light' | 'dark';
27
+ /** Pinned CDN URLs for the preview-iframe assets (one source of truth). */
28
+ export declare const PREVIEW_CDN: {
29
+ readonly katexCss: "https://cdn.jsdelivr.net/npm/katex@0.16.35/dist/katex.min.css";
30
+ readonly hljsJs: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js";
31
+ readonly hljsLightCss: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css";
32
+ readonly hljsDarkCss: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css";
33
+ readonly mermaidJs: "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js";
34
+ readonly smilesJs: "https://unpkg.com/smiles-drawer@1.0.10/dist/smiles-drawer.min.js";
35
+ readonly chartJs: "https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js";
36
+ };
37
+ export interface PreviewFrameAssets {
38
+ /** Pinned CDN URLs. */
39
+ cdn: typeof PREVIEW_CDN;
40
+ /** The orz browser runtime source (copy-as-Markdown + tabs + QR expand). */
41
+ runtimeScript: string;
42
+ /** highlight.js stylesheet URL for a scheme (swap `#orz-hljs`.href on theme change). */
43
+ hljsCss(scheme?: ColorScheme): string;
44
+ /** `<link>` tags for the iframe `<head>`: KaTeX + highlight.js CSS for the scheme.
45
+ * The highlight.js link carries `id="orz-hljs"` for swapping. */
46
+ headLinks(scheme?: ColorScheme): string;
47
+ /** `<script>` tags for the iframe `<body>`: load the libs + the runtime and
48
+ * define `window.__orzEnhance()`. Call `__orzEnhance()` after each render
49
+ * (set `window.__orzSmilesTheme='dark'` first on dark themes). */
50
+ bodyScripts(): string;
51
+ }
52
+ /**
53
+ * Everything a host app needs to wire the orz-markdown preview iframe the way the
54
+ * bundled themes and tested apps do: the copy-as-Markdown runtime, code
55
+ * highlighting, mermaid / SMILES / chart drawing, tabs, and QR expand.
56
+ * See `references/embedding.md`.
57
+ */
58
+ export declare function getPreviewFrameAssets(): PreviewFrameAssets;
59
+ //# sourceMappingURL=preview-frame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-frame.d.ts","sourceRoot":"","sources":["../src/preview-frame.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3C,2EAA2E;AAC3E,eAAO,MAAM,WAAW;;;;;;;;CAQd,CAAC;AAoBX,MAAM,WAAW,kBAAkB;IACjC,uBAAuB;IACvB,GAAG,EAAE,OAAO,WAAW,CAAC;IACxB,4EAA4E;IAC5E,aAAa,EAAE,MAAM,CAAC;IACtB,wFAAwF;IACxF,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IACtC;sEACkE;IAClE,SAAS,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IACxC;;uEAEmE;IACnE,WAAW,IAAI,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,kBAAkB,CA6B1D"}
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ /**
3
+ * Preview-frame assets — one place that wires the orz-markdown preview the way
4
+ * `references/embedding.md` prescribes, so every host app (mdhtml, slides, paged,
5
+ * the editor) loads identical, tested CDN versions and runs the same
6
+ * highlight / mermaid / SMILES / chart / runtime steps instead of each
7
+ * re-deriving them (and drifting).
8
+ *
9
+ * Usage in a host that mounts rendered HTML in an <iframe>:
10
+ *
11
+ * import { getPreviewFrameAssets } from 'orz-markdown/preview-frame';
12
+ * const pa = getPreviewFrameAssets();
13
+ * const html =
14
+ * '<!doctype html><html><head><meta charset=utf8>' +
15
+ * '<link rel=stylesheet href="' + myThemeHref + '">' +
16
+ * pa.headLinks(scheme) + // KaTeX + highlight.js CSS
17
+ * '</head><body><article class="markdown-body" id="doc"></article>' +
18
+ * pa.bodyScripts() + // libs + runtime + __orzEnhance
19
+ * '</body></html>';
20
+ * // mount html in the iframe, then on every render:
21
+ * iframeWindow.__orzSmilesTheme = scheme; // 'dark' on dark themes
22
+ * doc.querySelector('.markdown-body').innerHTML = md.render(src);
23
+ * iframeWindow.__orzEnhance();
24
+ * // on theme change, swap the highlight.js stylesheet:
25
+ * doc.getElementById('orz-hljs').href = pa.hljsCss(scheme);
26
+ */
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.PREVIEW_CDN = void 0;
29
+ exports.getPreviewFrameAssets = getPreviewFrameAssets;
30
+ const runtime_js_1 = require("./runtime.js");
31
+ /** Pinned CDN URLs for the preview-iframe assets (one source of truth). */
32
+ exports.PREVIEW_CDN = {
33
+ katexCss: 'https://cdn.jsdelivr.net/npm/katex@0.16.35/dist/katex.min.css',
34
+ hljsJs: 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js',
35
+ hljsLightCss: 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css',
36
+ hljsDarkCss: 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css',
37
+ mermaidJs: 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js',
38
+ smilesJs: 'https://unpkg.com/smiles-drawer@1.0.10/dist/smiles-drawer.min.js',
39
+ chartJs: 'https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js',
40
+ };
41
+ /** Guard inline <script> content against premature `</script>` termination. */
42
+ function guard(js) {
43
+ return js.replace(/<\/(script)/gi, '<\\/$1');
44
+ }
45
+ /* Body of window.__orzEnhance(). Scoped to .markdown-body so it works whatever
46
+ * id/wrapper the host gives the rendered region. Idempotent: highlight/tabs/QR
47
+ * skip already-processed nodes, SMILES/chart track a JS flag. SMILES honors
48
+ * window.__orzSmilesTheme ('dark' → light bonds); reset its flag and re-run to
49
+ * redraw after a theme switch. */
50
+ const ENHANCE_BODY = "var R='.markdown-body ';" +
51
+ "try{if(window.hljs)document.querySelectorAll(R+'pre code:not(.hljs)').forEach(function(b){window.hljs.highlightElement(b)})}catch(e){}" +
52
+ "try{if(window.mermaid)window.mermaid.run({nodes:document.querySelectorAll(R+'.mermaid:not([data-processed])')})}catch(e){}" +
53
+ "try{if(window.SmilesDrawer)document.querySelectorAll(R+'canvas[data-smiles]').forEach(function(v){if(v.__d)return;v.__d=1;if(v.__ow===undefined){v.__ow=v.width;v.__oh=v.height}v.width=v.__ow;v.height=v.__oh;var d=new window.SmilesDrawer.Drawer({width:v.__ow,height:v.__oh});window.SmilesDrawer.parse(v.getAttribute('data-smiles'),function(t){try{d.draw(t,v,window.__orzSmilesTheme||'light',false)}catch(e){}})})}catch(e){}" +
54
+ "try{if(window.Chart)document.querySelectorAll(R+'canvas.orz-chart[data-chart]').forEach(function(v){if(v.__d)return;v.__d=1;var w=v.ownerDocument.createElement('div');w.style.cssText='position:relative;width:100%;max-width:440px;margin:.4em auto';v.parentNode.insertBefore(w,v);w.appendChild(v);v.removeAttribute('width');v.removeAttribute('height');try{var g=JSON.parse(v.getAttribute('data-chart')||'{}');g.options=Object.assign({responsive:true,maintainAspectRatio:true,animation:false},g.options||{});new window.Chart(v,g)}catch(e){}})}catch(e){}" +
55
+ "try{if(window.OrzMarkdownRuntime)window.OrzMarkdownRuntime.init(document)}catch(e){}";
56
+ /**
57
+ * Everything a host app needs to wire the orz-markdown preview iframe the way the
58
+ * bundled themes and tested apps do: the copy-as-Markdown runtime, code
59
+ * highlighting, mermaid / SMILES / chart drawing, tabs, and QR expand.
60
+ * See `references/embedding.md`.
61
+ */
62
+ function getPreviewFrameAssets() {
63
+ const cdn = exports.PREVIEW_CDN;
64
+ const runtimeScript = (0, runtime_js_1.getBrowserRuntimeScript)();
65
+ return {
66
+ cdn,
67
+ runtimeScript,
68
+ hljsCss(scheme = 'light') {
69
+ return scheme === 'dark' ? cdn.hljsDarkCss : cdn.hljsLightCss;
70
+ },
71
+ headLinks(scheme = 'light') {
72
+ return ('<link rel="stylesheet" href="' + cdn.katexCss + '">' +
73
+ '<link id="orz-hljs" rel="stylesheet" href="' +
74
+ (scheme === 'dark' ? cdn.hljsDarkCss : cdn.hljsLightCss) +
75
+ '">');
76
+ },
77
+ bodyScripts() {
78
+ return ('<script src="' + cdn.hljsJs + '"></script>' +
79
+ '<script src="' + cdn.mermaidJs + '"></script>' +
80
+ '<script src="' + cdn.smilesJs + '"></script>' +
81
+ '<script src="' + cdn.chartJs + '"></script>' +
82
+ '<script>try{mermaid.initialize({startOnLoad:false})}catch(e){}</script>' +
83
+ '<script>' + guard(runtimeScript) + '</script>' +
84
+ '<script>window.__orzEnhance=function(){' + ENHANCE_BODY + '\n};</script>');
85
+ },
86
+ };
87
+ }
88
+ //# sourceMappingURL=preview-frame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-frame.js","sourceRoot":"","sources":["../src/preview-frame.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;;;AAyDH,sDA6BC;AApFD,6CAAuD;AAIvD,2EAA2E;AAC9D,QAAA,WAAW,GAAG;IACzB,QAAQ,EAAE,+DAA+D;IACzE,MAAM,EAAE,6EAA6E;IACrF,YAAY,EAAE,kFAAkF;IAChG,WAAW,EAAE,yFAAyF;IACtG,SAAS,EAAE,6DAA6D;IACxE,QAAQ,EAAE,kEAAkE;IAC5E,OAAO,EAAE,+DAA+D;CAChE,CAAC;AAEX,+EAA+E;AAC/E,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,EAAE,CAAC,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;AAC/C,CAAC;AAED;;;;kCAIkC;AAClC,MAAM,YAAY,GAChB,0BAA0B;IAC1B,wIAAwI;IACxI,4HAA4H;IAC5H,waAAwa;IACxa,wiBAAwiB;IACxiB,sFAAsF,CAAC;AAkBzF;;;;;GAKG;AACH,SAAgB,qBAAqB;IACnC,MAAM,GAAG,GAAG,mBAAW,CAAC;IACxB,MAAM,aAAa,GAAG,IAAA,oCAAuB,GAAE,CAAC;IAChD,OAAO;QACL,GAAG;QACH,aAAa;QACb,OAAO,CAAC,SAAsB,OAAO;YACnC,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC;QAChE,CAAC;QACD,SAAS,CAAC,SAAsB,OAAO;YACrC,OAAO,CACL,+BAA+B,GAAG,GAAG,CAAC,QAAQ,GAAG,IAAI;gBACrD,6CAA6C;gBAC7C,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC;gBACxD,IAAI,CACL,CAAC;QACJ,CAAC;QACD,WAAW;YACT,OAAO,CACL,eAAe,GAAG,GAAG,CAAC,MAAM,GAAG,aAAa;gBAC5C,eAAe,GAAG,GAAG,CAAC,SAAS,GAAG,aAAa;gBAC/C,eAAe,GAAG,GAAG,CAAC,QAAQ,GAAG,aAAa;gBAC9C,eAAe,GAAG,GAAG,CAAC,OAAO,GAAG,aAAa;gBAC7C,yEAAyE;gBACzE,UAAU,GAAG,KAAK,CAAC,aAAa,CAAC,GAAG,WAAW;gBAC/C,yCAAyC,GAAG,YAAY,GAAG,eAAe,CAC3E,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,QA+ehC,CAAC;AAEF,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,QA+iBhC,CAAC;AAEF,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD"}
package/dist/runtime.js CHANGED
@@ -191,6 +191,9 @@ exports.browserRuntimeScript = String.raw `
191
191
  case 'br': return ' \n';
192
192
  case 'img': return rt_img(node);
193
193
  case 'input': return '';
194
+ case 'span':
195
+ var spCls = (rt_attr(node, 'class') || '').trim();
196
+ return spCls ? '{{sp[' + spCls + '] ' + rt_inlineChildren(node) + '}}' : rt_inlineChildren(node);
194
197
  default: return rt_inlineChildren(node);
195
198
  }
196
199
  }
@@ -346,6 +349,53 @@ exports.browserRuntimeScript = String.raw `
346
349
  return parts.join('\n\n');
347
350
  }
348
351
 
352
+ var rt_containerNames = ['info', 'success', 'warning', 'danger', 'left', 'right', 'center', 'cols', 'col', 'tabs', 'tab'];
353
+ // A markdown-it-container div.name (or details.spoil) -> its ::: name
354
+ // directive name, or null if the node is not a container.
355
+ function rt_containerName(node) {
356
+ if (node.nodeType !== 1 || !node.classList) return null;
357
+ var tag = node.tagName.toLowerCase();
358
+ if (tag === 'details' && node.classList.contains('spoil')) {
359
+ var sum = node.querySelector ? node.querySelector('summary') : null;
360
+ var title = sum ? (sum.textContent || '').trim() : '';
361
+ return title ? 'spoil ' + title : 'spoil';
362
+ }
363
+ if (tag !== 'div') return null;
364
+ for (var i = 0; i < rt_containerNames.length; i++) {
365
+ var n = rt_containerNames[i];
366
+ if (node.classList.contains(n)) {
367
+ if (n === 'tab') { var lbl = rt_attr(node, 'data-label'); return lbl ? 'tab ' + lbl : 'tab'; }
368
+ return n;
369
+ }
370
+ }
371
+ return null;
372
+ }
373
+ // Emit a ::: name ... ::: block, using a fence longer than any inner fence so
374
+ // nested containers (cols > col, tabs > tab) re-parse correctly.
375
+ function rt_containerMd(node, name) {
376
+ var parts = [];
377
+ var kids = node.childNodes;
378
+ for (var i = 0; i < kids.length; i++) {
379
+ var k = kids[i];
380
+ if (k.nodeType === 1) {
381
+ var ktag = k.tagName.toLowerCase();
382
+ if (ktag === 'summary') continue; // spoil title, captured in the name
383
+ if (k.classList && k.classList.contains('tabs-bar')) continue; // JS-injected tab buttons
384
+ }
385
+ var m = rt_blockNode(k);
386
+ if (m && m.trim()) parts.push(m.trim());
387
+ }
388
+ var inner = parts.join('\n\n');
389
+ var maxFence = 2;
390
+ var lines = inner.split('\n');
391
+ for (var j = 0; j < lines.length; j++) {
392
+ var mm = lines[j].match(/^(:{3,})/);
393
+ if (mm && mm[1].length > maxFence) maxFence = mm[1].length;
394
+ }
395
+ var fence = rt_repeat(':', Math.max(3, maxFence + 1));
396
+ return fence + ' ' + name + '\n' + inner + '\n' + fence;
397
+ }
398
+
349
399
  function rt_blockNode(node) {
350
400
  if (node.nodeType === 3) {
351
401
  var t = node.nodeValue;
@@ -355,7 +405,10 @@ exports.browserRuntimeScript = String.raw `
355
405
  var dm = rt_attr(node, 'data-md');
356
406
  if (dm != null) return dm;
357
407
  if (node.classList) {
358
- if (node.classList.contains('katex-display')) {
408
+ // Display math: the katex-display span OR its katex-block <p> wrapper.
409
+ // Without this the wrapper is walked as a paragraph and the inner katex is
410
+ // emitted as inline math instead of a block equation.
411
+ if (node.classList.contains('katex-display') || node.classList.contains('katex-block')) {
359
412
  var k = node.querySelector ? node.querySelector('.katex') : null;
360
413
  return rt_katex(k || node, true);
361
414
  }
@@ -374,6 +427,8 @@ exports.browserRuntimeScript = String.raw `
374
427
  case 'hr': return '---';
375
428
  case 'li': return rt_inlineChildren(node).trim();
376
429
  case 'figure': case 'div': case 'section': case 'article': case 'details': case 'summary':
430
+ var cn = rt_containerName(node);
431
+ if (cn) return rt_containerMd(node, cn);
377
432
  return rt_blockChildren(node);
378
433
  default: return rt_inlineNode(node).trim();
379
434
  }
@@ -414,18 +469,27 @@ exports.browserRuntimeScript = String.raw `
414
469
  return false;
415
470
  }
416
471
 
417
- // When a selection sits entirely within one table/blockquote/pre, copy that
418
- // whole block: a partial table/quote/code fragment isn't valid Markdown, and
419
- // browsers often clone such selections without the wrapping element.
472
+ // When a selection sits entirely within one table/blockquote/pre or inside a
473
+ // ::: container — copy that whole block, so the wrapper is included (a partial
474
+ // table/quote fragment isn't valid Markdown, and a copied container should keep
475
+ // its ::: fence). Browsers often clone such selections without the wrapper.
476
+ // Tables/quotes/code don't nest, so the innermost wins; containers DO nest
477
+ // (cols > col, tabs > tab), so promote to the OUTERMOST one.
420
478
  function rt_promotableBlock(node) {
479
+ var container = null;
421
480
  while (node && !rt_isCopyRoot(node)) {
422
481
  if (node.nodeType === 1) {
423
482
  var tag = node.tagName.toLowerCase();
424
483
  if (tag === 'table' || tag === 'blockquote' || tag === 'pre') return node;
484
+ // A selection inside a display equation copies the whole block equation;
485
+ // a partial KaTeX fragment is not valid Markdown.
486
+ if (node.classList &&
487
+ (node.classList.contains('katex-block') || node.classList.contains('katex-display'))) return node;
488
+ if (rt_containerName(node)) container = node;
425
489
  }
426
490
  node = node.parentNode;
427
491
  }
428
- return null;
492
+ return container;
429
493
  }
430
494
 
431
495
  function onCopy(event) {
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":";;;AAifA,0DAEC;AAnfY,QAAA,oBAAoB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+e7C,CAAC;AAEF,SAAgB,uBAAuB;IACrC,OAAO,4BAAoB,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":";;;AAijBA,0DAEC;AAnjBY,QAAA,oBAAoB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+iB7C,CAAC;AAEF,SAAgB,uBAAuB;IACrC,OAAO,4BAAoB,CAAC;AAC9B,CAAC"}
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: orz-markdown
3
- description: "orz-markdown usage skill. Use this skill whenever you need to render markdown with this parser, write markdown that uses {{...}} custom plugin syntax (mermaid, qrcode, youtube, smiles, toc, span, emoji, attrs, space, yaml, nyml, or their aliases mm/qr/yt/sm/sp/em), use :::container syntax (success/info/warning/danger/spoil/tabs/tab/cols/col/left/right/center), set up a complete HTML page to display parser output, choose or import one of the 10 bundled CSS themes, or create a custom theme stylesheet. Also invoke when asked about .markdown-body class, prepareSources, browser runtime scripts for QR codes or tabs, or any KaTeX math syntax in this project. ALWAYS invoke before editing documents whose headings carry stable block IDs ({{attrs[#blk-...]}})."
3
+ description: "orz-markdown usage skill. Use this skill whenever you need to render markdown with this parser, write markdown that uses {{...}} custom plugin syntax (mermaid, chart, qrcode, youtube, smiles, toc, span, emoji, attrs, space, yaml, nyml, or their aliases mm/qr/yt/sm/sp/em), use :::container syntax (success/info/warning/danger/spoil/tabs/tab/cols/col/left/right/center), set up a complete HTML page to display parser output, choose or import one of the 12 bundled CSS themes, or create a custom theme stylesheet. Also invoke when asked about .markdown-body class, prepareSources, browser runtime scripts for QR codes or tabs, or any KaTeX math syntax in this project. ALWAYS invoke before editing documents whose headings carry stable block IDs ({{attrs[#blk-...]}})."
4
4
  compatibility:
5
5
  runtime: "Node.js 20+, ESM"
6
6
  package: "orz-markdown"
@@ -8,7 +8,7 @@ compatibility:
8
8
 
9
9
  # orz-markdown
10
10
 
11
- A deeply customized `markdown-it` instance with 10+ plugins, 9 official plugin bundles, and 10 ready-to-use CSS themes. All rendered HTML lives inside `<article class="markdown-body">`.
11
+ A deeply customized `markdown-it` instance with 10+ plugins, 9 official plugin bundles, and 12 ready-to-use CSS themes. All rendered HTML lives inside `<article class="markdown-body">`.
12
12
 
13
13
  ## Rendering (Node.js / ESM)
14
14
 
@@ -46,6 +46,8 @@ Every page that displays parser output needs **all five** of these:
46
46
 
47
47
  **Use `assets/template.html`** — all CDN links, scripts, and the `.markdown-body` wrapper are pre-wired. Copy it and replace the `<!-- INSERT RENDERED HTML HERE -->` comment.
48
48
 
49
+ **Mounting output in an `<iframe>` (viewer / editor / slide or page engine)?** Call `getPreviewFrameAssets()` from `orz-markdown/preview-frame` — it returns the pinned CDN URLs, the runtime, `headLinks(scheme)` / `bodyScripts()` strings, and a `window.__orzEnhance()` that does all of items 3–5 (highlight code, draw mermaid/SMILES/charts, init tabs + QR). One call instead of re-deriving the wiring. See `references/embedding.md`.
50
+
49
51
  CDN URLs (pinned versions):
50
52
  | Library | URL |
51
53
  |---|---|
@@ -75,14 +77,16 @@ The runtime also provides **copy-as-Markdown**: with it loaded, copying a select
75
77
 
76
78
  ## Themes
77
79
 
78
- Ten bundled themes — each auto-imports `common.css` (structural rules for tables, images, QR overlays, print).
80
+ Twelve bundled themes — each auto-imports `common.css` (structural rules for tables, images, QR overlays, print).
79
81
 
80
82
  | File | Style | Scheme |
81
83
  |---|---|---|
82
84
  | `dark-elegant-1.css` | Cinzel headings · scholarly serif | Dark |
83
85
  | `dark-elegant-2.css` | Dark elegant variant | Dark |
86
+ | `dark-elegant-3.css` | Lora · VS Code-dark, colourful headings "Nocturne" | Dark |
84
87
  | `light-neat-1.css` | Figtree · clean modern sans | Light |
85
88
  | `light-neat-2.css` | Light neat variant | Light |
89
+ | `light-neat-3.css` | Bricolage · calm green "Orchard" | Light |
86
90
  | `beige-decent-1.css` | Warm beige · print-like prose | Light |
87
91
  | `beige-decent-2.css` | Beige decent variant | Light |
88
92
  | `light-academic-1.css` | Alegreya · justified scholarly prose | Light |
@@ -98,7 +102,7 @@ import 'orz-markdown/themes/light-neat-1.css';
98
102
  // <link rel="stylesheet" href="node_modules/orz-markdown/themes/light-neat-1.css">
99
103
  ```
100
104
 
101
- For custom themes start from `assets/minimal.css` (structural only, no decoration) and add your visual layer. See `references/themes.md` for the design token pattern, element checklist, and design guidelines. See `references/css-classes.md` for the full list of every CSS class the parser emits.
105
+ For custom themes start from `assets/minimal.css` (structural only, no decoration) and add your visual layer. See `references/themes.md` for the design token pattern, element checklist, and design guidelines. See `references/css-classes.md` for the full list of every CSS class the parser emits. **Building a host app that supplies its own CSS and page shell (a slide engine, viewer, or editor)?** Read `references/embedding.md` — it gathers the CSS contract, the JS runtime + diagram-drawing duties, and the copy-as-Markdown requirements into one checklist (and the non-obvious gotchas, like a host CSS reset stripping bold/sub/sup).
102
106
 
103
107
  ---
104
108
 
@@ -120,6 +124,7 @@ Escape with backslash: `\{{name}}` renders as literal `{{name}}`.
120
124
  | **youtube** | `yt` | `{{youtube dQw4w9WgXcQ}}` (responsive iframe) |
121
125
  | **mermaid** | `mm` | `{{mm\ngraph LR\nA-->B\n}}` |
122
126
  | **smiles** | `sm` | `{{smiles C1=CC=CC=C1}}` (chemical structure) |
127
+ | **chart** | — | `{{chart\ntype: bar\nlabels: A, B\ndata: 1, 2\n}}` (Chart.js bar/line/pie/doughnut) |
123
128
  | **toc** | — | `{{toc}}` or `{{toc 2,3}}` (heading levels) |
124
129
  | **attrs** | — | `# Title{{attrs[id="hero"]}}` |
125
130
  | **markdown** | `md`, `md-include` | `{{md ./path/to/file.md}}` |
@@ -175,5 +180,6 @@ Documents may carry stable block IDs on headings: `## Title{{attrs[#blk-abc12345
175
180
  | `references/block-ids.md` | Stable block-ID preservation rules — REQUIRED reading before editing documents that use `{{attrs[#blk-...]}}` |
176
181
  | `references/themes.md` | Custom theme guide: design tokens, element checklist, 10 design guidelines |
177
182
  | `references/css-classes.md` | Every CSS class and HTML element the parser emits — the spec for theme authors |
183
+ | `references/embedding.md` | Host-integration guide for apps that bring their own CSS/shell (slide engines, viewers, editors): the CSS contract + reset gotchas, the JS runtime + diagram drawing, and what copy-as-Markdown needs |
178
184
  | `assets/template.html` | Ready-to-use HTML page template with all scripts and CDN links wired up |
179
185
  | `assets/minimal.css` | Structural-only stylesheet — starting point for custom themes |
@@ -19,8 +19,8 @@
19
19
 
20
20
  <!-- Parser stylesheet — choose one of the bundled themes or link your own.
21
21
  Bundled themes (each imports common.css automatically):
22
- dark-elegant-1.css dark-elegant-2.css
23
- light-neat-1.css light-neat-2.css
22
+ dark-elegant-1.css dark-elegant-2.css dark-elegant-3.css
23
+ light-neat-1.css light-neat-2.css light-neat-3.css
24
24
  beige-decent-1.css beige-decent-2.css
25
25
  light-academic-1.css light-academic-2.css
26
26
  light-playful-1.css light-playful-2.css